cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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:
March/x86/kvm/mmu/mmu.c | 3+++
March/x86/kvm/svm/svm.c | 28++++++++++++++++++++--------
March/x86/kvm/svm/vmenter.S | 39+++++++++++++++++++++++++++------------
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