From da9326a66bd534de38ab07dac96e8af051e94923 Mon Sep 17 00:00:00 2001 From: Louis Burda Date: Thu, 2 Feb 2023 09:42:58 -0600 Subject: Add event batching and handling of instructions loads on page boundaries for CPC_TRACK_PAGES --- test/kvm-pagestep.c | 9 +++++++++ test/kvm-pagestep_guest.S | 12 ++++++++++++ test/qemu-pagestep.c | 45 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/kvm-pagestep.c b/test/kvm-pagestep.c index be313e2..320da68 100644 --- a/test/kvm-pagestep.c +++ b/test/kvm-pagestep.c @@ -41,6 +41,13 @@ monitor(struct kvm *kvm, bool baseline) return 1; } +void +kill_child(void) +{ + printf("Killing vm..\n"); + kill(child, SIGKILL); +} + int main(int argc, const char **argv) { @@ -96,6 +103,8 @@ main(int argc, const char **argv) } else { pin_process(0, SECONDARY_CORE, true); + atexit(kill_child); + ipc_wait_child(ipc); printf("Monitor start\n"); diff --git a/test/kvm-pagestep_guest.S b/test/kvm-pagestep_guest.S index b40d230..45d77ba 100644 --- a/test/kvm-pagestep_guest.S +++ b/test/kvm-pagestep_guest.S @@ -11,6 +11,17 @@ guest: nop .endr +# instruction on page boundary test + nop +.rept 2 +.rept L1_LINESIZE * L1_SETS - 2 + nop +.endr + cpuid # two byte instruction +.endr +# --------------------------------- + +# speculation on conditional jump test mov $0x01, %bx cmp $0x00, %bx @@ -19,6 +30,7 @@ guest: nop .endr skip: +# ----------------------------------- jmp guest diff --git a/test/qemu-pagestep.c b/test/qemu-pagestep.c index eea8c40..d46debd 100644 --- a/test/qemu-pagestep.c +++ b/test/qemu-pagestep.c @@ -15,23 +15,48 @@ #include #include +struct cpc_event *batch_buffer; + +void +report(struct cpc_event *event) +{ + if (event->type == CPC_EVENT_TRACK_PAGE) { + printf("Page event: rip:%016llx prev:%08llx next:%08llx ret:%llu\n", + vm_get_rip(), event->page.inst_gfn_prev, + event->page.inst_gfn, event->page.retinst); + } else if (event->type == CPC_EVENT_GUEST) { + printf("Guest event: type:%u arg:%u\n", + event->guest.type, event->guest.val); + } else { + printf("Unexpected event type %i\n", event->type); + } + printf("\n"); +} + void monitor(void) { struct cpc_event event; + struct cpc_event_batch batch; + size_t i; int ret; ret = ioctl(kvm_dev, KVM_CPC_POLL_EVENT, &event); if (ret && errno == EAGAIN) return; if (ret) err(1, "KVM_CPC_POLL_EVENT"); - if (event.type == CPC_EVENT_TRACK_PAGE) { - printf("Event: rip:%016llx prev:%08llx next:%08llx ret:%llu\n", - vm_get_rip(), event.page.inst_gfn_prev, - event.page.inst_gfn, event.page.retinst); - printf("\n"); + if (event.type == CPC_EVENT_BATCH) { + batch.cnt = 0; + batch.maxcnt = CPC_EVENT_BATCH_MAX; + batch.buf = batch_buffer; + + ret = ioctl(kvm_dev, KVM_CPC_READ_BATCH, &batch); + if (ret) err(1, "KVM_CPC_READ_BATCH"); + + for (i = 0; i < batch.cnt; i++) + report(&batch.buf[i]); } else { - printf("Unexpected event type %i\n", event.type); + report(&event); } ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id); @@ -42,8 +67,12 @@ int main(int argc, const char **argv) { struct cpc_track_cfg cfg; + uint32_t arg; int ret; + batch_buffer = malloc(sizeof(struct cpc_event) * CPC_EVENT_BATCH_MAX); + if (!batch_buffer) err(1, "malloc"); + setvbuf(stdout, NULL, _IONBF, 0); kvm_setup_init(); @@ -53,6 +82,10 @@ main(int argc, const char **argv) ret = ioctl(kvm_dev, KVM_CPC_RESET); if (ret) err(1, "KVM_CPC_RESET"); + arg = true; + ret = ioctl(kvm_dev, KVM_CPC_BATCH_EVENTS, &arg); + if (ret) err(1, "KVM_CPC_BATCH_EVENTS"); + memset(&cfg, 0, sizeof(cfg)); cfg.mode = CPC_TRACK_PAGES; ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &cfg); -- cgit v1.2.3-71-gd317