]>
Commit | Line | Data |
---|---|---|
eb035b48 PM |
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" | |
1b20616f | 16 | #include "qemu/error-report.h" |
eb035b48 | 17 | |
d45efe47 EA |
18 | #define KVM_ARM_VGIC_V2 (1 << 0) |
19 | #define KVM_ARM_VGIC_V3 (1 << 1) | |
20 | ||
eb035b48 PM |
21 | /** |
22 | * kvm_arm_register_device: | |
23 | * @mr: memory region for this device | |
24 | * @devid: the KVM device ID | |
1da41cc1 CD |
25 | * @group: device control API group for setting addresses |
26 | * @attr: device control API address type | |
27 | * @dev_fd: device control device file descriptor (or -1 if not supported) | |
19d1bd0b | 28 | * @addr_ormask: value to be OR'ed with resolved address |
eb035b48 PM |
29 | * |
30 | * Remember the memory region @mr, and when it is mapped by the | |
31 | * machine model, tell the kernel that base address using the | |
1da41cc1 CD |
32 | * KVM_ARM_SET_DEVICE_ADDRESS ioctl or the newer device control API. @devid |
33 | * should be the ID of the device as defined by KVM_ARM_SET_DEVICE_ADDRESS or | |
34 | * the arm-vgic device in the device control API. | |
35 | * The machine model may map | |
36 | * and unmap the device multiple times; the kernel will only be told the final | |
37 | * address at the point where machine init is complete. | |
eb035b48 | 38 | */ |
1da41cc1 | 39 | void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group, |
19d1bd0b | 40 | uint64_t attr, int dev_fd, uint64_t addr_ormask); |
eb035b48 | 41 | |
38df27c8 AB |
42 | /** |
43 | * kvm_arm_init_cpreg_list: | |
c8a44709 | 44 | * @cpu: ARMCPU |
38df27c8 | 45 | * |
c8a44709 | 46 | * Initialize the ARMCPU cpreg list according to the kernel's |
38df27c8 AB |
47 | * definition of what CPU registers it knows about (and throw away |
48 | * the previous TCG-created cpreg list). | |
49 | * | |
50 | * Returns: 0 if success, else < 0 error code | |
51 | */ | |
52 | int kvm_arm_init_cpreg_list(ARMCPU *cpu); | |
53 | ||
ff047453 PM |
54 | /** |
55 | * write_list_to_kvmstate: | |
56 | * @cpu: ARMCPU | |
4b7a6bf4 | 57 | * @level: the state level to sync |
ff047453 PM |
58 | * |
59 | * For each register listed in the ARMCPU cpreg_indexes list, write | |
60 | * its value from the cpreg_values list into the kernel (via ioctl). | |
61 | * This updates KVM's working data structures from TCG data or | |
62 | * from incoming migration state. | |
63 | * | |
64 | * Returns: true if all register values were updated correctly, | |
65 | * false if some register was unknown to the kernel or could not | |
66 | * be written (eg constant register with the wrong value). | |
67 | * Note that we do not stop early on failure -- we will attempt | |
68 | * writing all registers in the list. | |
69 | */ | |
4b7a6bf4 | 70 | bool write_list_to_kvmstate(ARMCPU *cpu, int level); |
ff047453 PM |
71 | |
72 | /** | |
73 | * write_kvmstate_to_list: | |
74 | * @cpu: ARMCPU | |
75 | * | |
76 | * For each register listed in the ARMCPU cpreg_indexes list, write | |
77 | * its value from the kernel into the cpreg_values list. This is used to | |
78 | * copy info from KVM's working data structures into TCG or | |
79 | * for outbound migration. | |
80 | * | |
81 | * Returns: true if all register values were read correctly, | |
82 | * false if some register was unknown or could not be read. | |
83 | * Note that we do not stop early on failure -- we will attempt | |
84 | * reading all registers in the list. | |
85 | */ | |
86 | bool write_kvmstate_to_list(ARMCPU *cpu); | |
87 | ||
e5ac4200 AJ |
88 | /** |
89 | * kvm_arm_cpu_pre_save: | |
90 | * @cpu: ARMCPU | |
91 | * | |
92 | * Called after write_kvmstate_to_list() from cpu_pre_save() to update | |
93 | * the cpreg list with KVM CPU state. | |
94 | */ | |
95 | void kvm_arm_cpu_pre_save(ARMCPU *cpu); | |
96 | ||
97 | /** | |
98 | * kvm_arm_cpu_post_load: | |
99 | * @cpu: ARMCPU | |
100 | * | |
101 | * Called from cpu_post_load() to update KVM CPU state from the cpreg list. | |
102 | */ | |
103 | void kvm_arm_cpu_post_load(ARMCPU *cpu); | |
104 | ||
50a2c6e5 PB |
105 | /** |
106 | * kvm_arm_reset_vcpu: | |
107 | * @cpu: ARMCPU | |
108 | * | |
109 | * Called at reset time to kernel registers to their initial values. | |
110 | */ | |
111 | void kvm_arm_reset_vcpu(ARMCPU *cpu); | |
112 | ||
202ccb6b DG |
113 | /** |
114 | * kvm_arm_init_serror_injection: | |
115 | * @cs: CPUState | |
116 | * | |
117 | * Check whether KVM can set guest SError syndrome. | |
118 | */ | |
119 | void kvm_arm_init_serror_injection(CPUState *cs); | |
120 | ||
121 | /** | |
122 | * kvm_get_vcpu_events: | |
123 | * @cpu: ARMCPU | |
124 | * | |
125 | * Get VCPU related state from kvm. | |
d1ebbc9d AJ |
126 | * |
127 | * Returns: 0 if success else < 0 error code | |
202ccb6b DG |
128 | */ |
129 | int kvm_get_vcpu_events(ARMCPU *cpu); | |
130 | ||
131 | /** | |
132 | * kvm_put_vcpu_events: | |
133 | * @cpu: ARMCPU | |
134 | * | |
135 | * Put VCPU related state to kvm. | |
d1ebbc9d AJ |
136 | * |
137 | * Returns: 0 if success else < 0 error code | |
202ccb6b DG |
138 | */ |
139 | int kvm_put_vcpu_events(ARMCPU *cpu); | |
140 | ||
a96c0514 PM |
141 | #ifdef CONFIG_KVM |
142 | /** | |
143 | * kvm_arm_create_scratch_host_vcpu: | |
144 | * @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with | |
145 | * QEMU_KVM_ARM_TARGET_NONE) to try as fallback if the kernel does not | |
2f340e9c PX |
146 | * know the PREFERRED_TARGET ioctl. Passing NULL is the same as passing |
147 | * an empty array. | |
a96c0514 | 148 | * @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order |
2f340e9c PX |
149 | * @init: filled in with the necessary values for creating a host |
150 | * vcpu. If NULL is provided, will not init the vCPU (though the cpufd | |
151 | * will still be set up). | |
a96c0514 PM |
152 | * |
153 | * Create a scratch vcpu in its own VM of the type preferred by the host | |
154 | * kernel (as would be used for '-cpu host'), for purposes of probing it | |
155 | * for capabilities. | |
156 | * | |
157 | * Returns: true on success (and fdarray and init are filled in), | |
158 | * false on failure (and fdarray and init are not valid). | |
159 | */ | |
160 | bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, | |
161 | int *fdarray, | |
162 | struct kvm_vcpu_init *init); | |
163 | ||
164 | /** | |
165 | * kvm_arm_destroy_scratch_host_vcpu: | |
166 | * @fdarray: array of fds as set up by kvm_arm_create_scratch_host_vcpu | |
167 | * | |
168 | * Tear down the scratch vcpu created by kvm_arm_create_scratch_host_vcpu. | |
169 | */ | |
170 | void kvm_arm_destroy_scratch_host_vcpu(int *fdarray); | |
171 | ||
6fa8a379 AJ |
172 | /** |
173 | * kvm_arm_sve_get_vls: | |
174 | * @cs: CPUState | |
6fa8a379 AJ |
175 | * |
176 | * Get all the SVE vector lengths supported by the KVM host, setting | |
177 | * the bits corresponding to their length in quadwords minus one | |
886902ec | 178 | * (vq - 1) up to ARM_MAX_VQ. Return the resulting map. |
6fa8a379 | 179 | */ |
886902ec | 180 | uint32_t kvm_arm_sve_get_vls(CPUState *cs); |
6fa8a379 | 181 | |
c4487d76 PM |
182 | /** |
183 | * kvm_arm_set_cpu_features_from_host: | |
184 | * @cpu: ARMCPU to set the features for | |
185 | * | |
186 | * Set up the ARMCPU struct fields up to match the information probed | |
187 | * from the host CPU. | |
188 | */ | |
189 | void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); | |
1a1753f7 | 190 | |
dea101a1 AJ |
191 | /** |
192 | * kvm_arm_add_vcpu_properties: | |
193 | * @obj: The CPU object to add the properties to | |
194 | * | |
195 | * Add all KVM specific CPU properties to the CPU object. These | |
196 | * are the CPU properties with "kvm-" prefixed names. | |
197 | */ | |
198 | void kvm_arm_add_vcpu_properties(Object *obj); | |
199 | ||
68970d1e AJ |
200 | /** |
201 | * kvm_arm_steal_time_finalize: | |
202 | * @cpu: ARMCPU for which to finalize kvm-steal-time | |
203 | * @errp: Pointer to Error* for error propagation | |
204 | * | |
205 | * Validate the kvm-steal-time property selection and set its default | |
206 | * based on KVM support and guest configuration. | |
207 | */ | |
208 | void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp); | |
209 | ||
b9e758f0 AJ |
210 | /** |
211 | * kvm_arm_aarch32_supported: | |
b9e758f0 | 212 | * |
7d20e681 | 213 | * Returns: true if KVM can enable AArch32 mode |
b9e758f0 AJ |
214 | * and false otherwise. |
215 | */ | |
7d20e681 | 216 | bool kvm_arm_aarch32_supported(void); |
b9e758f0 | 217 | |
ae502508 | 218 | /** |
d1ebbc9d | 219 | * kvm_arm_pmu_supported: |
ae502508 | 220 | * |
7d20e681 | 221 | * Returns: true if KVM can enable the PMU |
ae502508 AJ |
222 | * and false otherwise. |
223 | */ | |
7d20e681 | 224 | bool kvm_arm_pmu_supported(void); |
ae502508 | 225 | |
14e99e0f | 226 | /** |
d1ebbc9d | 227 | * kvm_arm_sve_supported: |
14e99e0f | 228 | * |
7d20e681 | 229 | * Returns true if KVM can enable SVE and false otherwise. |
14e99e0f | 230 | */ |
7d20e681 | 231 | bool kvm_arm_sve_supported(void); |
14e99e0f | 232 | |
a27382e2 | 233 | /** |
d1ebbc9d | 234 | * kvm_arm_get_max_vm_ipa_size: |
a27382e2 | 235 | * @ms: Machine state handle |
bcb902a1 AJ |
236 | * @fixed_ipa: True when the IPA limit is fixed at 40. This is the case |
237 | * for legacy KVM. | |
d1ebbc9d AJ |
238 | * |
239 | * Returns the number of bits in the IPA address space supported by KVM | |
a27382e2 | 240 | */ |
bcb902a1 | 241 | int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa); |
a27382e2 | 242 | |
1a1753f7 | 243 | /** |
d1ebbc9d | 244 | * kvm_arm_sync_mpstate_to_kvm: |
1a1753f7 AB |
245 | * @cpu: ARMCPU |
246 | * | |
247 | * If supported set the KVM MP_STATE based on QEMU's model. | |
d1ebbc9d AJ |
248 | * |
249 | * Returns 0 on success and -1 on failure. | |
1a1753f7 AB |
250 | */ |
251 | int kvm_arm_sync_mpstate_to_kvm(ARMCPU *cpu); | |
252 | ||
253 | /** | |
d1ebbc9d | 254 | * kvm_arm_sync_mpstate_to_qemu: |
1a1753f7 AB |
255 | * @cpu: ARMCPU |
256 | * | |
257 | * If supported get the MP_STATE from KVM and store in QEMU's model. | |
d1ebbc9d AJ |
258 | * |
259 | * Returns 0 on success and aborts on failure. | |
1a1753f7 AB |
260 | */ |
261 | int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu); | |
262 | ||
538f0497 | 263 | void kvm_arm_vm_state_change(void *opaque, bool running, RunState state); |
e5ac4200 | 264 | |
34e85cd9 PF |
265 | int kvm_arm_vgic_probe(void); |
266 | ||
b2bfe9f7 AJ |
267 | void kvm_arm_pmu_set_irq(CPUState *cs, int irq); |
268 | void kvm_arm_pmu_init(CPUState *cs); | |
68970d1e AJ |
269 | |
270 | /** | |
271 | * kvm_arm_pvtime_init: | |
272 | * @cs: CPUState | |
273 | * @ipa: Per-vcpu guest physical base address of the pvtime structures | |
274 | * | |
275 | * Initializes PVTIME for the VCPU, setting the PVTIME IPA to @ipa. | |
276 | */ | |
277 | void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa); | |
278 | ||
f6530926 | 279 | int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level); |
01fe6b60 | 280 | |
34e85cd9 PF |
281 | #else |
282 | ||
281a3c33 AJ |
283 | /* |
284 | * It's safe to call these functions without KVM support. | |
285 | * They should either do nothing or return "not supported". | |
286 | */ | |
7d20e681 | 287 | static inline bool kvm_arm_aarch32_supported(void) |
b9e758f0 AJ |
288 | { |
289 | return false; | |
290 | } | |
291 | ||
7d20e681 | 292 | static inline bool kvm_arm_pmu_supported(void) |
ae502508 AJ |
293 | { |
294 | return false; | |
295 | } | |
296 | ||
7d20e681 | 297 | static inline bool kvm_arm_sve_supported(void) |
14e99e0f AJ |
298 | { |
299 | return false; | |
300 | } | |
301 | ||
281a3c33 AJ |
302 | /* |
303 | * These functions should never actually be called without KVM support. | |
304 | */ | |
305 | static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) | |
306 | { | |
307 | g_assert_not_reached(); | |
308 | } | |
309 | ||
310 | static inline void kvm_arm_add_vcpu_properties(Object *obj) | |
311 | { | |
312 | g_assert_not_reached(); | |
313 | } | |
314 | ||
bcb902a1 | 315 | static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa) |
a27382e2 | 316 | { |
281a3c33 | 317 | g_assert_not_reached(); |
a27382e2 EA |
318 | } |
319 | ||
34e85cd9 PF |
320 | static inline int kvm_arm_vgic_probe(void) |
321 | { | |
281a3c33 | 322 | g_assert_not_reached(); |
34e85cd9 PF |
323 | } |
324 | ||
281a3c33 AJ |
325 | static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) |
326 | { | |
327 | g_assert_not_reached(); | |
328 | } | |
01fe6b60 | 329 | |
281a3c33 AJ |
330 | static inline void kvm_arm_pmu_init(CPUState *cs) |
331 | { | |
332 | g_assert_not_reached(); | |
333 | } | |
334 | ||
68970d1e AJ |
335 | static inline void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa) |
336 | { | |
337 | g_assert_not_reached(); | |
338 | } | |
339 | ||
340 | static inline void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp) | |
341 | { | |
342 | g_assert_not_reached(); | |
343 | } | |
344 | ||
886902ec | 345 | static inline uint32_t kvm_arm_sve_get_vls(CPUState *cs) |
281a3c33 AJ |
346 | { |
347 | g_assert_not_reached(); | |
348 | } | |
e5ac4200 | 349 | |
a96c0514 PM |
350 | #endif |
351 | ||
eb035b48 | 352 | #endif |