summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-01-30 13:59:15 +0100
committerLouis Burda <quent.burda@gmail.com>2023-01-30 13:59:15 +0100
commit9b32ccbc6df928ef75e15ee361ff64543ec4df95 (patch)
tree5d8bdfb51e286d9f10b3c4f08be829ff4a629871
parent396b02778d5c007554adf93433588632ea89267d (diff)
downloadcachepc-linux-9b32ccbc6df928ef75e15ee361ff64543ec4df95.tar.gz
cachepc-linux-9b32ccbc6df928ef75e15ee361ff64543ec4df95.zip
Combine TRACK_STEPS_* modes
-rw-r--r--arch/x86/kvm/mmu/mmu.c68
-rw-r--r--arch/x86/kvm/svm/svm.c45
-rw-r--r--arch/x86/kvm/x86.c14
3 files changed, 46 insertions, 81 deletions
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 96c262728967..896f5513d7e9 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -3960,39 +3960,41 @@ static bool page_fault_handle_page_track(struct kvm_vcpu *vcpu,
return true;
case CPC_TRACK_STEPS:
- BUG_ON(modes[i] != KVM_PAGE_TRACK_EXEC);
-
- if (!inst_fetch || !fault->present) return false;
+ if (cpc_track_steps.with_data && cpc_track_steps.stepping)
+ BUG_ON(modes[i] != KVM_PAGE_TRACK_ACCESS);
+ else
+ BUG_ON(modes[i] != KVM_PAGE_TRACK_EXEC);
CPC_INFO("Got fault cnt:%lu gfn:%08llx err:%u\n", count,
fault->gfn, fault->error_code);
cpc_untrack_single(vcpu, fault->gfn, modes[i]);
- alloc = kmalloc(sizeof(struct cpc_fault), GFP_KERNEL);
- BUG_ON(!alloc);
- alloc->gfn = fault->gfn;
- alloc->err = fault->error_code;
- list_add_tail(&alloc->list, &cpc_faults);
-
- cpc_singlestep_reset = true;
-
- break;
- case CPC_TRACK_STEPS_AND_FAULTS:
- BUG_ON(modes[i] != KVM_PAGE_TRACK_ACCESS);
-
- CPC_INFO("Got fault cnt:%lu gfn:%08llx err:%u\n", count,
- fault->gfn, fault->error_code);
+ if (!cpc_track_steps.stepping) {
+ if (!inst_fetch || !fault->present) return false;
- cpc_untrack_single(vcpu, fault->gfn, modes[i]);
+ if (fault->gfn == cpc_track_steps.target_gfn) {
+ cpc_track_steps.stepping = true;
+ if (cpc_track_steps.with_data) {
+ cpc_untrack_all(vcpu, KVM_PAGE_TRACK_EXEC);
+ cpc_track_all(vcpu, KVM_PAGE_TRACK_ACCESS);
+ cpc_untrack_single(vcpu, fault->gfn,
+ KVM_PAGE_TRACK_ACCESS);
+ }
+ }
+ }
- alloc = kmalloc(sizeof(struct cpc_fault), GFP_KERNEL);
- BUG_ON(!alloc);
- alloc->gfn = fault->gfn;
- alloc->err = fault->error_code;
- list_add_tail(&alloc->list, &cpc_faults);
+ if (cpc_track_steps.stepping) {
+ alloc = kmalloc(sizeof(struct cpc_fault), GFP_KERNEL);
+ BUG_ON(!alloc);
+ alloc->gfn = fault->gfn;
+ alloc->err = fault->error_code;
+ list_add_tail(&alloc->list, &cpc_faults);
- cpc_singlestep_reset = true;
+ cpc_singlestep_reset = true;
+ if (cpc_track_steps.with_data)
+ cpc_prime_probe = true;
+ }
break;
case CPC_TRACK_PAGES:
@@ -4035,28 +4037,10 @@ static bool page_fault_handle_page_track(struct kvm_vcpu *vcpu,
}
break;
- case CPC_TRACK_STEPS_SIGNALLED:
BUG_ON(modes[i] != KVM_PAGE_TRACK_EXEC);
if (!inst_fetch || !fault->present) return false;
- if (cpc_track_steps_signalled.enabled) {
- CPC_INFO("Got fault cnt:%lu gfn:%08llx err:%u\n", count,
- fault->gfn, fault->error_code);
-
- if (!cpc_track_steps_signalled.target_avail) {
- cpc_track_steps_signalled.target_gfn = fault->gfn;
- cpc_track_steps_signalled.target_avail = true;
- cpc_untrack_all(vcpu, KVM_PAGE_TRACK_EXEC);
- } else {
- cpc_untrack_single(vcpu, fault->gfn,
- KVM_PAGE_TRACK_EXEC);
- }
-
- cpc_singlestep_reset = true;
- cpc_prime_probe = true;
- }
-
break;
}
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 0bef86c8a38c..88b36da13a60 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -2114,6 +2114,7 @@ static int intr_interception(struct kvm_vcpu *vcpu)
struct vmcb_control_area *control;
struct vcpu_svm *svm;
struct cpc_fault *fault, *next;
+ uint64_t inst_gfn;
bool inst_gfn_seen;
size_t count;
@@ -2190,41 +2191,35 @@ static int intr_interception(struct kvm_vcpu *vcpu)
}
break;
case CPC_TRACK_STEPS:
- list_for_each_entry_safe(fault, next, &cpc_faults, list) {
- cpc_track_single(vcpu, fault->gfn, KVM_PAGE_TRACK_EXEC);
- list_del(&fault->list);
- kfree(fault);
- }
- cpc_singlestep_reset = true;
- break;
- case CPC_TRACK_STEPS_AND_FAULTS:
inst_gfn_seen = false;
list_for_each_entry_safe(fault, next, &cpc_faults, list) {
- if (!inst_gfn_seen && (fault->err & PFERR_FETCH_MASK))
+ if (!inst_gfn_seen && (fault->err & PFERR_FETCH_MASK)) {
+ inst_gfn = fault->gfn;
inst_gfn_seen = true;
- if (!inst_gfn_seen) {
+ }
+ if (!inst_gfn_seen && cpc_track_steps.use_filter) {
list_del(&fault->list);
kfree(fault);
- } else {
- cpc_track_single(vcpu, fault->gfn,
- KVM_PAGE_TRACK_ACCESS);
}
}
- cpc_send_track_step_event(&cpc_faults);
- cpc_singlestep_reset = true;
- break;
- case CPC_TRACK_STEPS_SIGNALLED:
- if (cpc_track_steps_signalled.enabled
- && cpc_track_steps_signalled.target_avail) {
- cpc_send_track_step_event_single(
- cpc_track_steps_signalled.target_gfn,
- 0, cpc_retinst);
- cpc_track_single(vcpu,
- cpc_track_steps_signalled.target_gfn,
- KVM_PAGE_TRACK_EXEC);
+ WARN_ON(!inst_gfn_seen);
+ if (cpc_track_steps.use_target &&
+ inst_gfn != cpc_track_steps.target_gfn) {
+ cpc_track_steps.stepping = false;
cpc_prime_probe = false;
cpc_singlestep = false;
}
+ if (cpc_track_steps.stepping)
+ cpc_send_track_step_event(&cpc_faults);
+ list_for_each_entry_safe(fault, next, &cpc_faults, list) {
+ if (cpc_track_steps.with_data && cpc_track_steps.stepping)
+ cpc_track_single(vcpu, fault->gfn, KVM_PAGE_TRACK_ACCESS);
+ else
+ cpc_track_single(vcpu, fault->gfn, KVM_PAGE_TRACK_EXEC);
+ list_del(&fault->list);
+ kfree(fault);
+ }
+ cpc_singlestep_reset = true;
break;
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bc6864d930ea..249ae44e21c2 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9332,20 +9332,6 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
}
case KVM_HC_CPC_VMMCALL_SIGNAL:
CPC_DBG("SIGNAL VMMCALL %lu:%lu\n", a0, a1);
- if (cpc_track_mode == CPC_TRACK_STEPS_SIGNALLED) {
- if (a0 == CPC_GUEST_START_TRACK) {
- cpc_track_steps_signalled.enabled = true;
- cpc_track_steps_signalled.target_avail = false;
- cpc_singlestep = false;
- cpc_prime_probe = false;
- cpc_track_all(vcpu, KVM_PAGE_TRACK_EXEC);
- } else if (a0 == CPC_GUEST_STOP_TRACK) {
- cpc_track_steps_signalled.enabled = false;
- cpc_singlestep = false;
- cpc_prime_probe = false;
- cpc_untrack_all(vcpu, KVM_PAGE_TRACK_EXEC);
- }
- }
cpc_send_guest_event(a0, a1);
ret = 0;
break;