diff options
Diffstat (limited to 'test')
| -rwxr-xr-x | test/.gitignore | 1 | ||||
| -rw-r--r-- | test/access-detect_guest.c | 6 | ||||
| -rw-r--r-- | test/access-detect_host.c | 146 | ||||
| -rw-r--r-- | test/debug.c | 26 | ||||
| -rw-r--r-- | test/sevstep.c | 30 |
5 files changed, 115 insertions, 94 deletions
diff --git a/test/.gitignore b/test/.gitignore index 09920dc..cf12911 100755 --- a/test/.gitignore +++ b/test/.gitignore @@ -10,4 +10,3 @@ aes-detect_host access-detect_guest access-detect_host readsvme -debug diff --git a/test/access-detect_guest.c b/test/access-detect_guest.c index 67e58fe..9fdf4ce 100644 --- a/test/access-detect_guest.c +++ b/test/access-detect_guest.c @@ -4,6 +4,7 @@ #include <unistd.h> #include <stdint.h> #include <string.h> +#include <stdio.h> #include <stdlib.h> int @@ -17,10 +18,9 @@ main(int argc, const char **argv) memset(buf, 0, L1_LINESIZE * L1_SETS); while (1) { + printf("LOOP\n"); CPC_DO_VMMCALL(CPC_CPUID_START_TRACK, 0); - - *(uint8_t *)(buf + L1_LINESIZE * 15) += 1; - + *(uint8_t *)(buf + L1_LINESIZE * 15) = 1; CPC_DO_VMMCALL(CPC_CPUID_STOP_TRACK, 0); } } diff --git a/test/access-detect_host.c b/test/access-detect_host.c index fb68dbd..f8e9b10 100644 --- a/test/access-detect_host.c +++ b/test/access-detect_host.c @@ -20,6 +20,7 @@ #include <err.h> #include <fcntl.h> #include <sched.h> +#include <dirent.h> #include <string.h> #include <stdbool.h> #include <stdlib.h> @@ -79,7 +80,7 @@ read_counts() if (!counts) err(1, "malloc"); ret = ioctl(kvm_dev, KVM_CPC_READ_COUNTS, counts); - if (ret == -1) err(1, "ioctl READ_COUNTS"); + if (ret) err(1, "ioctl READ_COUNTS"); for (i = 0; i < L1_SETS; i++) { if (counts[i] > 8) @@ -132,8 +133,9 @@ monitor(bool baseline) { struct cpc_event event; cpc_msrmt_t counts[64]; - uint64_t track_mode; - uint32_t arg; + uint64_t inst_fault_gfn; + uint64_t read_fault_gfn; + uint64_t arg; int ret, i; /* Get page fault info */ @@ -142,25 +144,32 @@ monitor(bool baseline) if (event.type == CPC_EVENT_CPUID) { printf("CPUID EVENT\n"); if (event.guest.type == CPC_CPUID_START_TRACK) { - arg = CPC_TRACK_DATA_ACCESS; - ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &arg); - if (ret == -1) err(1, "ioctl TRACK_MODE"); + ret = ioctl(kvm_dev, KVM_CPC_TRACK_EXEC_CUR, &inst_fault_gfn); + if (ret) err(1, "ioctl TRACK_EXEC_CUR"); + + printf("CPUID INST PAGE: %lu\n", inst_fault_gfn); + + arg = inst_fault_gfn; + ret = ioctl(kvm_dev, KVM_CPC_TRACK_RANGE_START, &arg); + if (ret) err(1, "ioctl TRACK_RANGE_START"); - track_mode = KVM_PAGE_TRACK_ACCESS; - ret = ioctl(kvm_dev, KVM_CPC_TRACK_ALL, &track_mode); - if (ret) err(1, "ioctl TRACK_ALL"); + arg = inst_fault_gfn+8; + ret = ioctl(kvm_dev, KVM_CPC_TRACK_RANGE_END, &arg); + if (ret) err(1, "ioctl TRACK_RANGE_END"); } else if (event.guest.type == CPC_CPUID_STOP_TRACK) { - arg = CPC_TRACK_NONE; - ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &arg); - if (ret == -1) err(1, "ioctl TRACK_MODE"); + arg = 0; + ret = ioctl(kvm_dev, KVM_CPC_TRACK_RANGE_START, &arg); + if (ret) err(1, "ioctl TRACK_RANGE_START"); - track_mode = KVM_PAGE_TRACK_ACCESS; - ret = ioctl(kvm_dev, KVM_CPC_UNTRACK_ALL, &track_mode); - if (ret) err(1, "ioctl UNTRACK_ALL"); + arg = 0; + ret = ioctl(kvm_dev, KVM_CPC_TRACK_RANGE_END, &arg); + if (ret) err(1, "ioctl TRACK_RANGE_END"); } ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id); - if (ret == -1) err(1, "ioctl ACK_EVENT"); + if (ret) err(1, "ioctl ACK_EVENT"); + + faultcnt++; return 0; } else if (event.type != CPC_EVENT_TRACK) { @@ -170,28 +179,37 @@ monitor(bool baseline) printf("EVENT\n"); ret = ioctl(kvm_dev, KVM_CPC_READ_COUNTS, counts); - if (ret == -1) err(1, "ioctl READ_COUNTS"); + if (ret) err(1, "ioctl READ_COUNTS"); + + inst_fault_gfn = 0; + read_fault_gfn = 0; + for (i = 0; i < event.track.fault_count; i++) { + if ((event.track.fault_errs[i] & 0b11111) == 0b10100) + inst_fault_gfn = event.track.fault_gfns[i]; + else if ((event.track.fault_errs[i] & 0b00110) == 0b00100) + read_fault_gfn = event.track.fault_gfns[i]; + } if (!baseline) { - printf("Event: inst:%llu data:%llu retired:%llu\n", - event.track.inst_fault_gfn, - event.track.data_fault_gfn, - event.track.retinst); + printf("Event: cnt:%llu inst:%lu data:%lu retired:%llu\n", + event.track.fault_count, inst_fault_gfn, + read_fault_gfn, event.track.retinst); print_counts(counts); printf("\n"); } for (i = 0; i < 64; i++) { if (counts[i] > 8) { - errx(1, "Invalid count for set %i (%llu)", + warnx("Invalid count for set %i (%llu)", i, counts[i]); + counts[i] = 8; } } ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id); - if (ret == -1) err(1, "ioctl ACK_EVENT"); + if (ret) err(1, "ioctl ACK_EVENT"); - faultcnt++; + if (baseline) faultcnt++; } else if (errno != EAGAIN) { perror("ioctl POLL_EVENT"); return 1; @@ -201,6 +219,39 @@ monitor(bool baseline) } int +pgrep(const char *bin) +{ + char path[PATH_MAX]; + char buf[PATH_MAX]; + char *cmp; + struct dirent *ent; + FILE *f; + DIR *dir; + + dir = opendir("/proc"); + if (!dir) err(1, "opendir"); + + while ((ent = readdir(dir))) { + snprintf(path, sizeof(path), "/proc/%s/cmdline", ent->d_name); + f = fopen(path, "rb"); + if (!f) continue; + memset(buf, 0, sizeof(buf)); + fread(buf, 1, sizeof(buf), f); + if ((cmp = strrchr(buf, '/'))) + cmp += 1; + else + cmp = buf; + if (!strcmp(cmp, bin)) + return atoi(ent->d_name); + fclose(f); + } + + closedir(dir); + + return 0; +} + +int main(int argc, const char **argv) { pid_t pid; @@ -208,20 +259,17 @@ main(int argc, const char **argv) struct cpc_event event; cpc_msrmt_t baseline[64]; int ret, i; - - if (argc <= 1 || !atoi(argv[1])) { - printf("Specify qemu process to pin\n"); - return 0; - } kvm_dev = open("/dev/kvm", O_RDWR); if (!kvm_dev) err(1, "open /dev/kvm"); setvbuf(stdout, NULL, _IONBF, 0); - pid = atoi(argv[1]); - pin_process(pid, TARGET_CORE, true); + pid = pgrep("qemu-system-x86_64"); + if (!pid) errx(1, "Failed to find qemu instance"); + printf("PID %i\n", pid); + pin_process(pid, TARGET_CORE, true); pin_process(0, TARGET_CORE, true); /* Setup needed performance counters */ @@ -230,18 +278,18 @@ main(int argc, const char **argv) /* Reset previous tracking */ ret = ioctl(kvm_dev, KVM_CPC_RESET_TRACKING, NULL); - if (ret == -1) err(1, "ioctl RESET_TRACKING"); + if (ret) err(1, "ioctl RESET_TRACKING"); pin_process(0, SECONDARY_CORE, true); printf("PINNED\n"); arg = false; ret = ioctl(kvm_dev, KVM_CPC_SUB_BASELINE, &arg); - if (ret == -1) err(1, "ioctl SUB_BASELINE"); + if (ret) err(1, "ioctl SUB_BASELINE"); arg = true; ret = ioctl(kvm_dev, KVM_CPC_MEASURE_BASELINE, &arg); - if (ret == -1) err(1, "ioctl MEASURE_BASELINE"); + if (ret) err(1, "ioctl MEASURE_BASELINE"); arg = KVM_PAGE_TRACK_ACCESS; ret = ioctl(kvm_dev, KVM_CPC_TRACK_ALL, &arg); @@ -249,7 +297,7 @@ main(int argc, const char **argv) arg = CPC_TRACK_DATA_ACCESS; ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &arg); - if (ret == -1) err(1, "ioctl TRACK_MODE"); + if (ret) err(1, "ioctl TRACK_MODE"); faultcnt = 0; while (faultcnt < 100) { @@ -258,24 +306,28 @@ main(int argc, const char **argv) do { ret = ioctl(kvm_dev, KVM_CPC_POLL_EVENT, &event); - if (ret == -1 && errno != EAGAIN) + if (ret && errno != EAGAIN) err(1, "ioctl POLL_EVENT"); - } while (ret == -1 && errno == EAGAIN); - - arg = CPC_TRACK_NONE; - ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &arg); - if (ret == -1) err(1, "ioctl TRACK_MODE"); + } while (ret && errno == EAGAIN); arg = KVM_PAGE_TRACK_ACCESS; ret = ioctl(kvm_dev, KVM_CPC_UNTRACK_ALL, &arg); + if (ret) err(1, "ioctl UNTRACK_ALL"); + + arg = CPC_TRACK_EXEC; + ret = ioctl(kvm_dev, KVM_CPC_TRACK_MODE, &arg); + if (ret) err(1, "ioctl TRACK_MODE"); + + arg = KVM_PAGE_TRACK_EXEC; + ret = ioctl(kvm_dev, KVM_CPC_TRACK_ALL, &arg); if (ret) err(1, "ioctl TRACK_ALL"); arg = false; ret = ioctl(kvm_dev, KVM_CPC_MEASURE_BASELINE, &arg); - if (ret == -1) err(1, "ioctl MEASURE_BASELINE"); + if (ret) err(1, "ioctl MEASURE_BASELINE"); ret = ioctl(kvm_dev, KVM_CPC_READ_BASELINE, baseline); - if (ret == -1) err(1, "ioctl READ_BASELINE"); + if (ret) err(1, "ioctl READ_BASELINE"); printf("\n>>> BASELINE:\n"); print_counts(baseline); @@ -291,14 +343,18 @@ main(int argc, const char **argv) arg = true; ret = ioctl(kvm_dev, KVM_CPC_SUB_BASELINE, &arg); - if (ret == -1) err(1, "ioctl SUB_BASELINE"); + if (ret) err(1, "ioctl SUB_BASELINE"); ret = ioctl(kvm_dev, KVM_CPC_ACK_EVENT, &event.id); - if (ret == -1) err(1, "ioctl ACK_EVENT"); + if (ret) err(1, "ioctl ACK_EVENT"); faultcnt = 0; while (faultcnt < 10) { if (monitor(false)) break; } + + arg = KVM_PAGE_TRACK_EXEC; + ret = ioctl(kvm_dev, KVM_CPC_UNTRACK_ALL, &arg); + if (ret) err(1, "ioctl UNTRACK_ALL"); } diff --git a/test/debug.c b/test/debug.c deleted file mode 100644 index 7a1e259..0000000 --- a/test/debug.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "cachepc/uapi.h" - -#include <sys/ioctl.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <stdint.h> -#include <err.h> -#include <fcntl.h> -#include <unistd.h> - -int -main(int argc, const char **argv) -{ - uint32_t arg; - int fd, ret; - - fd = open("/dev/kvm", O_RDONLY); - if (fd < 0) err(1, "open"); - - arg = argc > 1 ? atoi(argv[1]) : 1; - ret = ioctl(fd, KVM_CPC_DEBUG, &arg); - if (ret == -1) err(1, "ioctl DEBUG"); - - close(fd); -} diff --git a/test/sevstep.c b/test/sevstep.c index 833fafa..a8dd3aa 100644 --- a/test/sevstep.c +++ b/test/sevstep.c @@ -109,6 +109,9 @@ vm_guest_with(void) while (1) { asm volatile("mov (%0), %%eax" : : "r" (L1_LINESIZE * (L1_SETS * 3 + TARGET_SET)) : "rax"); + asm volatile("nop"); + asm volatile("mov (%0), %%eax" : : + "r" (L1_LINESIZE * (L1_SETS * 3 + TARGET_SET)) : "rax"); } } @@ -231,7 +234,7 @@ snp_dbg_decrypt(int vmfd, void *dst, void *src, size_t size) struct kvm_sev_dbg enc; int ret, fwerr; - assert(false); /* ioctl not implemented yet */ + // assert(false); /* ioctl not implemented yet */ memset(&enc, 0, sizeof(struct kvm_sev_dbg)); enc.src_uaddr = (uintptr_t) src; @@ -246,22 +249,14 @@ snp_dbg_decrypt(int vmfd, void *dst, void *src, size_t size) uint64_t snp_dbg_rip(int vmfd) { - void *vmsa; + uint8_t vmsa[PAGE_SIZE]; uint64_t rip; - int ret; - vmsa = NULL; - if (posix_memalign(&vmsa, PAGE_SIZE, PAGE_SIZE)) - err(1, "memalign"); memset(vmsa, 0, PAGE_SIZE); - snp_dbg_decrypt(vmfd, vmsa, CPC_VMSA_MAGIC_ADDR, PAGE_SIZE); - // hexdump(vmsa, PAGE_SIZE); rip = *(uint64_t *)(vmsa + 0x178); - free(vmsa); - return rip; } @@ -447,7 +442,6 @@ runonce(struct kvm *kvm) int monitor(struct kvm *kvm, bool baseline) { - static uint64_t rip_prev = 1; struct cpc_event event; cpc_msrmt_t counts[64]; uint64_t rip; @@ -463,18 +457,16 @@ monitor(struct kvm *kvm, bool baseline) if (ret == -1) err(1, "ioctl READ_COUNTS"); rip = 0; // snp_dbg_rip(kvm->vmfd); - if (!baseline && rip != rip_prev) { - printf("Event: inst:%llu data:%llu retired:%llu rip:%lu\n", - event.track.inst_fault_gfn, - event.track.data_fault_gfn, + if (!baseline) { + printf("Event: cnt:%llu inst:%llu data:%llu retired:%llu rip:%lu\n", + event.track.fault_count, + event.track.fault_gfns[0], + event.track.fault_gfns[1], event.track.retinst, rip); print_counts(counts); printf("\n"); - rip_prev = rip; - faultcnt++; - } else if (baseline) { - faultcnt++; } + faultcnt++; for (i = 0; i < 64; i++) { if (counts[i] > 8) { |
