commit 32331c7f421411bccb87ea818a2a0198b8cf88aa
parent a2cdd64c6f915d969dfa21e23049ff4b3836b13d
Author: Louis Burda <quent.burda@gmail.com>
Date: Tue, 7 Feb 2023 07:58:27 -0600
Add syscall to deinit events to prevent blocking on send
Diffstat:
10 files changed, 92 insertions(+), 52 deletions(-)
diff --git a/cachepc/event.c b/cachepc/event.c
@@ -24,6 +24,8 @@ rwlock_t cpc_event_lock;
struct cpc_event cpc_event;
bool cpc_event_avail;
+bool cpc_skip_events;
+
EXPORT_SYMBOL(cpc_send_guest_event);
EXPORT_SYMBOL(cpc_send_pause_event);
EXPORT_SYMBOL(cpc_send_track_step_event);
@@ -51,6 +53,7 @@ void
cpc_events_reset(void)
{
write_lock(&cpc_event_lock);
+ cpc_skip_events = false;
cpc_eventbuf_len = 0;
cpc_event_batching = false;
cpc_last_event_sent = 1;
@@ -59,11 +62,29 @@ cpc_events_reset(void)
write_unlock(&cpc_event_lock);
}
+void
+cpc_events_skip(void)
+{
+ write_lock(&cpc_event_lock);
+ cpc_skip_events = true;
+ cpc_last_event_sent = 1;
+ cpc_last_event_acked = 1;
+ cpc_event_avail = false;
+ write_unlock(&cpc_event_lock);
+}
+
int
cpc_send_event(struct cpc_event event)
{
ktime_t deadline;
+ read_lock(&cpc_event_lock);
+ if (cpc_skip_events) {
+ read_unlock(&cpc_event_lock);
+ return 1;
+ }
+ read_unlock(&cpc_event_lock);
+
write_lock(&cpc_event_lock);
if (cpc_last_event_sent != cpc_last_event_acked) {
CPC_WARN("Event IDs out of sync\n");
diff --git a/cachepc/event.h b/cachepc/event.h
@@ -14,6 +14,7 @@ extern bool cpc_event_batching;
void cpc_events_init(void);
void cpc_events_deinit(void);
void cpc_events_reset(void);
+void cpc_events_skip(void);
int cpc_send_guest_event(uint64_t type, uint64_t val);
int cpc_send_pause_event(void);
diff --git a/cachepc/kvm.c b/cachepc/kvm.c
@@ -109,6 +109,8 @@ static void cpc_pmc_setup(void *p);
static void cpc_system_setup(void);
static int cpc_reset_ioctl(void __user *arg_user);
+static int cpc_deinit_ioctl(void __user *arg_user);
+
static int cpc_loglevel_ioctl(void __user *arg_user);
static int cpc_memory_encrypt_op_ioctl(void __user *arg_user);
@@ -306,6 +308,13 @@ cpc_reset_ioctl(void __user *arg_user)
}
int
+cpc_deinit_ioctl(void __user *arg_user)
+{
+ cpc_events_skip();
+ return 0;
+}
+
+int
cpc_loglevel_ioctl(void __user *arg_user)
{
uint32_t level;
@@ -561,6 +570,8 @@ cpc_kvm_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
switch (ioctl) {
case KVM_CPC_RESET:
return cpc_reset_ioctl(arg_user);
+ case KVM_CPC_DEINIT:
+ return cpc_deinit_ioctl(arg_user);
case KVM_CPC_LOGLEVEL:
return cpc_loglevel_ioctl(arg_user);
case KVM_CPC_MEMORY_ENCRYPT_OP:
diff --git a/cachepc/uapi.h b/cachepc/uapi.h
@@ -9,10 +9,12 @@
#define CPC_DO_VMMCALL(action, type, val) \
asm volatile("vmmcall" : : "a" (action), "b"(type), "c" (val) : "rdx")
-#define KVM_CPC_RESET _IOWR(KVMIO, 0x20, __u32)
-#define KVM_CPC_LOGLEVEL _IOW(KVMIO, 0x21, __u32)
+#define KVM_CPC_RESET _IO(KVMIO, 0x20)
+#define KVM_CPC_DEINIT _IO(KVMIO, 0x21)
-#define KVM_CPC_MEMORY_ENCRYPT_OP _IOWR(KVMIO, 0x22, struct kvm_sev_cmd)
+#define KVM_CPC_LOGLEVEL _IOW(KVMIO, 0x22, __u32)
+
+#define KVM_CPC_MEMORY_ENCRYPT_OP _IOWR(KVMIO, 0x23, struct kvm_sev_cmd)
#define KVM_CPC_TEST_EVICTION _IOWR(KVMIO, 0x24, __u32)
diff --git a/test/eviction.c b/test/eviction.c
@@ -40,5 +40,8 @@ main(int argc, const char **argv)
close(fd);
+ ret = ioctl(fd, KVM_CPC_DEINIT, &arg);
+ if (ret == -1) err(1, "KVM_CPC_DEINIT");
+
return arg;
}
diff --git a/test/kvm-eviction.c b/test/kvm-eviction.c
@@ -45,15 +45,10 @@ main(int argc, const char **argv)
struct cpc_track_cfg cfg;
int i, k, ret, exitcode;
- vmtype = "kvm";
- if (argc > 1) vmtype = argv[1];
- if (strcmp(vmtype, "kvm") && strcmp(vmtype, "sev")
- && strcmp(vmtype, "sev-es")
- && strcmp(vmtype, "sev-snp"))
- errx(1, "invalid vm mode: %s", vmtype);
-
setvbuf(stdout, NULL, _IONBF, 0);
+ parse_vmtype(argc, argv);
+
pin_process(0, TARGET_CORE, true);
kvm_setup_init();
@@ -153,6 +148,9 @@ main(int argc, const char **argv)
vm_deinit(&vms[WITH]);
vm_deinit(&vms[WITHOUT]);
+ ret = ioctl(kvm_dev, KVM_CPC_DEINIT);
+ if (ret == -1) err(1, "KVM_CPC_DEINIT");
+
kvm_setup_deinit();
return exitcode;
diff --git a/test/kvm-pagestep.c b/test/kvm-pagestep.c
@@ -42,10 +42,13 @@ monitor(struct kvm *kvm, bool baseline)
}
void
-kill_child(void)
+deinit(void)
{
- printf("Killing vm..\n");
+ ioctl(kvm_dev, KVM_CPC_DEINIT);
+
kill(child, SIGKILL);
+
+ kvm_setup_deinit();
}
int
@@ -58,15 +61,10 @@ main(int argc, const char **argv)
uint64_t eventcnt;
int ret;
- vmtype = "kvm";
- if (argc > 1) vmtype = argv[1];
- if (strcmp(vmtype, "kvm") && strcmp(vmtype, "sev")
- && strcmp(vmtype, "sev-es")
- && strcmp(vmtype, "sev-snp"))
- errx(1, "invalid vm mode: %s", vmtype);
-
setvbuf(stdout, NULL, _IONBF, 0);
+ parse_vmtype(argc, argv);
+
kvm_setup_init();
ipc = ipc_alloc();
@@ -100,10 +98,14 @@ main(int argc, const char **argv)
printf("VM exit\n");
vm_deinit(&kvm);
+
+ ipc_free(ipc);
+
+ kvm_setup_deinit();
} else {
pin_process(0, SECONDARY_CORE, true);
- atexit(kill_child);
+ atexit(deinit);
ipc_wait_child(ipc);
@@ -123,13 +125,8 @@ main(int argc, const char **argv)
}
printf("Monitor exit\n");
- }
-
- ipc_free(ipc);
- ret = ioctl(kvm_dev, KVM_CPC_RESET, NULL);
- if (ret < 0) err(1, "KVM_CPC_RESET");
-
- kvm_setup_deinit();
+ ipc_free(ipc);
+ }
}
diff --git a/test/kvm-step.c b/test/kvm-step.c
@@ -50,10 +50,13 @@ monitor(struct kvm *kvm, bool baseline)
}
void
-kill_child(void)
+deinit(void)
{
- printf("Killing vm..\n");
+ ioctl(kvm_dev, KVM_CPC_DEINIT);
+
kill(child, SIGKILL);
+
+ kvm_setup_deinit();
}
int
@@ -69,6 +72,8 @@ main(int argc, const char **argv)
bool with_data;
int ret;
+ setvbuf(stdout, NULL, _IONBF, 0);
+
with_data = true;
if (argc > 1 && !strcmp(argv[1], "--exec-only")) {
with_data = false;
@@ -78,8 +83,6 @@ main(int argc, const char **argv)
parse_vmtype(argc, argv);
- setvbuf(stdout, NULL, _IONBF, 0);
-
kvm_setup_init();
ipc = ipc_alloc();
@@ -111,10 +114,13 @@ main(int argc, const char **argv)
printf("VM exit\n");
vm_deinit(&kvm);
+
+ ipc_free(ipc);
+ kvm_setup_deinit();
} else {
pin_process(0, SECONDARY_CORE, true);
- atexit(kill_child);
+ atexit(deinit);
ipc_wait_child(ipc);
@@ -178,10 +184,8 @@ main(int argc, const char **argv)
}
printf("Monitor exit\n");
- }
- ipc_free(ipc);
-
- kvm_setup_deinit();
+ ipc_free(ipc);
+ }
}
diff --git a/test/kvm-targetstep.c b/test/kvm-targetstep.c
@@ -53,10 +53,13 @@ monitor(struct kvm *kvm, bool baseline)
}
void
-kill_child(void)
+deinit(void)
{
- printf("Killing vm..\n");
+ ioctl(kvm_dev, KVM_CPC_DEINIT);
+
kill(child, SIGKILL);
+
+ kvm_setup_deinit();
}
int
@@ -73,15 +76,10 @@ main(int argc, const char **argv)
uint32_t arg;
int ret;
- vmtype = "kvm";
- if (argc > 1) vmtype = argv[1];
- if (strcmp(vmtype, "kvm") && strcmp(vmtype, "sev")
- && strcmp(vmtype, "sev-es")
- && strcmp(vmtype, "sev-snp"))
- errx(1, "invalid vm mode: %s", vmtype);
-
setvbuf(stdout, NULL, _IONBF, 0);
+ parse_vmtype(argc, argv);
+
kvm_setup_init();
ipc = ipc_alloc();
@@ -113,10 +111,13 @@ main(int argc, const char **argv)
printf("VM exit\n");
vm_deinit(&kvm);
+
+ ipc_free(ipc);
+ kvm_setup_deinit();
} else {
pin_process(0, SECONDARY_CORE, true);
- atexit(kill_child);
+ atexit(deinit);
ipc_wait_child(ipc);
@@ -218,10 +219,8 @@ main(int argc, const char **argv)
while (monitor(&kvm, false) != 2);
printf("Monitor exit\n");
- }
-
- ipc_free(ipc);
- kvm_setup_deinit();
+ ipc_free(ipc);
+ }
}
diff --git a/test/kvm.c b/test/kvm.c
@@ -28,8 +28,9 @@
#include <stdio.h>
#include <stdlib.h>
-int kvm_dev, sev_dev;
-const char *vmtype;
+int kvm_dev = -1;
+int sev_dev = -1;
+const char *vmtype = NULL;
const char *sev_fwerr_strs[] = {
[0x00] = "Success",
@@ -504,5 +505,8 @@ void
kvm_setup_deinit(void)
{
close(kvm_dev);
+ kvm_dev = -1;
+
close(sev_dev);
+ sev_dev = -1;
}