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 a4739148e856454028512a8a1b8ce54d1d9dd7bf
parent c840a299c9755a171a120a70d866262e062d5af0
Author: Louis Burda <quent.burda@gmail.com>
Date:   Mon, 29 Aug 2022 21:25:24 +0200

Update

Diffstat:
Mtest/.gitignore | 0
Mtest/access.c | 0
Mtest/eviction.c | 0
Mtest/kvm.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/test/.gitignore b/test/.gitignore diff --git a/test/access.c b/test/access.c diff --git a/test/eviction.c b/test/eviction.c diff --git a/test/kvm.c b/test/kvm.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include <stdint.h> #include <stdio.h> +#include <stdarg.h> #define ARRLEN(x) (sizeof(x) / sizeof((x)[0])) #define MIN(a,b) ((a) > (b) ? (b) : (a)) @@ -244,6 +245,86 @@ kvm_init(size_t ramsize, void *code_start, void *code_stop) if (ret < 0) err(1, "KVM_SET_REGS"); } + +int kvm_vm_ioctl(int vmfd, int type, ...) +{ + int ret; + void *arg; + va_list ap; + + va_start(ap, type); + arg = va_arg(ap, void *); + va_end(ap); + + + ret = ioctl(vmfd, type, arg); + if (ret == -1) { + ret = -errno; + } + return ret; +} + + +//VU: Copied the below function from qemu, +//e.g. https://github.dev/OpenChannelSSD/qemu-nvme/blob/master/target/i386/sev.c +//SEe also here: https://www.kernel.org/doc/Documentation/virt/kvm/amd-memory-encryption.rst +//"The The main ioctl to access SEV is KVM_MEMORY_ENCRYPT_OP. " +//If non-NULL, the argument to KVM_MEMORY_ENCRYPT_OP must be a struct kvm_sev_cmd:: +/* + struct kvm_sev_cmd { + __u32 id; + __u64 data; + __u32 error; + __u32 sev_fd; + }; + + +The ``id`` field contains the subcommand, and the ``data`` field points to +another struct containing arguments specific to command. The ``sev_fd`` +should point to a file descriptor that is opened on the ``/dev/sev`` +device, if needed (see individual commands). +*/ +static int +sev_ioctl(int fd, int cmd, void *data, int *error) +{ + int r; + struct kvm_sev_cmd input; + + memset(&input, 0x0, sizeof(input)); + + input.id = cmd; + input.sev_fd = fd; + input.data = (__u64)(unsigned long)data; + + r = kvm_vm_ioctl(kvm.fd, KVM_MEMORY_ENCRYPT_OP, &input); + + if (error) { + *error = input.error; + } + + return r; +} + +void +kvm_svm_init() +{ + int sev_fd; + int fw_error; + int status; + + sev_fd = open("/dev/sev", O_RDWR | O_CLOEXEC); + if (sev_fd < 0) err(1, "/dev/sev"); + kvm.fd = open("/dev/kvm", O_RDWR | O_CLOEXEC); + if (kvm.fd < 0) err(1, "/dev/kvm"); + int r = ioctl(kvm.fd, KVM_MEMORY_ENCRYPT_OP, NULL); //sev_ioctl(sev_fd, NULL, NULL, &fw_error); + printf("SEV ioctol %d \n",r); + printf("fw_error %d \n", fw_error); + if (r < 0) err(1,"SEV ioctol"); + + //printf("Return code opening /dev/sev %d\n", sev_fd); + //printf("Return code %d \n", ioctl(sev_fd, KVM_SEV_ES_INIT, NULL)); +} + uint16_t * read_counts() { @@ -330,7 +411,7 @@ main(int argc, const char **argv) pin_process(0, TARGET_CORE, true); cachepc_fd = open("/proc/cachepc", O_RDONLY); - if (cachepc_fd < 0) err(1, "open"); + if (cachepc_fd < 0) err(1, "open /proc/cachepc"); /* init L1 miss counter */ arg = 0x000064D8; @@ -341,7 +422,8 @@ main(int argc, const char **argv) if (!baseline) err(1, "counts"); for (k = 0; k < 64; k++) baseline[k] = UINT16_MAX; - + kvm_svm_init(); + return 0; for (i = 0; i < SAMPLE_COUNT; i++) { counts = collect("without", __start_guest_without, __stop_guest_without); memcpy(without_access[i], counts, 64 * sizeof(uint16_t));