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

qemu-pagestep.c (2124B)


      1#include "test/kvm-eviction.h"
      2#include "test/kvm.h"
      3#include "test/util.h"
      4#include "cachepc/uapi.h"
      5
      6#include <sys/ioctl.h>
      7#include <sys/mman.h>
      8#include <signal.h>
      9#include <unistd.h>
     10#include <fcntl.h>
     11#include <errno.h>
     12#include <err.h>
     13#include <string.h>
     14#include <stdbool.h>
     15#include <stdio.h>
     16#include <stdlib.h>
     17
     18struct cpc_event *batch_buffer;
     19
     20void
     21report(struct cpc_event *event)
     22{
     23	if (event->type == CPC_EVENT_TRACK_PAGE) {
     24		printf("Page event: rip:%016llx prev:%08llx next:%08llx ret:%llu\n",
     25			vm_get_rip(), event->page.inst_gfn_prev,
     26			event->page.inst_gfn, event->page.retinst);
     27	} else if (event->type == CPC_EVENT_GUEST) {
     28		printf("Guest event: type:%u arg:%u\n",
     29			event->guest.type, event->guest.val);
     30	} else {
     31		printf("Unexpected event type %i\n", event->type);
     32	}
     33	printf("\n");
     34}
     35
     36void
     37monitor(void)
     38{
     39	struct cpc_event event;
     40	struct cpc_event_batch batch;
     41	size_t i;
     42	int ret;
     43
     44	ret = ioctl(kvm_dev, KVM_CPC_POLL_EVENT, &event);
     45	if (ret && errno == EAGAIN) return;
     46	if (ret) err(1, "KVM_CPC_POLL_EVENT");
     47
     48	if (event.type == CPC_EVENT_BATCH) {
     49		batch.cnt = 0;
     50		batch.maxcnt = CPC_EVENT_BATCH_MAX;
     51		batch.buf = batch_buffer;
     52
     53		ret = ioctl(kvm_dev, KVM_CPC_READ_BATCH, &batch);
     54		if (ret) err(1, "KVM_CPC_READ_BATCH");
     55
     56		for (i = 0; i < batch.cnt; i++)
     57			report(&batch.buf[i]);
     58	} else {
     59		report(&event);
     60	}
     61
     62	ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id);
     63	if (ret) err(1, "KVM_CPC_ACK_EVENT");
     64}
     65
     66int
     67main(int argc, const char **argv)
     68{
     69	struct cpc_track_cfg cfg;
     70	uint32_t arg;
     71	int ret;
     72
     73	batch_buffer = malloc(sizeof(struct cpc_event) * CPC_EVENT_BATCH_MAX);
     74	if (!batch_buffer) err(1, "malloc");
     75
     76	setvbuf(stdout, NULL, _IONBF, 0);
     77
     78	kvm_setup_init();
     79
     80	pin_process(0, SECONDARY_CORE, true);
     81
     82	ret = ioctl(kvm_dev, KVM_CPC_RESET);
     83	if (ret) err(1, "KVM_CPC_RESET");
     84
     85	arg = true;
     86	ret = ioctl(kvm_dev, KVM_CPC_BATCH_EVENTS, &arg);
     87	if (ret) err(1, "KVM_CPC_BATCH_EVENTS");
     88
     89	memset(&cfg, 0, sizeof(cfg));
     90	cfg.mode = CPC_TRACK_PAGES;
     91	ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &cfg);
     92	if (ret) err(1, "KVM_CPC_TRACK_MODE");
     93
     94	while (1) monitor();
     95
     96	kvm_setup_deinit();
     97}
     98