qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] hostmem-file: add the 'hmem' option


From: Zhigang Luo
Subject: [PATCH] hostmem-file: add the 'hmem' option
Date: Wed, 4 Dec 2024 12:11:14 -0500

This boolean option 'hmem' allows users to set a memory region from
memory-backend-file as heterogeneous memory. If 'hmem=on', QEMU will
set the flag RAM_HMEM in the RAM block of the corresponding memory
region and set the e820 type to E820_SOFT_RESERVED for this region.

Signed-off-by: Zhigang Luo <Zhigang.Luo@amd.com>
---
 backends/hostmem-file.c      | 23 +++++++++++++++++++++++
 hw/i386/e820_memory_layout.h |  1 +
 hw/i386/pc.c                 | 16 ++++++++++++++++
 include/exec/cpu-common.h    |  1 +
 include/exec/memory.h        |  3 +++
 qapi/qom.json                |  4 ++++
 system/physmem.c             |  7 ++++++-
 7 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 7e5072e33e..5ddfdbaf86 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -32,6 +32,7 @@ struct HostMemoryBackendFile {
     uint64_t offset;
     bool discard_data;
     bool is_pmem;
+    bool is_hmem;
     bool readonly;
     OnOffAuto rom;
 };
@@ -88,6 +89,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
     ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
     ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
+    ram_flags |= fb->is_hmem ? RAM_HMEM : 0;
     ram_flags |= RAM_NAMED_FILE;
     return memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), 
name,
                                             backend->size, fb->align, 
ram_flags,
@@ -256,6 +258,25 @@ static void file_memory_backend_set_rom(Object *obj, 
Visitor *v,
     visit_type_OnOffAuto(v, name, &fb->rom, errp);
 }
 
