[RFC PATCH v1 04/17] accel/kvm: add kvm_gpa_to_userspace_addr()

Baolong Duan <[email protected]> Fri, 31 Jul 2026 11:49:58 +0800
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
Translate a guest physical address into the host userspace address
backing it by walking the memory slots of the accelerator.

The RISC-V CoVE code needs this to tell the TSM which host memory holds
the guest images that have to be measured.

Signed-off-by: Baolong Duan <[email protected]>
---
 accel/kvm/kvm-all.c  | 21 +++++++++++++++++++++
 include/system/kvm.h | 18 ++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 83cbd120a8..005abb1c54 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -366,6 +366,27 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
     return ret;
 }
 
+void *kvm_gpa_to_userspace_addr(KVMState *s, hwaddr gpa)
+{
+    KVMMemoryListener *kml = &s->memory_listener;
+    void *result = NULL;
+    int i;
+    KVMSlot *mem;
+
+    kvm_slots_lock();
+    for (i = 0; i < kml->nr_slots_allocated; i++) {
+        mem = &kml->slots[i];
+        if (gpa >= mem->start_addr &&
+            gpa < mem->start_addr + mem->memory_size) {
+            result = mem->ram + (gpa - mem->start_addr);
+            break;
+        }
+    }
+    kvm_slots_unlock();
+
+    return result;
+}
+
 static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, bool new)
 {
     KVMState *s = kvm_state;
diff --git a/include/system/kvm.h b/include/system/kvm.h
index 714b8c7b01..67a0b9f7ac 100644
--- a/include/system/kvm.h
+++ b/include/system/kvm.h
@@ -454,6 +454,24 @@ void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
 int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
                                        hwaddr *phys_addr);
 
+/**
+ * kvm_gpa_to_userspace_addr:
+ * @s: #KVMState
+ * @gpa: guest physical address
+ *
+ * Returns the host userspace address @gpa is backed by, or NULL if @gpa is
+ * not covered by any memory slot.
+ */
+#ifdef CONFIG_KVM
+void *kvm_gpa_to_userspace_addr(KVMState *s, hwaddr gpa);
+#else
+static inline void *kvm_gpa_to_userspace_addr(KVMState *s, hwaddr gpa)
+{
+    /* Without KVM there are no memory slots to look up. */
+    return NULL;
+}
+#endif
+
 #endif /* COMPILING_PER_TARGET */
 
 bool kvm_arch_supports_vmfd_change(void);
-- 
2.34.1