diff options
| -rwxr-xr-x | Makefile | 2 | ||||
| -rw-r--r-- | cachepc/cachepc.h | 9 | ||||
| -rw-r--r-- | cachepc/const.h | 1 | ||||
| -rw-r--r-- | cachepc/event.c | 5 | ||||
| -rw-r--r-- | cachepc/event.h | 3 | ||||
| -rw-r--r-- | cachepc/kvm.c | 9 | ||||
| -rw-r--r-- | cachepc/macro.S | 1 | ||||
| -rw-r--r-- | cachepc/uapi.h | 3 | ||||
| m--------- | linux | 0 | ||||
| -rwxr-xr-x | test/.gitignore | 4 | ||||
| -rw-r--r-- | test/qemu-targetstep.c (renamed from test/qemu-eviction.c) | 28 | ||||
| -rw-r--r-- | test/qemu-targetstep_guest.c (renamed from test/qemu-eviction_guest.c) | 7 |
12 files changed, 60 insertions, 12 deletions
@@ -11,7 +11,7 @@ BINS += test/kvm-step test/kvm-step_guest BINS += test/kvm-targetstep test/kvm-targetstep_guest BINS += test/kvm-pagestep test/kvm-pagestep_guest BINS += test/qemu-pagestep -BINS += test/qemu-eviction test/qemu-eviction_guest +BINS += test/qemu-targetstep test/qemu-targetstep_guest # BINS += test/qemu-aes_guest test/qemu-aes BINS += util/loglevel util/reset util/mainpfn diff --git a/cachepc/cachepc.h b/cachepc/cachepc.h index 21e136b..71ac49f 100644 --- a/cachepc/cachepc.h +++ b/cachepc/cachepc.h @@ -44,21 +44,29 @@ struct cpc_fault { struct cpc_track_pages { bool singlestep_resolve; uint64_t retinst; + uint64_t retinst_user; bool in_step; bool prev_avail; uint64_t prev_gfn; + uint16_t prev_err; + bool cur_avail; uint64_t cur_gfn; + uint16_t cur_err; + bool next_avail; uint64_t next_gfn; + uint16_t next_err; }; struct cpc_track_steps { bool with_data; bool use_target; + bool target_user; uint64_t target_gfn; bool stepping; + bool in_target; bool use_filter; }; @@ -118,6 +126,7 @@ extern uint64_t cpc_track_start_gfn; extern uint64_t cpc_track_end_gfn; extern uint64_t cpc_retinst; +extern uint64_t cpc_retinst_user; extern uint64_t cpc_retinst_prev; extern uint64_t cpc_rip; diff --git a/cachepc/const.h b/cachepc/const.h index b5deb53..633805e 100644 --- a/cachepc/const.h +++ b/cachepc/const.h @@ -10,6 +10,7 @@ #define CPC_L1MISS_PMC 0 #define CPC_RETINST_PMC 1 +#define CPC_RETINST_USER_PMC 2 #define CPC_VMSA_MAGIC_ADDR ((void *) 0xC0FFEE) diff --git a/cachepc/event.c b/cachepc/event.c index d863790..b85c2fc 100644 --- a/cachepc/event.c +++ b/cachepc/event.c @@ -158,14 +158,17 @@ cpc_send_track_step_event(struct list_head *list) } int -cpc_send_track_page_event(uint64_t gfn_prev, uint64_t gfn, uint64_t retinst) +cpc_send_track_page_event(uint64_t gfn_prev, uint64_t gfn, uint16_t err, + uint64_t retinst, uint64_t retinst_user) { struct cpc_event event = { 0 }; event.type = CPC_EVENT_TRACK_PAGE; event.page.inst_gfn_prev = gfn_prev; event.page.inst_gfn = gfn; + event.page.fault_err = err; event.page.retinst = retinst; + event.page.retinst_user = retinst_user; return cpc_send_event(event); } diff --git a/cachepc/event.h b/cachepc/event.h index 1464f75..bd923a2 100644 --- a/cachepc/event.h +++ b/cachepc/event.h @@ -19,7 +19,8 @@ int cpc_send_guest_event(uint64_t type, uint64_t val); int cpc_send_pause_event(void); int cpc_send_track_step_event(struct list_head *list); int cpc_send_track_step_event_single(uint64_t gfn, uint32_t err, uint64_t retinst); -int cpc_send_track_page_event(uint64_t gfn_prev, uint64_t gfn, uint64_t retinst); +int cpc_send_track_page_event(uint64_t gfn_prev, uint64_t gfn, uint16_t err, + uint64_t retinst, uint64_t retinst_user); bool cpc_event_is_done(void); diff --git a/cachepc/kvm.c b/cachepc/kvm.c index d2bb5f7..4358a3f 100644 --- a/cachepc/kvm.c +++ b/cachepc/kvm.c @@ -41,8 +41,10 @@ bool cpc_prime_probe = false; EXPORT_SYMBOL(cpc_prime_probe); uint64_t cpc_retinst = 0; +uint64_t cpc_retinst_user = 0; uint64_t cpc_retinst_prev = 0; EXPORT_SYMBOL(cpc_retinst); +EXPORT_SYMBOL(cpc_retinst_user); EXPORT_SYMBOL(cpc_retinst_prev); uint64_t cpc_rip = 0; @@ -244,6 +246,10 @@ cpc_pmc_setup(void *p) /* retired instructions in guest */ cpc_init_pmc(CPC_RETINST_PMC, 0xC0, 0x00, PMC_GUEST, PMC_KERNEL | PMC_USER); + + /* retired instructions in guest userspace */ + cpc_init_pmc(CPC_RETINST_USER_PMC, 0xC0, 0x00, + PMC_GUEST, PMC_USER); } void @@ -510,9 +516,11 @@ cpc_track_mode_ioctl(void __user *arg_user) break; case CPC_TRACK_STEPS: cpc_track_steps.use_target = cfg.steps.use_target; + cpc_track_steps.target_user = cfg.steps.target_user; cpc_track_steps.target_gfn = cfg.steps.target_gfn; cpc_track_steps.with_data = cfg.steps.with_data; cpc_track_steps.use_filter = cfg.steps.use_filter; + cpc_track_steps.in_target = false; if (!cpc_track_steps.use_target && cpc_track_steps.with_data) { cpc_track_all(vcpu, KVM_PAGE_TRACK_ACCESS); @@ -705,6 +713,7 @@ cpc_kvm_init(void) cpc_ds_ul = NULL; cpc_retinst = 0; + cpc_retinst_user = 0; cpc_long_step = false; cpc_singlestep = false; cpc_singlestep_reset = false; diff --git a/cachepc/macro.S b/cachepc/macro.S index 53332a4..249f805 100644 --- a/cachepc/macro.S +++ b/cachepc/macro.S @@ -4,6 +4,7 @@ .macro barrier mfence # finish load and stores lfence # prevent reordering + rdtsc # prevent reordering .endm # clobbers rax, rbx, rcx, rdx, (out) diff --git a/cachepc/uapi.h b/cachepc/uapi.h index e3665a3..f04b9d8 100644 --- a/cachepc/uapi.h +++ b/cachepc/uapi.h @@ -63,6 +63,7 @@ struct cpc_track_cfg { union { struct { __u64 target_gfn; + __u8 target_user; __u8 use_target; __u8 use_filter; __u8 with_data; @@ -84,7 +85,9 @@ struct cpc_track_step_event { struct cpc_track_page_event { __u64 inst_gfn_prev; __u64 inst_gfn; + __u16 fault_err; __u64 retinst; + __u64 retinst_user; }; struct cpc_guest_event { diff --git a/linux b/linux -Subproject c017dafb1efb1e28b9f5b3500bf5f87e451709d +Subproject dc737cafcbc0d030d797b66a45ccf9fe92d0970 diff --git a/test/.gitignore b/test/.gitignore index cea8b5a..9c69377 100755 --- a/test/.gitignore +++ b/test/.gitignore @@ -7,10 +7,10 @@ kvm-step kvm-step_guest kvm-pagestep kvm-pagestep_guest -qemu-eviction -qemu-eviction_guest qemu-pagestep qemu-aes qemu-aes_guest qemu-poc qemu-poc_guest +qemu-targetstep +qemu-targetstep_guest diff --git a/test/qemu-eviction.c b/test/qemu-targetstep.c index 2392472..a7345a3 100644 --- a/test/qemu-eviction.c +++ b/test/qemu-targetstep.c @@ -17,6 +17,7 @@ static struct cpc_event event; static struct cpc_event_batch batch; +static uint64_t last_user_inst_gfn; int monitor(bool baseline) @@ -30,7 +31,7 @@ monitor(bool baseline) switch (event.type) { case CPC_EVENT_GUEST: - printf("Guest event: %i\n", event.guest.type); + printf("Guest %s\n", !event.guest.type ? "start" : "stop"); if (event.guest.type == CPC_GUEST_STOP_TRACK) return 2; break; @@ -71,7 +72,14 @@ read_batch(void) if (batch.buf[i].type != CPC_EVENT_TRACK_PAGE) continue; - printf("GFN %08llx\n", batch.buf[i].page.inst_gfn); + if (batch.buf[i].page.retinst_user > 0) { + printf("GFN %08llx %04x %4llu %4llu\n", + batch.buf[i].page.inst_gfn, + batch.buf[i].page.fault_err, + batch.buf[i].page.retinst, + batch.buf[i].page.retinst_user); + last_user_inst_gfn = batch.buf[i].page.inst_gfn; + } } } @@ -185,8 +193,12 @@ main(int argc, const char **argv) ret = ioctl(kvm_dev, KVM_CPC_POLL_EVENT, &event); if (ret && errno == EAGAIN) continue; if (ret) err(1, "KVM_CPC_POLL_EVENT"); - - printf("EVENT %i\n", event.type); + + if (event.type == CPC_EVENT_GUEST) { + read_batch(); + printf("Guest %s\n", + !event.guest.type ? "start" : "stop"); + } if (event.type == CPC_EVENT_GUEST && event.guest.type == CPC_GUEST_START_TRACK) { @@ -207,17 +219,21 @@ main(int argc, const char **argv) if (!batch.cnt) errx(1, "empty batch buffer"); memset(&cfg, 0, sizeof(cfg)); cfg.mode = CPC_TRACK_STEPS; - cfg.steps.target_gfn = batch.buf[batch.cnt - 3].page.inst_gfn; + cfg.steps.target_gfn = last_user_inst_gfn; + cfg.steps.target_user = true; cfg.steps.use_target = true; cfg.steps.use_filter = true; - cfg.steps.with_data = true; + //cfg.steps.with_data = true; ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &cfg); if (ret) err(1, "KVM_CPC_TRACK_MODE"); ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id); if (ret) err(1, "KVM_CPC_ACK_EVENT"); + printf("Target GFN: %08llx\n", cfg.steps.target_gfn); + while (monitor(false) != 2); + read_batch(); signal(SIGINT, NULL); diff --git a/test/qemu-eviction_guest.c b/test/qemu-targetstep_guest.c index 086fee5..9ef36e1 100644 --- a/test/qemu-eviction_guest.c +++ b/test/qemu-targetstep_guest.c @@ -2,6 +2,7 @@ #include <sys/time.h> #include <sys/resource.h> +#include <errno.h> #include <err.h> #include <unistd.h> #include <stdint.h> @@ -13,13 +14,17 @@ int main(int argc, const char **argv) { void *buf; + int ret; buf = NULL; if (posix_memalign(&buf, L1_LINESIZE * L1_SETS, L1_LINESIZE * L1_SETS)) err(1, "memalign"); memset(buf, 0, L1_LINESIZE * L1_SETS); - setpriority(PRIO_PROCESS, 0, -20); + errno = 0; + ret = setpriority(PRIO_PROCESS, 0, -20); + if (errno) err(1, "setpriority"); + printf("NICE %i\n", ret); while (1) { printf("LOOP\n"); |
