| 1 | /* |
| 2 | * Xen HVM emulation support in KVM |
| 3 | * |
| 4 | * Copyright © 2019 Oracle and/or its affiliates. All rights reserved. |
| 5 | * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 6 | * |
| 7 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 8 | * See the COPYING file in the top-level directory. |
| 9 | * |
| 10 | */ |
| 11 | |
| 12 | #include "qemu/osdep.h" |
| 13 | #include "qemu/log.h" |
| 14 | #include "qemu/main-loop.h" |
| 15 | #include "qemu/error-report.h" |
| 16 | #include "exec/target_page.h" |
| 17 | #include "hw/xen/xen.h" |
| 18 | #include "system/kvm_int.h" |
| 19 | #include "system/kvm_xen.h" |
| 20 | #include "kvm/kvm_i386.h" |
| 21 | #include "system/address-spaces.h" |
| 22 | #include "xen-emu.h" |
| 23 | #include "trace.h" |
| 24 | #include "system/memory.h" |
| 25 | #include "system/runstate.h" |
| 26 | |
| 27 | #include "hw/pci/msi.h" |
| 28 | #include "hw/i386/apic-msidef.h" |
| 29 | #include "hw/i386/e820_memory_layout.h" |
| 30 | #include "hw/i386/kvm/xen_overlay.h" |
| 31 | #include "hw/i386/kvm/xen_evtchn.h" |
| 32 | #include "hw/i386/kvm/xen_gnttab.h" |
| 33 | #include "hw/i386/kvm/xen_primary_console.h" |
| 34 | #include "hw/i386/kvm/xen_xenstore.h" |
| 35 | |
| 36 | #include "hw/xen/interface/version.h" |
| 37 | #include "hw/xen/interface/sched.h" |
| 38 | #include "hw/xen/interface/memory.h" |
| 39 | #include "hw/xen/interface/hvm/hvm_op.h" |
| 40 | #include "hw/xen/interface/hvm/params.h" |
| 41 | #include "hw/xen/interface/vcpu.h" |
| 42 | #include "hw/xen/interface/event_channel.h" |
| 43 | #include "hw/xen/interface/grant_table.h" |
| 44 | |
| 45 | #include "xen-compat.h" |
| 46 | |
| 47 | NotifierWithReturn xen_vmfd_change_notifier; |
| 48 | static uint32_t xen_msr; |
| 49 | static void xen_vcpu_singleshot_timer_event(void *opaque); |
| 50 | static void xen_vcpu_periodic_timer_event(void *opaque); |
| 51 | static int vcpuop_stop_singleshot_timer(CPUState *cs); |
| 52 | static int do_initialize_xen_caps(KVMState *s, uint32_t hypercall_msr); |
| 53 | |
| 54 | #ifdef TARGET_X86_64 |
| 55 | #define hypercall_compat32(longmode) (!(longmode)) |
| 56 | #else |
| 57 | #define hypercall_compat32(longmode) (false) |
| 58 | #endif |
| 59 | |
| 60 | static int xen_handle_vmfd_change(NotifierWithReturn *n, |
| 61 | void *data, Error** errp) |
| 62 | { |
| 63 | int ret; |
| 64 | |
| 65 | /* we are not interested in pre vmfd change notification */ |
| 66 | if (((VmfdChangeNotifier *)data)->pre) { |
| 67 | return 0; |
| 68 | } |
| 69 | |
| 70 | ret = do_initialize_xen_caps(kvm_state, xen_msr); |
| 71 | if (ret < 0) { |
| 72 | return ret; |
| 73 | } |
| 74 | return 0; |
| 75 | } |
| 76 | |
| 77 | static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa, |
| 78 | size_t *len, bool is_write) |
| 79 | { |
| 80 | struct kvm_translation tr = { |
| 81 | .linear_address = gva, |
| 82 | }; |
| 83 | |
| 84 | if (len) { |
| 85 | *len = TARGET_PAGE_SIZE - (gva & ~TARGET_PAGE_MASK); |
| 86 | } |
| 87 | |
| 88 | if (kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr) || !tr.valid || |
| 89 | (is_write && !tr.writeable)) { |
| 90 | return false; |
| 91 | } |
| 92 | *gpa = tr.physical_address; |
| 93 | return true; |
| 94 | } |
| 95 | |
| 96 | static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz, |
| 97 | bool is_write) |
| 98 | { |
| 99 | AddressSpace *as = cpu_addressspace(cs, MEMTXATTRS_UNSPECIFIED); |
| 100 | uint8_t *buf = (uint8_t *)_buf; |
| 101 | uint64_t gpa; |
| 102 | size_t len; |
| 103 | |
| 104 | while (sz) { |
| 105 | if (!kvm_gva_to_gpa(cs, gva, &gpa, &len, is_write)) { |
| 106 | return -EFAULT; |
| 107 | } |
| 108 | if (len > sz) { |
| 109 | len = sz; |
| 110 | } |
| 111 | |
| 112 | address_space_rw(as, gpa, MEMTXATTRS_UNSPECIFIED, buf, len, is_write); |
| 113 | |
| 114 | buf += len; |
| 115 | sz -= len; |
| 116 | gva += len; |
| 117 | } |
| 118 | |
| 119 | return 0; |
| 120 | } |
| 121 | |
| 122 | static inline int kvm_copy_from_gva(CPUState *cs, uint64_t gva, void *buf, |
| 123 | size_t sz) |
| 124 | { |
| 125 | return kvm_gva_rw(cs, gva, buf, sz, false); |
| 126 | } |
| 127 | |
| 128 | static inline int kvm_copy_to_gva(CPUState *cs, uint64_t gva, void *buf, |
| 129 | size_t sz) |
| 130 | { |
| 131 | return kvm_gva_rw(cs, gva, buf, sz, true); |
| 132 | } |
| 133 | |
| 134 | static int do_initialize_xen_caps(KVMState *s, uint32_t hypercall_msr) |
| 135 | { |
| 136 | const int required_caps = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR | |
| 137 | KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL | KVM_XEN_HVM_CONFIG_SHARED_INFO; |
| 138 | struct kvm_xen_hvm_config cfg = { |
| 139 | .msr = hypercall_msr, |
| 140 | .flags = KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL, |
| 141 | }; |
| 142 | int xen_caps, ret; |
| 143 | |
| 144 | xen_caps = kvm_check_extension(s, KVM_CAP_XEN_HVM); |
| 145 | if (required_caps & ~xen_caps) { |
| 146 | error_report("kvm: Xen HVM guest support not present or insufficient"); |
| 147 | return -ENOSYS; |
| 148 | } |
| 149 | |
| 150 | if (xen_caps & KVM_XEN_HVM_CONFIG_EVTCHN_SEND) { |
| 151 | struct kvm_xen_hvm_attr ha = { |
| 152 | .type = KVM_XEN_ATTR_TYPE_XEN_VERSION, |
| 153 | .u.xen_version = s->xen_version, |
| 154 | }; |
| 155 | (void)kvm_vm_ioctl(s, KVM_XEN_HVM_SET_ATTR, &ha); |
| 156 | |
| 157 | cfg.flags |= KVM_XEN_HVM_CONFIG_EVTCHN_SEND; |
| 158 | } |
| 159 | |
| 160 | ret = kvm_vm_ioctl(s, KVM_XEN_HVM_CONFIG, &cfg); |
| 161 | if (ret < 0) { |
| 162 | error_report("kvm: Failed to enable Xen HVM support: %s", |
| 163 | strerror(-ret)); |
| 164 | return ret; |
| 165 | } |
| 166 | return xen_caps; |
| 167 | } |
| 168 | |
| 169 | int kvm_xen_init(KVMState *s, uint32_t hypercall_msr) |
| 170 | { |
| 171 | int xen_caps; |
| 172 | |
| 173 | xen_caps = do_initialize_xen_caps(s, hypercall_msr); |
| 174 | if (xen_caps < 0) { |
| 175 | return xen_caps; |
| 176 | } |
| 177 | |
| 178 | xen_msr = hypercall_msr; |
| 179 | |
| 180 | /* If called a second time, don't repeat the rest of the setup. */ |
| 181 | if (s->xen_caps) { |
| 182 | return 0; |
| 183 | } |
| 184 | |
| 185 | /* |
| 186 | * Event channel delivery via GSI/PCI_INTX needs to poll the vcpu_info |
| 187 | * of vCPU0 to deassert the IRQ when ->evtchn_upcall_pending is cleared. |
| 188 | * |
| 189 | * In the kernel, there's a notifier hook on the PIC/IOAPIC which allows |
| 190 | * such things to be polled at precisely the right time. We *could* do |
| 191 | * it nicely in the kernel: check vcpu_info[0]->evtchn_upcall_pending at |
| 192 | * the moment the IRQ is acked, and see if it should be reasserted. |
| 193 | * |
| 194 | * But the in-kernel irqchip is deprecated, so we're unlikely to add |
| 195 | * that support in the kernel. Insist on using the split irqchip mode |
| 196 | * instead. |
| 197 | * |
| 198 | * This leaves us polling for the level going low in QEMU, which lacks |
| 199 | * the appropriate hooks in its PIC/IOAPIC code. Even VFIO is sending a |
| 200 | * spurious 'ack' to an INTX IRQ every time there's any MMIO access to |
| 201 | * the device (for which it has to unmap the device and trap access, for |
| 202 | * some period after an IRQ!!). In the Xen case, we do it on exit from |
| 203 | * KVM_RUN, if the flag is set to say that the GSI is currently asserted. |
| 204 | * Which is kind of icky, but less so than the VFIO one. I may fix them |
| 205 | * both later... |
| 206 | */ |
| 207 | if (!kvm_kernel_irqchip_split()) { |
| 208 | error_report("kvm: Xen support requires kernel-irqchip=split"); |
| 209 | return -EINVAL; |
| 210 | } |
| 211 | |
| 212 | s->xen_caps = xen_caps; |
| 213 | |
| 214 | /* Tell fw_cfg to notify the BIOS to reserve the range. */ |
| 215 | e820_add_entry(XEN_SPECIAL_AREA_ADDR, XEN_SPECIAL_AREA_SIZE, E820_RESERVED); |
| 216 | |
| 217 | /* The pages couldn't be overlaid until KVM was initialized */ |
| 218 | xen_primary_console_reset(); |
| 219 | xen_xenstore_reset(); |
| 220 | |
| 221 | xen_vmfd_change_notifier.notify = xen_handle_vmfd_change; |
| 222 | kvm_vmfd_add_change_notifier(&xen_vmfd_change_notifier); |
| 223 | |
| 224 | return 0; |
| 225 | } |
| 226 | |
| 227 | int kvm_xen_init_vcpu(CPUState *cs) |
| 228 | { |
| 229 | X86CPU *cpu = X86_CPU(cs); |
| 230 | CPUX86State *env = &cpu->env; |
| 231 | int err; |
| 232 | |
| 233 | /* |
| 234 | * The kernel needs to know the Xen/ACPI vCPU ID because that's |
| 235 | * what the guest uses in hypercalls such as timers. It doesn't |
| 236 | * match the APIC ID which is generally used for talking to the |
| 237 | * kernel about vCPUs. And if vCPU threads race with creating |
| 238 | * their KVM vCPUs out of order, it doesn't necessarily match |
| 239 | * with the kernel's internal vCPU indices either. |
| 240 | */ |
| 241 | if (kvm_xen_has_cap(EVTCHN_SEND)) { |
| 242 | struct kvm_xen_vcpu_attr va = { |
| 243 | .type = KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID, |
| 244 | .u.vcpu_id = cs->cpu_index, |
| 245 | }; |
| 246 | err = kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &va); |
| 247 | if (err) { |
| 248 | error_report("kvm: Failed to set Xen vCPU ID attribute: %s", |
| 249 | strerror(-err)); |
| 250 | return err; |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | env->xen_vcpu_info_gpa = INVALID_GPA; |
| 255 | env->xen_vcpu_info_default_gpa = INVALID_GPA; |
| 256 | env->xen_vcpu_time_info_gpa = INVALID_GPA; |
| 257 | env->xen_vcpu_runstate_gpa = INVALID_GPA; |
| 258 | |
| 259 | qemu_mutex_init(&env->xen_timers_lock); |
| 260 | env->xen_singleshot_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, |
| 261 | xen_vcpu_singleshot_timer_event, |
| 262 | cpu); |
| 263 | if (!env->xen_singleshot_timer) { |
| 264 | return -ENOMEM; |
| 265 | } |
| 266 | env->xen_singleshot_timer->opaque = cs; |
| 267 | |
| 268 | env->xen_periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, |
| 269 | xen_vcpu_periodic_timer_event, |
| 270 | cpu); |
| 271 | if (!env->xen_periodic_timer) { |
| 272 | return -ENOMEM; |
| 273 | } |
| 274 | env->xen_periodic_timer->opaque = cs; |
| 275 | |
| 276 | return 0; |
| 277 | } |
| 278 | |
| 279 | uint32_t kvm_xen_get_caps(void) |
| 280 | { |
| 281 | return kvm_state->xen_caps; |
| 282 | } |
| 283 | |
| 284 | static bool kvm_xen_hcall_xen_version(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 285 | int cmd, uint64_t arg) |
| 286 | { |
| 287 | int err = 0; |
| 288 | |
| 289 | switch (cmd) { |
| 290 | case XENVER_get_features: { |
| 291 | struct xen_feature_info fi; |
| 292 | |
| 293 | /* No need for 32/64 compat handling */ |
| 294 | qemu_build_assert(sizeof(fi) == 8); |
| 295 | |
| 296 | err = kvm_copy_from_gva(CPU(cpu), arg, &fi, sizeof(fi)); |
| 297 | if (err) { |
| 298 | break; |
| 299 | } |
| 300 | |
| 301 | fi.submap = 0; |
| 302 | if (fi.submap_idx == 0) { |
| 303 | fi.submap |= 1 << XENFEAT_writable_page_tables | |
| 304 | 1 << XENFEAT_writable_descriptor_tables | |
| 305 | 1 << XENFEAT_auto_translated_physmap | |
| 306 | 1 << XENFEAT_hvm_callback_vector | |
| 307 | 1 << XENFEAT_hvm_safe_pvclock | |
| 308 | 1 << XENFEAT_hvm_pirqs; |
| 309 | } |
| 310 | |
| 311 | err = kvm_copy_to_gva(CPU(cpu), arg, &fi, sizeof(fi)); |
| 312 | break; |
| 313 | } |
| 314 | |
| 315 | default: |
| 316 | return false; |
| 317 | } |
| 318 | |
| 319 | exit->u.hcall.result = err; |
| 320 | return true; |
| 321 | } |
| 322 | |
| 323 | static int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, uint64_t gpa) |
| 324 | { |
| 325 | struct kvm_xen_vcpu_attr xhsi; |
| 326 | |
| 327 | xhsi.type = type; |
| 328 | xhsi.u.gpa = gpa; |
| 329 | |
| 330 | trace_kvm_xen_set_vcpu_attr(cs->cpu_index, type, gpa); |
| 331 | |
| 332 | return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xhsi); |
| 333 | } |
| 334 | |
| 335 | static int kvm_xen_set_vcpu_callback_vector(CPUState *cs) |
| 336 | { |
| 337 | uint8_t vector = X86_CPU(cs)->env.xen_vcpu_callback_vector; |
| 338 | struct kvm_xen_vcpu_attr xva; |
| 339 | |
| 340 | xva.type = KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR; |
| 341 | xva.u.vector = vector; |
| 342 | |
| 343 | trace_kvm_xen_set_vcpu_callback(cs->cpu_index, vector); |
| 344 | |
| 345 | return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xva); |
| 346 | } |
| 347 | |
| 348 | static void do_set_vcpu_callback_vector(CPUState *cs, run_on_cpu_data data) |
| 349 | { |
| 350 | X86CPU *cpu = X86_CPU(cs); |
| 351 | CPUX86State *env = &cpu->env; |
| 352 | |
| 353 | env->xen_vcpu_callback_vector = data.host_int; |
| 354 | |
| 355 | if (kvm_xen_has_cap(EVTCHN_SEND)) { |
| 356 | kvm_xen_set_vcpu_callback_vector(cs); |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | static int set_vcpu_info(CPUState *cs, uint64_t gpa) |
| 361 | { |
| 362 | X86CPU *cpu = X86_CPU(cs); |
| 363 | CPUX86State *env = &cpu->env; |
| 364 | MemoryRegionSection mrs = { .mr = NULL }; |
| 365 | void *vcpu_info_hva = NULL; |
| 366 | int ret; |
| 367 | |
| 368 | ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO, gpa); |
| 369 | if (ret || gpa == INVALID_GPA) { |
| 370 | goto out; |
| 371 | } |
| 372 | |
| 373 | mrs = memory_region_find(get_system_memory(), gpa, |
| 374 | sizeof(struct vcpu_info)); |
| 375 | if (mrs.mr && mrs.mr->ram_block && |
| 376 | !int128_lt(mrs.size, int128_make64(sizeof(struct vcpu_info)))) { |
| 377 | vcpu_info_hva = qemu_map_ram_ptr(mrs.mr->ram_block, |
| 378 | mrs.offset_within_region); |
| 379 | } |
| 380 | if (!vcpu_info_hva) { |
| 381 | if (mrs.mr) { |
| 382 | memory_region_unref(mrs.mr); |
| 383 | mrs.mr = NULL; |
| 384 | } |
| 385 | ret = -EINVAL; |
| 386 | } |
| 387 | |
| 388 | out: |
| 389 | if (env->xen_vcpu_info_mr) { |
| 390 | memory_region_unref(env->xen_vcpu_info_mr); |
| 391 | } |
| 392 | env->xen_vcpu_info_hva = vcpu_info_hva; |
| 393 | env->xen_vcpu_info_mr = mrs.mr; |
| 394 | return ret; |
| 395 | } |
| 396 | |
| 397 | static void do_set_vcpu_info_default_gpa(CPUState *cs, run_on_cpu_data data) |
| 398 | { |
| 399 | X86CPU *cpu = X86_CPU(cs); |
| 400 | CPUX86State *env = &cpu->env; |
| 401 | |
| 402 | env->xen_vcpu_info_default_gpa = data.host_ulong; |
| 403 | |
| 404 | /* Changing the default does nothing if a vcpu_info was explicitly set. */ |
| 405 | if (env->xen_vcpu_info_gpa == INVALID_GPA) { |
| 406 | set_vcpu_info(cs, env->xen_vcpu_info_default_gpa); |
| 407 | } |
| 408 | } |
| 409 | |
| 410 | static void do_set_vcpu_info_gpa(CPUState *cs, run_on_cpu_data data) |
| 411 | { |
| 412 | X86CPU *cpu = X86_CPU(cs); |
| 413 | CPUX86State *env = &cpu->env; |
| 414 | |
| 415 | env->xen_vcpu_info_gpa = data.host_ulong; |
| 416 | |
| 417 | set_vcpu_info(cs, env->xen_vcpu_info_gpa); |
| 418 | } |
| 419 | |
| 420 | void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id) |
| 421 | { |
| 422 | CPUState *cs = qemu_get_cpu(vcpu_id); |
| 423 | if (!cs) { |
| 424 | return NULL; |
| 425 | } |
| 426 | |
| 427 | return X86_CPU(cs)->env.xen_vcpu_info_hva; |
| 428 | } |
| 429 | |
| 430 | void kvm_xen_maybe_deassert_callback(CPUState *cs) |
| 431 | { |
| 432 | CPUX86State *env = &X86_CPU(cs)->env; |
| 433 | struct vcpu_info *vi = env->xen_vcpu_info_hva; |
| 434 | if (!vi) { |
| 435 | return; |
| 436 | } |
| 437 | |
| 438 | /* If the evtchn_upcall_pending flag is cleared, turn the GSI off. */ |
| 439 | if (!vi->evtchn_upcall_pending) { |
| 440 | bql_lock(); |
| 441 | /* |
| 442 | * Check again now we have the lock, because it may have been |
| 443 | * asserted in the interim. And we don't want to take the lock |
| 444 | * every time because this is a fast path. |
| 445 | */ |
| 446 | if (!vi->evtchn_upcall_pending) { |
| 447 | X86_CPU(cs)->env.xen_callback_asserted = false; |
| 448 | xen_evtchn_set_callback_level(0); |
| 449 | } |
| 450 | bql_unlock(); |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | void kvm_xen_set_callback_asserted(void) |
| 455 | { |
| 456 | CPUState *cs = qemu_get_cpu(0); |
| 457 | |
| 458 | if (cs) { |
| 459 | X86_CPU(cs)->env.xen_callback_asserted = true; |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | bool kvm_xen_has_vcpu_callback_vector(void) |
| 464 | { |
| 465 | CPUState *cs = qemu_get_cpu(0); |
| 466 | |
| 467 | return cs && !!X86_CPU(cs)->env.xen_vcpu_callback_vector; |
| 468 | } |
| 469 | |
| 470 | void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type) |
| 471 | { |
| 472 | CPUState *cs = qemu_get_cpu(vcpu_id); |
| 473 | uint8_t vector; |
| 474 | |
| 475 | if (!cs) { |
| 476 | return; |
| 477 | } |
| 478 | |
| 479 | vector = X86_CPU(cs)->env.xen_vcpu_callback_vector; |
| 480 | if (vector) { |
| 481 | /* |
| 482 | * The per-vCPU callback vector injected via lapic. Just |
| 483 | * deliver it as an MSI. |
| 484 | */ |
| 485 | MSIMessage msg = { |
| 486 | .address = APIC_DEFAULT_ADDRESS | |
| 487 | (X86_CPU(cs)->apic_id << MSI_ADDR_DEST_ID_SHIFT), |
| 488 | .data = vector | (1UL << MSI_DATA_LEVEL_SHIFT), |
| 489 | }; |
| 490 | kvm_irqchip_send_msi(kvm_state, msg); |
| 491 | return; |
| 492 | } |
| 493 | |
| 494 | switch (type) { |
| 495 | case HVM_PARAM_CALLBACK_TYPE_VECTOR: |
| 496 | /* |
| 497 | * If the evtchn_upcall_pending field in the vcpu_info is set, then |
| 498 | * KVM will automatically deliver the vector on entering the vCPU |
| 499 | * so all we have to do is kick it out. |
| 500 | */ |
| 501 | qemu_cpu_kick(cs); |
| 502 | break; |
| 503 | |
| 504 | case HVM_PARAM_CALLBACK_TYPE_GSI: |
| 505 | case HVM_PARAM_CALLBACK_TYPE_PCI_INTX: |
| 506 | if (vcpu_id == 0) { |
| 507 | xen_evtchn_set_callback_level(1); |
| 508 | } |
| 509 | break; |
| 510 | } |
| 511 | } |
| 512 | |
| 513 | /* Must always be called with xen_timers_lock held */ |
| 514 | static int kvm_xen_set_vcpu_timer(CPUState *cs) |
| 515 | { |
| 516 | X86CPU *cpu = X86_CPU(cs); |
| 517 | CPUX86State *env = &cpu->env; |
| 518 | |
| 519 | struct kvm_xen_vcpu_attr va = { |
| 520 | .type = KVM_XEN_VCPU_ATTR_TYPE_TIMER, |
| 521 | .u.timer.port = env->xen_virq[VIRQ_TIMER], |
| 522 | .u.timer.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL, |
| 523 | .u.timer.expires_ns = env->xen_singleshot_timer_ns, |
| 524 | }; |
| 525 | |
| 526 | return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &va); |
| 527 | } |
| 528 | |
| 529 | static void do_set_vcpu_timer_virq(CPUState *cs, run_on_cpu_data data) |
| 530 | { |
| 531 | QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock); |
| 532 | kvm_xen_set_vcpu_timer(cs); |
| 533 | } |
| 534 | |
| 535 | int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port) |
| 536 | { |
| 537 | CPUState *cs = qemu_get_cpu(vcpu_id); |
| 538 | |
| 539 | if (!cs) { |
| 540 | return -ENOENT; |
| 541 | } |
| 542 | |
| 543 | /* cpu.h doesn't include the actual Xen header. */ |
| 544 | qemu_build_assert(NR_VIRQS == XEN_NR_VIRQS); |
| 545 | |
| 546 | if (virq >= NR_VIRQS) { |
| 547 | return -EINVAL; |
| 548 | } |
| 549 | |
| 550 | if (port && X86_CPU(cs)->env.xen_virq[virq]) { |
| 551 | return -EEXIST; |
| 552 | } |
| 553 | |
| 554 | X86_CPU(cs)->env.xen_virq[virq] = port; |
| 555 | if (virq == VIRQ_TIMER && kvm_xen_has_cap(EVTCHN_SEND)) { |
| 556 | async_run_on_cpu(cs, do_set_vcpu_timer_virq, |
| 557 | RUN_ON_CPU_HOST_INT(port)); |
| 558 | } |
| 559 | return 0; |
| 560 | } |
| 561 | |
| 562 | static void do_set_vcpu_time_info_gpa(CPUState *cs, run_on_cpu_data data) |
| 563 | { |
| 564 | X86CPU *cpu = X86_CPU(cs); |
| 565 | CPUX86State *env = &cpu->env; |
| 566 | |
| 567 | env->xen_vcpu_time_info_gpa = data.host_ulong; |
| 568 | |
| 569 | kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO, |
| 570 | env->xen_vcpu_time_info_gpa); |
| 571 | } |
| 572 | |
| 573 | static void do_set_vcpu_runstate_gpa(CPUState *cs, run_on_cpu_data data) |
| 574 | { |
| 575 | X86CPU *cpu = X86_CPU(cs); |
| 576 | CPUX86State *env = &cpu->env; |
| 577 | |
| 578 | env->xen_vcpu_runstate_gpa = data.host_ulong; |
| 579 | |
| 580 | kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR, |
| 581 | env->xen_vcpu_runstate_gpa); |
| 582 | } |
| 583 | |
| 584 | static void do_vcpu_soft_reset(CPUState *cs, run_on_cpu_data data) |
| 585 | { |
| 586 | X86CPU *cpu = X86_CPU(cs); |
| 587 | CPUX86State *env = &cpu->env; |
| 588 | |
| 589 | env->xen_vcpu_info_gpa = INVALID_GPA; |
| 590 | env->xen_vcpu_info_default_gpa = INVALID_GPA; |
| 591 | env->xen_vcpu_time_info_gpa = INVALID_GPA; |
| 592 | env->xen_vcpu_runstate_gpa = INVALID_GPA; |
| 593 | env->xen_vcpu_callback_vector = 0; |
| 594 | memset(env->xen_virq, 0, sizeof(env->xen_virq)); |
| 595 | |
| 596 | set_vcpu_info(cs, INVALID_GPA); |
| 597 | kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO, |
| 598 | INVALID_GPA); |
| 599 | kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR, |
| 600 | INVALID_GPA); |
| 601 | if (kvm_xen_has_cap(EVTCHN_SEND)) { |
| 602 | kvm_xen_set_vcpu_callback_vector(cs); |
| 603 | |
| 604 | QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock); |
| 605 | env->xen_singleshot_timer_ns = 0; |
| 606 | kvm_xen_set_vcpu_timer(cs); |
| 607 | } else { |
| 608 | vcpuop_stop_singleshot_timer(cs); |
| 609 | }; |
| 610 | |
| 611 | } |
| 612 | |
| 613 | static int xen_set_shared_info(uint64_t gfn) |
| 614 | { |
| 615 | uint64_t gpa = gfn << TARGET_PAGE_BITS; |
| 616 | int i, err; |
| 617 | |
| 618 | BQL_LOCK_GUARD(); |
| 619 | |
| 620 | /* |
| 621 | * The xen_overlay device tells KVM about it too, since it had to |
| 622 | * do that on migration load anyway (unless we're going to jump |
| 623 | * through lots of hoops to maintain the fiction that this isn't |
| 624 | * KVM-specific. |
| 625 | */ |
| 626 | err = xen_overlay_map_shinfo_page(gpa); |
| 627 | if (err) { |
| 628 | return err; |
| 629 | } |
| 630 | |
| 631 | trace_kvm_xen_set_shared_info(gfn); |
| 632 | |
| 633 | for (i = 0; i < XEN_LEGACY_MAX_VCPUS; i++) { |
| 634 | CPUState *cpu = qemu_get_cpu(i); |
| 635 | if (cpu) { |
| 636 | async_run_on_cpu(cpu, do_set_vcpu_info_default_gpa, |
| 637 | RUN_ON_CPU_HOST_ULONG(gpa)); |
| 638 | } |
| 639 | gpa += sizeof(vcpu_info_t); |
| 640 | } |
| 641 | |
| 642 | return err; |
| 643 | } |
| 644 | |
| 645 | static int add_to_physmap_one(uint32_t space, uint64_t idx, uint64_t gfn) |
| 646 | { |
| 647 | switch (space) { |
| 648 | case XENMAPSPACE_shared_info: |
| 649 | if (idx > 0) { |
| 650 | return -EINVAL; |
| 651 | } |
| 652 | return xen_set_shared_info(gfn); |
| 653 | |
| 654 | case XENMAPSPACE_grant_table: |
| 655 | return xen_gnttab_map_page(idx, gfn); |
| 656 | |
| 657 | case XENMAPSPACE_gmfn: |
| 658 | case XENMAPSPACE_gmfn_range: |
| 659 | return -ENOTSUP; |
| 660 | |
| 661 | case XENMAPSPACE_gmfn_foreign: |
| 662 | case XENMAPSPACE_dev_mmio: |
| 663 | return -EPERM; |
| 664 | |
| 665 | default: |
| 666 | return -EINVAL; |
| 667 | } |
| 668 | } |
| 669 | |
| 670 | static int do_add_to_physmap(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 671 | uint64_t arg) |
| 672 | { |
| 673 | struct xen_add_to_physmap xatp; |
| 674 | CPUState *cs = CPU(cpu); |
| 675 | |
| 676 | if (hypercall_compat32(exit->u.hcall.longmode)) { |
| 677 | struct compat_xen_add_to_physmap xatp32; |
| 678 | |
| 679 | qemu_build_assert(sizeof(struct compat_xen_add_to_physmap) == 16); |
| 680 | if (kvm_copy_from_gva(cs, arg, &xatp32, sizeof(xatp32))) { |
| 681 | return -EFAULT; |
| 682 | } |
| 683 | xatp.domid = xatp32.domid; |
| 684 | xatp.size = xatp32.size; |
| 685 | xatp.space = xatp32.space; |
| 686 | xatp.idx = xatp32.idx; |
| 687 | xatp.gpfn = xatp32.gpfn; |
| 688 | } else { |
| 689 | if (kvm_copy_from_gva(cs, arg, &xatp, sizeof(xatp))) { |
| 690 | return -EFAULT; |
| 691 | } |
| 692 | } |
| 693 | |
| 694 | if (xatp.domid != DOMID_SELF && xatp.domid != xen_domid) { |
| 695 | return -ESRCH; |
| 696 | } |
| 697 | |
| 698 | return add_to_physmap_one(xatp.space, xatp.idx, xatp.gpfn); |
| 699 | } |
| 700 | |
| 701 | static int do_add_to_physmap_batch(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 702 | uint64_t arg) |
| 703 | { |
| 704 | struct xen_add_to_physmap_batch xatpb; |
| 705 | unsigned long idxs_gva, gpfns_gva, errs_gva; |
| 706 | CPUState *cs = CPU(cpu); |
| 707 | size_t op_sz; |
| 708 | |
| 709 | if (hypercall_compat32(exit->u.hcall.longmode)) { |
| 710 | struct compat_xen_add_to_physmap_batch xatpb32; |
| 711 | |
| 712 | qemu_build_assert(sizeof(struct compat_xen_add_to_physmap_batch) == 20); |
| 713 | if (kvm_copy_from_gva(cs, arg, &xatpb32, sizeof(xatpb32))) { |
| 714 | return -EFAULT; |
| 715 | } |
| 716 | xatpb.domid = xatpb32.domid; |
| 717 | xatpb.space = xatpb32.space; |
| 718 | xatpb.size = xatpb32.size; |
| 719 | |
| 720 | idxs_gva = xatpb32.idxs.c; |
| 721 | gpfns_gva = xatpb32.gpfns.c; |
| 722 | errs_gva = xatpb32.errs.c; |
| 723 | op_sz = sizeof(uint32_t); |
| 724 | } else { |
| 725 | if (kvm_copy_from_gva(cs, arg, &xatpb, sizeof(xatpb))) { |
| 726 | return -EFAULT; |
| 727 | } |
| 728 | op_sz = sizeof(unsigned long); |
| 729 | idxs_gva = (unsigned long)xatpb.idxs.p; |
| 730 | gpfns_gva = (unsigned long)xatpb.gpfns.p; |
| 731 | errs_gva = (unsigned long)xatpb.errs.p; |
| 732 | } |
| 733 | |
| 734 | if (xatpb.domid != DOMID_SELF && xatpb.domid != xen_domid) { |
| 735 | return -ESRCH; |
| 736 | } |
| 737 | |
| 738 | /* Explicitly invalid for the batch op. Not that we implement it anyway. */ |
| 739 | if (xatpb.space == XENMAPSPACE_gmfn_range) { |
| 740 | return -EINVAL; |
| 741 | } |
| 742 | |
| 743 | while (xatpb.size--) { |
| 744 | unsigned long idx = 0; |
| 745 | unsigned long gpfn = 0; |
| 746 | int err; |
| 747 | |
| 748 | /* For 32-bit compat this only copies the low 32 bits of each */ |
| 749 | if (kvm_copy_from_gva(cs, idxs_gva, &idx, op_sz) || |
| 750 | kvm_copy_from_gva(cs, gpfns_gva, &gpfn, op_sz)) { |
| 751 | return -EFAULT; |
| 752 | } |
| 753 | idxs_gva += op_sz; |
| 754 | gpfns_gva += op_sz; |
| 755 | |
| 756 | err = add_to_physmap_one(xatpb.space, idx, gpfn); |
| 757 | |
| 758 | if (kvm_copy_to_gva(cs, errs_gva, &err, sizeof(err))) { |
| 759 | return -EFAULT; |
| 760 | } |
| 761 | errs_gva += sizeof(err); |
| 762 | } |
| 763 | return 0; |
| 764 | } |
| 765 | |
| 766 | static bool kvm_xen_hcall_memory_op(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 767 | int cmd, uint64_t arg) |
| 768 | { |
| 769 | int err; |
| 770 | |
| 771 | switch (cmd) { |
| 772 | case XENMEM_add_to_physmap: |
| 773 | err = do_add_to_physmap(exit, cpu, arg); |
| 774 | break; |
| 775 | |
| 776 | case XENMEM_add_to_physmap_batch: |
| 777 | err = do_add_to_physmap_batch(exit, cpu, arg); |
| 778 | break; |
| 779 | |
| 780 | default: |
| 781 | return false; |
| 782 | } |
| 783 | |
| 784 | exit->u.hcall.result = err; |
| 785 | return true; |
| 786 | } |
| 787 | |
| 788 | static bool handle_set_param(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 789 | uint64_t arg) |
| 790 | { |
| 791 | CPUState *cs = CPU(cpu); |
| 792 | struct xen_hvm_param hp; |
| 793 | int err = 0; |
| 794 | |
| 795 | /* No need for 32/64 compat handling */ |
| 796 | qemu_build_assert(sizeof(hp) == 16); |
| 797 | |
| 798 | if (kvm_copy_from_gva(cs, arg, &hp, sizeof(hp))) { |
| 799 | err = -EFAULT; |
| 800 | goto out; |
| 801 | } |
| 802 | |
| 803 | if (hp.domid != DOMID_SELF && hp.domid != xen_domid) { |
| 804 | err = -ESRCH; |
| 805 | goto out; |
| 806 | } |
| 807 | |
| 808 | switch (hp.index) { |
| 809 | case HVM_PARAM_CALLBACK_IRQ: |
| 810 | bql_lock(); |
| 811 | err = xen_evtchn_set_callback_param(hp.value); |
| 812 | bql_unlock(); |
| 813 | xen_set_long_mode(exit->u.hcall.longmode); |
| 814 | break; |
| 815 | default: |
| 816 | return false; |
| 817 | } |
| 818 | |
| 819 | out: |
| 820 | exit->u.hcall.result = err; |
| 821 | return true; |
| 822 | } |
| 823 | |
| 824 | static bool handle_get_param(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 825 | uint64_t arg) |
| 826 | { |
| 827 | CPUState *cs = CPU(cpu); |
| 828 | struct xen_hvm_param hp; |
| 829 | int err = 0; |
| 830 | |
| 831 | /* No need for 32/64 compat handling */ |
| 832 | qemu_build_assert(sizeof(hp) == 16); |
| 833 | |
| 834 | if (kvm_copy_from_gva(cs, arg, &hp, sizeof(hp))) { |
| 835 | err = -EFAULT; |
| 836 | goto out; |
| 837 | } |
| 838 | |
| 839 | if (hp.domid != DOMID_SELF && hp.domid != xen_domid) { |
| 840 | err = -ESRCH; |
| 841 | goto out; |
| 842 | } |
| 843 | |
| 844 | switch (hp.index) { |
| 845 | case HVM_PARAM_STORE_PFN: |
| 846 | hp.value = XEN_SPECIAL_PFN(XENSTORE); |
| 847 | break; |
| 848 | case HVM_PARAM_STORE_EVTCHN: |
| 849 | hp.value = xen_xenstore_get_port(); |
| 850 | break; |
| 851 | case HVM_PARAM_CONSOLE_PFN: |
| 852 | hp.value = xen_primary_console_get_pfn(); |
| 853 | if (!hp.value) { |
| 854 | err = -EINVAL; |
| 855 | } |
| 856 | break; |
| 857 | case HVM_PARAM_CONSOLE_EVTCHN: |
| 858 | hp.value = xen_primary_console_get_port(); |
| 859 | if (!hp.value) { |
| 860 | err = -EINVAL; |
| 861 | } |
| 862 | break; |
| 863 | default: |
| 864 | return false; |
| 865 | } |
| 866 | |
| 867 | if (!err && kvm_copy_to_gva(cs, arg, &hp, sizeof(hp))) { |
| 868 | err = -EFAULT; |
| 869 | } |
| 870 | out: |
| 871 | exit->u.hcall.result = err; |
| 872 | return true; |
| 873 | } |
| 874 | |
| 875 | static int kvm_xen_hcall_evtchn_upcall_vector(struct kvm_xen_exit *exit, |
| 876 | X86CPU *cpu, uint64_t arg) |
| 877 | { |
| 878 | struct xen_hvm_evtchn_upcall_vector up; |
| 879 | CPUState *target_cs; |
| 880 | |
| 881 | /* No need for 32/64 compat handling */ |
| 882 | qemu_build_assert(sizeof(up) == 8); |
| 883 | |
| 884 | if (kvm_copy_from_gva(CPU(cpu), arg, &up, sizeof(up))) { |
| 885 | return -EFAULT; |
| 886 | } |
| 887 | |
| 888 | if (up.vector < 0x10) { |
| 889 | return -EINVAL; |
| 890 | } |
| 891 | |
| 892 | target_cs = qemu_get_cpu(up.vcpu); |
| 893 | if (!target_cs) { |
| 894 | return -EINVAL; |
| 895 | } |
| 896 | |
| 897 | async_run_on_cpu(target_cs, do_set_vcpu_callback_vector, |
| 898 | RUN_ON_CPU_HOST_INT(up.vector)); |
| 899 | return 0; |
| 900 | } |
| 901 | |
| 902 | static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 903 | int cmd, uint64_t arg) |
| 904 | { |
| 905 | int ret = -ENOSYS; |
| 906 | switch (cmd) { |
| 907 | case HVMOP_set_evtchn_upcall_vector: |
| 908 | ret = kvm_xen_hcall_evtchn_upcall_vector(exit, cpu, arg); |
| 909 | break; |
| 910 | |
| 911 | case HVMOP_pagetable_dying: |
| 912 | ret = -ENOSYS; |
| 913 | break; |
| 914 | |
| 915 | case HVMOP_set_param: |
| 916 | return handle_set_param(exit, cpu, arg); |
| 917 | |
| 918 | case HVMOP_get_param: |
| 919 | return handle_get_param(exit, cpu, arg); |
| 920 | |
| 921 | default: |
| 922 | return false; |
| 923 | } |
| 924 | |
| 925 | exit->u.hcall.result = ret; |
| 926 | return true; |
| 927 | } |
| 928 | |
| 929 | static int vcpuop_register_vcpu_info(CPUState *cs, CPUState *target, |
| 930 | uint64_t arg) |
| 931 | { |
| 932 | struct vcpu_register_vcpu_info rvi; |
| 933 | uint64_t gpa; |
| 934 | |
| 935 | /* No need for 32/64 compat handling */ |
| 936 | qemu_build_assert(sizeof(rvi) == 16); |
| 937 | qemu_build_assert(sizeof(struct vcpu_info) == 64); |
| 938 | |
| 939 | if (!target) { |
| 940 | return -ENOENT; |
| 941 | } |
| 942 | |
| 943 | if (kvm_copy_from_gva(cs, arg, &rvi, sizeof(rvi))) { |
| 944 | return -EFAULT; |
| 945 | } |
| 946 | |
| 947 | if (rvi.offset > TARGET_PAGE_SIZE - sizeof(struct vcpu_info)) { |
| 948 | return -EINVAL; |
| 949 | } |
| 950 | |
| 951 | gpa = ((rvi.mfn << TARGET_PAGE_BITS) + rvi.offset); |
| 952 | async_run_on_cpu(target, do_set_vcpu_info_gpa, RUN_ON_CPU_HOST_ULONG(gpa)); |
| 953 | return 0; |
| 954 | } |
| 955 | |
| 956 | static int vcpuop_register_vcpu_time_info(CPUState *cs, CPUState *target, |
| 957 | uint64_t arg) |
| 958 | { |
| 959 | struct vcpu_register_time_memory_area tma; |
| 960 | uint64_t gpa; |
| 961 | size_t len; |
| 962 | |
| 963 | /* No need for 32/64 compat handling */ |
| 964 | qemu_build_assert(sizeof(tma) == 8); |
| 965 | qemu_build_assert(sizeof(struct vcpu_time_info) == 32); |
| 966 | |
| 967 | if (!target) { |
| 968 | return -ENOENT; |
| 969 | } |
| 970 | |
| 971 | if (kvm_copy_from_gva(cs, arg, &tma, sizeof(tma))) { |
| 972 | return -EFAULT; |
| 973 | } |
| 974 | |
| 975 | /* |
| 976 | * Xen actually uses the GVA and does the translation through the guest |
| 977 | * page tables each time. But Linux/KVM uses the GPA, on the assumption |
| 978 | * that guests only ever use *global* addresses (kernel virtual addresses) |
| 979 | * for it. If Linux is changed to redo the GVA→GPA translation each time, |
| 980 | * it will offer a new vCPU attribute for that, and we'll use it instead. |
| 981 | */ |
| 982 | if (!kvm_gva_to_gpa(cs, tma.addr.p, &gpa, &len, false) || |
| 983 | len < sizeof(struct vcpu_time_info)) { |
| 984 | return -EFAULT; |
| 985 | } |
| 986 | |
| 987 | async_run_on_cpu(target, do_set_vcpu_time_info_gpa, |
| 988 | RUN_ON_CPU_HOST_ULONG(gpa)); |
| 989 | return 0; |
| 990 | } |
| 991 | |
| 992 | static int vcpuop_register_runstate_info(CPUState *cs, CPUState *target, |
| 993 | uint64_t arg) |
| 994 | { |
| 995 | struct vcpu_register_runstate_memory_area rma; |
| 996 | uint64_t gpa; |
| 997 | size_t len; |
| 998 | |
| 999 | /* No need for 32/64 compat handling */ |
| 1000 | qemu_build_assert(sizeof(rma) == 8); |
| 1001 | /* The runstate area actually does change size, but Linux copes. */ |
| 1002 | |
| 1003 | if (!target) { |
| 1004 | return -ENOENT; |
| 1005 | } |
| 1006 | |
| 1007 | if (kvm_copy_from_gva(cs, arg, &rma, sizeof(rma))) { |
| 1008 | return -EFAULT; |
| 1009 | } |
| 1010 | |
| 1011 | /* As with vcpu_time_info, Xen actually uses the GVA but KVM doesn't. */ |
| 1012 | if (!kvm_gva_to_gpa(cs, rma.addr.p, &gpa, &len, false)) { |
| 1013 | return -EFAULT; |
| 1014 | } |
| 1015 | |
| 1016 | async_run_on_cpu(target, do_set_vcpu_runstate_gpa, |
| 1017 | RUN_ON_CPU_HOST_ULONG(gpa)); |
| 1018 | return 0; |
| 1019 | } |
| 1020 | |
| 1021 | static uint64_t kvm_get_current_ns(void) |
| 1022 | { |
| 1023 | struct kvm_clock_data data; |
| 1024 | int ret; |
| 1025 | |
| 1026 | ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); |
| 1027 | if (ret < 0) { |
| 1028 | fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); |
| 1029 | abort(); |
| 1030 | } |
| 1031 | |
| 1032 | return data.clock; |
| 1033 | } |
| 1034 | |
| 1035 | static void xen_vcpu_singleshot_timer_event(void *opaque) |
| 1036 | { |
| 1037 | CPUState *cpu = opaque; |
| 1038 | CPUX86State *env = &X86_CPU(cpu)->env; |
| 1039 | uint16_t port = env->xen_virq[VIRQ_TIMER]; |
| 1040 | |
| 1041 | if (likely(port)) { |
| 1042 | xen_evtchn_set_port(port); |
| 1043 | } |
| 1044 | |
| 1045 | qemu_mutex_lock(&env->xen_timers_lock); |
| 1046 | env->xen_singleshot_timer_ns = 0; |
| 1047 | qemu_mutex_unlock(&env->xen_timers_lock); |
| 1048 | } |
| 1049 | |
| 1050 | static void xen_vcpu_periodic_timer_event(void *opaque) |
| 1051 | { |
| 1052 | CPUState *cpu = opaque; |
| 1053 | CPUX86State *env = &X86_CPU(cpu)->env; |
| 1054 | uint16_t port = env->xen_virq[VIRQ_TIMER]; |
| 1055 | int64_t qemu_now; |
| 1056 | |
| 1057 | if (likely(port)) { |
| 1058 | xen_evtchn_set_port(port); |
| 1059 | } |
| 1060 | |
| 1061 | qemu_mutex_lock(&env->xen_timers_lock); |
| 1062 | |
| 1063 | qemu_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
| 1064 | timer_mod_ns(env->xen_periodic_timer, |
| 1065 | qemu_now + env->xen_periodic_timer_period); |
| 1066 | |
| 1067 | qemu_mutex_unlock(&env->xen_timers_lock); |
| 1068 | } |
| 1069 | |
| 1070 | static int do_set_periodic_timer(CPUState *target, uint64_t period_ns) |
| 1071 | { |
| 1072 | CPUX86State *tenv = &X86_CPU(target)->env; |
| 1073 | int64_t qemu_now; |
| 1074 | |
| 1075 | timer_del(tenv->xen_periodic_timer); |
| 1076 | |
| 1077 | qemu_mutex_lock(&tenv->xen_timers_lock); |
| 1078 | |
| 1079 | qemu_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
| 1080 | timer_mod_ns(tenv->xen_periodic_timer, qemu_now + period_ns); |
| 1081 | tenv->xen_periodic_timer_period = period_ns; |
| 1082 | |
| 1083 | qemu_mutex_unlock(&tenv->xen_timers_lock); |
| 1084 | return 0; |
| 1085 | } |
| 1086 | |
| 1087 | #define MILLISECS(_ms) ((int64_t)((_ms) * 1000000ULL)) |
| 1088 | #define MICROSECS(_us) ((int64_t)((_us) * 1000ULL)) |
| 1089 | #define STIME_MAX ((time_t)((int64_t)~0ull >> 1)) |
| 1090 | /* Chosen so (NOW() + delta) won't overflow without an uptime of 200 years */ |
| 1091 | #define STIME_DELTA_MAX ((int64_t)((uint64_t)~0ull >> 2)) |
| 1092 | |
| 1093 | static int vcpuop_set_periodic_timer(CPUState *cs, CPUState *target, |
| 1094 | uint64_t arg) |
| 1095 | { |
| 1096 | struct vcpu_set_periodic_timer spt; |
| 1097 | |
| 1098 | qemu_build_assert(sizeof(spt) == 8); |
| 1099 | if (kvm_copy_from_gva(cs, arg, &spt, sizeof(spt))) { |
| 1100 | return -EFAULT; |
| 1101 | } |
| 1102 | |
| 1103 | if (spt.period_ns < MILLISECS(1) || spt.period_ns > STIME_DELTA_MAX) { |
| 1104 | return -EINVAL; |
| 1105 | } |
| 1106 | |
| 1107 | return do_set_periodic_timer(target, spt.period_ns); |
| 1108 | } |
| 1109 | |
| 1110 | static int vcpuop_stop_periodic_timer(CPUState *target) |
| 1111 | { |
| 1112 | CPUX86State *tenv = &X86_CPU(target)->env; |
| 1113 | |
| 1114 | qemu_mutex_lock(&tenv->xen_timers_lock); |
| 1115 | |
| 1116 | timer_del(tenv->xen_periodic_timer); |
| 1117 | tenv->xen_periodic_timer_period = 0; |
| 1118 | |
| 1119 | qemu_mutex_unlock(&tenv->xen_timers_lock); |
| 1120 | return 0; |
| 1121 | } |
| 1122 | |
| 1123 | /* |
| 1124 | * Userspace handling of timer, for older kernels. |
| 1125 | * Must always be called with xen_timers_lock held. |
| 1126 | */ |
| 1127 | static int do_set_singleshot_timer(CPUState *cs, uint64_t timeout_abs, |
| 1128 | bool linux_wa) |
| 1129 | { |
| 1130 | CPUX86State *env = &X86_CPU(cs)->env; |
| 1131 | int64_t now = kvm_get_current_ns(); |
| 1132 | int64_t qemu_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
| 1133 | int64_t delta = timeout_abs - now; |
| 1134 | |
| 1135 | if (linux_wa && unlikely((int64_t)timeout_abs < 0 || |
| 1136 | (delta > 0 && (uint32_t)(delta >> 50) != 0))) { |
| 1137 | /* |
| 1138 | * Xen has a 'Linux workaround' in do_set_timer_op() which checks |
| 1139 | * for negative absolute timeout values (caused by integer |
| 1140 | * overflow), and for values about 13 days in the future (2^50ns) |
| 1141 | * which would be caused by jiffies overflow. For those cases, it |
| 1142 | * sets the timeout 100ms in the future (not *too* soon, since if |
| 1143 | * a guest really did set a long timeout on purpose we don't want |
| 1144 | * to keep churning CPU time by waking it up). |
| 1145 | */ |
| 1146 | delta = (100 * SCALE_MS); |
| 1147 | timeout_abs = now + delta; |
| 1148 | } |
| 1149 | |
| 1150 | timer_mod_ns(env->xen_singleshot_timer, qemu_now + delta); |
| 1151 | env->xen_singleshot_timer_ns = now + delta; |
| 1152 | return 0; |
| 1153 | } |
| 1154 | |
| 1155 | static int vcpuop_set_singleshot_timer(CPUState *cs, uint64_t arg) |
| 1156 | { |
| 1157 | struct vcpu_set_singleshot_timer sst = { 0 }; |
| 1158 | |
| 1159 | /* |
| 1160 | * The struct is a uint64_t followed by a uint32_t. On 32-bit that |
| 1161 | * makes it 12 bytes. On 64-bit it gets padded to 16. The parts |
| 1162 | * that get used are identical, and there's four bytes of padding |
| 1163 | * unused at the end. For true Xen compatibility we should attempt |
| 1164 | * to copy the full 16 bytes from 64-bit guests, and return -EFAULT |
| 1165 | * if we can't get the padding too. But that's daft. Just copy what |
| 1166 | * we need. |
| 1167 | */ |
| 1168 | qemu_build_assert(offsetof(struct vcpu_set_singleshot_timer, flags) == 8); |
| 1169 | qemu_build_assert(sizeof(sst) >= 12); |
| 1170 | |
| 1171 | if (kvm_copy_from_gva(cs, arg, &sst, 12)) { |
| 1172 | return -EFAULT; |
| 1173 | } |
| 1174 | |
| 1175 | QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock); |
| 1176 | |
| 1177 | /* |
| 1178 | * We ignore the VCPU_SSHOTTMR_future flag, just as Xen now does. |
| 1179 | * The only guest that ever used it, got it wrong. |
| 1180 | * https://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=19c6cbd909 |
| 1181 | */ |
| 1182 | return do_set_singleshot_timer(cs, sst.timeout_abs_ns, false); |
| 1183 | } |
| 1184 | |
| 1185 | static int vcpuop_stop_singleshot_timer(CPUState *cs) |
| 1186 | { |
| 1187 | CPUX86State *env = &X86_CPU(cs)->env; |
| 1188 | |
| 1189 | qemu_mutex_lock(&env->xen_timers_lock); |
| 1190 | |
| 1191 | timer_del(env->xen_singleshot_timer); |
| 1192 | env->xen_singleshot_timer_ns = 0; |
| 1193 | |
| 1194 | qemu_mutex_unlock(&env->xen_timers_lock); |
| 1195 | return 0; |
| 1196 | } |
| 1197 | |
| 1198 | static bool kvm_xen_hcall_set_timer_op(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 1199 | uint64_t timeout) |
| 1200 | { |
| 1201 | int err; |
| 1202 | |
| 1203 | if (unlikely(timeout == 0)) { |
| 1204 | err = vcpuop_stop_singleshot_timer(CPU(cpu)); |
| 1205 | } else { |
| 1206 | QEMU_LOCK_GUARD(&X86_CPU(cpu)->env.xen_timers_lock); |
| 1207 | err = do_set_singleshot_timer(CPU(cpu), timeout, true); |
| 1208 | } |
| 1209 | exit->u.hcall.result = err; |
| 1210 | return true; |
| 1211 | } |
| 1212 | |
| 1213 | static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 1214 | int cmd, int vcpu_id, uint64_t arg) |
| 1215 | { |
| 1216 | CPUState *cs = CPU(cpu); |
| 1217 | CPUState *dest = cs->cpu_index == vcpu_id ? cs : qemu_get_cpu(vcpu_id); |
| 1218 | int err; |
| 1219 | |
| 1220 | if (!dest) { |
| 1221 | err = -ENOENT; |
| 1222 | goto out; |
| 1223 | } |
| 1224 | |
| 1225 | switch (cmd) { |
| 1226 | case VCPUOP_register_runstate_memory_area: |
| 1227 | err = vcpuop_register_runstate_info(cs, dest, arg); |
| 1228 | break; |
| 1229 | case VCPUOP_register_vcpu_time_memory_area: |
| 1230 | err = vcpuop_register_vcpu_time_info(cs, dest, arg); |
| 1231 | break; |
| 1232 | case VCPUOP_register_vcpu_info: |
| 1233 | err = vcpuop_register_vcpu_info(cs, dest, arg); |
| 1234 | break; |
| 1235 | case VCPUOP_set_singleshot_timer: { |
| 1236 | if (cs->cpu_index == vcpu_id) { |
| 1237 | err = vcpuop_set_singleshot_timer(dest, arg); |
| 1238 | } else { |
| 1239 | err = -EINVAL; |
| 1240 | } |
| 1241 | break; |
| 1242 | } |
| 1243 | case VCPUOP_stop_singleshot_timer: |
| 1244 | if (cs->cpu_index == vcpu_id) { |
| 1245 | err = vcpuop_stop_singleshot_timer(dest); |
| 1246 | } else { |
| 1247 | err = -EINVAL; |
| 1248 | } |
| 1249 | break; |
| 1250 | case VCPUOP_set_periodic_timer: { |
| 1251 | err = vcpuop_set_periodic_timer(cs, dest, arg); |
| 1252 | break; |
| 1253 | } |
| 1254 | case VCPUOP_stop_periodic_timer: |
| 1255 | err = vcpuop_stop_periodic_timer(dest); |
| 1256 | break; |
| 1257 | |
| 1258 | default: |
| 1259 | return false; |
| 1260 | } |
| 1261 | |
| 1262 | out: |
| 1263 | exit->u.hcall.result = err; |
| 1264 | return true; |
| 1265 | } |
| 1266 | |
| 1267 | static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 1268 | int cmd, uint64_t arg) |
| 1269 | { |
| 1270 | CPUState *cs = CPU(cpu); |
| 1271 | int err = -ENOSYS; |
| 1272 | |
| 1273 | switch (cmd) { |
| 1274 | case EVTCHNOP_init_control: |
| 1275 | case EVTCHNOP_expand_array: |
| 1276 | case EVTCHNOP_set_priority: |
| 1277 | /* We do not support FIFO channels at this point */ |
| 1278 | err = -ENOSYS; |
| 1279 | break; |
| 1280 | |
| 1281 | case EVTCHNOP_status: { |
| 1282 | struct evtchn_status status; |
| 1283 | |
| 1284 | qemu_build_assert(sizeof(status) == 24); |
| 1285 | if (kvm_copy_from_gva(cs, arg, &status, sizeof(status))) { |
| 1286 | err = -EFAULT; |
| 1287 | break; |
| 1288 | } |
| 1289 | |
| 1290 | err = xen_evtchn_status_op(&status); |
| 1291 | if (!err && kvm_copy_to_gva(cs, arg, &status, sizeof(status))) { |
| 1292 | err = -EFAULT; |
| 1293 | } |
| 1294 | break; |
| 1295 | } |
| 1296 | case EVTCHNOP_close: { |
| 1297 | struct evtchn_close close; |
| 1298 | |
| 1299 | qemu_build_assert(sizeof(close) == 4); |
| 1300 | if (kvm_copy_from_gva(cs, arg, &close, sizeof(close))) { |
| 1301 | err = -EFAULT; |
| 1302 | break; |
| 1303 | } |
| 1304 | |
| 1305 | err = xen_evtchn_close_op(&close); |
| 1306 | break; |
| 1307 | } |
| 1308 | case EVTCHNOP_unmask: { |
| 1309 | struct evtchn_unmask unmask; |
| 1310 | |
| 1311 | qemu_build_assert(sizeof(unmask) == 4); |
| 1312 | if (kvm_copy_from_gva(cs, arg, &unmask, sizeof(unmask))) { |
| 1313 | err = -EFAULT; |
| 1314 | break; |
| 1315 | } |
| 1316 | |
| 1317 | err = xen_evtchn_unmask_op(&unmask); |
| 1318 | break; |
| 1319 | } |
| 1320 | case EVTCHNOP_bind_virq: { |
| 1321 | struct evtchn_bind_virq virq; |
| 1322 | |
| 1323 | qemu_build_assert(sizeof(virq) == 12); |
| 1324 | if (kvm_copy_from_gva(cs, arg, &virq, sizeof(virq))) { |
| 1325 | err = -EFAULT; |
| 1326 | break; |
| 1327 | } |
| 1328 | |
| 1329 | err = xen_evtchn_bind_virq_op(&virq); |
| 1330 | if (!err && kvm_copy_to_gva(cs, arg, &virq, sizeof(virq))) { |
| 1331 | err = -EFAULT; |
| 1332 | } |
| 1333 | break; |
| 1334 | } |
| 1335 | case EVTCHNOP_bind_pirq: { |
| 1336 | struct evtchn_bind_pirq pirq; |
| 1337 | |
| 1338 | qemu_build_assert(sizeof(pirq) == 12); |
| 1339 | if (kvm_copy_from_gva(cs, arg, &pirq, sizeof(pirq))) { |
| 1340 | err = -EFAULT; |
| 1341 | break; |
| 1342 | } |
| 1343 | |
| 1344 | err = xen_evtchn_bind_pirq_op(&pirq); |
| 1345 | if (!err && kvm_copy_to_gva(cs, arg, &pirq, sizeof(pirq))) { |
| 1346 | err = -EFAULT; |
| 1347 | } |
| 1348 | break; |
| 1349 | } |
| 1350 | case EVTCHNOP_bind_ipi: { |
| 1351 | struct evtchn_bind_ipi ipi; |
| 1352 | |
| 1353 | qemu_build_assert(sizeof(ipi) == 8); |
| 1354 | if (kvm_copy_from_gva(cs, arg, &ipi, sizeof(ipi))) { |
| 1355 | err = -EFAULT; |
| 1356 | break; |
| 1357 | } |
| 1358 | |
| 1359 | err = xen_evtchn_bind_ipi_op(&ipi); |
| 1360 | if (!err && kvm_copy_to_gva(cs, arg, &ipi, sizeof(ipi))) { |
| 1361 | err = -EFAULT; |
| 1362 | } |
| 1363 | break; |
| 1364 | } |
| 1365 | case EVTCHNOP_send: { |
| 1366 | struct evtchn_send send; |
| 1367 | |
| 1368 | qemu_build_assert(sizeof(send) == 4); |
| 1369 | if (kvm_copy_from_gva(cs, arg, &send, sizeof(send))) { |
| 1370 | err = -EFAULT; |
| 1371 | break; |
| 1372 | } |
| 1373 | |
| 1374 | err = xen_evtchn_send_op(&send); |
| 1375 | break; |
| 1376 | } |
| 1377 | case EVTCHNOP_alloc_unbound: { |
| 1378 | struct evtchn_alloc_unbound alloc; |
| 1379 | |
| 1380 | qemu_build_assert(sizeof(alloc) == 8); |
| 1381 | if (kvm_copy_from_gva(cs, arg, &alloc, sizeof(alloc))) { |
| 1382 | err = -EFAULT; |
| 1383 | break; |
| 1384 | } |
| 1385 | |
| 1386 | err = xen_evtchn_alloc_unbound_op(&alloc); |
| 1387 | if (!err && kvm_copy_to_gva(cs, arg, &alloc, sizeof(alloc))) { |
| 1388 | err = -EFAULT; |
| 1389 | } |
| 1390 | break; |
| 1391 | } |
| 1392 | case EVTCHNOP_bind_interdomain: { |
| 1393 | struct evtchn_bind_interdomain interdomain; |
| 1394 | |
| 1395 | qemu_build_assert(sizeof(interdomain) == 12); |
| 1396 | if (kvm_copy_from_gva(cs, arg, &interdomain, sizeof(interdomain))) { |
| 1397 | err = -EFAULT; |
| 1398 | break; |
| 1399 | } |
| 1400 | |
| 1401 | err = xen_evtchn_bind_interdomain_op(&interdomain); |
| 1402 | if (!err && |
| 1403 | kvm_copy_to_gva(cs, arg, &interdomain, sizeof(interdomain))) { |
| 1404 | err = -EFAULT; |
| 1405 | } |
| 1406 | break; |
| 1407 | } |
| 1408 | case EVTCHNOP_bind_vcpu: { |
| 1409 | struct evtchn_bind_vcpu vcpu; |
| 1410 | |
| 1411 | qemu_build_assert(sizeof(vcpu) == 8); |
| 1412 | if (kvm_copy_from_gva(cs, arg, &vcpu, sizeof(vcpu))) { |
| 1413 | err = -EFAULT; |
| 1414 | break; |
| 1415 | } |
| 1416 | |
| 1417 | err = xen_evtchn_bind_vcpu_op(&vcpu); |
| 1418 | break; |
| 1419 | } |
| 1420 | case EVTCHNOP_reset: { |
| 1421 | struct evtchn_reset reset; |
| 1422 | |
| 1423 | qemu_build_assert(sizeof(reset) == 2); |
| 1424 | if (kvm_copy_from_gva(cs, arg, &reset, sizeof(reset))) { |
| 1425 | err = -EFAULT; |
| 1426 | break; |
| 1427 | } |
| 1428 | |
| 1429 | err = xen_evtchn_reset_op(&reset); |
| 1430 | break; |
| 1431 | } |
| 1432 | default: |
| 1433 | return false; |
| 1434 | } |
| 1435 | |
| 1436 | exit->u.hcall.result = err; |
| 1437 | return true; |
| 1438 | } |
| 1439 | |
| 1440 | int kvm_xen_soft_reset(void) |
| 1441 | { |
| 1442 | CPUState *cpu; |
| 1443 | int err; |
| 1444 | |
| 1445 | assert(bql_locked()); |
| 1446 | |
| 1447 | trace_kvm_xen_soft_reset(); |
| 1448 | |
| 1449 | err = xen_evtchn_soft_reset(); |
| 1450 | if (err) { |
| 1451 | return err; |
| 1452 | } |
| 1453 | |
| 1454 | /* |
| 1455 | * Zero is the reset/startup state for HVM_PARAM_CALLBACK_IRQ. Strictly, |
| 1456 | * it maps to HVM_PARAM_CALLBACK_TYPE_GSI with GSI#0, but Xen refuses to |
| 1457 | * to deliver to the timer interrupt and treats that as 'disabled'. |
| 1458 | */ |
| 1459 | err = xen_evtchn_set_callback_param(0); |
| 1460 | if (err) { |
| 1461 | return err; |
| 1462 | } |
| 1463 | |
| 1464 | CPU_FOREACH(cpu) { |
| 1465 | async_run_on_cpu(cpu, do_vcpu_soft_reset, RUN_ON_CPU_NULL); |
| 1466 | } |
| 1467 | |
| 1468 | err = xen_overlay_map_shinfo_page(INVALID_GFN); |
| 1469 | if (err) { |
| 1470 | return err; |
| 1471 | } |
| 1472 | |
| 1473 | err = xen_gnttab_reset(); |
| 1474 | if (err) { |
| 1475 | return err; |
| 1476 | } |
| 1477 | |
| 1478 | err = xen_primary_console_reset(); |
| 1479 | if (err) { |
| 1480 | return err; |
| 1481 | } |
| 1482 | |
| 1483 | err = xen_xenstore_reset(); |
| 1484 | if (err) { |
| 1485 | return err; |
| 1486 | } |
| 1487 | |
| 1488 | return 0; |
| 1489 | } |
| 1490 | |
| 1491 | static int schedop_shutdown(CPUState *cs, uint64_t arg) |
| 1492 | { |
| 1493 | struct sched_shutdown shutdown; |
| 1494 | int ret = 0; |
| 1495 | |
| 1496 | /* No need for 32/64 compat handling */ |
| 1497 | qemu_build_assert(sizeof(shutdown) == 4); |
| 1498 | |
| 1499 | if (kvm_copy_from_gva(cs, arg, &shutdown, sizeof(shutdown))) { |
| 1500 | return -EFAULT; |
| 1501 | } |
| 1502 | |
| 1503 | switch (shutdown.reason) { |
| 1504 | case SHUTDOWN_crash: |
| 1505 | cpu_dump_state(cs, stderr, CPU_DUMP_CODE); |
| 1506 | qemu_system_guest_panicked(NULL); |
| 1507 | break; |
| 1508 | |
| 1509 | case SHUTDOWN_reboot: |
| 1510 | qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); |
| 1511 | break; |
| 1512 | |
| 1513 | case SHUTDOWN_poweroff: |
| 1514 | qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); |
| 1515 | break; |
| 1516 | |
| 1517 | case SHUTDOWN_soft_reset: |
| 1518 | bql_lock(); |
| 1519 | ret = kvm_xen_soft_reset(); |
| 1520 | bql_unlock(); |
| 1521 | break; |
| 1522 | |
| 1523 | default: |
| 1524 | ret = -EINVAL; |
| 1525 | break; |
| 1526 | } |
| 1527 | |
| 1528 | return ret; |
| 1529 | } |
| 1530 | |
| 1531 | static bool kvm_xen_hcall_sched_op(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 1532 | int cmd, uint64_t arg) |
| 1533 | { |
| 1534 | CPUState *cs = CPU(cpu); |
| 1535 | int err = -ENOSYS; |
| 1536 | |
| 1537 | switch (cmd) { |
| 1538 | case SCHEDOP_shutdown: |
| 1539 | err = schedop_shutdown(cs, arg); |
| 1540 | break; |
| 1541 | |
| 1542 | case SCHEDOP_poll: |
| 1543 | /* |
| 1544 | * Linux will panic if this doesn't work. Just yield; it's not |
| 1545 | * worth overthinking it because with event channel handling |
| 1546 | * in KVM, the kernel will intercept this and it will never |
| 1547 | * reach QEMU anyway. The semantics of the hypercall explicltly |
| 1548 | * permit spurious wakeups. |
| 1549 | */ |
| 1550 | case SCHEDOP_yield: |
| 1551 | sched_yield(); |
| 1552 | err = 0; |
| 1553 | break; |
| 1554 | |
| 1555 | default: |
| 1556 | return false; |
| 1557 | } |
| 1558 | |
| 1559 | exit->u.hcall.result = err; |
| 1560 | return true; |
| 1561 | } |
| 1562 | |
| 1563 | static bool kvm_xen_hcall_gnttab_op(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 1564 | int cmd, uint64_t arg, int count) |
| 1565 | { |
| 1566 | CPUState *cs = CPU(cpu); |
| 1567 | int err; |
| 1568 | |
| 1569 | switch (cmd) { |
| 1570 | case GNTTABOP_set_version: { |
| 1571 | struct gnttab_set_version set; |
| 1572 | |
| 1573 | qemu_build_assert(sizeof(set) == 4); |
| 1574 | if (kvm_copy_from_gva(cs, arg, &set, sizeof(set))) { |
| 1575 | err = -EFAULT; |
| 1576 | break; |
| 1577 | } |
| 1578 | |
| 1579 | err = xen_gnttab_set_version_op(&set); |
| 1580 | if (!err && kvm_copy_to_gva(cs, arg, &set, sizeof(set))) { |
| 1581 | err = -EFAULT; |
| 1582 | } |
| 1583 | break; |
| 1584 | } |
| 1585 | case GNTTABOP_get_version: { |
| 1586 | struct gnttab_get_version get; |
| 1587 | |
| 1588 | qemu_build_assert(sizeof(get) == 8); |
| 1589 | if (kvm_copy_from_gva(cs, arg, &get, sizeof(get))) { |
| 1590 | err = -EFAULT; |
| 1591 | break; |
| 1592 | } |
| 1593 | |
| 1594 | err = xen_gnttab_get_version_op(&get); |
| 1595 | if (!err && kvm_copy_to_gva(cs, arg, &get, sizeof(get))) { |
| 1596 | err = -EFAULT; |
| 1597 | } |
| 1598 | break; |
| 1599 | } |
| 1600 | case GNTTABOP_query_size: { |
| 1601 | struct gnttab_query_size size; |
| 1602 | |
| 1603 | qemu_build_assert(sizeof(size) == 16); |
| 1604 | if (kvm_copy_from_gva(cs, arg, &size, sizeof(size))) { |
| 1605 | err = -EFAULT; |
| 1606 | break; |
| 1607 | } |
| 1608 | |
| 1609 | err = xen_gnttab_query_size_op(&size); |
| 1610 | if (!err && kvm_copy_to_gva(cs, arg, &size, sizeof(size))) { |
| 1611 | err = -EFAULT; |
| 1612 | } |
| 1613 | break; |
| 1614 | } |
| 1615 | case GNTTABOP_setup_table: |
| 1616 | case GNTTABOP_copy: |
| 1617 | case GNTTABOP_map_grant_ref: |
| 1618 | case GNTTABOP_unmap_grant_ref: |
| 1619 | case GNTTABOP_swap_grant_ref: |
| 1620 | return false; |
| 1621 | |
| 1622 | default: |
| 1623 | /* Xen explicitly returns -ENOSYS to HVM guests for all others */ |
| 1624 | err = -ENOSYS; |
| 1625 | break; |
| 1626 | } |
| 1627 | |
| 1628 | exit->u.hcall.result = err; |
| 1629 | return true; |
| 1630 | } |
| 1631 | |
| 1632 | static bool kvm_xen_hcall_physdev_op(struct kvm_xen_exit *exit, X86CPU *cpu, |
| 1633 | int cmd, uint64_t arg) |
| 1634 | { |
| 1635 | CPUState *cs = CPU(cpu); |
| 1636 | int err; |
| 1637 | |
| 1638 | switch (cmd) { |
| 1639 | case PHYSDEVOP_map_pirq: { |
| 1640 | struct physdev_map_pirq map; |
| 1641 | |
| 1642 | if (hypercall_compat32(exit->u.hcall.longmode)) { |
| 1643 | struct compat_physdev_map_pirq *map32 = (void *)↦ |
| 1644 | |
| 1645 | if (kvm_copy_from_gva(cs, arg, map32, sizeof(*map32))) { |
| 1646 | return -EFAULT; |
| 1647 | } |
| 1648 | |
| 1649 | /* |
| 1650 | * The only thing that's different is the alignment of the |
| 1651 | * uint64_t table_base at the end, which gets padding to make |
| 1652 | * it 64-bit aligned in the 64-bit version. |
| 1653 | */ |
| 1654 | qemu_build_assert(sizeof(*map32) == 36); |
| 1655 | qemu_build_assert(offsetof(struct physdev_map_pirq, entry_nr) == |
| 1656 | offsetof(struct compat_physdev_map_pirq, entry_nr)); |
| 1657 | memmove(&map.table_base, &map32->table_base, sizeof(map.table_base)); |
| 1658 | } else { |
| 1659 | if (kvm_copy_from_gva(cs, arg, &map, sizeof(map))) { |
| 1660 | err = -EFAULT; |
| 1661 | break; |
| 1662 | } |
| 1663 | } |
| 1664 | err = xen_physdev_map_pirq(&map); |
| 1665 | /* |
| 1666 | * Since table_base is an IN parameter and won't be changed, just |
| 1667 | * copy the size of the compat structure back to the guest. |
| 1668 | */ |
| 1669 | if (!err && kvm_copy_to_gva(cs, arg, &map, |
| 1670 | sizeof(struct compat_physdev_map_pirq))) { |
| 1671 | err = -EFAULT; |
| 1672 | } |
| 1673 | break; |
| 1674 | } |
| 1675 | case PHYSDEVOP_unmap_pirq: { |
| 1676 | struct physdev_unmap_pirq unmap; |
| 1677 | |
| 1678 | qemu_build_assert(sizeof(unmap) == 8); |
| 1679 | if (kvm_copy_from_gva(cs, arg, &unmap, sizeof(unmap))) { |
| 1680 | err = -EFAULT; |
| 1681 | break; |
| 1682 | } |
| 1683 | |
| 1684 | err = xen_physdev_unmap_pirq(&unmap); |
| 1685 | if (!err && kvm_copy_to_gva(cs, arg, &unmap, sizeof(unmap))) { |
| 1686 | err = -EFAULT; |
| 1687 | } |
| 1688 | break; |
| 1689 | } |
| 1690 | case PHYSDEVOP_eoi: { |
| 1691 | struct physdev_eoi eoi; |
| 1692 | |
| 1693 | qemu_build_assert(sizeof(eoi) == 4); |
| 1694 | if (kvm_copy_from_gva(cs, arg, &eoi, sizeof(eoi))) { |
| 1695 | err = -EFAULT; |
| 1696 | break; |
| 1697 | } |
| 1698 | |
| 1699 | err = xen_physdev_eoi_pirq(&eoi); |
| 1700 | if (!err && kvm_copy_to_gva(cs, arg, &eoi, sizeof(eoi))) { |
| 1701 | err = -EFAULT; |
| 1702 | } |
| 1703 | break; |
| 1704 | } |
| 1705 | case PHYSDEVOP_irq_status_query: { |
| 1706 | struct physdev_irq_status_query query; |
| 1707 | |
| 1708 | qemu_build_assert(sizeof(query) == 8); |
| 1709 | if (kvm_copy_from_gva(cs, arg, &query, sizeof(query))) { |
| 1710 | err = -EFAULT; |
| 1711 | break; |
| 1712 | } |
| 1713 | |
| 1714 | err = xen_physdev_query_pirq(&query); |
| 1715 | if (!err && kvm_copy_to_gva(cs, arg, &query, sizeof(query))) { |
| 1716 | err = -EFAULT; |
| 1717 | } |
| 1718 | break; |
| 1719 | } |
| 1720 | case PHYSDEVOP_get_free_pirq: { |
| 1721 | struct physdev_get_free_pirq get; |
| 1722 | |
| 1723 | qemu_build_assert(sizeof(get) == 8); |
| 1724 | if (kvm_copy_from_gva(cs, arg, &get, sizeof(get))) { |
| 1725 | err = -EFAULT; |
| 1726 | break; |
| 1727 | } |
| 1728 | |
| 1729 | err = xen_physdev_get_free_pirq(&get); |
| 1730 | if (!err && kvm_copy_to_gva(cs, arg, &get, sizeof(get))) { |
| 1731 | err = -EFAULT; |
| 1732 | } |
| 1733 | break; |
| 1734 | } |
| 1735 | case PHYSDEVOP_pirq_eoi_gmfn_v2: /* FreeBSD 13 makes this hypercall */ |
| 1736 | err = -ENOSYS; |
| 1737 | break; |
| 1738 | |
| 1739 | default: |
| 1740 | return false; |
| 1741 | } |
| 1742 | |
| 1743 | exit->u.hcall.result = err; |
| 1744 | return true; |
| 1745 | } |
| 1746 | |
| 1747 | static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) |
| 1748 | { |
| 1749 | uint16_t code = exit->u.hcall.input; |
| 1750 | |
| 1751 | if (exit->u.hcall.cpl > 0) { |
| 1752 | exit->u.hcall.result = -EPERM; |
| 1753 | return true; |
| 1754 | } |
| 1755 | |
| 1756 | switch (code) { |
| 1757 | case __HYPERVISOR_set_timer_op: |
| 1758 | if (exit->u.hcall.longmode) { |
| 1759 | return kvm_xen_hcall_set_timer_op(exit, cpu, |
| 1760 | exit->u.hcall.params[0]); |
| 1761 | } else { |
| 1762 | /* In 32-bit mode, the 64-bit timer value is in two args. */ |
| 1763 | uint64_t val = ((uint64_t)exit->u.hcall.params[1]) << 32 | |
| 1764 | (uint32_t)exit->u.hcall.params[0]; |
| 1765 | return kvm_xen_hcall_set_timer_op(exit, cpu, val); |
| 1766 | } |
| 1767 | case __HYPERVISOR_grant_table_op: |
| 1768 | return kvm_xen_hcall_gnttab_op(exit, cpu, exit->u.hcall.params[0], |
| 1769 | exit->u.hcall.params[1], |
| 1770 | exit->u.hcall.params[2]); |
| 1771 | case __HYPERVISOR_sched_op: |
| 1772 | return kvm_xen_hcall_sched_op(exit, cpu, exit->u.hcall.params[0], |
| 1773 | exit->u.hcall.params[1]); |
| 1774 | case __HYPERVISOR_event_channel_op: |
| 1775 | return kvm_xen_hcall_evtchn_op(exit, cpu, exit->u.hcall.params[0], |
| 1776 | exit->u.hcall.params[1]); |
| 1777 | case __HYPERVISOR_vcpu_op: |
| 1778 | return kvm_xen_hcall_vcpu_op(exit, cpu, |
| 1779 | exit->u.hcall.params[0], |
| 1780 | exit->u.hcall.params[1], |
| 1781 | exit->u.hcall.params[2]); |
| 1782 | case __HYPERVISOR_hvm_op: |
| 1783 | return kvm_xen_hcall_hvm_op(exit, cpu, exit->u.hcall.params[0], |
| 1784 | exit->u.hcall.params[1]); |
| 1785 | case __HYPERVISOR_memory_op: |
| 1786 | return kvm_xen_hcall_memory_op(exit, cpu, exit->u.hcall.params[0], |
| 1787 | exit->u.hcall.params[1]); |
| 1788 | case __HYPERVISOR_physdev_op: |
| 1789 | return kvm_xen_hcall_physdev_op(exit, cpu, exit->u.hcall.params[0], |
| 1790 | exit->u.hcall.params[1]); |
| 1791 | case __HYPERVISOR_xen_version: |
| 1792 | return kvm_xen_hcall_xen_version(exit, cpu, exit->u.hcall.params[0], |
| 1793 | exit->u.hcall.params[1]); |
| 1794 | default: |
| 1795 | return false; |
| 1796 | } |
| 1797 | } |
| 1798 | |
| 1799 | int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) |
| 1800 | { |
| 1801 | if (exit->type != KVM_EXIT_XEN_HCALL) { |
| 1802 | return -1; |
| 1803 | } |
| 1804 | |
| 1805 | /* |
| 1806 | * The kernel latches the guest 32/64 mode when the MSR is used to fill |
| 1807 | * the hypercall page. So if we see a hypercall in a mode that doesn't |
| 1808 | * match our own idea of the guest mode, fetch the kernel's idea of the |
| 1809 | * "long mode" to remain in sync. |
| 1810 | */ |
| 1811 | if (exit->u.hcall.longmode != xen_is_long_mode()) { |
| 1812 | xen_sync_long_mode(); |
| 1813 | } |
| 1814 | |
| 1815 | if (!do_kvm_xen_handle_exit(cpu, exit)) { |
| 1816 | /* |
| 1817 | * Some hypercalls will be deliberately "implemented" by returning |
| 1818 | * -ENOSYS. This case is for hypercalls which are unexpected. |
| 1819 | */ |
| 1820 | exit->u.hcall.result = -ENOSYS; |
| 1821 | qemu_log_mask(LOG_UNIMP, "Unimplemented Xen hypercall %" |
| 1822 | PRId64 " (0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 ")\n", |
| 1823 | (uint64_t)exit->u.hcall.input, |
| 1824 | (uint64_t)exit->u.hcall.params[0], |
| 1825 | (uint64_t)exit->u.hcall.params[1], |
| 1826 | (uint64_t)exit->u.hcall.params[2]); |
| 1827 | } |
| 1828 | |
| 1829 | trace_kvm_xen_hypercall(CPU(cpu)->cpu_index, exit->u.hcall.cpl, |
| 1830 | exit->u.hcall.input, exit->u.hcall.params[0], |
| 1831 | exit->u.hcall.params[1], exit->u.hcall.params[2], |
| 1832 | exit->u.hcall.result); |
| 1833 | return 0; |
| 1834 | } |
| 1835 | |
| 1836 | uint16_t kvm_xen_get_gnttab_max_frames(void) |
| 1837 | { |
| 1838 | KVMState *s = KVM_STATE(current_accel()); |
| 1839 | return s->xen_gnttab_max_frames; |
| 1840 | } |
| 1841 | |
| 1842 | uint16_t kvm_xen_get_evtchn_max_pirq(void) |
| 1843 | { |
| 1844 | KVMState *s = KVM_STATE(current_accel()); |
| 1845 | return s->xen_evtchn_max_pirq; |
| 1846 | } |
| 1847 | |
| 1848 | int kvm_put_xen_state(CPUState *cs) |
| 1849 | { |
| 1850 | X86CPU *cpu = X86_CPU(cs); |
| 1851 | CPUX86State *env = &cpu->env; |
| 1852 | uint64_t gpa; |
| 1853 | int ret; |
| 1854 | |
| 1855 | gpa = env->xen_vcpu_info_gpa; |
| 1856 | if (gpa == INVALID_GPA) { |
| 1857 | gpa = env->xen_vcpu_info_default_gpa; |
| 1858 | } |
| 1859 | |
| 1860 | if (gpa != INVALID_GPA) { |
| 1861 | ret = set_vcpu_info(cs, gpa); |
| 1862 | if (ret < 0) { |
| 1863 | return ret; |
| 1864 | } |
| 1865 | } |
| 1866 | |
| 1867 | gpa = env->xen_vcpu_time_info_gpa; |
| 1868 | if (gpa != INVALID_GPA) { |
| 1869 | ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO, |
| 1870 | gpa); |
| 1871 | if (ret < 0) { |
| 1872 | return ret; |
| 1873 | } |
| 1874 | } |
| 1875 | |
| 1876 | gpa = env->xen_vcpu_runstate_gpa; |
| 1877 | if (gpa != INVALID_GPA) { |
| 1878 | ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR, |
| 1879 | gpa); |
| 1880 | if (ret < 0) { |
| 1881 | return ret; |
| 1882 | } |
| 1883 | } |
| 1884 | |
| 1885 | if (env->xen_periodic_timer_period) { |
| 1886 | ret = do_set_periodic_timer(cs, env->xen_periodic_timer_period); |
| 1887 | if (ret < 0) { |
| 1888 | return ret; |
| 1889 | } |
| 1890 | } |
| 1891 | |
| 1892 | if (!kvm_xen_has_cap(EVTCHN_SEND)) { |
| 1893 | /* |
| 1894 | * If the kernel has EVTCHN_SEND support then it handles timers too, |
| 1895 | * so the timer will be restored by kvm_xen_set_vcpu_timer() below. |
| 1896 | */ |
| 1897 | QEMU_LOCK_GUARD(&env->xen_timers_lock); |
| 1898 | if (env->xen_singleshot_timer_ns) { |
| 1899 | ret = do_set_singleshot_timer(cs, env->xen_singleshot_timer_ns, |
| 1900 | false); |
| 1901 | if (ret < 0) { |
| 1902 | return ret; |
| 1903 | } |
| 1904 | } |
| 1905 | return 0; |
| 1906 | } |
| 1907 | |
| 1908 | if (env->xen_vcpu_callback_vector) { |
| 1909 | ret = kvm_xen_set_vcpu_callback_vector(cs); |
| 1910 | if (ret < 0) { |
| 1911 | return ret; |
| 1912 | } |
| 1913 | } |
| 1914 | |
| 1915 | if (env->xen_virq[VIRQ_TIMER]) { |
| 1916 | do_set_vcpu_timer_virq(cs, |
| 1917 | RUN_ON_CPU_HOST_INT(env->xen_virq[VIRQ_TIMER])); |
| 1918 | } |
| 1919 | return 0; |
| 1920 | } |
| 1921 | |
| 1922 | int kvm_get_xen_state(CPUState *cs) |
| 1923 | { |
| 1924 | X86CPU *cpu = X86_CPU(cs); |
| 1925 | CPUX86State *env = &cpu->env; |
| 1926 | uint64_t gpa; |
| 1927 | int ret; |
| 1928 | |
| 1929 | /* |
| 1930 | * The kernel does not mark vcpu_info as dirty when it delivers interrupts |
| 1931 | * to it. It's up to userspace to *assume* that any page shared thus is |
| 1932 | * always considered dirty. The shared_info page is different since it's |
| 1933 | * an overlay and migrated separately anyway. |
| 1934 | */ |
| 1935 | gpa = env->xen_vcpu_info_gpa; |
| 1936 | if (gpa == INVALID_GPA) { |
| 1937 | gpa = env->xen_vcpu_info_default_gpa; |
| 1938 | } |
| 1939 | if (gpa != INVALID_GPA) { |
| 1940 | MemoryRegionSection mrs = memory_region_find(get_system_memory(), |
| 1941 | gpa, |
| 1942 | sizeof(struct vcpu_info)); |
| 1943 | if (mrs.mr && |
| 1944 | !int128_lt(mrs.size, int128_make64(sizeof(struct vcpu_info)))) { |
| 1945 | memory_region_set_dirty(mrs.mr, mrs.offset_within_region, |
| 1946 | sizeof(struct vcpu_info)); |
| 1947 | } |
| 1948 | } |
| 1949 | |
| 1950 | if (!kvm_xen_has_cap(EVTCHN_SEND)) { |
| 1951 | return 0; |
| 1952 | } |
| 1953 | |
| 1954 | /* |
| 1955 | * If the kernel is accelerating timers, read out the current value of the |
| 1956 | * singleshot timer deadline. |
| 1957 | */ |
| 1958 | if (env->xen_virq[VIRQ_TIMER]) { |
| 1959 | struct kvm_xen_vcpu_attr va = { |
| 1960 | .type = KVM_XEN_VCPU_ATTR_TYPE_TIMER, |
| 1961 | }; |
| 1962 | ret = kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_GET_ATTR, &va); |
| 1963 | if (ret < 0) { |
| 1964 | return ret; |
| 1965 | } |
| 1966 | |
| 1967 | /* |
| 1968 | * This locking is fairly pointless, and is here to appease Coverity. |
| 1969 | * There is an unavoidable race condition if a different vCPU sets a |
| 1970 | * timer for this vCPU after the value has been read out. But that's |
| 1971 | * OK in practice because *all* the vCPUs need to be stopped before |
| 1972 | * we set about migrating their state. |
| 1973 | */ |
| 1974 | QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock); |
| 1975 | env->xen_singleshot_timer_ns = va.u.timer.expires_ns; |
| 1976 | } |
| 1977 | |
| 1978 | return 0; |
| 1979 | } |