summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-02-05 16:02:54 -0600
committerLouis Burda <quent.burda@gmail.com>2023-02-06 07:01:01 -0600
commit4dd9fe04e1399e8629ab2a98b54db6a7dcdb0076 (patch)
tree887ef659e545698927c9997b53a80beaebcbd4ce
parent0d4f62bcc065026390dd1f19b0bb462d07dcf9ff (diff)
downloadcachepc-4dd9fe04e1399e8629ab2a98b54db6a7dcdb0076.tar.gz
cachepc-4dd9fe04e1399e8629ab2a98b54db6a7dcdb0076.zip
Fix stepping inconsistency by moving oneshot after primee
-rw-r--r--cachepc/cachepc.c7
-rw-r--r--cachepc/cachepc.h7
-rw-r--r--cachepc/const.h6
-rw-r--r--cachepc/kvm.c13
m---------linux0
-rw-r--r--test/kvm-step.c19
-rw-r--r--test/kvm-step_guest.S4
-rwxr-xr-xtest/kvm-targetstep_guest2
-rw-r--r--test/kvm-targetstep_guest.S10
9 files changed, 40 insertions, 28 deletions
diff --git a/cachepc/cachepc.c b/cachepc/cachepc.c
index cdaddac..53869e1 100644
--- a/cachepc/cachepc.c
+++ b/cachepc/cachepc.c
@@ -214,7 +214,10 @@ cpc_print_msrmts(struct cpc_cl *head)
void
cpc_apic_oneshot_run(uint32_t interval)
{
+ /* 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 */
native_apic_mem_write(APIC_LVTT, LOCAL_TIMER_VECTOR | APIC_LVT_TIMER_ONESHOT);
- native_apic_mem_write(APIC_TDCR, CPC_APIC_TIMER_TDCR);
- native_apic_mem_write(APIC_TMICT, interval / CPC_APIC_TIMER_SOFTDIV);
+ native_apic_mem_write(APIC_TDCR, APIC_TDR_DIV_1);
+ native_apic_mem_write(APIC_TMICT, interval / cpc_apic_timer_softdiv);
}
diff --git a/cachepc/cachepc.h b/cachepc/cachepc.h
index f44b169..21e136b 100644
--- a/cachepc/cachepc.h
+++ b/cachepc/cachepc.h
@@ -108,9 +108,10 @@ extern bool cpc_long_step;
extern bool cpc_apic_oneshot;
extern int32_t cpc_apic_timer;
-extern uint32_t cpc_apic_timer_min;
-extern uint32_t cpc_apic_timer_dec_npf;
-extern uint32_t cpc_apic_timer_dec_intr;
+extern int32_t cpc_apic_timer_softdiv;
+extern int32_t cpc_apic_timer_min;
+extern int32_t cpc_apic_timer_dec_npf;
+extern int32_t cpc_apic_timer_dec_intr;
extern uint32_t cpc_track_mode;
extern uint64_t cpc_track_start_gfn;
diff --git a/cachepc/const.h b/cachepc/const.h
index d527735..b5deb53 100644
--- a/cachepc/const.h
+++ b/cachepc/const.h
@@ -23,12 +23,6 @@
#define CPC_CL_PREV_OFFSET 8
#define CPC_CL_COUNT_OFFSET 16
-/* 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_EVENT_BATCH_MAX 10000
#define CPC_LOGLVL_INFO 1
diff --git a/cachepc/kvm.c b/cachepc/kvm.c
index 11a18d2..d2bb5f7 100644
--- a/cachepc/kvm.c
+++ b/cachepc/kvm.c
@@ -64,9 +64,11 @@ int32_t cpc_apic_timer = 0;
EXPORT_SYMBOL(cpc_apic_oneshot);
EXPORT_SYMBOL(cpc_apic_timer);
-uint32_t cpc_apic_timer_min = 0;
-uint32_t cpc_apic_timer_dec_npf = 0;
-uint32_t cpc_apic_timer_dec_intr = 0;
+int32_t cpc_apic_timer_softdiv = 1;
+int32_t cpc_apic_timer_min = 0;
+int32_t cpc_apic_timer_dec_npf = 0;
+int32_t cpc_apic_timer_dec_intr = 0;
+EXPORT_SYMBOL(cpc_apic_timer_softdiv);
EXPORT_SYMBOL(cpc_apic_timer_min);
EXPORT_SYMBOL(cpc_apic_timer_dec_npf);
EXPORT_SYMBOL(cpc_apic_timer_dec_intr);
@@ -481,6 +483,7 @@ cpc_track_mode_ioctl(void __user *arg_user)
cpc_singlestep_reset = false;
cpc_long_step = false;
+ cpc_apic_timer_softdiv = 3;
if (sev_es_guest(vcpu->kvm)) {
cpc_apic_timer_min = 200;
cpc_apic_timer_dec_npf = 25;
@@ -506,9 +509,6 @@ cpc_track_mode_ioctl(void __user *arg_user)
cpc_track_all(vcpu, KVM_PAGE_TRACK_EXEC);
break;
case CPC_TRACK_STEPS:
- cpc_apic_timer_min = 7000;
- cpc_apic_timer_dec_npf = 50;
- cpc_apic_timer_dec_intr = 100;
cpc_track_steps.use_target = cfg.steps.use_target;
cpc_track_steps.target_gfn = cfg.steps.target_gfn;
cpc_track_steps.with_data = cfg.steps.with_data;
@@ -714,6 +714,7 @@ cpc_kvm_init(void)
cpc_apic_oneshot = false;
cpc_apic_timer = 0;
+ cpc_apic_timer_softdiv = 1;
cpc_apic_timer_min = 0;
cpc_apic_timer_dec_npf = 0;
cpc_apic_timer_dec_intr = 0;
diff --git a/linux b/linux
-Subproject 6342cefc67f3b4dff3d3b0ac031e2d9513596d8
+Subproject c017dafb1efb1e28b9f5b3500bf5f87e451709d
diff --git a/test/kvm-step.c b/test/kvm-step.c
index 4cae764..4c1b6b5 100644
--- a/test/kvm-step.c
+++ b/test/kvm-step.c
@@ -66,14 +66,17 @@ main(int argc, const char **argv)
struct cpc_track_cfg cfg;
uint64_t eventcnt;
uint32_t arg;
+ bool with_data;
int ret;
- vmtype = "kvm";
- if (argc > 1) vmtype = argv[1];
- if (strcmp(vmtype, "kvm") && strcmp(vmtype, "sev")
- && strcmp(vmtype, "sev-es")
- && strcmp(vmtype, "sev-snp"))
- errx(1, "invalid vm mode: %s", vmtype);
+ with_data = true;
+ if (argc > 1 && !strcmp(argv[1], "--exec-only")) {
+ with_data = false;
+ argc--;
+ argv++;
+ }
+
+ parse_vmtype(argc, argv);
setvbuf(stdout, NULL, _IONBF, 0);
@@ -122,7 +125,7 @@ main(int argc, const char **argv)
memset(&cfg, 0, sizeof(cfg));
cfg.mode = CPC_TRACK_STEPS;
- cfg.steps.with_data = true;
+ cfg.steps.with_data = with_data;
ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &cfg);
if (ret) err(1, "KVM_CPC_TRACK_MODE");
@@ -173,7 +176,7 @@ main(int argc, const char **argv)
if (ret) err(1, "KVM_CPC_ACK_EVENT");
eventcnt = 0;
- while (eventcnt < 50) {
+ while (eventcnt < 110) {
eventcnt += monitor(&kvm, false);
}
diff --git a/test/kvm-step_guest.S b/test/kvm-step_guest.S
index dcc8ff3..4c154d5 100644
--- a/test/kvm-step_guest.S
+++ b/test/kvm-step_guest.S
@@ -7,6 +7,10 @@
.code16gcc
guest:
+.rept 100
+ nop
+.endr
+
mov $(L1_LINESIZE * (L1_SETS + 11)), %bx
movb (%bx), %bl
hlt
diff --git a/test/kvm-targetstep_guest b/test/kvm-targetstep_guest
index 2dab495..22d2dc7 100755
--- a/test/kvm-targetstep_guest
+++ b/test/kvm-targetstep_guest
@@ -1 +1 @@
diff --git a/test/kvm-targetstep_guest.S b/test/kvm-targetstep_guest.S
index 6625c54..f8ef6d8 100644
--- a/test/kvm-targetstep_guest.S
+++ b/test/kvm-targetstep_guest.S
@@ -25,8 +25,14 @@ guest:
mov $(L1_LINESIZE * (L1_SETS + 15)), %bx
movb (%bx), %bl
- # this should only be partially single-stepped if
- # single-stepping is limited to the first page
+ jmp skip
+.rept L1_LINESIZE * L1_SETS
+ nop
+.endr
+skip:
+
+ # these nops should not be single-stepped
+ # since they are outside the target gfn
.rept L1_LINESIZE * L1_SETS * 2
nop
.endr