]>
Commit | Line | Data |
---|---|---|
494b00c7 CD |
1 | /* |
2 | * ARM implementation of KVM hooks | |
3 | * | |
4 | * Copyright Christoffer Dall 2009-2010 | |
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 | ||
74c21bd0 | 11 | #include "qemu/osdep.h" |
494b00c7 | 12 | #include <sys/ioctl.h> |
494b00c7 CD |
13 | |
14 | #include <linux/kvm.h> | |
15 | ||
16 | #include "qemu-common.h" | |
17 | #include "qemu/timer.h" | |
2ecb2027 | 18 | #include "qemu/error-report.h" |
db725815 | 19 | #include "qemu/main-loop.h" |
dea101a1 AJ |
20 | #include "qom/object.h" |
21 | #include "qapi/error.h" | |
494b00c7 CD |
22 | #include "sysemu/sysemu.h" |
23 | #include "sysemu/kvm.h" | |
a27382e2 | 24 | #include "sysemu/kvm_int.h" |
eb035b48 | 25 | #include "kvm_arm.h" |
494b00c7 | 26 | #include "cpu.h" |
b05c81d2 | 27 | #include "trace.h" |
38df27c8 | 28 | #include "internals.h" |
b05c81d2 | 29 | #include "hw/pci/pci.h" |
4c663752 | 30 | #include "exec/memattrs.h" |
4344af65 | 31 | #include "exec/address-spaces.h" |
15eafc2e | 32 | #include "hw/boards.h" |
64552b6b | 33 | #include "hw/irq.h" |
03dd024f | 34 | #include "qemu/log.h" |
494b00c7 CD |
35 | |
36 | const KVMCapabilityInfo kvm_arch_required_capabilities[] = { | |
37 | KVM_CAP_LAST_INFO | |
38 | }; | |
39 | ||
1a1753f7 | 40 | static bool cap_has_mp_state; |
202ccb6b | 41 | static bool cap_has_inject_serror_esr; |
1a1753f7 | 42 | |
c4487d76 PM |
43 | static ARMHostCPUFeatures arm_host_cpu_features; |
44 | ||
228d5e04 PS |
45 | int kvm_arm_vcpu_init(CPUState *cs) |
46 | { | |
47 | ARMCPU *cpu = ARM_CPU(cs); | |
48 | struct kvm_vcpu_init init; | |
49 | ||
50 | init.target = cpu->kvm_target; | |
51 | memcpy(init.features, cpu->kvm_init_features, sizeof(init.features)); | |
52 | ||
53 | return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); | |
54 | } | |
55 | ||
14e99e0f AJ |
56 | int kvm_arm_vcpu_finalize(CPUState *cs, int feature) |
57 | { | |
58 | return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_FINALIZE, &feature); | |
59 | } | |
60 | ||
202ccb6b DG |
61 | void kvm_arm_init_serror_injection(CPUState *cs) |
62 | { | |
63 | cap_has_inject_serror_esr = kvm_check_extension(cs->kvm_state, | |
64 | KVM_CAP_ARM_INJECT_SERROR_ESR); | |
65 | } | |
66 | ||
a96c0514 PM |
67 | bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, |
68 | int *fdarray, | |
69 | struct kvm_vcpu_init *init) | |
70 | { | |
0cdb4020 | 71 | int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1; |
a96c0514 PM |
72 | |
73 | kvmfd = qemu_open("/dev/kvm", O_RDWR); | |
74 | if (kvmfd < 0) { | |
75 | goto err; | |
76 | } | |
77 | vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0); | |
78 | if (vmfd < 0) { | |
79 | goto err; | |
80 | } | |
81 | cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0); | |
82 | if (cpufd < 0) { | |
83 | goto err; | |
84 | } | |
85 | ||
2f340e9c PX |
86 | if (!init) { |
87 | /* Caller doesn't want the VCPU to be initialized, so skip it */ | |
88 | goto finish; | |
89 | } | |
90 | ||
0cdb4020 AJ |
91 | if (init->target == -1) { |
92 | struct kvm_vcpu_init preferred; | |
93 | ||
94 | ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred); | |
95 | if (!ret) { | |
96 | init->target = preferred.target; | |
97 | } | |
98 | } | |
a96c0514 PM |
99 | if (ret >= 0) { |
100 | ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init); | |
101 | if (ret < 0) { | |
102 | goto err; | |
103 | } | |
2f340e9c | 104 | } else if (cpus_to_try) { |
a96c0514 PM |
105 | /* Old kernel which doesn't know about the |
106 | * PREFERRED_TARGET ioctl: we know it will only support | |
107 | * creating one kind of guest CPU which is its preferred | |
108 | * CPU type. | |
109 | */ | |
0cdb4020 AJ |
110 | struct kvm_vcpu_init try; |
111 | ||
a96c0514 | 112 | while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) { |
0cdb4020 AJ |
113 | try.target = *cpus_to_try++; |
114 | memcpy(try.features, init->features, sizeof(init->features)); | |
115 | ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, &try); | |
a96c0514 PM |
116 | if (ret >= 0) { |
117 | break; | |
118 | } | |
119 | } | |
120 | if (ret < 0) { | |
121 | goto err; | |
122 | } | |
0cdb4020 | 123 | init->target = try.target; |
2f340e9c PX |
124 | } else { |
125 | /* Treat a NULL cpus_to_try argument the same as an empty | |
126 | * list, which means we will fail the call since this must | |
127 | * be an old kernel which doesn't support PREFERRED_TARGET. | |
128 | */ | |
129 | goto err; | |
a96c0514 PM |
130 | } |
131 | ||
2f340e9c | 132 | finish: |
a96c0514 PM |
133 | fdarray[0] = kvmfd; |
134 | fdarray[1] = vmfd; | |
135 | fdarray[2] = cpufd; | |
136 | ||
137 | return true; | |
138 | ||
139 | err: | |
140 | if (cpufd >= 0) { | |
141 | close(cpufd); | |
142 | } | |
143 | if (vmfd >= 0) { | |
144 | close(vmfd); | |
145 | } | |
146 | if (kvmfd >= 0) { | |
147 | close(kvmfd); | |
148 | } | |
149 | ||
150 | return false; | |
151 | } | |
152 | ||
153 | void kvm_arm_destroy_scratch_host_vcpu(int *fdarray) | |
154 | { | |
155 | int i; | |
156 | ||
157 | for (i = 2; i >= 0; i--) { | |
158 | close(fdarray[i]); | |
159 | } | |
160 | } | |
161 | ||
c4487d76 | 162 | void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) |
a96c0514 | 163 | { |
c4487d76 | 164 | CPUARMState *env = &cpu->env; |
a96c0514 | 165 | |
c4487d76 PM |
166 | if (!arm_host_cpu_features.dtb_compatible) { |
167 | if (!kvm_enabled() || | |
168 | !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) { | |
169 | /* We can't report this error yet, so flag that we need to | |
170 | * in arm_cpu_realizefn(). | |
171 | */ | |
172 | cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE; | |
173 | cpu->host_cpu_probe_failed = true; | |
174 | return; | |
175 | } | |
a96c0514 | 176 | } |
c4487d76 PM |
177 | |
178 | cpu->kvm_target = arm_host_cpu_features.target; | |
179 | cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible; | |
4674097c | 180 | cpu->isar = arm_host_cpu_features.isar; |
c4487d76 | 181 | env->features = arm_host_cpu_features.features; |
a96c0514 PM |
182 | } |
183 | ||
dea101a1 AJ |
184 | static bool kvm_no_adjvtime_get(Object *obj, Error **errp) |
185 | { | |
186 | return !ARM_CPU(obj)->kvm_adjvtime; | |
187 | } | |
188 | ||
189 | static void kvm_no_adjvtime_set(Object *obj, bool value, Error **errp) | |
190 | { | |
191 | ARM_CPU(obj)->kvm_adjvtime = !value; | |
192 | } | |
193 | ||
194 | /* KVM VCPU properties should be prefixed with "kvm-". */ | |
195 | void kvm_arm_add_vcpu_properties(Object *obj) | |
196 | { | |
197 | if (!kvm_enabled()) { | |
198 | return; | |
199 | } | |
200 | ||
201 | ARM_CPU(obj)->kvm_adjvtime = true; | |
202 | object_property_add_bool(obj, "kvm-no-adjvtime", kvm_no_adjvtime_get, | |
203 | kvm_no_adjvtime_set, &error_abort); | |
204 | object_property_set_description(obj, "kvm-no-adjvtime", | |
205 | "Set on to disable the adjustment of " | |
206 | "the virtual counter. VM stopped time " | |
207 | "will be counted.", &error_abort); | |
208 | } | |
209 | ||
ae502508 AJ |
210 | bool kvm_arm_pmu_supported(CPUState *cpu) |
211 | { | |
d70c996d | 212 | return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3); |
ae502508 AJ |
213 | } |
214 | ||
a27382e2 EA |
215 | int kvm_arm_get_max_vm_ipa_size(MachineState *ms) |
216 | { | |
217 | KVMState *s = KVM_STATE(ms->accelerator); | |
218 | int ret; | |
219 | ||
220 | ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE); | |
221 | return ret > 0 ? ret : 40; | |
222 | } | |
223 | ||
b16565b3 | 224 | int kvm_arch_init(MachineState *ms, KVMState *s) |
494b00c7 | 225 | { |
fff9f555 | 226 | int ret = 0; |
494b00c7 CD |
227 | /* For ARM interrupt delivery is always asynchronous, |
228 | * whether we are using an in-kernel VGIC or not. | |
229 | */ | |
230 | kvm_async_interrupts_allowed = true; | |
a96c0514 | 231 | |
5d721b78 AG |
232 | /* |
233 | * PSCI wakes up secondary cores, so we always need to | |
234 | * have vCPUs waiting in kernel space | |
235 | */ | |
236 | kvm_halt_in_kernel_allowed = true; | |
237 | ||
1a1753f7 AB |
238 | cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE); |
239 | ||
fff9f555 EA |
240 | if (ms->smp.cpus > 256 && |
241 | !kvm_check_extension(s, KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) { | |
242 | error_report("Using more than 256 vcpus requires a host kernel " | |
243 | "with KVM_CAP_ARM_IRQ_LINE_LAYOUT_2"); | |
244 | ret = -EINVAL; | |
245 | } | |
246 | ||
247 | return ret; | |
494b00c7 CD |
248 | } |
249 | ||
250 | unsigned long kvm_arch_vcpu_id(CPUState *cpu) | |
251 | { | |
252 | return cpu->cpu_index; | |
253 | } | |
254 | ||
eb035b48 PM |
255 | /* We track all the KVM devices which need their memory addresses |
256 | * passing to the kernel in a list of these structures. | |
257 | * When board init is complete we run through the list and | |
258 | * tell the kernel the base addresses of the memory regions. | |
259 | * We use a MemoryListener to track mapping and unmapping of | |
260 | * the regions during board creation, so the board models don't | |
261 | * need to do anything special for the KVM case. | |
19d1bd0b EA |
262 | * |
263 | * Sometimes the address must be OR'ed with some other fields | |
264 | * (for example for KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION). | |
265 | * @kda_addr_ormask aims at storing the value of those fields. | |
eb035b48 PM |
266 | */ |
267 | typedef struct KVMDevice { | |
268 | struct kvm_arm_device_addr kda; | |
1da41cc1 | 269 | struct kvm_device_attr kdattr; |
19d1bd0b | 270 | uint64_t kda_addr_ormask; |
eb035b48 PM |
271 | MemoryRegion *mr; |
272 | QSLIST_ENTRY(KVMDevice) entries; | |
1da41cc1 | 273 | int dev_fd; |
eb035b48 PM |
274 | } KVMDevice; |
275 | ||
b58deb34 | 276 | static QSLIST_HEAD(, KVMDevice) kvm_devices_head; |
eb035b48 PM |
277 | |
278 | static void kvm_arm_devlistener_add(MemoryListener *listener, | |
279 | MemoryRegionSection *section) | |
280 | { | |
281 | KVMDevice *kd; | |
282 | ||
283 | QSLIST_FOREACH(kd, &kvm_devices_head, entries) { | |
284 | if (section->mr == kd->mr) { | |
285 | kd->kda.addr = section->offset_within_address_space; | |
286 | } | |
287 | } | |
288 | } | |
289 | ||
290 | static void kvm_arm_devlistener_del(MemoryListener *listener, | |
291 | MemoryRegionSection *section) | |
292 | { | |
293 | KVMDevice *kd; | |
294 | ||
295 | QSLIST_FOREACH(kd, &kvm_devices_head, entries) { | |
296 | if (section->mr == kd->mr) { | |
297 | kd->kda.addr = -1; | |
298 | } | |
299 | } | |
300 | } | |
301 | ||
302 | static MemoryListener devlistener = { | |
303 | .region_add = kvm_arm_devlistener_add, | |
304 | .region_del = kvm_arm_devlistener_del, | |
305 | }; | |
306 | ||
1da41cc1 CD |
307 | static void kvm_arm_set_device_addr(KVMDevice *kd) |
308 | { | |
309 | struct kvm_device_attr *attr = &kd->kdattr; | |
310 | int ret; | |
311 | ||
312 | /* If the device control API is available and we have a device fd on the | |
313 | * KVMDevice struct, let's use the newer API | |
314 | */ | |
315 | if (kd->dev_fd >= 0) { | |
316 | uint64_t addr = kd->kda.addr; | |
19d1bd0b EA |
317 | |
318 | addr |= kd->kda_addr_ormask; | |
1da41cc1 CD |
319 | attr->addr = (uintptr_t)&addr; |
320 | ret = kvm_device_ioctl(kd->dev_fd, KVM_SET_DEVICE_ATTR, attr); | |
321 | } else { | |
322 | ret = kvm_vm_ioctl(kvm_state, KVM_ARM_SET_DEVICE_ADDR, &kd->kda); | |
323 | } | |
324 | ||
325 | if (ret < 0) { | |
326 | fprintf(stderr, "Failed to set device address: %s\n", | |
327 | strerror(-ret)); | |
328 | abort(); | |
329 | } | |
330 | } | |
331 | ||
eb035b48 PM |
332 | static void kvm_arm_machine_init_done(Notifier *notifier, void *data) |
333 | { | |
334 | KVMDevice *kd, *tkd; | |
335 | ||
eb035b48 PM |
336 | QSLIST_FOREACH_SAFE(kd, &kvm_devices_head, entries, tkd) { |
337 | if (kd->kda.addr != -1) { | |
1da41cc1 | 338 | kvm_arm_set_device_addr(kd); |
eb035b48 | 339 | } |
dfde4e6e | 340 | memory_region_unref(kd->mr); |
5ff9aaab | 341 | QSLIST_REMOVE_HEAD(&kvm_devices_head, entries); |
eb035b48 PM |
342 | g_free(kd); |
343 | } | |
0bbe4354 | 344 | memory_listener_unregister(&devlistener); |
eb035b48 PM |
345 | } |
346 | ||
347 | static Notifier notify = { | |
348 | .notify = kvm_arm_machine_init_done, | |
349 | }; | |
350 | ||
1da41cc1 | 351 | void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group, |
19d1bd0b | 352 | uint64_t attr, int dev_fd, uint64_t addr_ormask) |
eb035b48 PM |
353 | { |
354 | KVMDevice *kd; | |
355 | ||
356 | if (!kvm_irqchip_in_kernel()) { | |
357 | return; | |
358 | } | |
359 | ||
360 | if (QSLIST_EMPTY(&kvm_devices_head)) { | |
4344af65 | 361 | memory_listener_register(&devlistener, &address_space_memory); |
eb035b48 PM |
362 | qemu_add_machine_init_done_notifier(¬ify); |
363 | } | |
364 | kd = g_new0(KVMDevice, 1); | |
365 | kd->mr = mr; | |
366 | kd->kda.id = devid; | |
367 | kd->kda.addr = -1; | |
1da41cc1 CD |
368 | kd->kdattr.flags = 0; |
369 | kd->kdattr.group = group; | |
370 | kd->kdattr.attr = attr; | |
371 | kd->dev_fd = dev_fd; | |
19d1bd0b | 372 | kd->kda_addr_ormask = addr_ormask; |
eb035b48 | 373 | QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries); |
dfde4e6e | 374 | memory_region_ref(kd->mr); |
eb035b48 PM |
375 | } |
376 | ||
38df27c8 AB |
377 | static int compare_u64(const void *a, const void *b) |
378 | { | |
379 | if (*(uint64_t *)a > *(uint64_t *)b) { | |
380 | return 1; | |
381 | } | |
382 | if (*(uint64_t *)a < *(uint64_t *)b) { | |
383 | return -1; | |
384 | } | |
385 | return 0; | |
386 | } | |
387 | ||
e5ac4200 AJ |
388 | /* |
389 | * cpreg_values are sorted in ascending order by KVM register ID | |
390 | * (see kvm_arm_init_cpreg_list). This allows us to cheaply find | |
391 | * the storage for a KVM register by ID with a binary search. | |
392 | */ | |
393 | static uint64_t *kvm_arm_get_cpreg_ptr(ARMCPU *cpu, uint64_t regidx) | |
394 | { | |
395 | uint64_t *res; | |
396 | ||
397 | res = bsearch(®idx, cpu->cpreg_indexes, cpu->cpreg_array_len, | |
398 | sizeof(uint64_t), compare_u64); | |
399 | assert(res); | |
400 | ||
401 | return &cpu->cpreg_values[res - cpu->cpreg_indexes]; | |
402 | } | |
403 | ||
c8a44709 | 404 | /* Initialize the ARMCPU cpreg list according to the kernel's |
38df27c8 AB |
405 | * definition of what CPU registers it knows about (and throw away |
406 | * the previous TCG-created cpreg list). | |
407 | */ | |
408 | int kvm_arm_init_cpreg_list(ARMCPU *cpu) | |
409 | { | |
410 | struct kvm_reg_list rl; | |
411 | struct kvm_reg_list *rlp; | |
412 | int i, ret, arraylen; | |
413 | CPUState *cs = CPU(cpu); | |
414 | ||
415 | rl.n = 0; | |
416 | ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, &rl); | |
417 | if (ret != -E2BIG) { | |
418 | return ret; | |
419 | } | |
420 | rlp = g_malloc(sizeof(struct kvm_reg_list) + rl.n * sizeof(uint64_t)); | |
421 | rlp->n = rl.n; | |
422 | ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, rlp); | |
423 | if (ret) { | |
424 | goto out; | |
425 | } | |
426 | /* Sort the list we get back from the kernel, since cpreg_tuples | |
427 | * must be in strictly ascending order. | |
428 | */ | |
429 | qsort(&rlp->reg, rlp->n, sizeof(rlp->reg[0]), compare_u64); | |
430 | ||
431 | for (i = 0, arraylen = 0; i < rlp->n; i++) { | |
432 | if (!kvm_arm_reg_syncs_via_cpreg_list(rlp->reg[i])) { | |
433 | continue; | |
434 | } | |
435 | switch (rlp->reg[i] & KVM_REG_SIZE_MASK) { | |
436 | case KVM_REG_SIZE_U32: | |
437 | case KVM_REG_SIZE_U64: | |
438 | break; | |
439 | default: | |
440 | fprintf(stderr, "Can't handle size of register in kernel list\n"); | |
441 | ret = -EINVAL; | |
442 | goto out; | |
443 | } | |
444 | ||
445 | arraylen++; | |
446 | } | |
447 | ||
448 | cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, arraylen); | |
449 | cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, arraylen); | |
450 | cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes, | |
451 | arraylen); | |
452 | cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values, | |
453 | arraylen); | |
454 | cpu->cpreg_array_len = arraylen; | |
455 | cpu->cpreg_vmstate_array_len = arraylen; | |
456 | ||
457 | for (i = 0, arraylen = 0; i < rlp->n; i++) { | |
458 | uint64_t regidx = rlp->reg[i]; | |
459 | if (!kvm_arm_reg_syncs_via_cpreg_list(regidx)) { | |
460 | continue; | |
461 | } | |
462 | cpu->cpreg_indexes[arraylen] = regidx; | |
463 | arraylen++; | |
464 | } | |
465 | assert(cpu->cpreg_array_len == arraylen); | |
466 | ||
467 | if (!write_kvmstate_to_list(cpu)) { | |
468 | /* Shouldn't happen unless kernel is inconsistent about | |
469 | * what registers exist. | |
470 | */ | |
471 | fprintf(stderr, "Initial read of kernel register state failed\n"); | |
472 | ret = -EINVAL; | |
473 | goto out; | |
474 | } | |
475 | ||
476 | out: | |
477 | g_free(rlp); | |
478 | return ret; | |
479 | } | |
480 | ||
ff047453 PM |
481 | bool write_kvmstate_to_list(ARMCPU *cpu) |
482 | { | |
483 | CPUState *cs = CPU(cpu); | |
484 | int i; | |
485 | bool ok = true; | |
486 | ||
487 | for (i = 0; i < cpu->cpreg_array_len; i++) { | |
488 | struct kvm_one_reg r; | |
489 | uint64_t regidx = cpu->cpreg_indexes[i]; | |
490 | uint32_t v32; | |
491 | int ret; | |
492 | ||
493 | r.id = regidx; | |
494 | ||
495 | switch (regidx & KVM_REG_SIZE_MASK) { | |
496 | case KVM_REG_SIZE_U32: | |
497 | r.addr = (uintptr_t)&v32; | |
498 | ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); | |
499 | if (!ret) { | |
500 | cpu->cpreg_values[i] = v32; | |
501 | } | |
502 | break; | |
503 | case KVM_REG_SIZE_U64: | |
504 | r.addr = (uintptr_t)(cpu->cpreg_values + i); | |
505 | ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); | |
506 | break; | |
507 | default: | |
508 | abort(); | |
509 | } | |
510 | if (ret) { | |
511 | ok = false; | |
512 | } | |
513 | } | |
514 | return ok; | |
515 | } | |
516 | ||
4b7a6bf4 | 517 | bool write_list_to_kvmstate(ARMCPU *cpu, int level) |
ff047453 PM |
518 | { |
519 | CPUState *cs = CPU(cpu); | |
520 | int i; | |
521 | bool ok = true; | |
522 | ||
523 | for (i = 0; i < cpu->cpreg_array_len; i++) { | |
524 | struct kvm_one_reg r; | |
525 | uint64_t regidx = cpu->cpreg_indexes[i]; | |
526 | uint32_t v32; | |
527 | int ret; | |
528 | ||
4b7a6bf4 CD |
529 | if (kvm_arm_cpreg_level(regidx) > level) { |
530 | continue; | |
531 | } | |
532 | ||
ff047453 PM |
533 | r.id = regidx; |
534 | switch (regidx & KVM_REG_SIZE_MASK) { | |
535 | case KVM_REG_SIZE_U32: | |
536 | v32 = cpu->cpreg_values[i]; | |
537 | r.addr = (uintptr_t)&v32; | |
538 | break; | |
539 | case KVM_REG_SIZE_U64: | |
540 | r.addr = (uintptr_t)(cpu->cpreg_values + i); | |
541 | break; | |
542 | default: | |
543 | abort(); | |
544 | } | |
545 | ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); | |
546 | if (ret) { | |
547 | /* We might fail for "unknown register" and also for | |
548 | * "you tried to set a register which is constant with | |
549 | * a different value from what it actually contains". | |
550 | */ | |
551 | ok = false; | |
552 | } | |
553 | } | |
554 | return ok; | |
555 | } | |
556 | ||
e5ac4200 AJ |
557 | void kvm_arm_cpu_pre_save(ARMCPU *cpu) |
558 | { | |
559 | /* KVM virtual time adjustment */ | |
560 | if (cpu->kvm_vtime_dirty) { | |
561 | *kvm_arm_get_cpreg_ptr(cpu, KVM_REG_ARM_TIMER_CNT) = cpu->kvm_vtime; | |
562 | } | |
563 | } | |
564 | ||
565 | void kvm_arm_cpu_post_load(ARMCPU *cpu) | |
566 | { | |
567 | /* KVM virtual time adjustment */ | |
568 | if (cpu->kvm_adjvtime) { | |
569 | cpu->kvm_vtime = *kvm_arm_get_cpreg_ptr(cpu, KVM_REG_ARM_TIMER_CNT); | |
570 | cpu->kvm_vtime_dirty = true; | |
571 | } | |
572 | } | |
573 | ||
38df27c8 AB |
574 | void kvm_arm_reset_vcpu(ARMCPU *cpu) |
575 | { | |
25f2895e CD |
576 | int ret; |
577 | ||
38df27c8 AB |
578 | /* Re-init VCPU so that all registers are set to |
579 | * their respective reset values. | |
580 | */ | |
25f2895e CD |
581 | ret = kvm_arm_vcpu_init(CPU(cpu)); |
582 | if (ret < 0) { | |
583 | fprintf(stderr, "kvm_arm_vcpu_init failed: %s\n", strerror(-ret)); | |
584 | abort(); | |
585 | } | |
586 | if (!write_kvmstate_to_list(cpu)) { | |
587 | fprintf(stderr, "write_kvmstate_to_list failed\n"); | |
588 | abort(); | |
589 | } | |
b698e4ee PM |
590 | /* |
591 | * Sync the reset values also into the CPUState. This is necessary | |
592 | * because the next thing we do will be a kvm_arch_put_registers() | |
593 | * which will update the list values from the CPUState before copying | |
594 | * the list values back to KVM. It's OK to ignore failure returns here | |
595 | * for the same reason we do so in kvm_arch_get_registers(). | |
596 | */ | |
597 | write_list_to_cpustate(cpu); | |
38df27c8 AB |
598 | } |
599 | ||
1a1753f7 AB |
600 | /* |
601 | * Update KVM's MP_STATE based on what QEMU thinks it is | |
602 | */ | |
603 | int kvm_arm_sync_mpstate_to_kvm(ARMCPU *cpu) | |
604 | { | |
605 | if (cap_has_mp_state) { | |
606 | struct kvm_mp_state mp_state = { | |
062ba099 AB |
607 | .mp_state = (cpu->power_state == PSCI_OFF) ? |
608 | KVM_MP_STATE_STOPPED : KVM_MP_STATE_RUNNABLE | |
1a1753f7 AB |
609 | }; |
610 | int ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MP_STATE, &mp_state); | |
611 | if (ret) { | |
612 | fprintf(stderr, "%s: failed to set MP_STATE %d/%s\n", | |
613 | __func__, ret, strerror(-ret)); | |
614 | return -1; | |
615 | } | |
616 | } | |
617 | ||
618 | return 0; | |
619 | } | |
620 | ||
621 | /* | |
622 | * Sync the KVM MP_STATE into QEMU | |
623 | */ | |
624 | int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu) | |
625 | { | |
626 | if (cap_has_mp_state) { | |
627 | struct kvm_mp_state mp_state; | |
628 | int ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MP_STATE, &mp_state); | |
629 | if (ret) { | |
630 | fprintf(stderr, "%s: failed to get MP_STATE %d/%s\n", | |
631 | __func__, ret, strerror(-ret)); | |
632 | abort(); | |
633 | } | |
062ba099 AB |
634 | cpu->power_state = (mp_state.mp_state == KVM_MP_STATE_STOPPED) ? |
635 | PSCI_OFF : PSCI_ON; | |
1a1753f7 AB |
636 | } |
637 | ||
638 | return 0; | |
639 | } | |
640 | ||
e5ac4200 AJ |
641 | void kvm_arm_get_virtual_time(CPUState *cs) |
642 | { | |
643 | ARMCPU *cpu = ARM_CPU(cs); | |
644 | struct kvm_one_reg reg = { | |
645 | .id = KVM_REG_ARM_TIMER_CNT, | |
646 | .addr = (uintptr_t)&cpu->kvm_vtime, | |
647 | }; | |
648 | int ret; | |
649 | ||
650 | if (cpu->kvm_vtime_dirty) { | |
651 | return; | |
652 | } | |
653 | ||
654 | ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); | |
655 | if (ret) { | |
656 | error_report("Failed to get KVM_REG_ARM_TIMER_CNT"); | |
657 | abort(); | |
658 | } | |
659 | ||
660 | cpu->kvm_vtime_dirty = true; | |
661 | } | |
662 | ||
663 | void kvm_arm_put_virtual_time(CPUState *cs) | |
664 | { | |
665 | ARMCPU *cpu = ARM_CPU(cs); | |
666 | struct kvm_one_reg reg = { | |
667 | .id = KVM_REG_ARM_TIMER_CNT, | |
668 | .addr = (uintptr_t)&cpu->kvm_vtime, | |
669 | }; | |
670 | int ret; | |
671 | ||
672 | if (!cpu->kvm_vtime_dirty) { | |
673 | return; | |
674 | } | |
675 | ||
676 | ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); | |
677 | if (ret) { | |
678 | error_report("Failed to set KVM_REG_ARM_TIMER_CNT"); | |
679 | abort(); | |
680 | } | |
681 | ||
682 | cpu->kvm_vtime_dirty = false; | |
683 | } | |
684 | ||
202ccb6b DG |
685 | int kvm_put_vcpu_events(ARMCPU *cpu) |
686 | { | |
687 | CPUARMState *env = &cpu->env; | |
688 | struct kvm_vcpu_events events; | |
689 | int ret; | |
690 | ||
691 | if (!kvm_has_vcpu_events()) { | |
692 | return 0; | |
693 | } | |
694 | ||
695 | memset(&events, 0, sizeof(events)); | |
696 | events.exception.serror_pending = env->serror.pending; | |
697 | ||
698 | /* Inject SError to guest with specified syndrome if host kernel | |
699 | * supports it, otherwise inject SError without syndrome. | |
700 | */ | |
701 | if (cap_has_inject_serror_esr) { | |
702 | events.exception.serror_has_esr = env->serror.has_esr; | |
703 | events.exception.serror_esr = env->serror.esr; | |
704 | } | |
705 | ||
706 | ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_VCPU_EVENTS, &events); | |
707 | if (ret) { | |
708 | error_report("failed to put vcpu events"); | |
709 | } | |
710 | ||
711 | return ret; | |
712 | } | |
713 | ||
714 | int kvm_get_vcpu_events(ARMCPU *cpu) | |
715 | { | |
716 | CPUARMState *env = &cpu->env; | |
717 | struct kvm_vcpu_events events; | |
718 | int ret; | |
719 | ||
720 | if (!kvm_has_vcpu_events()) { | |
721 | return 0; | |
722 | } | |
723 | ||
724 | memset(&events, 0, sizeof(events)); | |
725 | ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_VCPU_EVENTS, &events); | |
726 | if (ret) { | |
727 | error_report("failed to get vcpu events"); | |
728 | return ret; | |
729 | } | |
730 | ||
731 | env->serror.pending = events.exception.serror_pending; | |
732 | env->serror.has_esr = events.exception.serror_has_esr; | |
733 | env->serror.esr = events.exception.serror_esr; | |
734 | ||
735 | return 0; | |
736 | } | |
737 | ||
494b00c7 CD |
738 | void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) |
739 | { | |
740 | } | |
741 | ||
4c663752 | 742 | MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) |
494b00c7 | 743 | { |
5d721b78 AG |
744 | ARMCPU *cpu; |
745 | uint32_t switched_level; | |
746 | ||
747 | if (kvm_irqchip_in_kernel()) { | |
748 | /* | |
749 | * We only need to sync timer states with user-space interrupt | |
750 | * controllers, so return early and save cycles if we don't. | |
751 | */ | |
752 | return MEMTXATTRS_UNSPECIFIED; | |
753 | } | |
754 | ||
755 | cpu = ARM_CPU(cs); | |
756 | ||
757 | /* Synchronize our shadowed in-kernel device irq lines with the kvm ones */ | |
758 | if (run->s.regs.device_irq_level != cpu->device_irq_level) { | |
759 | switched_level = cpu->device_irq_level ^ run->s.regs.device_irq_level; | |
760 | ||
761 | qemu_mutex_lock_iothread(); | |
762 | ||
763 | if (switched_level & KVM_ARM_DEV_EL1_VTIMER) { | |
764 | qemu_set_irq(cpu->gt_timer_outputs[GTIMER_VIRT], | |
765 | !!(run->s.regs.device_irq_level & | |
766 | KVM_ARM_DEV_EL1_VTIMER)); | |
767 | switched_level &= ~KVM_ARM_DEV_EL1_VTIMER; | |
768 | } | |
769 | ||
770 | if (switched_level & KVM_ARM_DEV_EL1_PTIMER) { | |
771 | qemu_set_irq(cpu->gt_timer_outputs[GTIMER_PHYS], | |
772 | !!(run->s.regs.device_irq_level & | |
773 | KVM_ARM_DEV_EL1_PTIMER)); | |
774 | switched_level &= ~KVM_ARM_DEV_EL1_PTIMER; | |
775 | } | |
776 | ||
b1659527 AJ |
777 | if (switched_level & KVM_ARM_DEV_PMU) { |
778 | qemu_set_irq(cpu->pmu_interrupt, | |
779 | !!(run->s.regs.device_irq_level & KVM_ARM_DEV_PMU)); | |
780 | switched_level &= ~KVM_ARM_DEV_PMU; | |
781 | } | |
5d721b78 AG |
782 | |
783 | if (switched_level) { | |
784 | qemu_log_mask(LOG_UNIMP, "%s: unhandled in-kernel device IRQ %x\n", | |
785 | __func__, switched_level); | |
786 | } | |
787 | ||
788 | /* We also mark unknown levels as processed to not waste cycles */ | |
789 | cpu->device_irq_level = run->s.regs.device_irq_level; | |
790 | qemu_mutex_unlock_iothread(); | |
791 | } | |
792 | ||
4c663752 | 793 | return MEMTXATTRS_UNSPECIFIED; |
494b00c7 CD |
794 | } |
795 | ||
e5ac4200 AJ |
796 | void kvm_arm_vm_state_change(void *opaque, int running, RunState state) |
797 | { | |
798 | CPUState *cs = opaque; | |
799 | ARMCPU *cpu = ARM_CPU(cs); | |
800 | ||
801 | if (running) { | |
802 | if (cpu->kvm_adjvtime) { | |
803 | kvm_arm_put_virtual_time(cs); | |
804 | } | |
805 | } else { | |
806 | if (cpu->kvm_adjvtime) { | |
807 | kvm_arm_get_virtual_time(cs); | |
808 | } | |
809 | } | |
810 | } | |
2ecb2027 | 811 | |
494b00c7 CD |
812 | int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) |
813 | { | |
2ecb2027 AB |
814 | int ret = 0; |
815 | ||
816 | switch (run->exit_reason) { | |
817 | case KVM_EXIT_DEBUG: | |
818 | if (kvm_arm_handle_debug(cs, &run->debug.arch)) { | |
819 | ret = EXCP_DEBUG; | |
820 | } /* otherwise return to guest */ | |
821 | break; | |
822 | default: | |
823 | qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n", | |
824 | __func__, run->exit_reason); | |
825 | break; | |
826 | } | |
827 | return ret; | |
494b00c7 CD |
828 | } |
829 | ||
494b00c7 CD |
830 | bool kvm_arch_stop_on_emulation_error(CPUState *cs) |
831 | { | |
832 | return true; | |
833 | } | |
834 | ||
835 | int kvm_arch_process_async_events(CPUState *cs) | |
836 | { | |
837 | return 0; | |
838 | } | |
839 | ||
2ecb2027 AB |
840 | /* The #ifdef protections are until 32bit headers are imported and can |
841 | * be removed once both 32 and 64 bit reach feature parity. | |
842 | */ | |
494b00c7 CD |
843 | void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg) |
844 | { | |
2ecb2027 AB |
845 | #ifdef KVM_GUESTDBG_USE_SW_BP |
846 | if (kvm_sw_breakpoints_active(cs)) { | |
847 | dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; | |
848 | } | |
849 | #endif | |
e4482ab7 AB |
850 | #ifdef KVM_GUESTDBG_USE_HW |
851 | if (kvm_arm_hw_debug_active(cs)) { | |
852 | dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW; | |
853 | kvm_arm_copy_hw_debug_data(&dbg->arch); | |
854 | } | |
855 | #endif | |
494b00c7 | 856 | } |
b3a1c626 AK |
857 | |
858 | void kvm_arch_init_irq_routing(KVMState *s) | |
859 | { | |
860 | } | |
1da41cc1 | 861 | |
4376c40d | 862 | int kvm_arch_irqchip_create(KVMState *s) |
1da41cc1 | 863 | { |
4376c40d PB |
864 | if (kvm_kernel_irqchip_split()) { |
865 | perror("-machine kernel_irqchip=split is not supported on ARM."); | |
866 | exit(1); | |
15eafc2e PB |
867 | } |
868 | ||
1da41cc1 CD |
869 | /* If we can create the VGIC using the newer device control API, we |
870 | * let the device do this when it initializes itself, otherwise we | |
871 | * fall back to the old API */ | |
34e85cd9 PF |
872 | return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL); |
873 | } | |
1da41cc1 | 874 | |
34e85cd9 PF |
875 | int kvm_arm_vgic_probe(void) |
876 | { | |
d45efe47 EA |
877 | int val = 0; |
878 | ||
34e85cd9 PF |
879 | if (kvm_create_device(kvm_state, |
880 | KVM_DEV_TYPE_ARM_VGIC_V3, true) == 0) { | |
d45efe47 EA |
881 | val |= KVM_ARM_VGIC_V3; |
882 | } | |
883 | if (kvm_create_device(kvm_state, | |
884 | KVM_DEV_TYPE_ARM_VGIC_V2, true) == 0) { | |
885 | val |= KVM_ARM_VGIC_V2; | |
1da41cc1 | 886 | } |
d45efe47 | 887 | return val; |
1da41cc1 | 888 | } |
9e03a040 | 889 | |
f6530926 EA |
890 | int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level) |
891 | { | |
892 | int kvm_irq = (irqtype << KVM_ARM_IRQ_TYPE_SHIFT) | irq; | |
893 | int cpu_idx1 = cpu % 256; | |
894 | int cpu_idx2 = cpu / 256; | |
895 | ||
896 | kvm_irq |= (cpu_idx1 << KVM_ARM_IRQ_VCPU_SHIFT) | | |
897 | (cpu_idx2 << KVM_ARM_IRQ_VCPU2_SHIFT); | |
898 | ||
899 | return kvm_set_irq(kvm_state, kvm_irq, !!level); | |
900 | } | |
901 | ||
9e03a040 | 902 | int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, |
dc9f06ca | 903 | uint64_t address, uint32_t data, PCIDevice *dev) |
9e03a040 | 904 | { |
b05c81d2 EA |
905 | AddressSpace *as = pci_device_iommu_address_space(dev); |
906 | hwaddr xlat, len, doorbell_gpa; | |
907 | MemoryRegionSection mrs; | |
908 | MemoryRegion *mr; | |
909 | int ret = 1; | |
910 | ||
911 | if (as == &address_space_memory) { | |
912 | return 0; | |
913 | } | |
914 | ||
915 | /* MSI doorbell address is translated by an IOMMU */ | |
916 | ||
917 | rcu_read_lock(); | |
bc6b1cec PM |
918 | mr = address_space_translate(as, address, &xlat, &len, true, |
919 | MEMTXATTRS_UNSPECIFIED); | |
b05c81d2 EA |
920 | if (!mr) { |
921 | goto unlock; | |
922 | } | |
923 | mrs = memory_region_find(mr, xlat, 1); | |
924 | if (!mrs.mr) { | |
925 | goto unlock; | |
926 | } | |
927 | ||
928 | doorbell_gpa = mrs.offset_within_address_space; | |
929 | memory_region_unref(mrs.mr); | |
930 | ||
931 | route->u.msi.address_lo = doorbell_gpa; | |
932 | route->u.msi.address_hi = doorbell_gpa >> 32; | |
933 | ||
934 | trace_kvm_arm_fixup_msi_route(address, doorbell_gpa); | |
935 | ||
936 | ret = 0; | |
937 | ||
938 | unlock: | |
939 | rcu_read_unlock(); | |
940 | return ret; | |
9e03a040 | 941 | } |
1850b6b7 | 942 | |
38d87493 PX |
943 | int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, |
944 | int vector, PCIDevice *dev) | |
945 | { | |
946 | return 0; | |
947 | } | |
948 | ||
949 | int kvm_arch_release_virq_post(int virq) | |
950 | { | |
951 | return 0; | |
952 | } | |
953 | ||
1850b6b7 EA |
954 | int kvm_arch_msi_data_to_gsi(uint32_t data) |
955 | { | |
956 | return (data - 32) & 0xffff; | |
957 | } |