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 5975ec7b44887ad54417218251e669cca14bde80
parent 80df08a54cfe9d531e932374cad55cc052a8a73d
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed, 25 Jan 2023 19:16:45 +0100

Debug copy_to_user occasionally failing in kvm-step

Diffstat:
MMakefile | 1+
Mcachepc/event.c | 25++++++++++++++++++++-----
Mcachepc/event.h | 4++--
Mcachepc/kvm.c | 26++------------------------
Mtest/kvm-step.c | 6++++--
5 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/Makefile b/Makefile @@ -57,6 +57,7 @@ load: prep: sudo sh -c "echo 0 > /proc/sys/kernel/watchdog" sudo cpupower frequency-set -d 3.7GHz -u 3.7GHz + sudo sh -c "echo 1 > /proc/irq/127/smp_affinity" util/%: util/%.c $(CACHEPC_UAPI) diff --git a/cachepc/event.c b/cachepc/event.c @@ -169,7 +169,7 @@ cachepc_event_is_done(uint64_t id) } int -cachepc_handle_poll_event_ioctl(struct cpc_event __user *event) +cachepc_poll_event_ioctl(void __user *arg_user) { int err; @@ -182,10 +182,19 @@ cachepc_handle_poll_event_ioctl(struct cpc_event __user *event) } read_unlock(&cachepc_event_lock); + err = 0; write_lock(&cachepc_event_lock); if (cachepc_event_avail) { - err = copy_to_user(event, &cachepc_event, sizeof(struct cpc_event)); + CPC_DBG("Event Poll: Event is avail %px %llu %llu\n", arg_user, + cachepc_last_event_sent, cachepc_last_event_acked); + err = copy_to_user(arg_user, &cachepc_event, sizeof(cachepc_event)); + if (err != 0) { + CPC_ERR("copy_to_user %i %lu\n", err, sizeof(cachepc_event)); + err = -EFAULT; + } } else { + CPC_DBG("Event Poll: Event was avail %llu %llu\n", + cachepc_last_event_sent, cachepc_last_event_acked); err = -EAGAIN; } if (!err) cachepc_event_avail = false; @@ -195,18 +204,24 @@ cachepc_handle_poll_event_ioctl(struct cpc_event __user *event) } int -cachepc_handle_ack_event_ioctl(uint64_t eventid) +cachepc_ack_event_ioctl(void __user *arg_user) { + uint64_t eventid; int err; + if (!arg_user) return -EINVAL; + + if (copy_from_user(&eventid, arg_user, sizeof(eventid))) + return -EFAULT; + + err = 0; write_lock(&cachepc_event_lock); if (!eventid || eventid == cachepc_last_event_sent) { if (cachepc_event.type == CPC_EVENT_PAUSE) cachepc_pause_vm = false; - err = 0; cachepc_last_event_acked = cachepc_last_event_sent; } else { - err = 1; + err = -EFAULT; CPC_WARN("Acked event (%llu) does not match sent (%llu)\n", eventid, cachepc_last_event_sent); } diff --git a/cachepc/event.h b/cachepc/event.h @@ -17,5 +17,5 @@ int cachepc_send_track_page_event(uint64_t gfn_prev, uint64_t gfn, uint64_t reti bool cachepc_event_is_done(uint64_t id); -int cachepc_handle_poll_event_ioctl(struct cpc_event *user); -int cachepc_handle_ack_event_ioctl(uint64_t eventid); +int cachepc_poll_event_ioctl(void __user *arg_user); +int cachepc_ack_event_ioctl(void __user *arg_user); diff --git a/cachepc/kvm.c b/cachepc/kvm.c @@ -110,9 +110,6 @@ static int cachepc_kvm_track_mode_ioctl(void __user *arg_user); // static int cachepc_kvm_track_range_end_ioctl(void __user *arg_user); // static int cachepc_kvm_track_exec_cur_ioctl(void __user *arg_user); -static int cachepc_kvm_poll_event_ioctl(void __user *arg_user); -static int cachepc_kvm_ack_event_ioctl(void __user *arg_user); - static int cachepc_kvm_req_pause_ioctl(void __user *arg_user); void @@ -586,25 +583,6 @@ cachepc_kvm_track_mode_ioctl(void __user *arg_user) // } int -cachepc_kvm_poll_event_ioctl(void __user *arg_user) -{ - return cachepc_handle_poll_event_ioctl(arg_user); -} - -int -cachepc_kvm_ack_event_ioctl(void __user *arg_user) -{ - uint64_t eventid; - - if (!arg_user) return -EINVAL; - - if (copy_from_user(&eventid, arg_user, sizeof(eventid))) - return -EFAULT; - - return cachepc_handle_ack_event_ioctl(eventid); -} - -int cachepc_kvm_req_pause_ioctl(void __user *arg_user) { if (arg_user) return -EINVAL; @@ -646,9 +624,9 @@ cachepc_kvm_ioctl(struct file *file, unsigned int ioctl, unsigned long arg) case KVM_CPC_TRACK_MODE: return cachepc_kvm_track_mode_ioctl(arg_user); case KVM_CPC_POLL_EVENT: - return cachepc_kvm_poll_event_ioctl(arg_user); + return cachepc_poll_event_ioctl(arg_user); case KVM_CPC_ACK_EVENT: - return cachepc_kvm_ack_event_ioctl(arg_user); + return cachepc_ack_event_ioctl(arg_user); // case KVM_CPC_TRACK_PAGE: // return cachepc_kvm_track_page_ioctl(arg_user); // case KVM_CPC_TRACK_RANGE_START: diff --git a/test/kvm-step.c b/test/kvm-step.c @@ -19,11 +19,11 @@ #define SECONDARY_CORE 3 static int child; +static struct cpc_event event; uint64_t monitor(struct kvm *kvm, bool baseline) { - struct cpc_event event; uint8_t counts[64]; int ret; @@ -44,6 +44,8 @@ monitor(struct kvm *kvm, bool baseline) event.step.retinst); print_counts(counts); printf("\n"); + print_counts_raw(counts); + printf("\n"); ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id); if (ret) err(1, "ioctl KVM_CPC_ACK_EVENT"); @@ -54,6 +56,7 @@ monitor(struct kvm *kvm, bool baseline) void kill_child(void) { + printf("Killing vm..\n"); kill(child, SIGKILL); } @@ -64,7 +67,6 @@ main(int argc, const char **argv) struct guest guest; struct kvm kvm; uint8_t baseline[L1_SETS]; - struct cpc_event event; uint64_t eventcnt; uint32_t arg; int ret;