diff mbox series

[RFC,v1,04/10] Implements the common MemoryRegion::ram_debug_ops for encrypted guests

Message ID 20210506014037.11982-5-yuan.yao@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series Enable encrypted guest memory access in QEMU | expand

Commit Message

Yuan Yao May 6, 2021, 1:40 a.m. UTC
From: Yuan Yao <yuan.yao@intel.com>

The new functions are added into target/i386/kvm/kvm.c as common functions
to support encrypted guest for KVM on x86.

Now we enable these only for INTEL TD guests.

Signed-off-by: Yuan Yao <yuan.yao@intel.com>
diff mbox series

Patch

diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 05bf4f8b8b..5050b2a82f 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -134,6 +134,9 @@  static struct kvm_msr_list *kvm_feature_msrs;
 
 static int vm_type;
 
+void kvm_encrypted_guest_set_memory_region_debug_ops(void *handle,
+                                                     MemoryRegion *mr);
+
 int kvm_set_vm_type(MachineState *ms, int kvm_type)
 {
     if (kvm_type == KVM_X86_LEGACY_VM ||
@@ -2228,6 +2231,10 @@  int kvm_arch_init(MachineState *ms, KVMState *s)
         return ret;
     }
 
+    if (kvm_tdx_enabled())
+        kvm_setup_memory_region_debug_ops(s,
+                                          kvm_encrypted_guest_set_memory_region_debug_ops);
+
     if (!kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
         error_report("kvm: KVM_CAP_IRQ_ROUTING not supported by KVM");
         return -ENOTSUP;
@@ -4917,3 +4924,62 @@  bool kvm_arch_cpu_check_are_resettable(void)
 {
     return !sev_es_enabled();
 }
+
+static int kvm_encrypted_guest_read_memory(uint8_t *dest,
+                                           const uint8_t *hva_src, hwaddr gpa_src,
+                                           uint32_t len, MemTxAttrs attrs)
+{
+    struct kvm_rw_memory rw;
+
+    /*
+      TODO:
+      Can we check SEV/TDX state to decide use
+      gpa_dest or hva_dest here ?
+
+      Also how shall we handle the kvm_vm_ioctl failure case ?
+      Some user like cpu_physical_memory_{read,write}() doesn't handle such
+      failure, because for non-encrypted guest these functions may do memory
+      reading/wrting with memcpy() dirctly before.
+      May memset() the buffer to a bad pattern (all 0x0 or 0xff)
+      for indicating this ?
+    */
+    rw.addr = gpa_src;
+    rw.buf = dest;
+    rw.len = len;
+
+    return kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_READ_MEMORY, &rw);
+}
+
+static int kvm_encrypted_guest_write_memory(uint8_t *hva_dest, hwaddr gpa_dest,
+                                            const uint8_t *src,
+                                            uint32_t len, MemTxAttrs attrs)
+{
+    struct kvm_rw_memory rw;
+
+    /*
+      TODO:
+      Can we check SEV/TDX state to decide use
+      gpa_dest or hva_dest here ?
+
+      Also how shall we handle the kvm_vm_ioctl failure case ?
+      Some user like cpu_physical_memory_{read,write}() doesn't handle such
+      failure, because for non-encrypted guest these functions may do memory
+      reading/wrting with memcpy() dirctly before.
+     */
+    rw.addr = gpa_dest;
+    rw.buf = (void*)src;
+    rw.len = len;
+
+    return kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_WRITE_MEMORY, &rw);
+}
+
+static MemoryRegionRAMReadWriteOps kvm_encrypted_guest_mr_debug_ops = {
+    .read = kvm_encrypted_guest_read_memory,
+    .write = kvm_encrypted_guest_write_memory,
+};
+
+void kvm_encrypted_guest_set_memory_region_debug_ops(void *handle,
+                                                     MemoryRegion *mr)
+{
+    memory_region_set_ram_debug_ops(mr, &kvm_encrypted_guest_mr_debug_ops);
+}