diff mbox series

[v1,2/3] accel/kvm: Add kvm_immediate_exit callback infrastructure

Message ID 20241218154939.1114831-3-michael.roth@amd.com (mailing list archive)
State New
Headers show
Series SEV-SNP: Add support for SNP certificate fetching | expand

Commit Message

Michael Roth Dec. 18, 2024, 3:49 p.m. UTC
Provide a generic mechanism so that users of struct kvm_run's
'immediate_exit' flag can register a callback that can be issued after
returning from KVM.

Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 accel/kvm/kvm-all.c  | 43 +++++++++++++++++++++++++++++++++++++++++++
 include/sysemu/kvm.h |  3 +++
 2 files changed, 46 insertions(+)
diff mbox series

Patch

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 801cff16a5..14e98a96e6 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -3080,6 +3080,46 @@  out_unref:
     return ret;
 }
 
+typedef struct ImmediateExitEntry ImmediateExitEntry;
+
+struct ImmediateExitEntry {
+    ImmediateExitCb *cb;
+    void *opaque;
+    QTAILQ_ENTRY(ImmediateExitEntry) next;
+};
+
+static QTAILQ_HEAD(, ImmediateExitEntry) immediate_exit_list = \
+    QTAILQ_HEAD_INITIALIZER(immediate_exit_list);
+
+void add_immediate_exit_callback(CPUState *cpu, ImmediateExitCb *cb, void *opaque)
+{
+    ImmediateExitEntry *entry = g_new(ImmediateExitEntry, 1);
+    entry->cb = cb;
+    entry->opaque = opaque;
+
+    bql_lock();
+    QTAILQ_INSERT_TAIL(&immediate_exit_list, entry, next);
+    bql_unlock();
+
+    kvm_cpu_kick(cpu);
+}
+
+static void process_immediate_exit_callbacks(void)
+{
+    ImmediateExitEntry *entry, *tmp;
+
+    bql_lock();
+
+    /* Handle any pending immediate-exit callbacks */
+    QTAILQ_FOREACH_SAFE(entry, &immediate_exit_list, next, tmp) {
+        entry->cb(entry->opaque);
+        QTAILQ_REMOVE(&immediate_exit_list, entry, next);
+        g_free(entry);
+    }
+
+    bql_unlock();
+}
+
 int kvm_cpu_exec(CPUState *cpu)
 {
     struct kvm_run *run = cpu->kvm_run;
@@ -3149,6 +3189,9 @@  int kvm_cpu_exec(CPUState *cpu)
             if (run_ret == -EINTR || run_ret == -EAGAIN) {
                 trace_kvm_io_window_exit();
                 kvm_eat_signals(cpu);
+                if (kvm_immediate_exit) {
+                    process_immediate_exit_callbacks();
+                }
                 ret = EXCP_INTERRUPT;
                 break;
             }
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index c3a60b2890..5974645c62 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -578,4 +578,7 @@  int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size);
 
 int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private);
 
+typedef void ImmediateExitCb(void *opaque);
+void add_immediate_exit_callback(CPUState *cpu, ImmediateExitCb *cb, void *opaque);
+
 #endif