summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2022-12-11 02:51:47 +0100
committerLouis Burda <quent.burda@gmail.com>2022-12-11 02:51:47 +0100
commit5e99ea7f111134c7a1c7103590b711d59edafa9b (patch)
tree0d27dc1e30a77123f31dc6dee678063f5258fe7d /test
parent05a4fbf680b806327a9c53525e9d8716dcdb55f3 (diff)
downloadcachepc-5e99ea7f111134c7a1c7103590b711d59edafa9b.tar.gz
cachepc-5e99ea7f111134c7a1c7103590b711d59edafa9b.zip
Adding support for exec based tracking (unstable)
Diffstat (limited to 'test')
-rwxr-xr-xtest/.gitignore1
-rw-r--r--test/access-detect_guest.c6
-rw-r--r--test/access-detect_host.c146
-rw-r--r--test/debug.c26
-rw-r--r--test/sevstep.c30
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) {