From ca3b348013267bf727ba52bb6fc97a7ab7d367dc Mon Sep 17 00:00:00 2001 From: Louis Burda Date: Thu, 2 Feb 2023 17:39:09 -0600 Subject: Debug single-stepping on page-boundaries in page_step --- Makefile | 1 + cachepc/cachepc.h | 5 +++-- cachepc/const.h | 7 +++++-- cachepc/kvm.c | 5 +++-- cachepc/macro.S | 6 ++---- cachepc/uapi.h | 3 +++ linux | 2 +- test/kvm-pagestep.c | 1 + test/kvm-pagestep_guest.S | 2 +- 9 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index cedeb9f..825b4bd 100755 --- a/Makefile +++ b/Makefile @@ -60,6 +60,7 @@ load: prep: sudo sh -c "echo 0 > /proc/sys/kernel/watchdog" + sudo sh -c "echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor" sudo sh -c "echo 1500000 > /sys/devices/system/cpu/cpu2/cpufreq/scaling_min_freq" sudo sh -c "echo 1500000 > /sys/devices/system/cpu/cpu2/cpufreq/scaling_max_freq" sudo sh -c "echo 1500000 > /sys/devices/system/cpu/cpu2/cpufreq/scaling_min_freq" diff --git a/cachepc/cachepc.h b/cachepc/cachepc.h index 60af52e..4af0977 100644 --- a/cachepc/cachepc.h +++ b/cachepc/cachepc.h @@ -37,6 +37,7 @@ struct cpc_fault { }; struct cpc_track_pages { + bool singlestep_resolve; bool prev_avail; bool cur_avail; bool next_avail; @@ -99,8 +100,8 @@ extern bool cpc_singlestep; extern bool cpc_singlestep_reset; extern bool cpc_long_step; -extern volatile bool cpc_apic_oneshot; -extern uint32_t cpc_apic_timer; +extern bool cpc_apic_oneshot; +extern int32_t cpc_apic_timer; extern uint32_t cpc_track_mode; extern uint64_t cpc_track_start_gfn; diff --git a/cachepc/const.h b/cachepc/const.h index a7a3c4f..907c5d2 100644 --- a/cachepc/const.h +++ b/cachepc/const.h @@ -20,8 +20,11 @@ #define CPC_CL_PREV_OFFSET 8 #define CPC_CL_COUNT_OFFSET 16 -#define CPC_APIC_TIMER_TDCR APIC_TDR_DIV_2 // APIC_TDR_DIV_1 +/* APIC divisor determines how much time is added per increment. + * A large divisor decreases the counter slower, which means more time + * is added for each increment, possiblpy skipping whole instructions */ +#define CPC_APIC_TIMER_TDCR APIC_TDR_DIV_1 #define CPC_APIC_TIMER_SOFTDIV 1 -#define CPC_APIC_TIMER_MIN (100 * CPC_APIC_TIMER_SOFTDIV) +#define CPC_APIC_TIMER_MIN (20 * CPC_APIC_TIMER_SOFTDIV) #define CPC_EVENT_BATCH_MAX 1000 diff --git a/cachepc/kvm.c b/cachepc/kvm.c index 1967e81..a1b747f 100644 --- a/cachepc/kvm.c +++ b/cachepc/kvm.c @@ -59,8 +59,8 @@ EXPORT_SYMBOL(cpc_singlestep); EXPORT_SYMBOL(cpc_singlestep_reset); EXPORT_SYMBOL(cpc_long_step); -volatile bool cpc_apic_oneshot = false; -uint32_t cpc_apic_timer = 0; +bool cpc_apic_oneshot = false; +int32_t cpc_apic_timer = 0; EXPORT_SYMBOL(cpc_apic_oneshot); EXPORT_SYMBOL(cpc_apic_timer); @@ -485,6 +485,7 @@ cpc_track_mode_ioctl(void __user *arg_user) break; case CPC_TRACK_PAGES: memset(&cpc_track_pages, 0, sizeof(cpc_track_pages)); + cpc_track_pages.singlestep_resolve = cfg.pages.singlestep_resolve; cpc_track_all(vcpu, KVM_PAGE_TRACK_EXEC); break; case CPC_TRACK_STEPS: diff --git a/cachepc/macro.S b/cachepc/macro.S index 1d39fe6..53332a4 100644 --- a/cachepc/macro.S +++ b/cachepc/macro.S @@ -2,10 +2,8 @@ # clobbers rax, rbx, rcx, rdx .macro barrier - mfence # memory barrier - rdtsc # serializing - # mov $0x80000005, %rax - # cpuid # serializing (cpuid alone does not work) + mfence # finish load and stores + lfence # prevent reordering .endm # clobbers rax, rbx, rcx, rdx, (out) diff --git a/cachepc/uapi.h b/cachepc/uapi.h index 761b494..059ae07 100644 --- a/cachepc/uapi.h +++ b/cachepc/uapi.h @@ -72,6 +72,9 @@ struct cpc_track_cfg { __u8 use_filter; __u8 with_data; } steps; + struct { + __u8 singlestep_resolve; + } pages; }; }; diff --git a/linux b/linux index a1bad01..2da04c1 160000 --- a/linux +++ b/linux @@ -1 +1 @@ -Subproject commit a1bad019795eb357099482d9ebeb7ee4eaef8655 +Subproject commit 2da04c145bcf7272de536a5dcf06af5eff435a26 diff --git a/test/kvm-pagestep.c b/test/kvm-pagestep.c index 320da68..03cd288 100644 --- a/test/kvm-pagestep.c +++ b/test/kvm-pagestep.c @@ -111,6 +111,7 @@ main(int argc, const char **argv) memset(&cfg, 0, sizeof(cfg)); cfg.mode = CPC_TRACK_PAGES; + cfg.pages.singlestep_resolve = true; ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &cfg); if (ret) err(1, "KVM_CPC_TRACK_MODE"); diff --git a/test/kvm-pagestep_guest.S b/test/kvm-pagestep_guest.S index 45d77ba..8c86f8b 100644 --- a/test/kvm-pagestep_guest.S +++ b/test/kvm-pagestep_guest.S @@ -17,7 +17,7 @@ guest: .rept L1_LINESIZE * L1_SETS - 2 nop .endr - cpuid # two byte instruction + rdtsc # two byte instruction .endr # --------------------------------- -- cgit v1.2.3-71-gd317