From f39ed19a71f9ae67ec1ac48d77c62469421416e0 Mon Sep 17 00:00:00 2001 From: Louis Burda Date: Mon, 29 Aug 2022 21:25:24 +0200 Subject: UPdate --- test/.gitignore | 0 test/access.c | 0 test/eviction.c | 0 test/kvm.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 84 insertions(+), 2 deletions(-) mode change 100644 => 100755 test/.gitignore mode change 100644 => 100755 test/access.c mode change 100644 => 100755 test/eviction.c mode change 100644 => 100755 test/kvm.c diff --git a/test/.gitignore b/test/.gitignore old mode 100644 new mode 100755 diff --git a/test/access.c b/test/access.c old mode 100644 new mode 100755 diff --git a/test/eviction.c b/test/eviction.c old mode 100644 new mode 100755 diff --git a/test/kvm.c b/test/kvm.c old mode 100644 new mode 100755 index c17c464..637a8f2 --- a/test/kvm.c +++ b/test/kvm.c @@ -25,6 +25,7 @@ #include #include #include +#include #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)); -- cgit v1.2.3-71-gd317 From 0e0e702c01a5af28f3a5149b4bae9609060fdf05 Mon Sep 17 00:00:00 2001 From: Louis Burda Date: Mon, 29 Aug 2022 22:39:10 +0200 Subject: Further progress on launching an encrypted vm --- test/kvm.c | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/test/kvm.c b/test/kvm.c index 637a8f2..a43cab1 100755 --- a/test/kvm.c +++ b/test/kvm.c @@ -296,7 +296,7 @@ sev_ioctl(int fd, int cmd, void *data, int *error) input.sev_fd = fd; input.data = (__u64)(unsigned long)data; - r = kvm_vm_ioctl(kvm.fd, KVM_MEMORY_ENCRYPT_OP, &input); + r = kvm_vm_ioctl(kvm.vmfd, KVM_MEMORY_ENCRYPT_OP, &input); if (error) { *error = input.error; @@ -306,20 +306,54 @@ sev_ioctl(int fd, int cmd, void *data, int *error) } void -kvm_svm_init() +kvm_svm_init(size_t ramsize, void *code_start, void *code_stop) { + //https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf + // int sev_fd; int fw_error; int status; + struct kvm_regs regs; + uint16_t *counts; + int ret, r; + + /* using cache size for alignment of kvm memory access */ + kvm_init(64 * 64 * 8 * 2, code_start, code_stop); + ret = 0; + kvm_run->exit_reason = 0; 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); + //kvm.fd = open("/dev/kvm", O_RDWR | O_CLOEXEC); + //if (kvm.fd < 0) err(1, "/dev/kvm"); + ///kvm.vmfd = ioctl(kvm.fd, KVM_CREATE_VM, 0); + //if (kvm.vmfd < 0) err(1, "KVM_CREATE_VM"); + //int r = ioctl(kvm.fd, KVM_GET_API_VERSION, NULL); //sev_ioctl(sev_fd, NULL, NULL, &fw_error); + //if (r == -1) err(1, "KVM_GET_API_VERSION"); + //if (r != 12) errx(1, "KVM_GET_API_VERSION %d, expected 12", r); + //printf("KVM API Version %d\n", r); + r = ioctl(kvm.vmfd, 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"); + if (r < 0) err(1,"SEV ioctol does not seem to be enabled"); + r = sev_ioctl(sev_fd,KVM_SEV_INIT, NULL, &fw_error); //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,"Problem with KVM_SEV_INIT"); + //Next command: + struct kvm_sev_launch_start start; + memset(&start, 0, sizeof(struct kvm_sev_launch_start)); + start.handle = 0; //Create a new handle + start.policy = 0x30000; + r = sev_ioctl(sev_fd,KVM_SEV_LAUNCH_START, &start, &fw_error); //sev_ioctl(sev_fd, NULL, NULL, &fw_error); + printf("SEV ioctol %d, start.handle %d \n",r, start.handle); + printf("fw_error %d \n", fw_error); + if (r < 0) err(1,"Problem with KVM_SEV_INIT"); + + + + + //printf("Return code opening /dev/sev %d\n", sev_fd); //printf("Return code %d \n", ioctl(sev_fd, KVM_SEV_ES_INIT, NULL)); @@ -422,7 +456,7 @@ main(int argc, const char **argv) if (!baseline) err(1, "counts"); for (k = 0; k < 64; k++) baseline[k] = UINT16_MAX; - kvm_svm_init(); + kvm_svm_init(64 * 64 * 8 * 2, __start_guest_with, __stop_guest_with); return 0; for (i = 0; i < SAMPLE_COUNT; i++) { counts = collect("without", __start_guest_without, __stop_guest_without); -- cgit v1.2.3-71-gd317