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 80df08a54cfe9d531e932374cad55cc052a8a73d
parent 8f02a7bcb39234442039ae92dd5d3500c5b3d46d
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed, 25 Jan 2023 18:00:00 +0100

Remove cachepc objects from kvm-amd module

Diffstat:
MREADME | 2+-
Mcachepc/asm.S | 14++++++++++----
Mcachepc/cachepc.c | 13++++++++++++-
Mcachepc/event.c | 14++++++++++++++
Mcachepc/event.h | 10+---------
Mcachepc/kvm.c | 21---------------------
6 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/README b/README @@ -74,7 +74,7 @@ The following kernel parameters were used: kvm_amd.sev=1 kvm_amd.sev_es=1 nokaslr debug systemd.log_level=info isolcpus=2,10,3,11 nohz_full=2,10,3,11 rcu_nocbs=2,10,3,11 nmi_watchdog=0 - transparent_hugepage=never apic lapic panic=-1 + transparent_hugepage=never apic lapic panic=-1 preempt=none quiet To successfully build and load the kvm.ko and kvm-amd.ko modules, ensure that a host kernel debian package was built using `make host`. diff --git a/cachepc/asm.S b/cachepc/asm.S @@ -1,11 +1,13 @@ #include "macro.S" +#include <linux/linkage.h> + .global cachepc_read_pmc .global cachepc_prime_probe_test_asm .global cachepc_stream_hwpf_test_asm .global cachepc_single_eviction_test_asm -cachepc_read_pmc: +SYM_FUNC_START(cachepc_read_pmc) push %rbx push %rcx push %rdx @@ -20,8 +22,9 @@ cachepc_read_pmc: pop %rbx ret +SYM_FUNC_END(cachepc_read_pmc) -cachepc_prime_probe_test_asm: +SYM_FUNC_START(cachepc_prime_probe_test_asm) push %rbx push %rcx push %rdx @@ -49,8 +52,9 @@ cachepc_prime_probe_test_asm: pop %rbx ret +SYM_FUNC_END(cachepc_prime_probe_test_asm) -cachepc_stream_hwpf_test_asm: +SYM_FUNC_START(cachepc_stream_hwpf_test_asm) push %rbx push %rcx push %rdx @@ -84,8 +88,9 @@ cachepc_stream_hwpf_test_asm: pop %rbx ret +SYM_FUNC_END(cachepc_stream_hwpf_test_asm) -cachepc_single_eviction_test_asm: +SYM_FUNC_START(cachepc_single_eviction_test_asm) push %rbx push %rcx push %rdx @@ -114,4 +119,5 @@ cachepc_single_eviction_test_asm: pop %rbx ret +SYM_FUNC_END(cachepc_single_eviction_test_asm) diff --git a/cachepc/cachepc.c b/cachepc/cachepc.c @@ -11,6 +11,8 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) +EXPORT_SYMBOL(cachepc_read_pmc); + bool cachepc_verify_topology(void) { @@ -45,6 +47,7 @@ cachepc_verify_topology(void) return false; } +EXPORT_SYMBOL(cachepc_verify_topology); void cachepc_write_msr(uint64_t addr, uint64_t clear_bits, uint64_t set_bits) @@ -62,6 +65,7 @@ cachepc_write_msr(uint64_t addr, uint64_t clear_bits, uint64_t set_bits) addr, val, newval); } } +EXPORT_SYMBOL(cachepc_write_msr); void cachepc_init_pmc(uint8_t index, uint8_t event_no, uint8_t event_mask, @@ -83,6 +87,7 @@ cachepc_init_pmc(uint8_t index, uint8_t event_no, uint8_t event_mask, index, event_no, event_mask, event); cachepc_write_msr(0xc0010200 + index * 2, ~0ULL, event); } +EXPORT_SYMBOL(cachepc_init_pmc); void cachepc_reset_pmc(uint8_t index) @@ -92,6 +97,7 @@ cachepc_reset_pmc(uint8_t index) cachepc_write_msr(0xc0010201 + index * 2, ~0ULL, 0); } +EXPORT_SYMBOL(cachepc_reset_pmc); struct cacheline * cachepc_ds_alloc(struct cacheline **cl_arr_out) @@ -129,6 +135,7 @@ cachepc_ds_alloc(struct cacheline **cl_arr_out) return ds; } +EXPORT_SYMBOL(cachepc_ds_alloc); void * cachepc_aligned_alloc(size_t alignment, size_t size) @@ -142,6 +149,7 @@ cachepc_aligned_alloc(size_t alignment, size_t size) return p; } +EXPORT_SYMBOL(cachepc_aligned_alloc); void cachepc_save_msrmts(struct cacheline *head) @@ -156,7 +164,7 @@ cachepc_save_msrmts(struct cacheline *head) WARN_ON(cl->count > L1_ASSOC); cachepc_msrmts[cl->cache_set] = cl->count; } else { - WARN_ON(cl->count != 0); + BUG_ON(cl->count != 0); } cl->count = 0; @@ -178,6 +186,7 @@ cachepc_save_msrmts(struct cacheline *head) } } } +EXPORT_SYMBOL(cachepc_save_msrmts); void cachepc_print_msrmts(struct cacheline *head) @@ -194,6 +203,7 @@ cachepc_print_msrmts(struct cacheline *head) cl = cl->prev; } while (cl != head); } +EXPORT_SYMBOL(cachepc_print_msrmts); void cachepc_apic_oneshot_run(uint32_t interval) @@ -202,3 +212,4 @@ cachepc_apic_oneshot_run(uint32_t interval) native_apic_mem_write(APIC_TDCR, APIC_TDR_DIV_1); native_apic_mem_write(APIC_TMICT, interval); } +EXPORT_SYMBOL(cachepc_apic_oneshot_run); diff --git a/cachepc/event.c b/cachepc/event.c @@ -13,6 +13,15 @@ #define ARRLEN(x) (sizeof(x)/sizeof((x)[0])) +uint64_t cachepc_last_event_sent; +uint64_t cachepc_last_event_acked; +rwlock_t cachepc_event_lock; + +struct cpc_event cachepc_event; +bool cachepc_event_avail; + +bool cachepc_events_init; + void cachepc_events_reset(void) { @@ -77,6 +86,7 @@ cachepc_send_guest_event(uint64_t type, uint64_t val) return cachepc_send_event(event); } +EXPORT_SYMBOL(cachepc_send_guest_event); int cachepc_send_pause_event(void) @@ -87,6 +97,7 @@ cachepc_send_pause_event(void) return cachepc_send_event(event); } +EXPORT_SYMBOL(cachepc_send_pause_event); int cachepc_send_track_step_event(struct list_head *list) @@ -110,6 +121,7 @@ cachepc_send_track_step_event(struct list_head *list) return cachepc_send_event(event); } +EXPORT_SYMBOL(cachepc_send_track_step_event); int cachepc_send_track_page_event(uint64_t gfn_prev, uint64_t gfn, uint64_t retinst) @@ -124,6 +136,7 @@ cachepc_send_track_page_event(uint64_t gfn_prev, uint64_t gfn, uint64_t retinst) return cachepc_send_event(event); } +EXPORT_SYMBOL(cachepc_send_track_page_event); int cachepc_send_track_step_event_single(uint64_t gfn, uint32_t err, uint64_t retinst) @@ -139,6 +152,7 @@ cachepc_send_track_step_event_single(uint64_t gfn, uint32_t err, uint64_t retins return cachepc_send_event(event); } +EXPORT_SYMBOL(cachepc_send_track_step_event_single); bool cachepc_event_is_done(uint64_t id) diff --git a/cachepc/event.h b/cachepc/event.h @@ -2,19 +2,11 @@ #include "uapi.h" +#include <linux/swait.h> #include <linux/kvm.h> #include <linux/kvm_host.h> #include <linux/types.h> -extern uint64_t cachepc_last_event_sent; -extern uint64_t cachepc_last_event_acked; -extern rwlock_t cachepc_event_lock; - -extern struct cpc_event cachepc_event; -extern bool cachepc_event_avail; - -extern bool cachepc_events_init; - void cachepc_events_reset(void); int cachepc_send_guest_event(uint64_t type, uint64_t val); diff --git a/cachepc/kvm.c b/cachepc/kvm.c @@ -80,21 +80,6 @@ uint64_t cachepc_regs_vm[16]; EXPORT_SYMBOL(cachepc_regs_tmp); EXPORT_SYMBOL(cachepc_regs_vm); -uint64_t cachepc_last_event_sent; -uint64_t cachepc_last_event_acked; -DEFINE_RWLOCK(cachepc_event_lock); -EXPORT_SYMBOL(cachepc_last_event_sent); -EXPORT_SYMBOL(cachepc_last_event_acked); -EXPORT_SYMBOL(cachepc_event_lock); - -struct cpc_event cachepc_event; -bool cachepc_event_avail; -EXPORT_SYMBOL(cachepc_event); -EXPORT_SYMBOL(cachepc_event_avail); - -bool cachepc_events_init; -EXPORT_SYMBOL(cachepc_events_init); - void cachepc_prime_probe_test_asm(void); static noinline void cachepc_prime_probe_test(void); @@ -603,9 +588,6 @@ cachepc_kvm_track_mode_ioctl(void __user *arg_user) int cachepc_kvm_poll_event_ioctl(void __user *arg_user) { - if (!cachepc_events_init) - return -EINVAL; - return cachepc_handle_poll_event_ioctl(arg_user); } @@ -616,9 +598,6 @@ cachepc_kvm_ack_event_ioctl(void __user *arg_user) if (!arg_user) return -EINVAL; - if (!cachepc_events_init) - return -EINVAL; - if (copy_from_user(&eventid, arg_user, sizeof(eventid))) return -EFAULT;