+static bool file_memory_backend_get_hmem(Object *o, Error **errp)
+{
+    return MEMORY_BACKEND_FILE(o)->is_hmem;
+}
+
+static void file_memory_backend_set_hmem(Object *o, bool value, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(o);
+    HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+    if (host_memory_backend_mr_inited(backend)) {
+        error_setg(errp, "cannot change property 'hmem' of %s.",
+                   object_get_typename(o));
+        return;
+    }
+
+    fb->is_hmem = value;
+}
+
 static void file_backend_unparent(Object *obj)
 {
     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
@@ -295,6 +316,8 @@ file_backend_class_init(ObjectClass *oc, void *data)
     object_class_property_add_bool(oc, "pmem",
         file_memory_backend_get_pmem, file_memory_backend_set_pmem);
 #endif
+    object_class_property_add_bool(oc, "hmem",
+        file_memory_backend_get_hmem, file_memory_backend_set_hmem);
     object_class_property_add_bool(oc, "readonly",
         file_memory_backend_get_readonly,
         file_memory_backend_set_readonly);
diff --git a/hw/i386/e820_memory_layout.h b/hw/i386/e820_memory_layout.h
index b50acfa201..8af6a9cfac 100644
--- a/hw/i386/e820_memory_layout.h
+++ b/hw/i386/e820_memory_layout.h
@@ -15,6 +15,7 @@
 #define E820_ACPI       3
 #define E820_NVS        4
 #define E820_UNUSABLE   5
+#define E820_SOFT_RESERVED  0xEFFFFFFF
 
 struct e820_entry {
     uint64_t address;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 317aaca25a..41e9cc276c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -785,6 +785,21 @@ static hwaddr pc_max_used_gpa(PCMachineState *pcms, 
uint64_t pci_hole64_size)
     return pc_above_4g_end(pcms) - 1;
 }
 
+static int pc_update_hmem_memory(RAMBlock *rb, void *opaque)
+{
+    X86MachineState *x86ms = opaque;
+    ram_addr_t offset;
+    ram_addr_t length;
+
+    if (qemu_ram_is_hmem(rb)) {
+        offset = qemu_ram_get_offset(rb) + (0x100000000ULL - 
x86ms->below_4g_mem_size);
+        length = qemu_ram_get_used_length(rb);
+        e820_add_entry(offset, length, E820_SOFT_RESERVED);
+    }
+
+    return 0;
+}
+
 /*
  * AMD systems with an IOMMU have an additional hole close to the
  * 1Tb, which are special GPAs that cannot be DMA mapped. Depending
@@ -895,6 +910,7 @@ void pc_memory_init(PCMachineState *pcms,
         e820_add_entry(x86ms->above_4g_mem_start, x86ms->above_4g_mem_size,
                        E820_RAM);
     }
+    qemu_ram_foreach_block(pc_update_hmem_memory, x86ms);
 
     if (pcms->sgx_epc.size != 0) {
         e820_add_entry(pcms->sgx_epc.base, pcms->sgx_epc.size, E820_RESERVED);
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 638dc806a5..1b2dfb31e8 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -98,6 +98,7 @@ ram_addr_t qemu_ram_get_offset(RAMBlock *rb);
 ram_addr_t qemu_ram_get_used_length(RAMBlock *rb);
 ram_addr_t qemu_ram_get_max_length(RAMBlock *rb);
 bool qemu_ram_is_shared(RAMBlock *rb);
+bool qemu_ram_is_hmem(RAMBlock *rb);
 bool qemu_ram_is_noreserve(RAMBlock *rb);
 bool qemu_ram_is_uf_zeroable(RAMBlock *rb);
 void qemu_ram_set_uf_zeroable(RAMBlock *rb);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 9458e2801d..18c593a00b 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -246,6 +246,9 @@ typedef struct IOMMUTLBEvent {
 /* RAM can be private that has kvm guest memfd backend */
 #define RAM_GUEST_MEMFD   (1 << 12)
 
+/* RAM is a heterogeneous kind memory */
+#define RAM_HMEM (1 << 13)
+
 static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
                                        IOMMUNotifierFlag flags,
                                        hwaddr start, hwaddr end,
diff --git a/qapi/qom.json b/qapi/qom.json
index 28ce24cd8d..7b8632697f 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -669,6 +669,9 @@
 #     in host persistent memory that can be accessed using the SNIA
 #     NVM programming model (e.g. Intel NVDIMM).
 #
+# @hmem: specifies whether the backing file specified by @mem-path is
+#     in host heterogeneous memory.
+#
 # @readonly: if true, the backing file is opened read-only; if false,
 #     it is opened read-write.  (default: false)
 #
@@ -696,6 +699,7 @@
             '*discard-data': 'bool',
             'mem-path': 'str',
             '*pmem': { 'type': 'bool', 'if': 'CONFIG_LIBPMEM' },
+            '*hmem': 'bool',
             '*readonly': 'bool',
             '*rom': 'OnOffAuto' } }
 
diff --git a/system/physmem.c b/system/physmem.c
index dc1db3a384..f703398359 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -1584,6 +1584,11 @@ bool qemu_ram_is_noreserve(RAMBlock *rb)
     return rb->flags & RAM_NORESERVE;
 }
 
+bool qemu_ram_is_hmem(RAMBlock *rb)
+{
+    return rb->flags & RAM_HMEM;
+}
+
 /* Note: Only set at the start of postcopy */
 bool qemu_ram_is_uf_zeroable(RAMBlock *rb)
 {
@@ -1951,7 +1956,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, 
MemoryRegion *mr,
     int64_t file_size, file_align;
 
     /* Just support these ram flags by now. */
-    assert((ram_flags & ~(RAM_SHARED | RAM_PMEM | RAM_NORESERVE |
+    assert((ram_flags & ~(RAM_SHARED | RAM_PMEM | RAM_HMEM | RAM_NORESERVE |
                           RAM_PROTECTED | RAM_NAMED_FILE | RAM_READONLY |
                           RAM_READONLY_FD | RAM_GUEST_MEMFD)) == 0);
 
-- 
2.25.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]