kvm-pagestep.c (2421B)
1#include "test/kvm-eviction.h" 2#include "test/kvm.h" 3#include "test/util.h" 4#include "cachepc/uapi.h" 5 6#include <sys/ioctl.h> 7#include <sys/mman.h> 8#include <signal.h> 9#include <unistd.h> 10#include <fcntl.h> 11#include <errno.h> 12#include <err.h> 13#include <string.h> 14#include <stdbool.h> 15#include <stdio.h> 16#include <stdlib.h> 17 18static int child; 19 20uint64_t 21monitor(struct kvm *kvm, bool baseline) 22{ 23 struct cpc_event event; 24 int ret; 25 26 ret = ioctl(kvm_dev, KVM_CPC_POLL_EVENT, &event); 27 if (ret && errno == EAGAIN) return 0; 28 if (ret) err(1, "KVM_CPC_POLL_EVENT"); 29 30 if (event.type != CPC_EVENT_TRACK_PAGE) 31 errx(1, "unexpected event type %i", event.type); 32 33 printf("Event: rip:%08llx prev:%llu next:%llu ret:%llu\n", 34 vm_get_rip(), event.page.inst_gfn_prev, 35 event.page.inst_gfn, event.page.retinst); 36 printf("\n"); 37 38 ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id); 39 if (ret) err(1, "KVM_CPC_ACK_EVENT"); 40 41 return 1; 42} 43 44void 45deinit(void) 46{ 47 ioctl(kvm_dev, KVM_CPC_DEINIT); 48 49 kill(child, SIGKILL); 50 51 kvm_setup_deinit(); 52} 53 54int 55main(int argc, const char **argv) 56{ 57 struct ipc *ipc; 58 struct guest guest; 59 struct kvm kvm; 60 struct cpc_track_cfg cfg; 61 uint64_t eventcnt; 62 int ret; 63 64 setvbuf(stdout, NULL, _IONBF, 0); 65 66 parse_vmtype(argc, argv); 67 68 kvm_setup_init(); 69 70 ipc = ipc_alloc(); 71 72 child = fork(); 73 if (child < 0) err(1, "fork"); 74 75 if (child == 0) { 76 pin_process(0, TARGET_CORE, true); 77 78 guest_init(&guest, "test/kvm-pagestep_guest"); 79 vm_init(&kvm, &guest); 80 guest_deinit(&guest); 81 82 ret = ioctl(kvm_dev, KVM_CPC_RESET, NULL); 83 if (ret < 0) err(1, "KVM_CPC_RESET"); 84 85 ipc_signal_parent(ipc); 86 ipc_wait_parent(ipc); 87 88 printf("VM start\n"); 89 90 do { 91 ret = ioctl(kvm.vcpufd, KVM_RUN, NULL); 92 if (ret < 0) err(1, "KVM_RUN"); 93 94 if (kvm.run->exit_reason == KVM_EXIT_HLT) 95 printf("VM halt\n"); 96 } while (kvm.run->exit_reason == KVM_EXIT_HLT); 97 98 printf("VM exit\n"); 99 100 vm_deinit(&kvm); 101 102 ipc_free(ipc); 103 104 kvm_setup_deinit(); 105 } else { 106 pin_process(0, SECONDARY_CORE, true); 107 108 atexit(deinit); 109 110 ipc_wait_child(ipc); 111 112 printf("Monitor start\n"); 113 114 memset(&cfg, 0, sizeof(cfg)); 115 cfg.mode = CPC_TRACK_PAGES; 116 cfg.pages.singlestep_resolve = true; 117 ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &cfg); 118 if (ret) err(1, "KVM_CPC_TRACK_MODE"); 119 120 ipc_signal_child(ipc); 121 122 eventcnt = 0; 123 while (eventcnt < 50) { 124 eventcnt += monitor(&kvm, true); 125 } 126 127 printf("Monitor exit\n"); 128 129 ipc_free(ipc); 130 } 131} 132