1162 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright © 2021 Amazon.com, Inc. or its affiliates.4 */5 6#include "test_util.h"7#include "kvm_util.h"8#include "processor.h"9 10#include <stdint.h>11#include <time.h>12#include <sched.h>13#include <signal.h>14#include <pthread.h>15 16#include <sys/eventfd.h>17 18#define SHINFO_REGION_GVA 0xc0000000ULL19#define SHINFO_REGION_GPA 0xc0000000ULL20#define SHINFO_REGION_SLOT 1021 22#define DUMMY_REGION_GPA (SHINFO_REGION_GPA + (3 * PAGE_SIZE))23#define DUMMY_REGION_SLOT 1124 25#define DUMMY_REGION_GPA_2 (SHINFO_REGION_GPA + (4 * PAGE_SIZE))26#define DUMMY_REGION_SLOT_2 1227 28#define SHINFO_ADDR (SHINFO_REGION_GPA)29#define VCPU_INFO_ADDR (SHINFO_REGION_GPA + 0x40)30#define PVTIME_ADDR (SHINFO_REGION_GPA + PAGE_SIZE)31#define RUNSTATE_ADDR (SHINFO_REGION_GPA + PAGE_SIZE + PAGE_SIZE - 15)32 33#define SHINFO_VADDR (SHINFO_REGION_GVA)34#define VCPU_INFO_VADDR (SHINFO_REGION_GVA + 0x40)35#define RUNSTATE_VADDR (SHINFO_REGION_GVA + PAGE_SIZE + PAGE_SIZE - 15)36 37#define EVTCHN_VECTOR 0x1038 39#define EVTCHN_TEST1 1540#define EVTCHN_TEST2 6641#define EVTCHN_TIMER 1342 43enum {44 TEST_INJECT_VECTOR = 0,45 TEST_RUNSTATE_runnable,46 TEST_RUNSTATE_blocked,47 TEST_RUNSTATE_offline,48 TEST_RUNSTATE_ADJUST,49 TEST_RUNSTATE_DATA,50 TEST_STEAL_TIME,51 TEST_EVTCHN_MASKED,52 TEST_EVTCHN_UNMASKED,53 TEST_EVTCHN_SLOWPATH,54 TEST_EVTCHN_SEND_IOCTL,55 TEST_EVTCHN_HCALL,56 TEST_EVTCHN_HCALL_SLOWPATH,57 TEST_EVTCHN_HCALL_EVENTFD,58 TEST_TIMER_SETUP,59 TEST_TIMER_WAIT,60 TEST_TIMER_RESTORE,61 TEST_POLL_READY,62 TEST_POLL_TIMEOUT,63 TEST_POLL_MASKED,64 TEST_POLL_WAKE,65 SET_VCPU_INFO,66 TEST_TIMER_PAST,67 TEST_LOCKING_SEND_RACE,68 TEST_LOCKING_POLL_RACE,69 TEST_LOCKING_POLL_TIMEOUT,70 TEST_DONE,71 72 TEST_GUEST_SAW_IRQ,73};74 75#define XEN_HYPERCALL_MSR 0x4000000076 77#define MIN_STEAL_TIME 5000078 79#define SHINFO_RACE_TIMEOUT 2 /* seconds */80 81#define __HYPERVISOR_set_timer_op 1582#define __HYPERVISOR_sched_op 2983#define __HYPERVISOR_event_channel_op 3284 85#define SCHEDOP_poll 386 87#define EVTCHNOP_send 488 89#define EVTCHNSTAT_interdomain 290 91struct evtchn_send {92 u32 port;93};94 95struct sched_poll {96 u32 *ports;97 unsigned int nr_ports;98 u64 timeout;99};100 101struct pvclock_vcpu_time_info {102 u32 version;103 u32 pad0;104 u64 tsc_timestamp;105 u64 system_time;106 u32 tsc_to_system_mul;107 s8 tsc_shift;108 u8 flags;109 u8 pad[2];110} __attribute__((__packed__)); /* 32 bytes */111 112struct pvclock_wall_clock {113 u32 version;114 u32 sec;115 u32 nsec;116} __attribute__((__packed__));117 118struct vcpu_runstate_info {119 uint32_t state;120 uint64_t state_entry_time;121 uint64_t time[5]; /* Extra field for overrun check */122};123 124struct compat_vcpu_runstate_info {125 uint32_t state;126 uint64_t state_entry_time;127 uint64_t time[5];128} __attribute__((__packed__));129 130struct arch_vcpu_info {131 unsigned long cr2;132 unsigned long pad; /* sizeof(vcpu_info_t) == 64 */133};134 135struct vcpu_info {136 uint8_t evtchn_upcall_pending;137 uint8_t evtchn_upcall_mask;138 unsigned long evtchn_pending_sel;139 struct arch_vcpu_info arch;140 struct pvclock_vcpu_time_info time;141}; /* 64 bytes (x86) */142 143struct shared_info {144 struct vcpu_info vcpu_info[32];145 unsigned long evtchn_pending[64];146 unsigned long evtchn_mask[64];147 struct pvclock_wall_clock wc;148 uint32_t wc_sec_hi;149 /* arch_shared_info here */150};151 152#define RUNSTATE_running 0153#define RUNSTATE_runnable 1154#define RUNSTATE_blocked 2155#define RUNSTATE_offline 3156 157static const char *runstate_names[] = {158 "running",159 "runnable",160 "blocked",161 "offline"162};163 164struct {165 struct kvm_irq_routing info;166 struct kvm_irq_routing_entry entries[2];167} irq_routes;168 169static volatile bool guest_saw_irq;170 171static void evtchn_handler(struct ex_regs *regs)172{173 struct vcpu_info *vi = (void *)VCPU_INFO_VADDR;174 175 vcpu_arch_put_guest(vi->evtchn_upcall_pending, 0);176 vcpu_arch_put_guest(vi->evtchn_pending_sel, 0);177 guest_saw_irq = true;178 179 GUEST_SYNC(TEST_GUEST_SAW_IRQ);180}181 182static void guest_wait_for_irq(void)183{184 while (!guest_saw_irq)185 __asm__ __volatile__ ("rep nop" : : : "memory");186 guest_saw_irq = false;187}188 189static void guest_code(void)190{191 struct vcpu_runstate_info *rs = (void *)RUNSTATE_VADDR;192 int i;193 194 __asm__ __volatile__(195 "sti\n"196 "nop\n"197 );198 199 /* Trigger an interrupt injection */200 GUEST_SYNC(TEST_INJECT_VECTOR);201 202 guest_wait_for_irq();203 204 /* Test having the host set runstates manually */205 GUEST_SYNC(TEST_RUNSTATE_runnable);206 GUEST_ASSERT(rs->time[RUNSTATE_runnable] != 0);207 GUEST_ASSERT(rs->state == 0);208 209 GUEST_SYNC(TEST_RUNSTATE_blocked);210 GUEST_ASSERT(rs->time[RUNSTATE_blocked] != 0);211 GUEST_ASSERT(rs->state == 0);212 213 GUEST_SYNC(TEST_RUNSTATE_offline);214 GUEST_ASSERT(rs->time[RUNSTATE_offline] != 0);215 GUEST_ASSERT(rs->state == 0);216 217 /* Test runstate time adjust */218 GUEST_SYNC(TEST_RUNSTATE_ADJUST);219 GUEST_ASSERT(rs->time[RUNSTATE_blocked] == 0x5a);220 GUEST_ASSERT(rs->time[RUNSTATE_offline] == 0x6b6b);221 222 /* Test runstate time set */223 GUEST_SYNC(TEST_RUNSTATE_DATA);224 GUEST_ASSERT(rs->state_entry_time >= 0x8000);225 GUEST_ASSERT(rs->time[RUNSTATE_runnable] == 0);226 GUEST_ASSERT(rs->time[RUNSTATE_blocked] == 0x6b6b);227 GUEST_ASSERT(rs->time[RUNSTATE_offline] == 0x5a);228 229 /* sched_yield() should result in some 'runnable' time */230 GUEST_SYNC(TEST_STEAL_TIME);231 GUEST_ASSERT(rs->time[RUNSTATE_runnable] >= MIN_STEAL_TIME);232 233 /* Attempt to deliver a *masked* interrupt */234 GUEST_SYNC(TEST_EVTCHN_MASKED);235 236 /* Wait until we see the bit set */237 struct shared_info *si = (void *)SHINFO_VADDR;238 while (!si->evtchn_pending[0])239 __asm__ __volatile__ ("rep nop" : : : "memory");240 241 /* Now deliver an *unmasked* interrupt */242 GUEST_SYNC(TEST_EVTCHN_UNMASKED);243 244 guest_wait_for_irq();245 246 /* Change memslots and deliver an interrupt */247 GUEST_SYNC(TEST_EVTCHN_SLOWPATH);248 249 guest_wait_for_irq();250 251 /* Deliver event channel with KVM_XEN_HVM_EVTCHN_SEND */252 GUEST_SYNC(TEST_EVTCHN_SEND_IOCTL);253 254 guest_wait_for_irq();255 256 GUEST_SYNC(TEST_EVTCHN_HCALL);257 258 /* Our turn. Deliver event channel (to ourselves) with259 * EVTCHNOP_send hypercall. */260 struct evtchn_send s = { .port = 127 };261 xen_hypercall(__HYPERVISOR_event_channel_op, EVTCHNOP_send, &s);262 263 guest_wait_for_irq();264 265 GUEST_SYNC(TEST_EVTCHN_HCALL_SLOWPATH);266 267 /*268 * Same again, but this time the host has messed with memslots so it269 * should take the slow path in kvm_xen_set_evtchn().270 */271 xen_hypercall(__HYPERVISOR_event_channel_op, EVTCHNOP_send, &s);272 273 guest_wait_for_irq();274 275 GUEST_SYNC(TEST_EVTCHN_HCALL_EVENTFD);276 277 /* Deliver "outbound" event channel to an eventfd which278 * happens to be one of our own irqfds. */279 s.port = 197;280 xen_hypercall(__HYPERVISOR_event_channel_op, EVTCHNOP_send, &s);281 282 guest_wait_for_irq();283 284 GUEST_SYNC(TEST_TIMER_SETUP);285 286 /* Set a timer 100ms in the future. */287 xen_hypercall(__HYPERVISOR_set_timer_op,288 rs->state_entry_time + 100000000, NULL);289 290 GUEST_SYNC(TEST_TIMER_WAIT);291 292 /* Now wait for the timer */293 guest_wait_for_irq();294 295 GUEST_SYNC(TEST_TIMER_RESTORE);296 297 /* The host has 'restored' the timer. Just wait for it. */298 guest_wait_for_irq();299 300 GUEST_SYNC(TEST_POLL_READY);301 302 /* Poll for an event channel port which is already set */303 u32 ports[1] = { EVTCHN_TIMER };304 struct sched_poll p = {305 .ports = ports,306 .nr_ports = 1,307 .timeout = 0,308 };309 310 xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);311 312 GUEST_SYNC(TEST_POLL_TIMEOUT);313 314 /* Poll for an unset port and wait for the timeout. */315 p.timeout = 100000000;316 xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);317 318 GUEST_SYNC(TEST_POLL_MASKED);319 320 /* A timer will wake the masked port we're waiting on, while we poll */321 p.timeout = 0;322 xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);323 324 GUEST_SYNC(TEST_POLL_WAKE);325 326 /* Set the vcpu_info to point at exactly the place it already is to327 * make sure the attribute is functional. */328 GUEST_SYNC(SET_VCPU_INFO);329 330 /* A timer wake an *unmasked* port which should wake us with an331 * actual interrupt, while we're polling on a different port. */332 ports[0]++;333 p.timeout = 0;334 xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);335 336 guest_wait_for_irq();337 338 GUEST_SYNC(TEST_TIMER_PAST);339 340 /* Timer should have fired already */341 guest_wait_for_irq();342 343 GUEST_SYNC(TEST_LOCKING_SEND_RACE);344 /* Racing host ioctls */345 346 guest_wait_for_irq();347 348 GUEST_SYNC(TEST_LOCKING_POLL_RACE);349 /* Racing vmcall against host ioctl */350 351 ports[0] = 0;352 353 p = (struct sched_poll) {354 .ports = ports,355 .nr_ports = 1,356 .timeout = 0357 };358 359wait_for_timer:360 /*361 * Poll for a timer wake event while the worker thread is mucking with362 * the shared info. KVM XEN drops timer IRQs if the shared info is363 * invalid when the timer expires. Arbitrarily poll 100 times before364 * giving up and asking the VMM to re-arm the timer. 100 polls should365 * consume enough time to beat on KVM without taking too long if the366 * timer IRQ is dropped due to an invalid event channel.367 */368 for (i = 0; i < 100 && !guest_saw_irq; i++)369 __xen_hypercall(__HYPERVISOR_sched_op, SCHEDOP_poll, &p);370 371 /*372 * Re-send the timer IRQ if it was (likely) dropped due to the timer373 * expiring while the event channel was invalid.374 */375 if (!guest_saw_irq) {376 GUEST_SYNC(TEST_LOCKING_POLL_TIMEOUT);377 goto wait_for_timer;378 }379 guest_saw_irq = false;380 381 GUEST_SYNC(TEST_DONE);382}383 384static struct shared_info *shinfo;385static struct vcpu_info *vinfo;386static struct kvm_vcpu *vcpu;387 388static void handle_alrm(int sig)389{390 if (vinfo)391 printf("evtchn_upcall_pending 0x%x\n", vinfo->evtchn_upcall_pending);392 vcpu_dump(stdout, vcpu, 0);393 TEST_FAIL("IRQ delivery timed out");394}395 396static void *juggle_shinfo_state(void *arg)397{398 struct kvm_vm *vm = (struct kvm_vm *)arg;399 400 struct kvm_xen_hvm_attr cache_activate_gfn = {401 .type = KVM_XEN_ATTR_TYPE_SHARED_INFO,402 .u.shared_info.gfn = SHINFO_REGION_GPA / PAGE_SIZE403 };404 405 struct kvm_xen_hvm_attr cache_deactivate_gfn = {406 .type = KVM_XEN_ATTR_TYPE_SHARED_INFO,407 .u.shared_info.gfn = KVM_XEN_INVALID_GFN408 };409 410 struct kvm_xen_hvm_attr cache_activate_hva = {411 .type = KVM_XEN_ATTR_TYPE_SHARED_INFO_HVA,412 .u.shared_info.hva = (unsigned long)shinfo413 };414 415 struct kvm_xen_hvm_attr cache_deactivate_hva = {416 .type = KVM_XEN_ATTR_TYPE_SHARED_INFO,417 .u.shared_info.hva = 0418 };419 420 int xen_caps = kvm_check_cap(KVM_CAP_XEN_HVM);421 422 for (;;) {423 __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_activate_gfn);424 pthread_testcancel();425 __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_deactivate_gfn);426 427 if (xen_caps & KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA) {428 __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_activate_hva);429 pthread_testcancel();430 __vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &cache_deactivate_hva);431 }432 }433 434 return NULL;435}436 437int main(int argc, char *argv[])438{439 struct kvm_xen_hvm_attr evt_reset;440 struct kvm_vm *vm;441 pthread_t thread;442 bool verbose;443 int ret;444 445 verbose = argc > 1 && (!strncmp(argv[1], "-v", 3) ||446 !strncmp(argv[1], "--verbose", 10));447 448 int xen_caps = kvm_check_cap(KVM_CAP_XEN_HVM);449 TEST_REQUIRE(xen_caps & KVM_XEN_HVM_CONFIG_SHARED_INFO);450 451 bool do_runstate_tests = !!(xen_caps & KVM_XEN_HVM_CONFIG_RUNSTATE);452 bool do_runstate_flag = !!(xen_caps & KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG);453 bool do_eventfd_tests = !!(xen_caps & KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL);454 bool do_evtchn_tests = do_eventfd_tests && !!(xen_caps & KVM_XEN_HVM_CONFIG_EVTCHN_SEND);455 bool has_shinfo_hva = !!(xen_caps & KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA);456 457 vm = vm_create_with_one_vcpu(&vcpu, guest_code);458 459 /* Map a region for the shared_info page */460 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,461 SHINFO_REGION_GPA, SHINFO_REGION_SLOT, 3, 0);462 virt_map(vm, SHINFO_REGION_GVA, SHINFO_REGION_GPA, 3);463 464 shinfo = addr_gpa2hva(vm, SHINFO_VADDR);465 466 int zero_fd = open("/dev/zero", O_RDONLY);467 TEST_ASSERT(zero_fd != -1, "Failed to open /dev/zero");468 469 struct kvm_xen_hvm_config hvmc = {470 .flags = KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL,471 .msr = XEN_HYPERCALL_MSR,472 };473 474 /* Let the kernel know that we *will* use it for sending all475 * event channels, which lets it intercept SCHEDOP_poll */476 if (do_evtchn_tests)477 hvmc.flags |= KVM_XEN_HVM_CONFIG_EVTCHN_SEND;478 479 vm_ioctl(vm, KVM_XEN_HVM_CONFIG, &hvmc);480 481 struct kvm_xen_hvm_attr lm = {482 .type = KVM_XEN_ATTR_TYPE_LONG_MODE,483 .u.long_mode = 1,484 };485 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &lm);486 487 if (do_runstate_flag) {488 struct kvm_xen_hvm_attr ruf = {489 .type = KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG,490 .u.runstate_update_flag = 1,491 };492 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &ruf);493 494 ruf.u.runstate_update_flag = 0;495 vm_ioctl(vm, KVM_XEN_HVM_GET_ATTR, &ruf);496 TEST_ASSERT(ruf.u.runstate_update_flag == 1,497 "Failed to read back RUNSTATE_UPDATE_FLAG attr");498 }499 500 struct kvm_xen_hvm_attr ha = {};501 502 if (has_shinfo_hva) {503 ha.type = KVM_XEN_ATTR_TYPE_SHARED_INFO_HVA;504 ha.u.shared_info.hva = (unsigned long)shinfo;505 } else {506 ha.type = KVM_XEN_ATTR_TYPE_SHARED_INFO;507 ha.u.shared_info.gfn = SHINFO_ADDR / PAGE_SIZE;508 }509 510 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &ha);511 512 /*513 * Test what happens when the HVA of the shinfo page is remapped after514 * the kernel has a reference to it. But make sure we copy the clock515 * info over since that's only set at setup time, and we test it later.516 */517 struct pvclock_wall_clock wc_copy = shinfo->wc;518 void *m = mmap(shinfo, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE, zero_fd, 0);519 TEST_ASSERT(m == shinfo, "Failed to map /dev/zero over shared info");520 shinfo->wc = wc_copy;521 522 struct kvm_xen_vcpu_attr vi = {523 .type = KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO,524 .u.gpa = VCPU_INFO_ADDR,525 };526 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &vi);527 528 struct kvm_xen_vcpu_attr pvclock = {529 .type = KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO,530 .u.gpa = PVTIME_ADDR,531 };532 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &pvclock);533 534 struct kvm_xen_hvm_attr vec = {535 .type = KVM_XEN_ATTR_TYPE_UPCALL_VECTOR,536 .u.vector = EVTCHN_VECTOR,537 };538 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &vec);539 540 vm_install_exception_handler(vm, EVTCHN_VECTOR, evtchn_handler);541 542 if (do_runstate_tests) {543 struct kvm_xen_vcpu_attr st = {544 .type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR,545 .u.gpa = RUNSTATE_ADDR,546 };547 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &st);548 }549 550 int irq_fd[2] = { -1, -1 };551 552 if (do_eventfd_tests) {553 irq_fd[0] = eventfd(0, 0);554 irq_fd[1] = eventfd(0, 0);555 556 /* Unexpected, but not a KVM failure */557 if (irq_fd[0] == -1 || irq_fd[1] == -1)558 do_evtchn_tests = do_eventfd_tests = false;559 }560 561 if (do_eventfd_tests) {562 irq_routes.info.nr = 2;563 564 irq_routes.entries[0].gsi = 32;565 irq_routes.entries[0].type = KVM_IRQ_ROUTING_XEN_EVTCHN;566 irq_routes.entries[0].u.xen_evtchn.port = EVTCHN_TEST1;567 irq_routes.entries[0].u.xen_evtchn.vcpu = vcpu->id;568 irq_routes.entries[0].u.xen_evtchn.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL;569 570 irq_routes.entries[1].gsi = 33;571 irq_routes.entries[1].type = KVM_IRQ_ROUTING_XEN_EVTCHN;572 irq_routes.entries[1].u.xen_evtchn.port = EVTCHN_TEST2;573 irq_routes.entries[1].u.xen_evtchn.vcpu = vcpu->id;574 irq_routes.entries[1].u.xen_evtchn.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL;575 576 vm_ioctl(vm, KVM_SET_GSI_ROUTING, &irq_routes.info);577 578 struct kvm_irqfd ifd = { };579 580 ifd.fd = irq_fd[0];581 ifd.gsi = 32;582 vm_ioctl(vm, KVM_IRQFD, &ifd);583 584 ifd.fd = irq_fd[1];585 ifd.gsi = 33;586 vm_ioctl(vm, KVM_IRQFD, &ifd);587 588 struct sigaction sa = { };589 sa.sa_handler = handle_alrm;590 sigaction(SIGALRM, &sa, NULL);591 }592 593 struct kvm_xen_vcpu_attr tmr = {594 .type = KVM_XEN_VCPU_ATTR_TYPE_TIMER,595 .u.timer.port = EVTCHN_TIMER,596 .u.timer.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL,597 .u.timer.expires_ns = 0598 };599 600 if (do_evtchn_tests) {601 struct kvm_xen_hvm_attr inj = {602 .type = KVM_XEN_ATTR_TYPE_EVTCHN,603 .u.evtchn.send_port = 127,604 .u.evtchn.type = EVTCHNSTAT_interdomain,605 .u.evtchn.flags = 0,606 .u.evtchn.deliver.port.port = EVTCHN_TEST1,607 .u.evtchn.deliver.port.vcpu = vcpu->id + 1,608 .u.evtchn.deliver.port.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL,609 };610 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &inj);611 612 /* Test migration to a different vCPU */613 inj.u.evtchn.flags = KVM_XEN_EVTCHN_UPDATE;614 inj.u.evtchn.deliver.port.vcpu = vcpu->id;615 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &inj);616 617 inj.u.evtchn.send_port = 197;618 inj.u.evtchn.deliver.eventfd.port = 0;619 inj.u.evtchn.deliver.eventfd.fd = irq_fd[1];620 inj.u.evtchn.flags = 0;621 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &inj);622 623 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);624 }625 vinfo = addr_gpa2hva(vm, VCPU_INFO_VADDR);626 vinfo->evtchn_upcall_pending = 0;627 628 struct vcpu_runstate_info *rs = addr_gpa2hva(vm, RUNSTATE_ADDR);629 rs->state = 0x5a;630 631 bool evtchn_irq_expected = false;632 633 for (;;) {634 struct ucall uc;635 636 vcpu_run(vcpu);637 TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);638 639 switch (get_ucall(vcpu, &uc)) {640 case UCALL_ABORT:641 REPORT_GUEST_ASSERT(uc);642 /* NOT REACHED */643 case UCALL_SYNC: {644 struct kvm_xen_vcpu_attr rst;645 long rundelay;646 647 if (do_runstate_tests)648 TEST_ASSERT(rs->state_entry_time == rs->time[0] +649 rs->time[1] + rs->time[2] + rs->time[3],650 "runstate times don't add up");651 652 switch (uc.args[1]) {653 case TEST_INJECT_VECTOR:654 if (verbose)655 printf("Delivering evtchn upcall\n");656 evtchn_irq_expected = true;657 vinfo->evtchn_upcall_pending = 1;658 break;659 660 case TEST_RUNSTATE_runnable...TEST_RUNSTATE_offline:661 TEST_ASSERT(!evtchn_irq_expected, "Event channel IRQ not seen");662 if (!do_runstate_tests)663 goto done;664 if (verbose)665 printf("Testing runstate %s\n", runstate_names[uc.args[1]]);666 rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT;667 rst.u.runstate.state = uc.args[1] + RUNSTATE_runnable -668 TEST_RUNSTATE_runnable;669 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &rst);670 break;671 672 case TEST_RUNSTATE_ADJUST:673 if (verbose)674 printf("Testing RUNSTATE_ADJUST\n");675 rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST;676 memset(&rst.u, 0, sizeof(rst.u));677 rst.u.runstate.state = (uint64_t)-1;678 rst.u.runstate.time_blocked =679 0x5a - rs->time[RUNSTATE_blocked];680 rst.u.runstate.time_offline =681 0x6b6b - rs->time[RUNSTATE_offline];682 rst.u.runstate.time_runnable = -rst.u.runstate.time_blocked -683 rst.u.runstate.time_offline;684 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &rst);685 break;686 687 case TEST_RUNSTATE_DATA:688 if (verbose)689 printf("Testing RUNSTATE_DATA\n");690 rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA;691 memset(&rst.u, 0, sizeof(rst.u));692 rst.u.runstate.state = RUNSTATE_running;693 rst.u.runstate.state_entry_time = 0x6b6b + 0x5a;694 rst.u.runstate.time_blocked = 0x6b6b;695 rst.u.runstate.time_offline = 0x5a;696 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &rst);697 break;698 699 case TEST_STEAL_TIME:700 if (verbose)701 printf("Testing steal time\n");702 /* Yield until scheduler delay exceeds target */703 rundelay = get_run_delay() + MIN_STEAL_TIME;704 do {705 sched_yield();706 } while (get_run_delay() < rundelay);707 break;708 709 case TEST_EVTCHN_MASKED:710 if (!do_eventfd_tests)711 goto done;712 if (verbose)713 printf("Testing masked event channel\n");714 shinfo->evtchn_mask[0] = 1UL << EVTCHN_TEST1;715 eventfd_write(irq_fd[0], 1UL);716 alarm(1);717 break;718 719 case TEST_EVTCHN_UNMASKED:720 if (verbose)721 printf("Testing unmasked event channel\n");722 /* Unmask that, but deliver the other one */723 shinfo->evtchn_pending[0] = 0;724 shinfo->evtchn_mask[0] = 0;725 eventfd_write(irq_fd[1], 1UL);726 evtchn_irq_expected = true;727 alarm(1);728 break;729 730 case TEST_EVTCHN_SLOWPATH:731 TEST_ASSERT(!evtchn_irq_expected,732 "Expected event channel IRQ but it didn't happen");733 shinfo->evtchn_pending[1] = 0;734 if (verbose)735 printf("Testing event channel after memslot change\n");736 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,737 DUMMY_REGION_GPA, DUMMY_REGION_SLOT, 1, 0);738 eventfd_write(irq_fd[0], 1UL);739 evtchn_irq_expected = true;740 alarm(1);741 break;742 743 case TEST_EVTCHN_SEND_IOCTL:744 TEST_ASSERT(!evtchn_irq_expected,745 "Expected event channel IRQ but it didn't happen");746 if (!do_evtchn_tests)747 goto done;748 749 shinfo->evtchn_pending[0] = 0;750 if (verbose)751 printf("Testing injection with KVM_XEN_HVM_EVTCHN_SEND\n");752 753 struct kvm_irq_routing_xen_evtchn e;754 e.port = EVTCHN_TEST2;755 e.vcpu = vcpu->id;756 e.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL;757 758 vm_ioctl(vm, KVM_XEN_HVM_EVTCHN_SEND, &e);759 evtchn_irq_expected = true;760 alarm(1);761 break;762 763 case TEST_EVTCHN_HCALL:764 TEST_ASSERT(!evtchn_irq_expected,765 "Expected event channel IRQ but it didn't happen");766 shinfo->evtchn_pending[1] = 0;767 768 if (verbose)769 printf("Testing guest EVTCHNOP_send direct to evtchn\n");770 evtchn_irq_expected = true;771 alarm(1);772 break;773 774 case TEST_EVTCHN_HCALL_SLOWPATH:775 TEST_ASSERT(!evtchn_irq_expected,776 "Expected event channel IRQ but it didn't happen");777 shinfo->evtchn_pending[0] = 0;778 779 if (verbose)780 printf("Testing guest EVTCHNOP_send direct to evtchn after memslot change\n");781 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,782 DUMMY_REGION_GPA_2, DUMMY_REGION_SLOT_2, 1, 0);783 evtchn_irq_expected = true;784 alarm(1);785 break;786 787 case TEST_EVTCHN_HCALL_EVENTFD:788 TEST_ASSERT(!evtchn_irq_expected,789 "Expected event channel IRQ but it didn't happen");790 shinfo->evtchn_pending[0] = 0;791 792 if (verbose)793 printf("Testing guest EVTCHNOP_send to eventfd\n");794 evtchn_irq_expected = true;795 alarm(1);796 break;797 798 case TEST_TIMER_SETUP:799 TEST_ASSERT(!evtchn_irq_expected,800 "Expected event channel IRQ but it didn't happen");801 shinfo->evtchn_pending[1] = 0;802 803 if (verbose)804 printf("Testing guest oneshot timer\n");805 break;806 807 case TEST_TIMER_WAIT:808 memset(&tmr, 0, sizeof(tmr));809 tmr.type = KVM_XEN_VCPU_ATTR_TYPE_TIMER;810 vcpu_ioctl(vcpu, KVM_XEN_VCPU_GET_ATTR, &tmr);811 TEST_ASSERT(tmr.u.timer.port == EVTCHN_TIMER,812 "Timer port not returned");813 TEST_ASSERT(tmr.u.timer.priority == KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL,814 "Timer priority not returned");815 TEST_ASSERT(tmr.u.timer.expires_ns > rs->state_entry_time,816 "Timer expiry not returned");817 evtchn_irq_expected = true;818 alarm(1);819 break;820 821 case TEST_TIMER_RESTORE:822 TEST_ASSERT(!evtchn_irq_expected,823 "Expected event channel IRQ but it didn't happen");824 shinfo->evtchn_pending[0] = 0;825 826 if (verbose)827 printf("Testing restored oneshot timer\n");828 829 tmr.u.timer.expires_ns = rs->state_entry_time + 100000000;830 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);831 evtchn_irq_expected = true;832 alarm(1);833 break;834 835 case TEST_POLL_READY:836 TEST_ASSERT(!evtchn_irq_expected,837 "Expected event channel IRQ but it didn't happen");838 839 if (verbose)840 printf("Testing SCHEDOP_poll with already pending event\n");841 shinfo->evtchn_pending[0] = shinfo->evtchn_mask[0] = 1UL << EVTCHN_TIMER;842 alarm(1);843 break;844 845 case TEST_POLL_TIMEOUT:846 if (verbose)847 printf("Testing SCHEDOP_poll timeout\n");848 shinfo->evtchn_pending[0] = 0;849 alarm(1);850 break;851 852 case TEST_POLL_MASKED:853 if (verbose)854 printf("Testing SCHEDOP_poll wake on masked event\n");855 856 tmr.u.timer.expires_ns = rs->state_entry_time + 100000000;857 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);858 alarm(1);859 break;860 861 case TEST_POLL_WAKE:862 shinfo->evtchn_pending[0] = shinfo->evtchn_mask[0] = 0;863 if (verbose)864 printf("Testing SCHEDOP_poll wake on unmasked event\n");865 866 evtchn_irq_expected = true;867 tmr.u.timer.expires_ns = rs->state_entry_time + 100000000;868 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);869 870 /* Read it back and check the pending time is reported correctly */871 tmr.u.timer.expires_ns = 0;872 vcpu_ioctl(vcpu, KVM_XEN_VCPU_GET_ATTR, &tmr);873 TEST_ASSERT(tmr.u.timer.expires_ns == rs->state_entry_time + 100000000,874 "Timer not reported pending");875 alarm(1);876 break;877 878 case SET_VCPU_INFO:879 if (has_shinfo_hva) {880 struct kvm_xen_vcpu_attr vih = {881 .type = KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO_HVA,882 .u.hva = (unsigned long)vinfo883 };884 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &vih);885 }886 break;887 888 case TEST_TIMER_PAST:889 TEST_ASSERT(!evtchn_irq_expected,890 "Expected event channel IRQ but it didn't happen");891 /* Read timer and check it is no longer pending */892 vcpu_ioctl(vcpu, KVM_XEN_VCPU_GET_ATTR, &tmr);893 TEST_ASSERT(!tmr.u.timer.expires_ns, "Timer still reported pending");894 895 shinfo->evtchn_pending[0] = 0;896 if (verbose)897 printf("Testing timer in the past\n");898 899 evtchn_irq_expected = true;900 tmr.u.timer.expires_ns = rs->state_entry_time - 100000000ULL;901 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);902 alarm(1);903 break;904 905 case TEST_LOCKING_SEND_RACE:906 TEST_ASSERT(!evtchn_irq_expected,907 "Expected event channel IRQ but it didn't happen");908 alarm(0);909 910 if (verbose)911 printf("Testing shinfo lock corruption (KVM_XEN_HVM_EVTCHN_SEND)\n");912 913 ret = pthread_create(&thread, NULL, &juggle_shinfo_state, (void *)vm);914 TEST_ASSERT(ret == 0, "pthread_create() failed: %s", strerror(ret));915 916 struct kvm_irq_routing_xen_evtchn uxe = {917 .port = 1,918 .vcpu = vcpu->id,919 .priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL920 };921 922 evtchn_irq_expected = true;923 for (time_t t = time(NULL) + SHINFO_RACE_TIMEOUT; time(NULL) < t;)924 __vm_ioctl(vm, KVM_XEN_HVM_EVTCHN_SEND, &uxe);925 break;926 927 case TEST_LOCKING_POLL_RACE:928 TEST_ASSERT(!evtchn_irq_expected,929 "Expected event channel IRQ but it didn't happen");930 931 if (verbose)932 printf("Testing shinfo lock corruption (SCHEDOP_poll)\n");933 934 shinfo->evtchn_pending[0] = 1;935 936 evtchn_irq_expected = true;937 tmr.u.timer.expires_ns = rs->state_entry_time +938 SHINFO_RACE_TIMEOUT * 1000000000ULL;939 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);940 break;941 942 case TEST_LOCKING_POLL_TIMEOUT:943 /*944 * Optional and possibly repeated sync point.945 * Injecting the timer IRQ may fail if the946 * shinfo is invalid when the timer expires.947 * If the timer has expired but the IRQ hasn't948 * been delivered, rearm the timer and retry.949 */950 vcpu_ioctl(vcpu, KVM_XEN_VCPU_GET_ATTR, &tmr);951 952 /* Resume the guest if the timer is still pending. */953 if (tmr.u.timer.expires_ns)954 break;955 956 /* All done if the IRQ was delivered. */957 if (!evtchn_irq_expected)958 break;959 960 tmr.u.timer.expires_ns = rs->state_entry_time +961 SHINFO_RACE_TIMEOUT * 1000000000ULL;962 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &tmr);963 break;964 case TEST_DONE:965 TEST_ASSERT(!evtchn_irq_expected,966 "Expected event channel IRQ but it didn't happen");967 968 ret = pthread_cancel(thread);969 TEST_ASSERT(ret == 0, "pthread_cancel() failed: %s", strerror(ret));970 971 ret = pthread_join(thread, 0);972 TEST_ASSERT(ret == 0, "pthread_join() failed: %s", strerror(ret));973 goto done;974 975 case TEST_GUEST_SAW_IRQ:976 TEST_ASSERT(evtchn_irq_expected, "Unexpected event channel IRQ");977 evtchn_irq_expected = false;978 break;979 }980 break;981 }982 case UCALL_DONE:983 goto done;984 default:985 TEST_FAIL("Unknown ucall 0x%lx.", uc.cmd);986 }987 }988 989 done:990 evt_reset.type = KVM_XEN_ATTR_TYPE_EVTCHN;991 evt_reset.u.evtchn.flags = KVM_XEN_EVTCHN_RESET;992 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &evt_reset);993 994 alarm(0);995 996 /*997 * Just a *really* basic check that things are being put in the998 * right place. The actual calculations are much the same for999 * Xen as they are for the KVM variants, so no need to check.1000 */1001 struct pvclock_wall_clock *wc;1002 struct pvclock_vcpu_time_info *ti, *ti2;1003 struct kvm_clock_data kcdata;1004 long long delta;1005 1006 wc = addr_gpa2hva(vm, SHINFO_REGION_GPA + 0xc00);1007 ti = addr_gpa2hva(vm, SHINFO_REGION_GPA + 0x40 + 0x20);1008 ti2 = addr_gpa2hva(vm, PVTIME_ADDR);1009 1010 if (verbose) {1011 printf("Wall clock (v %d) %d.%09d\n", wc->version, wc->sec, wc->nsec);1012 printf("Time info 1: v %u tsc %" PRIu64 " time %" PRIu64 " mul %u shift %u flags %x\n",1013 ti->version, ti->tsc_timestamp, ti->system_time, ti->tsc_to_system_mul,1014 ti->tsc_shift, ti->flags);1015 printf("Time info 2: v %u tsc %" PRIu64 " time %" PRIu64 " mul %u shift %u flags %x\n",1016 ti2->version, ti2->tsc_timestamp, ti2->system_time, ti2->tsc_to_system_mul,1017 ti2->tsc_shift, ti2->flags);1018 }1019 1020 TEST_ASSERT(wc->version && !(wc->version & 1),1021 "Bad wallclock version %x", wc->version);1022 1023 vm_ioctl(vm, KVM_GET_CLOCK, &kcdata);1024 1025 if (kcdata.flags & KVM_CLOCK_REALTIME) {1026 if (verbose) {1027 printf("KVM_GET_CLOCK clock: %lld.%09lld\n",1028 kcdata.clock / NSEC_PER_SEC, kcdata.clock % NSEC_PER_SEC);1029 printf("KVM_GET_CLOCK realtime: %lld.%09lld\n",1030 kcdata.realtime / NSEC_PER_SEC, kcdata.realtime % NSEC_PER_SEC);1031 }1032 1033 delta = (wc->sec * NSEC_PER_SEC + wc->nsec) - (kcdata.realtime - kcdata.clock);1034 1035 /*1036 * KVM_GET_CLOCK gives CLOCK_REALTIME which jumps on leap seconds updates but1037 * unfortunately KVM doesn't currently offer a CLOCK_TAI alternative. Accept 1s1038 * delta as testing clock accuracy is not the goal here. The test just needs to1039 * check that the value in shinfo is somewhat sane.1040 */1041 TEST_ASSERT(llabs(delta) < NSEC_PER_SEC,1042 "Guest's epoch from shinfo %d.%09d differs from KVM_GET_CLOCK %lld.%lld",1043 wc->sec, wc->nsec, (kcdata.realtime - kcdata.clock) / NSEC_PER_SEC,1044 (kcdata.realtime - kcdata.clock) % NSEC_PER_SEC);1045 } else {1046 pr_info("Missing KVM_CLOCK_REALTIME, skipping shinfo epoch sanity check\n");1047 }1048 1049 TEST_ASSERT(ti->version && !(ti->version & 1),1050 "Bad time_info version %x", ti->version);1051 TEST_ASSERT(ti2->version && !(ti2->version & 1),1052 "Bad time_info version %x", ti->version);1053 1054 if (do_runstate_tests) {1055 /*1056 * Fetch runstate and check sanity. Strictly speaking in the1057 * general case we might not expect the numbers to be identical1058 * but in this case we know we aren't running the vCPU any more.1059 */1060 struct kvm_xen_vcpu_attr rst = {1061 .type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA,1062 };1063 vcpu_ioctl(vcpu, KVM_XEN_VCPU_GET_ATTR, &rst);1064 1065 if (verbose) {1066 printf("Runstate: %s(%d), entry %" PRIu64 " ns\n",1067 rs->state <= RUNSTATE_offline ? runstate_names[rs->state] : "unknown",1068 rs->state, rs->state_entry_time);1069 for (int i = RUNSTATE_running; i <= RUNSTATE_offline; i++) {1070 printf("State %s: %" PRIu64 " ns\n",1071 runstate_names[i], rs->time[i]);1072 }1073 }1074 1075 /*1076 * Exercise runstate info at all points across the page boundary, in1077 * 32-bit and 64-bit mode. In particular, test the case where it is1078 * configured in 32-bit mode and then switched to 64-bit mode while1079 * active, which takes it onto the second page.1080 */1081 unsigned long runstate_addr;1082 struct compat_vcpu_runstate_info *crs;1083 for (runstate_addr = SHINFO_REGION_GPA + PAGE_SIZE + PAGE_SIZE - sizeof(*rs) - 4;1084 runstate_addr < SHINFO_REGION_GPA + PAGE_SIZE + PAGE_SIZE + 4; runstate_addr++) {1085 1086 rs = addr_gpa2hva(vm, runstate_addr);1087 crs = (void *)rs;1088 1089 memset(rs, 0xa5, sizeof(*rs));1090 1091 /* Set to compatibility mode */1092 lm.u.long_mode = 0;1093 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &lm);1094 1095 /* Set runstate to new address (kernel will write it) */1096 struct kvm_xen_vcpu_attr st = {1097 .type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR,1098 .u.gpa = runstate_addr,1099 };1100 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &st);1101 1102 if (verbose)1103 printf("Compatibility runstate at %08lx\n", runstate_addr);1104 1105 TEST_ASSERT(crs->state == rst.u.runstate.state, "Runstate mismatch");1106 TEST_ASSERT(crs->state_entry_time == rst.u.runstate.state_entry_time,1107 "State entry time mismatch");1108 TEST_ASSERT(crs->time[RUNSTATE_running] == rst.u.runstate.time_running,1109 "Running time mismatch");1110 TEST_ASSERT(crs->time[RUNSTATE_runnable] == rst.u.runstate.time_runnable,1111 "Runnable time mismatch");1112 TEST_ASSERT(crs->time[RUNSTATE_blocked] == rst.u.runstate.time_blocked,1113 "Blocked time mismatch");1114 TEST_ASSERT(crs->time[RUNSTATE_offline] == rst.u.runstate.time_offline,1115 "Offline time mismatch");1116 TEST_ASSERT(crs->time[RUNSTATE_offline + 1] == 0xa5a5a5a5a5a5a5a5ULL,1117 "Structure overrun");1118 TEST_ASSERT(crs->state_entry_time == crs->time[0] +1119 crs->time[1] + crs->time[2] + crs->time[3],1120 "runstate times don't add up");1121 1122 1123 /* Now switch to 64-bit mode */1124 lm.u.long_mode = 1;1125 vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &lm);1126 1127 memset(rs, 0xa5, sizeof(*rs));1128 1129 /* Don't change the address, just trigger a write */1130 struct kvm_xen_vcpu_attr adj = {1131 .type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST,1132 .u.runstate.state = (uint64_t)-11133 };1134 vcpu_ioctl(vcpu, KVM_XEN_VCPU_SET_ATTR, &adj);1135 1136 if (verbose)1137 printf("64-bit runstate at %08lx\n", runstate_addr);1138 1139 TEST_ASSERT(rs->state == rst.u.runstate.state, "Runstate mismatch");1140 TEST_ASSERT(rs->state_entry_time == rst.u.runstate.state_entry_time,1141 "State entry time mismatch");1142 TEST_ASSERT(rs->time[RUNSTATE_running] == rst.u.runstate.time_running,1143 "Running time mismatch");1144 TEST_ASSERT(rs->time[RUNSTATE_runnable] == rst.u.runstate.time_runnable,1145 "Runnable time mismatch");1146 TEST_ASSERT(rs->time[RUNSTATE_blocked] == rst.u.runstate.time_blocked,1147 "Blocked time mismatch");1148 TEST_ASSERT(rs->time[RUNSTATE_offline] == rst.u.runstate.time_offline,1149 "Offline time mismatch");1150 TEST_ASSERT(rs->time[RUNSTATE_offline + 1] == 0xa5a5a5a5a5a5a5a5ULL,1151 "Structure overrun");1152 1153 TEST_ASSERT(rs->state_entry_time == rs->time[0] +1154 rs->time[1] + rs->time[2] + rs->time[3],1155 "runstate times don't add up");1156 }1157 }1158 1159 kvm_vm_free(vm);1160 return 0;1161}1162