1 | /* |
2 | * QEMU KVM support -- ARM specific functions. |
3 | * |
4 | * Copyright (c) 2012 Linaro Limited |
5 | * |
6 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
7 | * See the COPYING file in the top-level directory. |
8 | * |
9 | */ |
10 | |
11 | #ifndef QEMU_KVM_ARM_H |
12 | #define QEMU_KVM_ARM_H |
13 | |
14 | #include "sysemu/kvm.h" |
15 | #include "exec/memory.h" |
16 | #include "qemu/error-report.h" |
17 | |
18 | /** |
19 | * kvm_arm_vcpu_init: |
20 | * @cs: CPUState |
21 | * |
22 | * Initialize (or reinitialize) the VCPU by invoking the |
23 | * KVM_ARM_VCPU_INIT ioctl with the CPU type and feature |
24 | * bitmask specified in the CPUState. |
25 | * |
26 | * Returns: 0 if success else < 0 error code |
27 | */ |
28 | int kvm_arm_vcpu_init(CPUState *cs); |
29 | |
30 | /** |
31 | * kvm_arm_register_device: |
32 | * @mr: memory region for this device |
33 | * @devid: the KVM device ID |
34 | * @group: device control API group for setting addresses |
35 | * @attr: device control API address type |
36 | * @dev_fd: device control device file descriptor (or -1 if not supported) |
37 | * @addr_ormask: value to be OR'ed with resolved address |
38 | * |
39 | * Remember the memory region @mr, and when it is mapped by the |
40 | * machine model, tell the kernel that base address using the |
41 | * KVM_ARM_SET_DEVICE_ADDRESS ioctl or the newer device control API. @devid |
42 | * should be the ID of the device as defined by KVM_ARM_SET_DEVICE_ADDRESS or |
43 | * the arm-vgic device in the device control API. |
44 | * The machine model may map |
45 | * and unmap the device multiple times; the kernel will only be told the final |
46 | * address at the point where machine init is complete. |
47 | */ |
48 | void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group, |
49 | uint64_t attr, int dev_fd, uint64_t addr_ormask); |
50 | |
51 | /** |
52 | * kvm_arm_init_cpreg_list: |
53 | * @cpu: ARMCPU |
54 | * |
55 | * Initialize the ARMCPU cpreg list according to the kernel's |
56 | * definition of what CPU registers it knows about (and throw away |
57 | * the previous TCG-created cpreg list). |
58 | * |
59 | * Returns: 0 if success, else < 0 error code |
60 | */ |
61 | int kvm_arm_init_cpreg_list(ARMCPU *cpu); |
62 | |
63 | /** |
64 | * kvm_arm_reg_syncs_via_cpreg_list |
65 | * regidx: KVM register index |
66 | * |
67 | * Return true if this KVM register should be synchronized via the |
68 | * cpreg list of arbitrary system registers, false if it is synchronized |
69 | * by hand using code in kvm_arch_get/put_registers(). |
70 | */ |
71 | bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx); |
72 | |
73 | /** |
74 | * kvm_arm_cpreg_level |
75 | * regidx: KVM register index |
76 | * |
77 | * Return the level of this coprocessor/system register. Return value is |
78 | * either KVM_PUT_RUNTIME_STATE, KVM_PUT_RESET_STATE, or KVM_PUT_FULL_STATE. |
79 | */ |
80 | int kvm_arm_cpreg_level(uint64_t regidx); |
81 | |
82 | /** |
83 | * write_list_to_kvmstate: |
84 | * @cpu: ARMCPU |
85 | * @level: the state level to sync |
86 | * |
87 | * For each register listed in the ARMCPU cpreg_indexes list, write |
88 | * its value from the cpreg_values list into the kernel (via ioctl). |
89 | * This updates KVM's working data structures from TCG data or |
90 | * from incoming migration state. |
91 | * |
92 | * Returns: true if all register values were updated correctly, |
93 | * false if some register was unknown to the kernel or could not |
94 | * be written (eg constant register with the wrong value). |
95 | * Note that we do not stop early on failure -- we will attempt |
96 | * writing all registers in the list. |
97 | */ |
98 | bool write_list_to_kvmstate(ARMCPU *cpu, int level); |
99 | |
100 | /** |
101 | * write_kvmstate_to_list: |
102 | * @cpu: ARMCPU |
103 | * |
104 | * For each register listed in the ARMCPU cpreg_indexes list, write |
105 | * its value from the kernel into the cpreg_values list. This is used to |
106 | * copy info from KVM's working data structures into TCG or |
107 | * for outbound migration. |
108 | * |
109 | * Returns: true if all register values were read correctly, |
110 | * false if some register was unknown or could not be read. |
111 | * Note that we do not stop early on failure -- we will attempt |
112 | * reading all registers in the list. |
113 | */ |
114 | bool write_kvmstate_to_list(ARMCPU *cpu); |
115 | |
116 | /** |
117 | * kvm_arm_reset_vcpu: |
118 | * @cpu: ARMCPU |
119 | * |
120 | * Called at reset time to kernel registers to their initial values. |
121 | */ |
122 | void kvm_arm_reset_vcpu(ARMCPU *cpu); |
123 | |
124 | /** |
125 | * kvm_arm_init_serror_injection: |
126 | * @cs: CPUState |
127 | * |
128 | * Check whether KVM can set guest SError syndrome. |
129 | */ |
130 | void kvm_arm_init_serror_injection(CPUState *cs); |
131 | |
132 | /** |
133 | * kvm_get_vcpu_events: |
134 | * @cpu: ARMCPU |
135 | * |
136 | * Get VCPU related state from kvm. |
137 | */ |
138 | int kvm_get_vcpu_events(ARMCPU *cpu); |
139 | |
140 | /** |
141 | * kvm_put_vcpu_events: |
142 | * @cpu: ARMCPU |
143 | * |
144 | * Put VCPU related state to kvm. |
145 | */ |
146 | int kvm_put_vcpu_events(ARMCPU *cpu); |
147 | |
148 | #ifdef CONFIG_KVM |
149 | /** |
150 | * kvm_arm_create_scratch_host_vcpu: |
151 | * @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with |
152 | * QEMU_KVM_ARM_TARGET_NONE) to try as fallback if the kernel does not |
153 | * know the PREFERRED_TARGET ioctl. Passing NULL is the same as passing |
154 | * an empty array. |
155 | * @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order |
156 | * @init: filled in with the necessary values for creating a host |
157 | * vcpu. If NULL is provided, will not init the vCPU (though the cpufd |
158 | * will still be set up). |
159 | * |
160 | * Create a scratch vcpu in its own VM of the type preferred by the host |
161 | * kernel (as would be used for '-cpu host'), for purposes of probing it |
162 | * for capabilities. |
163 | * |
164 | * Returns: true on success (and fdarray and init are filled in), |
165 | * false on failure (and fdarray and init are not valid). |
166 | */ |
167 | bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, |
168 | int *fdarray, |
169 | struct kvm_vcpu_init *init); |
170 | |
171 | /** |
172 | * kvm_arm_destroy_scratch_host_vcpu: |
173 | * @fdarray: array of fds as set up by kvm_arm_create_scratch_host_vcpu |
174 | * |
175 | * Tear down the scratch vcpu created by kvm_arm_create_scratch_host_vcpu. |
176 | */ |
177 | void kvm_arm_destroy_scratch_host_vcpu(int *fdarray); |
178 | |
179 | #define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU |
180 | |
181 | /** |
182 | * ARMHostCPUFeatures: information about the host CPU (identified |
183 | * by asking the host kernel) |
184 | */ |
185 | typedef struct ARMHostCPUFeatures { |
186 | ARMISARegisters isar; |
187 | uint64_t features; |
188 | uint32_t target; |
189 | const char *dtb_compatible; |
190 | } ARMHostCPUFeatures; |
191 | |
192 | /** |
193 | * kvm_arm_get_host_cpu_features: |
194 | * @ahcc: ARMHostCPUClass to fill in |
195 | * |
196 | * Probe the capabilities of the host kernel's preferred CPU and fill |
197 | * in the ARMHostCPUClass struct accordingly. |
198 | */ |
199 | bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf); |
200 | |
201 | /** |
202 | * kvm_arm_set_cpu_features_from_host: |
203 | * @cpu: ARMCPU to set the features for |
204 | * |
205 | * Set up the ARMCPU struct fields up to match the information probed |
206 | * from the host CPU. |
207 | */ |
208 | void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); |
209 | |
210 | /** |
211 | * kvm_arm_aarch32_supported: |
212 | * @cs: CPUState |
213 | * |
214 | * Returns: true if the KVM VCPU can enable AArch32 mode |
215 | * and false otherwise. |
216 | */ |
217 | bool kvm_arm_aarch32_supported(CPUState *cs); |
218 | |
219 | /** |
220 | * bool kvm_arm_pmu_supported: |
221 | * @cs: CPUState |
222 | * |
223 | * Returns: true if the KVM VCPU can enable its PMU |
224 | * and false otherwise. |
225 | */ |
226 | bool kvm_arm_pmu_supported(CPUState *cs); |
227 | |
228 | /** |
229 | * kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the |
230 | * IPA address space supported by KVM |
231 | * |
232 | * @ms: Machine state handle |
233 | */ |
234 | int kvm_arm_get_max_vm_ipa_size(MachineState *ms); |
235 | |
236 | /** |
237 | * kvm_arm_sync_mpstate_to_kvm |
238 | * @cpu: ARMCPU |
239 | * |
240 | * If supported set the KVM MP_STATE based on QEMU's model. |
241 | */ |
242 | int kvm_arm_sync_mpstate_to_kvm(ARMCPU *cpu); |
243 | |
244 | /** |
245 | * kvm_arm_sync_mpstate_to_qemu |
246 | * @cpu: ARMCPU |
247 | * |
248 | * If supported get the MP_STATE from KVM and store in QEMU's model. |
249 | */ |
250 | int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu); |
251 | |
252 | int kvm_arm_vgic_probe(void); |
253 | |
254 | void kvm_arm_pmu_set_irq(CPUState *cs, int irq); |
255 | void kvm_arm_pmu_init(CPUState *cs); |
256 | |
257 | #else |
258 | |
259 | static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) |
260 | { |
261 | /* This should never actually be called in the "not KVM" case, |
262 | * but set up the fields to indicate an error anyway. |
263 | */ |
264 | cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE; |
265 | cpu->host_cpu_probe_failed = true; |
266 | } |
267 | |
268 | static inline bool kvm_arm_aarch32_supported(CPUState *cs) |
269 | { |
270 | return false; |
271 | } |
272 | |
273 | static inline bool kvm_arm_pmu_supported(CPUState *cs) |
274 | { |
275 | return false; |
276 | } |
277 | |
278 | static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms) |
279 | { |
280 | return -ENOENT; |
281 | } |
282 | |
283 | static inline int kvm_arm_vgic_probe(void) |
284 | { |
285 | return 0; |
286 | } |
287 | |
288 | static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) {} |
289 | static inline void kvm_arm_pmu_init(CPUState *cs) {} |
290 | |
291 | #endif |
292 | |
293 | static inline const char *gic_class_name(void) |
294 | { |
295 | return kvm_irqchip_in_kernel() ? "kvm-arm-gic" : "arm_gic" ; |
296 | } |
297 | |
298 | /** |
299 | * gicv3_class_name |
300 | * |
301 | * Return name of GICv3 class to use depending on whether KVM acceleration is |
302 | * in use. May throw an error if the chosen implementation is not available. |
303 | * |
304 | * Returns: class name to use |
305 | */ |
306 | static inline const char *gicv3_class_name(void) |
307 | { |
308 | if (kvm_irqchip_in_kernel()) { |
309 | #ifdef TARGET_AARCH64 |
310 | return "kvm-arm-gicv3" ; |
311 | #else |
312 | error_report("KVM GICv3 acceleration is not supported on this " |
313 | "platform" ); |
314 | exit(1); |
315 | #endif |
316 | } else { |
317 | if (kvm_enabled()) { |
318 | error_report("Userspace GICv3 is not supported with KVM" ); |
319 | exit(1); |
320 | } |
321 | return "arm-gicv3" ; |
322 | } |
323 | } |
324 | |
325 | /** |
326 | * kvm_arm_handle_debug: |
327 | * @cs: CPUState |
328 | * @debug_exit: debug part of the KVM exit structure |
329 | * |
330 | * Returns: TRUE if the debug exception was handled. |
331 | */ |
332 | bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit); |
333 | |
334 | /** |
335 | * kvm_arm_hw_debug_active: |
336 | * @cs: CPU State |
337 | * |
338 | * Return: TRUE if any hardware breakpoints in use. |
339 | */ |
340 | |
341 | bool kvm_arm_hw_debug_active(CPUState *cs); |
342 | |
343 | /** |
344 | * kvm_arm_copy_hw_debug_data: |
345 | * |
346 | * @ptr: kvm_guest_debug_arch structure |
347 | * |
348 | * Copy the architecture specific debug registers into the |
349 | * kvm_guest_debug ioctl structure. |
350 | */ |
351 | struct kvm_guest_debug_arch; |
352 | |
353 | void kvm_arm_copy_hw_debug_data(struct kvm_guest_debug_arch *ptr); |
354 | |
355 | /** |
356 | * its_class_name |
357 | * |
358 | * Return the ITS class name to use depending on whether KVM acceleration |
359 | * and KVM CAP_SIGNAL_MSI are supported |
360 | * |
361 | * Returns: class name to use or NULL |
362 | */ |
363 | static inline const char *its_class_name(void) |
364 | { |
365 | if (kvm_irqchip_in_kernel()) { |
366 | /* KVM implementation requires this capability */ |
367 | return kvm_direct_msi_enabled() ? "arm-its-kvm" : NULL; |
368 | } else { |
369 | /* Software emulation is not implemented yet */ |
370 | return NULL; |
371 | } |
372 | } |
373 | |
374 | #endif |
375 | |