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 039144b8e7f7fb4074883e8037787d420e86f70c
parent 7cd66755ff29a9f56601d5612a902b45d14798d5
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed,  1 Feb 2023 12:20:58 -0600

fixup! Event batching

Diffstat:
MMakefile | 2+-
MREADME | 4++--
Mcachepc/event.c | 23+++++++++--------------
Mcachepc/uapi.h | 15++++++++-------
Mtest/kvm-step.c | 1+
Dtest/qemu-pagestep | 0
6 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/Makefile b/Makefile @@ -44,7 +44,7 @@ linux: # build host kernel for depmod git -C $(LINUX) stash git -C $(LINUX) checkout d9bd54fea4d2 rm -f $(LINUX)/arch/x86/kvm/cachepc - $(MAKE) -C $(LINUX) -j $(JOBS) -l $(LOAD) + $(MAKE) -C $(LINUX) -j $(JOBS) -l $(LOAD) vmlinux headers git -C $(LINUX) checkout master git -C $(LINUX) stash pop || true diff --git a/README b/README @@ -69,13 +69,13 @@ CPC_TRACK_EXIT_EVICTION: measurements over a clean run to a guest-invoked exit such as KVM_EXIT_HLT. CPC_TRACK_PAGES: - Track execution of all guest pages. While the guest is running untrack + Track execution of all guest pages. While the guest is running, untrack a single executable page at a time based on page-faults. Allows tracking which guest pages are executed and how long using retired instructions. CPC_TRACK_STEPS: Single-step guest exection. For each step, collect either only instruction - or instruction and page-faults. Allows tracking not only which sets were + or instruction and data page-faults. Allows tracking not only which sets were evicted but what gfns were involved in the access. A target page can be set, such that we will first page-step until the page is reached, then single-step while running instructions on that page. diff --git a/cachepc/event.c b/cachepc/event.c @@ -71,6 +71,7 @@ cpc_send_event(struct cpc_event event) if (cpc_event_batching) { if (cpc_eventbuf_len < CPC_EVENTBUF_CAP) { + event.id = 0; memcpy(&cpc_eventbuf[cpc_eventbuf_len], &event, sizeof(struct cpc_event)); cpc_eventbuf_len++; @@ -84,7 +85,7 @@ cpc_send_event(struct cpc_event event) } cpc_last_event_sent++; - event.id = cpc_last_event_sent; + cpc_event.id = cpc_last_event_sent; cpc_event_avail = true; write_unlock(&cpc_event_lock); @@ -193,23 +194,17 @@ cpc_poll_event_ioctl(void __user *arg_user) { int err; - read_lock(&cpc_event_lock); + write_lock(&cpc_event_lock); if (!cpc_event_avail) { - read_unlock(&cpc_event_lock); + write_unlock(&cpc_event_lock); return -EAGAIN; } - read_unlock(&cpc_event_lock); err = 0; - write_lock(&cpc_event_lock); - if (cpc_event_avail) { - if (copy_to_user(arg_user, &cpc_event, sizeof(cpc_event))) - err = -EFAULT; - else - cpc_event_avail = false; - } else { - err = -EAGAIN; - } + if (copy_to_user(arg_user, &cpc_event, sizeof(cpc_event))) + err = -EFAULT; + else + cpc_event_avail = false; write_unlock(&cpc_event_lock); return err; @@ -245,7 +240,7 @@ cpc_ack_event_ioctl(void __user *arg_user) int cpc_read_events_ioctl(void __user *arg_user) { - struct cpc_event_batch batch; + struct cpc_batch_event batch; size_t n; if (!arg_user) return -EINVAL; diff --git a/cachepc/uapi.h b/cachepc/uapi.h @@ -30,7 +30,7 @@ #define KVM_CPC_POLL_EVENT _IOWR(KVMIO, 0x40, struct cpc_event) #define KVM_CPC_ACK_EVENT _IOWR(KVMIO, 0x41, __u64) -#define KVM_CPC_READ_EVENTS _IOWR(KVMIO, 0x42, struct cpc_event_batch) +#define KVM_CPC_READ_EVENTS _IOWR(KVMIO, 0x42, struct cpc_batch_event) #define KVM_CPC_VM_REQ_PAUSE _IO(KVMIO, 0x50) @@ -93,6 +93,12 @@ struct cpc_guest_event { __u64 val; }; +struct cpc_batch_event { + __u64 cnt; + __u64 maxcnt; + struct cpc_event *buf; +}; + struct cpc_event { __u32 type; __u64 id; @@ -100,15 +106,10 @@ struct cpc_event { struct cpc_track_step_event step; struct cpc_track_page_event page; struct cpc_guest_event guest; + struct cpc_batch_event batch; }; }; -struct cpc_event_batch { - __u64 cnt; - __u64 maxcnt; - struct cpc_event *buf; -}; - struct cpc_sev_cmd { __u32 id; __u64 data; diff --git a/test/kvm-step.c b/test/kvm-step.c @@ -146,6 +146,7 @@ main(int argc, const char **argv) if (ret && errno == EAGAIN) continue; if (ret) err(1, "KVM_CPC_POLL_EVENT"); + printf("%lu\n", event.id); if (event.type == CPC_EVENT_PAUSE) break; ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id); diff --git a/test/qemu-pagestep b/test/qemu-pagestep Binary files differ.