diff options
| author | Louis Burda <quent.burda@gmail.com> | 2023-01-30 13:59:15 +0100 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2023-01-30 13:59:15 +0100 |
| commit | 9b32ccbc6df928ef75e15ee361ff64543ec4df95 (patch) | |
| tree | 5d8bdfb51e286d9f10b3c4f08be829ff4a629871 | |
| parent | 396b02778d5c007554adf93433588632ea89267d (diff) | |
| download | cachepc-linux-9b32ccbc6df928ef75e15ee361ff64543ec4df95.tar.gz cachepc-linux-9b32ccbc6df928ef75e15ee361ff64543ec4df95.zip | |
Combine TRACK_STEPS_* modes
| -rw-r--r-- | arch/x86/kvm/mmu/mmu.c | 68 | ||||
| -rw-r--r-- | arch/x86/kvm/svm/svm.c | 45 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 14 |
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; |
