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 2ee037acfeb15bbea48422199e09ce9911dfe117
parent 3f0a50bf0999a1aadfeae0568eb0852da01433f5
Author: Louis Burda <quent.burda@gmail.com>
Date:   Fri, 27 Jan 2023 17:26:54 +0100

Make CPC_TRACK_PAGES_RESOLVE the default since no extra overhead

Diffstat:
Mcachepc/cachepc.c | 14+++++++-------
Mcachepc/cachepc.h | 8+++++---
Mcachepc/event.c | 11++---------
Mcachepc/kvm.c | 4+++-
Mcachepc/uapi.h | 1-
Mtest/kvm-pagestep.c | 12+++---------
Mtest/qemu-pagestep | 0
Mtest/qemu-pagestep.c | 2+-
8 files changed, 21 insertions(+), 31 deletions(-)

diff --git a/cachepc/cachepc.c b/cachepc/cachepc.c @@ -115,8 +115,8 @@ cpc_ds_alloc(struct cpc_cl **cl_arr_out) for (i = 0; i < L1_LINES; i++) { idx = (i % L1_SETS) * L1_ASSOC + i / L1_SETS; cl_ptr_arr[idx] = cl_arr + i; - cl_ptr_arr[idx]->cache_set = i % L1_SETS; - cl_ptr_arr[idx]->cache_line = i / L1_SETS; + cl_ptr_arr[idx]->set = i % L1_SETS; + cl_ptr_arr[idx]->line = i / L1_SETS; cl_ptr_arr[idx]->first = (i / L1_SETS) == 0; cl_ptr_arr[idx]->count = 0; } @@ -160,12 +160,12 @@ cpc_save_msrmts(struct cpc_cl *head) cl = head; do { if (cl->first) { - BUG_ON(cl->cache_set >= L1_SETS); + BUG_ON(cl->set >= L1_SETS); if (cl->count > L1_ASSOC) { CPC_ERR("Read count %llu for set %u line %u", - cl->count, cl->cache_set, cl->cache_line); + cl->count, cl->set, cl->line); } - cpc_msrmts[cl->cache_set] = cl->count; + cpc_msrmts[cl->set] = cl->count; } else { BUG_ON(cl->count != 0); } @@ -187,7 +187,7 @@ cpc_save_msrmts(struct cpc_cl *head) CPC_ERR("Count (%u) under baseline (%u) " "for set %u line %u", cpc_msrmts[i], cpc_baseline[i], - cl->cache_set, cl->cache_line); + cl->set, cl->line); } cpc_msrmts[i] -= cpc_baseline[i]; } @@ -204,7 +204,7 @@ cpc_print_msrmts(struct cpc_cl *head) do { if (cl->first) { CPC_INFO("Count for cache set %i: %llu\n", - cl->cache_set, cl->count); + cl->set, cl->count); } cl = cl->prev; diff --git a/cachepc/cachepc.h b/cachepc/cachepc.h @@ -22,8 +22,8 @@ struct cpc_cl { struct cpc_cl *prev; uint64_t count; - uint32_t cache_set; - uint32_t cache_line; + uint32_t set; + uint32_t line; bool first; char padding[31]; @@ -40,7 +40,7 @@ struct cpc_track_pages { bool cur_avail; uint64_t cur_gfn; uint64_t retinst; - bool step; + bool in_step; }; struct cpc_track_steps { @@ -88,6 +88,8 @@ extern uint8_t *cpc_baseline; extern bool cpc_baseline_measure; extern bool cpc_baseline_active; +extern uint32_t cpc_svm_exitcode; + extern bool cpc_pause_vm; extern bool cpc_prime_probe; diff --git a/cachepc/event.c b/cachepc/event.c @@ -160,8 +160,6 @@ cpc_event_is_done(void) bool done; read_lock(&cpc_event_lock); - //CPC_DBG("Event Send: Event not done %llu %llu\n", - // cpc_last_event_acked, id); done = cpc_last_event_acked == cpc_last_event_sent; read_unlock(&cpc_event_lock); @@ -175,8 +173,6 @@ cpc_poll_event_ioctl(void __user *arg_user) read_lock(&cpc_event_lock); if (!cpc_event_avail) { - //CPC_DBG("Event Poll: No event avail %llu %llu\n", - // cpc_last_event_sent, cpc_last_event_acked); read_unlock(&cpc_event_lock); return -EAGAIN; } @@ -185,16 +181,13 @@ cpc_poll_event_ioctl(void __user *arg_user) err = 0; write_lock(&cpc_event_lock); if (cpc_event_avail) { - //CPC_DBG("Event Poll: Event is avail %px %llu %llu\n", arg_user, - // cpc_last_event_sent, cpc_last_event_acked); if (copy_to_user(arg_user, &cpc_event, sizeof(cpc_event))) err = -EFAULT; + else + cpc_event_avail = false; } else { - //CPC_DBG("Event Poll: Event was avail %llu %llu\n", - // cpc_last_event_sent, cpc_last_event_acked); err = -EAGAIN; } - if (!err) cpc_event_avail = false; write_unlock(&cpc_event_lock); return err; diff --git a/cachepc/kvm.c b/cachepc/kvm.c @@ -31,6 +31,9 @@ EXPORT_SYMBOL(cpc_baseline); EXPORT_SYMBOL(cpc_baseline_measure); EXPORT_SYMBOL(cpc_baseline_active); +uint32_t cpc_svm_exitcode = false; +EXPORT_SYMBOL(cpc_svm_exitcode); + bool cpc_pause_vm = false; EXPORT_SYMBOL(cpc_pause_vm); @@ -483,7 +486,6 @@ cpc_kvm_track_mode_ioctl(void __user *arg_user) cpc_long_step = true; break; case CPC_TRACK_PAGES: - case CPC_TRACK_PAGES_RESOLVE: memset(&cpc_track_pages, 0, sizeof(cpc_track_pages)); cpc_track_all(vcpu, KVM_PAGE_TRACK_EXEC); break; diff --git a/cachepc/uapi.h b/cachepc/uapi.h @@ -53,7 +53,6 @@ enum { CPC_TRACK_FAULT_NO_RUN, CPC_TRACK_EXIT_EVICTIONS, CPC_TRACK_PAGES, - CPC_TRACK_PAGES_RESOLVE, CPC_TRACK_STEPS, CPC_TRACK_STEPS_AND_FAULTS, CPC_TRACK_STEPS_SIGNALLED, diff --git a/test/kvm-pagestep.c b/test/kvm-pagestep.c @@ -41,12 +41,6 @@ monitor(struct kvm *kvm, bool baseline) return 1; } -void -kill_child(void) -{ - kill(child, SIGKILL); -} - int main(int argc, const char **argv) { @@ -80,7 +74,6 @@ main(int argc, const char **argv) vm_init(&kvm, &guest); guest_deinit(&guest); - /* reset kernel module state */ ret = ioctl(kvm_dev, KVM_CPC_RESET, NULL); if (ret < 0) err(1, "KVM_CPC_RESET"); @@ -103,8 +96,6 @@ main(int argc, const char **argv) } else { pin_process(0, SECONDARY_CORE, true); - atexit(kill_child); - ipc_wait_child(ipc); printf("Monitor start\n"); @@ -125,6 +116,9 @@ main(int argc, const char **argv) ipc_free(ipc); + ret = ioctl(kvm_dev, KVM_CPC_RESET, NULL); + if (ret < 0) err(1, "KVM_CPC_RESET"); + kvm_setup_deinit(); } diff --git a/test/qemu-pagestep b/test/qemu-pagestep Binary files differ. diff --git a/test/qemu-pagestep.c b/test/qemu-pagestep.c @@ -53,7 +53,7 @@ main(int argc, const char **argv) ret = ioctl(kvm_dev, KVM_CPC_RESET); if (ret) err(1, "KVM_CPC_RESET"); - arg = CPC_TRACK_PAGES_RESOLVE; + arg = CPC_TRACK_PAGES; ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &arg); if (ret) err(1, "KVM_CPC_TRACK_MODE");