commit c017dafb1efb1e28b9f5b3500bf5f87e451709d5
parent 6342cefc67f3b4dff3d3b0ac031e2d9513596d80
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 6 Feb 2023 07:00:55 -0600
Fix stepping inconsistency by moving oneshot after prime
Diffstat:
3 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
@@ -3967,6 +3967,9 @@ static bool page_fault_handle_page_track(struct kvm_vcpu *vcpu,
else
BUG_ON(modes[i] != KVM_PAGE_TRACK_EXEC);
+ //CPC_WARN("here\n");
+ //if (!fault->present) return false;
+
if (modes[i] == KVM_PAGE_TRACK_EXEC && !inst_fetch)
return false;
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
@@ -2109,14 +2109,24 @@ static int intr_interception(struct kvm_vcpu *vcpu)
WARN_ON(!cpc_rip_prev_set);
if (cpc_rip == cpc_rip_prev) {
- CPC_DBG("No RIP change (%016llx,%u)\n",
- cpc_rip, cpc_apic_timer);
+ CPC_DBG("No RIP change (%016llx,%u,%llu)\n",
+ cpc_rip, cpc_apic_timer, cpc_retinst);
cpc_apic_timer += 1;
return 1;
}
cpc_rip_prev = cpc_rip;
- CPC_INFO("Detected RIP change! (%016llx,%u)\n",
- cpc_rip, cpc_apic_timer);
+ CPC_INFO("Detected RIP change! (%016llx,%u,%llu)\n",
+ cpc_rip, cpc_apic_timer, cpc_retinst);
+
+ // if (!cpc_retinst_prev)
+ // cpc_retinst_prev = cpc_retinst;
+ // if (cpc_retinst_prev == cpc_retinst) {
+ // cpc_apic_timer += 1;
+ // return 1;
+ // }
+ // cpc_retinst_prev = cpc_retinst;
+ // CPC_INFO("Detected RETINST change! (%016llx,%u,%llu)\n",
+ // cpc_rip, cpc_apic_timer, cpc_retinst);
count = 0;
list_for_each_entry(fault, &cpc_faults, list)
@@ -3373,10 +3383,11 @@ int svm_invoke_exit_handler(struct kvm_vcpu *vcpu, u64 exit_code)
if (!svm_check_exit_valid(exit_code))
return svm_handle_invalid_exit(vcpu, exit_code);
- if (cpc_loglevel >= CPC_LOGLVL_DBG) {
+ if (cpc_loglevel >= CPC_LOGLVL_INFO && exit_code != SVM_EXIT_INTR) {
for (i = 0; i < sizeof(codelut) / sizeof(codelut[0]); i++) {
if (codelut[i].code == exit_code)
- CPC_INFO("KVM EXIT (%s)\n", codelut[i].name);
+ CPC_INFO("KVM EXIT %s (%u,%llu)\n",
+ codelut[i].name, cpc_apic_timer, cpc_retinst);
}
}
@@ -3932,6 +3943,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
cpc_rip_prev = kvm_rip_read(vcpu);
}
cpc_rip_prev_set = true;
+ cpc_retinst_prev = 0;
cpc_singlestep = true;
cpc_singlestep_reset = false;
@@ -3939,7 +3951,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
if (cpc_long_step) {
WARN_ON(cpc_singlestep);
- cpc_apic_timer = 500000 * CPC_APIC_TIMER_SOFTDIV;
+ cpc_apic_timer = 5000000;
cpc_apic_oneshot = true;
} else if (cpc_singlestep) {
cpc_apic_oneshot = true;
@@ -3984,7 +3996,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
if (cpc_apic_oneshot)
CPC_DBG("Oneshot %i\n", cpc_apic_timer);
- CPC_DBG("Post vcpu_run %llu\n", cpc_retinst);
+ CPC_DBG("Retinst %llu\n", cpc_retinst);
cpc_apic_oneshot = false;
}
diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S
@@ -74,27 +74,42 @@
apply_regs save_vm
apply_regs load_tmp
+ # read vars before prime
+ xor %rax, %rax
movb cpc_apic_oneshot, %al
- cmp $0, %al
- je skip_apic_\name
-
- mov cpc_apic_timer, %edi
- call cpc_apic_oneshot_run
-
-skip_apic_\name:
+ mov %rax, %r12
+ mov cpc_apic_timer, %eax
+ mov %rax, %r13
+ mov cpc_apic_timer_softdiv, %eax
+ mov %rax, %r14
movb cpc_prime_probe, %al
mov %rax, %r15
+
+ # do prime
cmp $0, %al
je skip_prime_\name
-
wbinvd
-
mov cpc_ds, %r9
prime \name %r9 %r10 %r8
prime 1_\name %r9 %r10 %r8
prime 2_\name %r9 %r10 %r8
-
skip_prime_\name:
+
+ # do oneshot
+ mov %r12, %rax
+ cmp $0, %al
+ je skip_apic_\name
+ # asm from cpc_apic_oneshot_run
+ mov $0xec, %edx
+ mov %edx, 0xffffffffff5fd320
+ mov $0x0b, %edx
+ mov %edx, 0xffffffffff5fd3e0
+ xor %edx, %edx
+ mov %r13, %rax
+ div %r14
+ mov %eax, 0xffffffffff5fd380
+skip_apic_\name:
+
apply_regs save_tmp
apply_regs load_vm
.endm
@@ -103,13 +118,13 @@ skip_prime_\name:
apply_regs save_vm
apply_regs load_tmp
+ # do probe
mov %r15, %rax
cmp $0, %al
je skip_probe_\name
-
probe \name %r8 %r9 %r10 %r11 %r12
-
skip_probe_\name:
+
apply_regs save_tmp
apply_regs load_vm
.endm