commit 1ffb06efd201e4d754a6295f70aecbe59152f18a
parent d8a7efe6eccefaf09c71889d808a57f4c17cbb2e
Author: Louis Burda <quent.burda@gmail.com>
Date: Sat, 12 Nov 2022 01:41:43 +0100
Implement track mode instead of just cachepc_track_single_step
Diffstat:
5 files changed, 72 insertions(+), 52 deletions(-)
diff --git a/cachepc/cachepc.h b/cachepc/cachepc.h
@@ -127,11 +127,13 @@ extern bool cachepc_baseline_active;
extern uint64_t cachepc_retinst;
extern bool cachepc_single_step;
-extern bool cachepc_track_single_step;
+extern uint32_t cachepc_track_mode;
extern uint32_t cachepc_apic_timer;
+
extern bool cachepc_inst_fault_avail;
extern uint64_t cachepc_inst_fault_gfn;
extern uint32_t cachepc_inst_fault_err;
+
extern bool cachepc_data_fault_avail;
extern uint64_t cachepc_data_fault_gfn;
extern uint32_t cachepc_data_fault_err;
diff --git a/cachepc/kvm.c b/cachepc/kvm.c
@@ -29,10 +29,10 @@ uint64_t cachepc_retinst = 0;
EXPORT_SYMBOL(cachepc_retinst);
bool cachepc_single_step = false;
-bool cachepc_track_single_step = false;
+uint32_t cachepc_track_mode = false;
uint32_t cachepc_apic_timer = 0;
EXPORT_SYMBOL(cachepc_single_step);
-EXPORT_SYMBOL(cachepc_track_single_step);
+EXPORT_SYMBOL(cachepc_track_mode);
EXPORT_SYMBOL(cachepc_apic_timer);
bool cachepc_inst_fault_avail = false;
@@ -91,7 +91,7 @@ static int cachepc_kvm_measure_baseline_ioctl(void __user *arg_user);
static int cachepc_kvm_read_baseline_ioctl(void __user *arg_user);
static int cachepc_kvm_sub_baseline_ioctl(void __user *arg_user);
static int cachepc_kvm_single_step_ioctl(void __user *arg_user);
-static int cachepc_kvm_track_single_step_ioctl(void __user *arg_user);
+static int cachepc_kvm_track_mode_ioctl(void __user *arg_user);
static int cachepc_kvm_track_page_ioctl(void __user *arg_user);
static int cachepc_kvm_track_all_ioctl(void __user *arg_user);
@@ -478,16 +478,16 @@ cachepc_kvm_single_step_ioctl(void __user *arg_user)
}
int
-cachepc_kvm_track_single_step_ioctl(void __user *arg_user)
+cachepc_kvm_track_mode_ioctl(void __user *arg_user)
{
- uint32_t state;
+ uint32_t mode;
if (!arg_user) return -EINVAL;
- if (copy_from_user(&state, arg_user, sizeof(state)))
+ if (copy_from_user(&mode, arg_user, sizeof(mode)))
return -EFAULT;
- cachepc_track_single_step = state;
+ cachepc_track_mode = mode;
return 0;
}
@@ -649,8 +649,8 @@ cachepc_kvm_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
return cachepc_kvm_sub_baseline_ioctl(arg_user);
case KVM_CPC_SINGLE_STEP:
return cachepc_kvm_single_step_ioctl(arg_user);
- case KVM_CPC_TRACK_SINGLE_STEP:
- return cachepc_kvm_track_single_step_ioctl(arg_user);
+ case KVM_CPC_TRACK_MODE:
+ return cachepc_kvm_track_mode_ioctl(arg_user);
case KVM_CPC_VMSA_READ:
return cachepc_kvm_vmsa_read_ioctl(arg_user);
case KVM_CPC_TRACK_PAGE:
@@ -707,7 +707,7 @@ cachepc_kvm_init(void)
cachepc_retinst = 0;
cachepc_single_step = false;
- cachepc_track_single_step = false;
+ cachepc_track_mode = CPC_TRACK_ACCESS;
cachepc_apic_timer = 200;
cachepc_data_fault_avail = false;
diff --git a/cachepc/mmu.c b/cachepc/mmu.c
@@ -8,44 +8,56 @@ sevstep_uspt_page_fault_handle(struct kvm_vcpu *vcpu,
{
int err;
- if (kvm_slot_page_track_is_active(vcpu->kvm,
- fault->slot, fault->gfn, KVM_PAGE_TRACK_ACCESS)) {
- pr_warn("Sevstep: Tracked page fault (gfn:%llu err:%u)\n",
- fault->gfn, fault->error_code);
- //pr_warn("Sevstep: Tracked page fault attrs %i %i %i\n",
- // fault->present, fault->write, fault->user);
-
- sevstep_untrack_single(vcpu, fault->gfn, KVM_PAGE_TRACK_ACCESS);
-
- if (cachepc_track_single_step) {
- if (cachepc_single_step && cachepc_inst_fault_avail) {
- /* second fault from data access */
- pr_warn("Sevstep: Got data fault gfn:%llu err:%u\n",
- fault->gfn, fault->error_code);
-
- cachepc_data_fault_gfn = fault->gfn;
- cachepc_data_fault_err = fault->error_code;
- cachepc_data_fault_avail = true;
-
- cachepc_apic_timer = 160;
- } else {
- /* first fault from instruction fetch */
- pr_warn("Sevstep: Got inst fault gfn:%llu err:%u\n",
- fault->gfn, fault->error_code);
-
- cachepc_inst_fault_gfn = fault->gfn;
- cachepc_inst_fault_err = fault->error_code;
- cachepc_inst_fault_avail = true;
- cachepc_data_fault_avail = false;
-
- cachepc_single_step = true;
- cachepc_apic_timer = 170;
- }
+ if (!kvm_slot_page_track_is_active(vcpu->kvm,
+ fault->slot, fault->gfn, KVM_PAGE_TRACK_ACCESS))
+ return;
+
+ pr_warn("Sevstep: Tracked page fault (gfn:%llu err:%u)\n",
+ fault->gfn, fault->error_code);
+ //pr_warn("Sevstep: Tracked page fault attrs %i %i %i\n",
+ // fault->present, fault->write, fault->user);
+
+ sevstep_untrack_single(vcpu, fault->gfn, KVM_PAGE_TRACK_ACCESS);
+
+ if (cachepc_track_mode == CPC_TRACK_DATA_ACCESS) {
+ if (cachepc_single_step && cachepc_inst_fault_avail) {
+ /* second fault from data access */
+ pr_warn("Sevstep: Got data fault gfn:%llu err:%u\n",
+ fault->gfn, fault->error_code);
+
+ cachepc_data_fault_gfn = fault->gfn;
+ cachepc_data_fault_err = fault->error_code;
+ cachepc_data_fault_avail = true;
+
+ cachepc_apic_timer = 160;
} else {
- sevstep_track_single(vcpu, fault->gfn, KVM_PAGE_TRACK_ACCESS);
- if (sevstep_uspt_send_and_block(fault->gfn, fault->error_code, 0, 0))
- pr_warn("Sevstep: uspt_send_and_block failed (%d)\n", err);
+ /* first fault from instruction fetch */
+ pr_warn("Sevstep: Got inst fault gfn:%llu err:%u\n",
+ fault->gfn, fault->error_code);
+
+ cachepc_inst_fault_gfn = fault->gfn;
+ cachepc_inst_fault_err = fault->error_code;
+ cachepc_inst_fault_avail = true;
+ cachepc_data_fault_avail = false;
+
+ cachepc_single_step = true;
+ cachepc_apic_timer = 170;
+ }
+ } else if (cachepc_track_mode == CPC_TRACK_EXEC_PAGES) {
+ /* TODO: skip if not exec */
+ /* TODO: calculate retired instructions (save and subtract global counter) */
+ if (cachepc_inst_fault_avail) {
+ sevstep_track_single(vcpu, cachepc_inst_fault_gfn,
+ KVM_PAGE_TRACK_ACCESS);
}
+ cachepc_inst_fault_gfn = fault->gfn;
+ cachepc_inst_fault_err = fault->error_code;
+ if (sevstep_uspt_send_and_block(fault->gfn, fault->error_code, 0, 0))
+ pr_warn("Sevstep: uspt_send_and_block failed (%d)\n", err);
+ } else if (cachepc_track_mode == CPC_TRACK_ACCESS) {
+ sevstep_track_single(vcpu, fault->gfn, KVM_PAGE_TRACK_ACCESS);
+ if (sevstep_uspt_send_and_block(fault->gfn, fault->error_code, 0, 0))
+ pr_warn("Sevstep: uspt_send_and_block failed (%d)\n", err);
}
}
diff --git a/cachepc/uapi.h b/cachepc/uapi.h
@@ -31,7 +31,7 @@
#define KVM_CPC_READ_BASELINE _IOR(KVMIO, 0x27, __u64)
#define KVM_CPC_SUB_BASELINE _IOR(KVMIO, 0x28, __u32)
#define KVM_CPC_SINGLE_STEP _IO(KVMIO, 0x29)
-#define KVM_CPC_TRACK_SINGLE_STEP _IOWR(KVMIO, 0x2A, __u32)
+#define KVM_CPC_TRACK_MODE _IOWR(KVMIO, 0x2A, __u32)
#define KVM_CPC_VMSA_READ _IOR(KVMIO, 0x2B, __u64)
#define KVM_CPC_TRACK_PAGE _IOWR(KVMIO, 0x30, struct cpc_track_config)
@@ -41,6 +41,12 @@
#define KVM_CPC_POLL_EVENT _IOWR(KVMIO, 0x34, struct cpc_track_event)
#define KVM_CPC_ACK_EVENT _IOWR(KVMIO, 0x35, __u64)
+enum {
+ CPC_TRACK_ACCESS,
+ CPC_TRACK_DATA_ACCESS,
+ CPC_TRACK_EXEC_PAGES
+};
+
enum kvm_page_track_mode {
KVM_PAGE_TRACK_WRITE,
KVM_PAGE_TRACK_ACCESS,
diff --git a/test/sevstep.c b/test/sevstep.c
@@ -629,7 +629,7 @@ monitor(struct kvm *kvm, bool baseline)
if (!ret) {
if (!baseline) {
rip = sev_dbg_rip(kvm->vmfd);
- printf("Event: inst:%llu data:%llu retired:%llu rip:%llu\n",
+ printf("Event: inst:%llu data:%llu retired:%llu rip:%lu\n",
event.inst_fault_gfn, event.data_fault_gfn,
event.retinst, rip);
}
@@ -701,9 +701,9 @@ main(int argc, const char **argv)
if (ret == -1) err(1, "ioctl RESET_TRACKING");
/* Do data access stepping */
- arg = true;
- ret = ioctl(kvm_dev, KVM_CPC_TRACK_SINGLE_STEP, &arg);
- if (ret == -1) err(1, "ioctl TRACK_SINGLE_STEP");
+ arg = CPC_TRACK_DATA_ACCESS;
+ ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &arg);
+ if (ret == -1) err(1, "ioctl TRACK_MODE");
/* Init page tracking */
track_mode = KVM_PAGE_TRACK_ACCESS;