All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory
@ 2026-06-16  9:08 fanhuang
  2026-06-16  9:08 ` [PATCH v12 1/4] " fanhuang
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: fanhuang @ 2026-06-16  9:08 UTC (permalink / raw)
  To: qemu-devel, david, imammedo, gourry, philmd
  Cc: Zhigang.Luo, Lianjie.Shi, fanhuang

This series adds a TYPE_MEMORY_DEVICE subclass `sp-mem` for boot-time
SOFT_RESERVED guest memory, following the direction from the v7
thread [1] and the v8 / v9 / v10 / v11 reviews [2][3][4][5].

Background
----------

This series targets coherent CPU + accelerator shared-address-space
systems, where the accelerator's HBM is not a device-private
framebuffer behind a PCIe BAR but a tier of host system memory:
visible to the CPU in the platform physical address space, shared
coherently with the accelerator over the platform fabric, and bound
to a NUMA proximity domain set by platform firmware at boot fabric
training.

For such a region to function correctly in the guest, two things
must hold simultaneously: the CPU memory subsystem has to see it in
the system memory map (so the CPU side can address it), and it has
to be reserved exclusively for the accelerator's driver (so the
kernel's general allocator does not hand SPM pages to unrelated
workloads). The SOFT_RESERVED memory type in E820 plus a matching
SRAT memory-affinity entry is the mechanism that delivers both: a
firmware-produced topology that the CPU memory subsystem honors and
the accelerator's driver consumes for its own range.

Approach
--------

The series introduces a new TYPE_MEMORY_DEVICE subclass `sp-mem`.
Each instance binds one host memory backend to a single NUMA
proximity domain and is boot-time only; placement, mapped-state
enforcement, and QMP introspection come from the existing
memory-device framework.

Testing
-------

Verified end-to-end on q35 + KVM, with both SeaBIOS and OVMF, for:

- single sp-mem instance
- two sp-mem instances on different NUMA nodes

Guest observations: /proc/iomem shows one SOFT_RESERVED entry per
sp-mem device, dmesg SRAT parsing reports the matching
memory_affinity entries with correct PXM, and the umbrella
HOTPLUGGABLE entry covers the remaining hotplug-memory window
without overlapping the sp-mem ranges.

Changes since v11
-----------------

  - Drop the unneeded memory-device.h and system/hostmem.h includes
    from sp-mem.h (HostMemoryBackend is forward-declared).
  - Use SP_MEM_MEMDEV_PROP in sp_mem_get_memory_region()'s error
    message, matching realize().
  - Move the .unmigratable comment next to the field it documents.

All v11 patch-1 review comments from Philippe; patches 2-4 unchanged.
Patch 4 (MAINTAINERS) retains the Acked-by from Igor and David.

Previous versions
-----------------

  v1: https://lore.kernel.org/qemu-devel/20250924103324.2074819-1-FangSheng.Huang@amd.com/
  v2: https://lore.kernel.org/qemu-devel/20251020090701.4036748-1-FangSheng.Huang@amd.com/
  v3: https://lore.kernel.org/qemu-devel/20251208105137.2058928-1-FangSheng.Huang@amd.com/
  v4: https://lore.kernel.org/qemu-devel/20251209093841.2250527-1-FangSheng.Huang@amd.com/
  v5: https://lore.kernel.org/qemu-devel/20260123024312.1601732-1-FangSheng.Huang@amd.com/
  v6: https://lore.kernel.org/qemu-devel/20260226105023.256568-1-FangSheng.Huang@amd.com/
  v7: https://lore.kernel.org/qemu-devel/20260306082735.1106690-1-FangSheng.Huang@amd.com/
  v8: https://lore.kernel.org/qemu-devel/20260527074215.229119-1-FangSheng.Huang@amd.com/
  v9: https://lore.kernel.org/qemu-devel/20260602084447.1100554-1-FangSheng.Huang@amd.com/
  v10: https://lore.kernel.org/qemu-devel/20260605104609.1739911-1-FangSheng.Huang@amd.com/
  v11: https://lore.kernel.org/qemu-devel/20260611100637.2460507-1-FangSheng.Huang@amd.com/

  [1] v7 thread closeout:
      https://lore.kernel.org/qemu-devel/666a7ba1-5d3a-4732-b872-0d9fb2fe8461@amd.com/
  [2] v8 review:
      https://lore.kernel.org/qemu-devel/20260601105057.2d764e55@imammedo/
  [3] v9 review:
      https://lore.kernel.org/qemu-devel/20260602084447.1100554-1-FangSheng.Huang@amd.com/T/
  [4] v10 review:
      https://lore.kernel.org/qemu-devel/20260605104609.1739911-1-FangSheng.Huang@amd.com/T/
  [5] v11 review:
      https://lore.kernel.org/qemu-devel/20260611100637.2460507-1-FangSheng.Huang@amd.com/T/

fanhuang (4):
  hw/mem: add sp-mem device for Specific Purpose Memory
  i386/acpi-build: partition device_memory SRAT umbrella for sp-mem
  hw/i386: hook sp-mem into the pc machine plug path
  MAINTAINERS: cover sp-mem under Memory devices, add R: tag

 MAINTAINERS                  |   3 +
 qapi/machine.json            |  43 ++++++++++-
 hw/i386/e820_memory_layout.h |  11 +--
 include/hw/mem/sp-mem.h      |  33 +++++++++
 hw/core/machine-hmp-cmds.c   |  11 +++
 hw/i386/acpi-build.c         |  96 +++++++++++++++++++++++--
 hw/i386/pc.c                 |  36 ++++++++++
 hw/mem/sp-mem.c              | 136 +++++++++++++++++++++++++++++++++++
 hw/i386/Kconfig              |   2 +
 hw/mem/Kconfig               |   4 ++
 hw/mem/meson.build           |   1 +
 11 files changed, 365 insertions(+), 11 deletions(-)
 create mode 100644 include/hw/mem/sp-mem.h
 create mode 100644 hw/mem/sp-mem.c


base-commit: 2f28d34ea0aead9830478cd1d3d0dd9d9191d82e
--
2.34.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v12 1/4] hw/mem: add sp-mem device for Specific Purpose Memory
  2026-06-16  9:08 [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
@ 2026-06-16  9:08 ` fanhuang
  2026-06-17  9:16   ` Igor Mammedov
  2026-06-16  9:08 ` [PATCH v12 2/4] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem fanhuang
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: fanhuang @ 2026-06-16  9:08 UTC (permalink / raw)
  To: qemu-devel, david, imammedo, gourry, philmd
  Cc: Zhigang.Luo, Lianjie.Shi, fanhuang

Introduce a TYPE_MEMORY_DEVICE subclass `sp-mem` for boot-time
SOFT_RESERVED memory exposed to the guest with a per-device NUMA
proximity domain.

The device targets accelerator memory (HBM and similar) that the
firmware hands to the guest OS as SOFT_RESERVED memory, so a driver
in the guest -- rather than the kernel's general allocator -- owns
the range.

Usage:

    -object memory-backend-ram,id=spm0,size=$SIZE
    -numa node,nodeid=$N
    -device sp-mem,id=dev0,memdev=spm0,node=$N[,addr=$GPA]

The device is boot-time only (no hotplug).

Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
 qapi/machine.json          |  43 +++++++++++-
 include/hw/mem/sp-mem.h    |  33 +++++++++
 hw/core/machine-hmp-cmds.c |  11 +++
 hw/mem/sp-mem.c            | 136 +++++++++++++++++++++++++++++++++++++
 hw/mem/Kconfig             |   4 ++
 hw/mem/meson.build         |   1 +
 6 files changed, 226 insertions(+), 2 deletions(-)
 create mode 100644 include/hw/mem/sp-mem.h
 create mode 100644 hw/mem/sp-mem.c

diff --git a/qapi/machine.json b/qapi/machine.json
index 685e4e29b8..777cfc81e1 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1413,6 +1413,32 @@
           }
 }
 
+##
+# @SpMemDeviceInfo:
+#
+# sp-mem device state information
+#
+# @id: device's ID
+#
+# @addr: physical address, where device is mapped
+#
+# @size: size of memory that the device provides
+#
+# @node: NUMA proximity domain to which the device is assigned
+#
+# @memdev: memory backend linked with device
+#
+# Since: 11.1
+##
+{ 'struct': 'SpMemDeviceInfo',
+  'data': { '*id': 'str',
+            'addr': 'size',
+            'size': 'size',
+            'node': 'int',
+            'memdev': 'str'
+          }
+}
+
 ##
 # @MemoryDeviceInfoKind:
 #
@@ -1426,11 +1452,13 @@
 #
 # @hv-balloon: since 8.2.
 #
+# @sp-mem: since 11.1.
+#
 # Since: 2.1
 ##
 { 'enum': 'MemoryDeviceInfoKind',
   'data': [ 'dimm', 'nvdimm', 'virtio-pmem', 'virtio-mem', 'sgx-epc',
-            'hv-balloon' ] }
+            'hv-balloon', 'sp-mem' ] }
 
 ##
 # @PCDIMMDeviceInfoWrapper:
@@ -1482,6 +1510,16 @@
 { 'struct': 'HvBalloonDeviceInfoWrapper',
   'data': { 'data': 'HvBalloonDeviceInfo' } }
 
+##
+# @SpMemDeviceInfoWrapper:
+#
+# @data: sp-mem device state information
+#
+# Since: 11.1
+##
+{ 'struct': 'SpMemDeviceInfoWrapper',
+  'data': { 'data': 'SpMemDeviceInfo' } }
+
 ##
 # @MemoryDeviceInfo:
 #
@@ -1499,7 +1537,8 @@
             'virtio-pmem': 'VirtioPMEMDeviceInfoWrapper',
             'virtio-mem': 'VirtioMEMDeviceInfoWrapper',
             'sgx-epc': 'SgxEPCDeviceInfoWrapper',
-            'hv-balloon': 'HvBalloonDeviceInfoWrapper'
+            'hv-balloon': 'HvBalloonDeviceInfoWrapper',
+            'sp-mem': 'SpMemDeviceInfoWrapper'
           }
 }
 
diff --git a/include/hw/mem/sp-mem.h b/include/hw/mem/sp-mem.h
new file mode 100644
index 0000000000..a8951b49e6
--- /dev/null
+++ b/include/hw/mem/sp-mem.h
@@ -0,0 +1,33 @@
+/*
+ * Specific Purpose Memory (SPM) device
+ *
+ * TYPE_MEMORY_DEVICE subclass for boot-time-only memory exposed to the
+ * guest as an E820 SOFT_RESERVED range with a SRAT memory-affinity entry.
+ *
+ * Copyright (c) 2026 Advanced Micro Devices, Inc.
+ *
+ * Authors:
+ *  FangSheng Huang <FangSheng.Huang@amd.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_SP_MEM_H
+#define QEMU_SP_MEM_H
+
+#include "hw/core/qdev.h"
+#include "qom/object.h"
+
+#define TYPE_SP_MEM "sp-mem"
+
+OBJECT_DECLARE_SIMPLE_TYPE(SpMemDevice, SP_MEM)
+
+struct SpMemDevice {
+    DeviceState parent_obj;
+
+    HostMemoryBackend *hostmem;
+    uint32_t node;
+    uint64_t addr;
+};
+
+#endif /* QEMU_SP_MEM_H */
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 46846f741a..686304bafa 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -279,6 +279,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
     PCDIMMDeviceInfo *di;
     SgxEPCDeviceInfo *se;
     HvBalloonDeviceInfo *hi;
+    SpMemDeviceInfo *spmi;
 
     for (info = info_list; info; info = info->next) {
         value = info->value;
@@ -350,6 +351,16 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
                     monitor_printf(mon, "  memdev: %s\n", hi->memdev);
                 }
                 break;
+            case MEMORY_DEVICE_INFO_KIND_SP_MEM:
+                spmi = value->u.sp_mem.data;
+                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
+                               MemoryDeviceInfoKind_str(value->type),
+                               spmi->id ? spmi->id : "");
+                monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", spmi->addr);
+                monitor_printf(mon, "  node: %" PRId64 "\n", spmi->node);
+                monitor_printf(mon, "  size: %" PRIu64 "\n", spmi->size);
+                monitor_printf(mon, "  memdev: %s\n", spmi->memdev);
+                break;
             default:
                 g_assert_not_reached();
             }
diff --git a/hw/mem/sp-mem.c b/hw/mem/sp-mem.c
new file mode 100644
index 0000000000..3b46cabc46
--- /dev/null
+++ b/hw/mem/sp-mem.c
@@ -0,0 +1,136 @@
+/*
+ * Specific Purpose Memory (SPM) device
+ *
+ * Copyright (c) 2026 Advanced Micro Devices, Inc.
+ *
+ * Authors:
+ *  FangSheng Huang <FangSheng.Huang@amd.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/qdev.h"
+#include "hw/mem/sp-mem.h"
+#include "hw/mem/memory-device.h"
+#include "migration/vmstate.h"
+#include "system/hostmem.h"
+
+#define SP_MEM_MEMDEV_PROP    "memdev"
+#define SP_MEM_NODE_PROP      "node"
+#define SP_MEM_ADDR_PROP      "addr"
+
+static const Property sp_mem_properties[] = {
+    DEFINE_PROP_LINK(SP_MEM_MEMDEV_PROP, SpMemDevice, hostmem,
+                     TYPE_MEMORY_BACKEND, HostMemoryBackend *),
+    DEFINE_PROP_UINT32(SP_MEM_NODE_PROP, SpMemDevice, node, 0),
+    DEFINE_PROP_UINT64(SP_MEM_ADDR_PROP, SpMemDevice, addr, 0),
+};
+
+static uint64_t sp_mem_get_addr(const MemoryDeviceState *md)
+{
+    return object_property_get_uint(OBJECT(md), SP_MEM_ADDR_PROP,
+                                    &error_abort);
+}
+
+static void sp_mem_set_addr(MemoryDeviceState *md, uint64_t addr,
+                            Error **errp)
+{
+    object_property_set_uint(OBJECT(md), SP_MEM_ADDR_PROP, addr, errp);
+}
+
+static MemoryRegion *sp_mem_get_memory_region(MemoryDeviceState *md,
+                                              Error **errp)
+{
+    SpMemDevice *spm = SP_MEM(md);
+
+    if (!spm->hostmem) {
+        error_setg(errp, "'%s' property must be set", SP_MEM_MEMDEV_PROP);
+        return NULL;
+    }
+    return host_memory_backend_get_memory(spm->hostmem);
+}
+
+static void sp_mem_fill_device_info(const MemoryDeviceState *md,
+                                    MemoryDeviceInfo *info)
+{
+    SpMemDeviceInfo *di = g_new0(SpMemDeviceInfo, 1);
+    SpMemDevice *spm = SP_MEM(md);
+    DeviceState *dev = DEVICE(md);
+
+    di->id = dev->id ? g_strdup(dev->id) : NULL;
+    di->addr = spm->addr;
+    di->size = memory_region_size(
+                   host_memory_backend_get_memory(spm->hostmem));
+    di->node = spm->node;
+    di->memdev = object_get_canonical_path(OBJECT(spm->hostmem));
+
+    info->u.sp_mem.data = di;
+    info->type = MEMORY_DEVICE_INFO_KIND_SP_MEM;
+}
+
+static void sp_mem_realize(DeviceState *dev, Error **errp)
+{
+    SpMemDevice *spm = SP_MEM(dev);
+
+    if (!spm->hostmem) {
+        error_setg(errp, "'%s' property is required", SP_MEM_MEMDEV_PROP);
+        return;
+    }
+    if (host_memory_backend_is_mapped(spm->hostmem)) {
+        error_setg(errp, "memory backend '%s' is already in use",
+                   object_get_canonical_path_component(OBJECT(spm->hostmem)));
+        return;
+    }
+    host_memory_backend_set_mapped(spm->hostmem, true);
+}
+
+static void sp_mem_unrealize(DeviceState *dev)
+{
+    SpMemDevice *spm = SP_MEM(dev);
+
+    host_memory_backend_set_mapped(spm->hostmem, false);
+}
+
+static const VMStateDescription vmstate_sp_mem = {
+    .name = TYPE_SP_MEM,
+    /* boot-time only; no plug/unplug state to migrate */
+    .unmigratable = 1,
+};
+
+static void sp_mem_class_init(ObjectClass *oc, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
+
+    dc->desc = "SPM (Specific Purpose Memory) device";
+    dc->hotpluggable = false;
+    dc->realize = sp_mem_realize;
+    dc->unrealize = sp_mem_unrealize;
+    dc->vmsd = &vmstate_sp_mem;
+    device_class_set_props(dc, sp_mem_properties);
+
+    mdc->get_addr            = sp_mem_get_addr;
+    mdc->set_addr            = sp_mem_set_addr;
+    mdc->get_memory_region   = sp_mem_get_memory_region;
+    mdc->get_plugged_size    = memory_device_get_region_size;
+    mdc->fill_device_info    = sp_mem_fill_device_info;
+}
+
+static const TypeInfo sp_mem_types[] = {
+    {
+        .name          = TYPE_SP_MEM,
+        .parent        = TYPE_DEVICE,
+        .class_init    = sp_mem_class_init,
+        .instance_size = sizeof(SpMemDevice),
+        .interfaces    = (InterfaceInfo[]) {
+            { TYPE_MEMORY_DEVICE },
+            { }
+        },
+    },
+};
+
+DEFINE_TYPES(sp_mem_types)
diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig
index 73c5ae8ad9..39ddb36710 100644
--- a/hw/mem/Kconfig
+++ b/hw/mem/Kconfig
@@ -16,3 +16,7 @@ config CXL_MEM_DEVICE
     bool
     default y if CXL
     select MEM_DEVICE
+
+config SP_MEM
+    bool
+    select MEM_DEVICE
diff --git a/hw/mem/meson.build b/hw/mem/meson.build
index 8c2beeb7d4..f410d75475 100644
--- a/hw/mem/meson.build
+++ b/hw/mem/meson.build
@@ -4,6 +4,7 @@ mem_ss.add(when: 'CONFIG_DIMM', if_true: files('pc-dimm.c'))
 mem_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_mc.c'))
 mem_ss.add(when: 'CONFIG_NVDIMM', if_true: files('nvdimm.c'))
 mem_ss.add(when: 'CONFIG_CXL_MEM_DEVICE', if_true: files('cxl_type3.c'))
+mem_ss.add(when: 'CONFIG_SP_MEM', if_true: files('sp-mem.c'))
 stub_ss.add(files('cxl_type3_stubs.c'))
 
 stub_ss.add(files('memory-device-stubs.c'))
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v12 2/4] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem
  2026-06-16  9:08 [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
  2026-06-16  9:08 ` [PATCH v12 1/4] " fanhuang
@ 2026-06-16  9:08 ` fanhuang
  2026-06-17 11:04   ` Igor Mammedov
  2026-06-16  9:08 ` [PATCH v12 3/4] hw/i386: hook sp-mem into the pc machine plug path fanhuang
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: fanhuang @ 2026-06-16  9:08 UTC (permalink / raw)
  To: qemu-devel, david, imammedo, gourry, philmd
  Cc: Zhigang.Luo, Lianjie.Shi, fanhuang

Restructure the device_memory SRAT umbrella entry into a per-kind
partition: each TYPE_SP_MEM device gets an ENABLED entry at its own
proximity_domain; the remaining sub-ranges get HOTPLUGGABLE | ENABLED
placeholders at the highest PXM, preserving the existing umbrella
convention.

Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
 hw/i386/acpi-build.c | 96 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 92 insertions(+), 4 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 0d7c83d5e9..db144b5706 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -52,6 +52,7 @@
 #include "migration/vmstate.h"
 #include "hw/mem/memory-device.h"
 #include "hw/mem/nvdimm.h"
+#include "hw/mem/sp-mem.h"
 #include "system/numa.h"
 #include "system/reset.h"
 #include "hw/hyperv/vmbus-bridge.h"
@@ -1346,6 +1347,96 @@ build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
 }
 #endif
 
+typedef struct {
+    uint64_t addr;
+    uint64_t size;
+    uint32_t node;
+} SpMemRange;
+
+static int sp_mem_collect_ranges_cb(Object *obj, void *opaque)
+{
+    GArray *ranges = opaque;
+    SpMemDevice *spm;
+    MemoryDeviceClass *mdc;
+    SpMemRange r;
+
+    if (!object_dynamic_cast(obj, TYPE_SP_MEM)) {
+        return 0;
+    }
+    spm = SP_MEM(obj);
+    mdc = MEMORY_DEVICE_GET_CLASS(MEMORY_DEVICE(spm));
+    r.addr = mdc->get_addr(MEMORY_DEVICE(spm));
+    r.size = memory_region_size(
+                 host_memory_backend_get_memory(spm->hostmem));
+    r.node = spm->node;
+    g_array_append_val(ranges, r);
+    return 0;
+}
+
+static gint sp_mem_range_compare(gconstpointer a, gconstpointer b)
+{
+    const SpMemRange *range_a = a;
+    const SpMemRange *range_b = b;
+
+    if (range_a->addr < range_b->addr) {
+        return -1;
+    }
+    if (range_a->addr > range_b->addr) {
+        return 1;
+    }
+    return 0;
+}
+
+/*
+ * Emit SRAT memory-affinity entries covering the device_memory region.
+ *
+ * For each plugged TYPE_SP_MEM device, emit an ENABLED entry at the
+ * device's own proximity_domain.  All remaining sub-ranges (gaps
+ * between sp-mem devices, leading and trailing padding, and ranges
+ * occupied by other memory devices) are covered by HOTPLUGGABLE |
+ * ENABLED placeholder entries at PXM = nb_numa_nodes - 1.
+ */
+static void build_srat_device_memory(GArray *table_data, MachineState *ms)
+{
+    g_autoptr(GArray) ranges = g_array_new(FALSE, TRUE, sizeof(SpMemRange));
+    uint32_t hotplug_pxm = ms->numa_state->num_nodes - 1;
+    uint64_t region_start, region_end;
+    guint i;
+
+    region_start = ms->device_memory->base;
+    region_end = region_start + memory_region_size(&ms->device_memory->mr);
+
+    object_child_foreach_recursive(qdev_get_machine(),
+                                   sp_mem_collect_ranges_cb, ranges);
+    g_array_sort(ranges, sp_mem_range_compare);
+
+    for (i = 0; i < ranges->len; i++) {
+        SpMemRange *r = &g_array_index(ranges, SpMemRange, i);
+
+        if (region_start < r->addr) {
+            build_srat_memory(table_data, region_start, r->addr - region_start,
+                              hotplug_pxm,
+                              MEM_AFFINITY_HOTPLUGGABLE |
+                              MEM_AFFINITY_ENABLED);
+        }
+        build_srat_memory(table_data, r->addr, r->size, r->node,
+                          MEM_AFFINITY_ENABLED);
+        region_start = r->addr + r->size;
+    }
+
+    /*
+     * Cover the rest of the device_memory window that no sp-mem device
+     * occupies. Keeping it HOTPLUGGABLE preserves the umbrella entry's
+     * role for future pc-dimm / virtio-mem hot-add into this window.
+     */
+    if (region_start < region_end) {
+        build_srat_memory(table_data, region_start, region_end - region_start,
+                          hotplug_pxm,
+                          MEM_AFFINITY_HOTPLUGGABLE |
+                          MEM_AFFINITY_ENABLED);
+    }
+}
+
 #define HOLE_640K_START  (640 * KiB)
 #define HOLE_640K_END   (1 * MiB)
 
@@ -1482,10 +1573,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
      * providing _PXM method if necessary.
      */
     if (machine->device_memory) {
-        build_srat_memory(table_data, machine->device_memory->base,
-                          memory_region_size(&machine->device_memory->mr),
-                          nb_numa_nodes - 1,
-                          MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
+        build_srat_device_memory(table_data, machine);
     }
 
     acpi_table_end(linker, &table);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v12 3/4] hw/i386: hook sp-mem into the pc machine plug path
  2026-06-16  9:08 [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
  2026-06-16  9:08 ` [PATCH v12 1/4] " fanhuang
  2026-06-16  9:08 ` [PATCH v12 2/4] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem fanhuang
@ 2026-06-16  9:08 ` fanhuang
  2026-06-17 11:14   ` Igor Mammedov
  2026-06-16  9:08 ` [PATCH v12 4/4] MAINTAINERS: cover sp-mem under Memory devices, add R: tag fanhuang
  2026-06-17 11:19 ` [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory Igor Mammedov
  4 siblings, 1 reply; 10+ messages in thread
From: fanhuang @ 2026-06-16  9:08 UTC (permalink / raw)
  To: qemu-devel, david, imammedo, gourry, philmd
  Cc: Zhigang.Luo, Lianjie.Shi, fanhuang

Add the pc machine hookup for TYPE_SP_MEM so each sp-mem instance is
placed by the memory-device framework and reported to the guest as
E820_SOFT_RESERVED.

Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
 hw/i386/e820_memory_layout.h | 11 ++++++-----
 hw/i386/pc.c                 | 36 ++++++++++++++++++++++++++++++++++++
 hw/i386/Kconfig              |  2 ++
 3 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/hw/i386/e820_memory_layout.h b/hw/i386/e820_memory_layout.h
index b50acfa201..6ef169db9c 100644
--- a/hw/i386/e820_memory_layout.h
+++ b/hw/i386/e820_memory_layout.h
@@ -10,11 +10,12 @@
 #define HW_I386_E820_MEMORY_LAYOUT_H
 
 /* e820 types */
-#define E820_RAM        1
-#define E820_RESERVED   2
-#define E820_ACPI       3
-#define E820_NVS        4
-#define E820_UNUSABLE   5
+#define E820_RAM           1
+#define E820_RESERVED      2
+#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 7b6ad97e5a..ec3459389b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -63,6 +63,7 @@
 #include "hw/i386/kvm/xen_gnttab.h"
 #include "hw/i386/kvm/xen_xenstore.h"
 #include "hw/mem/memory-device.h"
+#include "hw/mem/sp-mem.h"
 #include "e820_memory_layout.h"
 #include "trace.h"
 #include "sev.h"
@@ -1283,11 +1284,43 @@ static void pc_hv_balloon_plug(HotplugHandler *hotplug_dev,
     memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
 }
 
+static void pc_sp_mem_pre_plug(HotplugHandler *hotplug_dev,
+                               DeviceState *dev, Error **errp)
+{
+    MachineState *ms = MACHINE(hotplug_dev);
+    SpMemDevice *spm = SP_MEM(dev);
+
+    if (ms->numa_state && spm->node >= ms->numa_state->num_nodes) {
+        error_setg(errp,
+                   "'node' property value %" PRIu32
+                   " exceeds the number of NUMA nodes (%d)",
+                   spm->node, ms->numa_state->num_nodes);
+        return;
+    }
+    memory_device_pre_plug(MEMORY_DEVICE(dev), ms, errp);
+}
+
+static void pc_sp_mem_plug(HotplugHandler *hotplug_dev,
+                               DeviceState *dev, Error **errp)
+{
+    SpMemDevice *spm = SP_MEM(dev);
+    MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(MEMORY_DEVICE(dev));
+    uint64_t addr, size;
+
+    memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
+
+    addr = mdc->get_addr(MEMORY_DEVICE(dev));
+    size = memory_region_size(host_memory_backend_get_memory(spm->hostmem));
+    e820_add_entry(addr, size, E820_SOFT_RESERVED);
+}
+
 static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
                                           DeviceState *dev, Error **errp)
 {
     if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
         pc_memory_pre_plug(hotplug_dev, dev, errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM)) {
+        pc_sp_mem_pre_plug(hotplug_dev, dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
         x86_cpu_pre_plug(hotplug_dev, dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
@@ -1324,6 +1357,8 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
 {
     if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
         pc_memory_plug(hotplug_dev, dev, errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM)) {
+        pc_sp_mem_plug(hotplug_dev, dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
         x86_cpu_plug(hotplug_dev, dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
@@ -1368,6 +1403,7 @@ static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,
                                              DeviceState *dev)
 {
     if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
+        object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM) ||
         object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||
         object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI) ||
         object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index 12473acaa7..e27d8816e5 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -84,6 +84,7 @@ config I440FX
     select PCI_I440FX
     select PIIX
     select DIMM
+    select SP_MEM
     select SMBIOS
     select SMBIOS_LEGACY
     select FW_CFG_DMA
@@ -113,6 +114,7 @@ config Q35
     select LPC_ICH9
     select AHCI_ICH9
     select DIMM
+    select SP_MEM
     select SMBIOS
     select FW_CFG_DMA
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v12 4/4] MAINTAINERS: cover sp-mem under Memory devices, add R: tag
  2026-06-16  9:08 [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
                   ` (2 preceding siblings ...)
  2026-06-16  9:08 ` [PATCH v12 3/4] hw/i386: hook sp-mem into the pc machine plug path fanhuang
@ 2026-06-16  9:08 ` fanhuang
  2026-06-17 11:19 ` [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory Igor Mammedov
  4 siblings, 0 replies; 10+ messages in thread
From: fanhuang @ 2026-06-16  9:08 UTC (permalink / raw)
  To: qemu-devel, david, imammedo, gourry, philmd
  Cc: Zhigang.Luo, Lianjie.Shi, fanhuang

Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
Acked-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: David Hildenbrand <david@kernel.org>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2b5b581e17..192b5337d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3346,13 +3346,16 @@ F: scripts/coccinelle/memory-region-housekeeping.cocci
 Memory devices
 M: David Hildenbrand <david@kernel.org>
 M: Igor Mammedov <imammedo@redhat.com>
+R: FangSheng Huang <FangSheng.Huang@amd.com>
 S: Supported
 F: hw/mem/memory-device*.c
 F: hw/mem/nvdimm.c
 F: hw/mem/pc-dimm.c
+F: hw/mem/sp-mem.c
 F: include/hw/mem/memory-device.h
 F: include/hw/mem/nvdimm.h
 F: include/hw/mem/pc-dimm.h
+F: include/hw/mem/sp-mem.h
 F: docs/nvdimm.txt
 
 SPICE
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v12 1/4] hw/mem: add sp-mem device for Specific Purpose Memory
  2026-06-16  9:08 ` [PATCH v12 1/4] " fanhuang
@ 2026-06-17  9:16   ` Igor Mammedov
  2026-06-17 10:00     ` Huang, FangSheng (Jerry)
  0 siblings, 1 reply; 10+ messages in thread
From: Igor Mammedov @ 2026-06-17  9:16 UTC (permalink / raw)
  To: fanhuang
  Cc: qemu-devel, david, gourry, philmd, Zhigang.Luo, Lianjie.Shi,
	Peter Xu

On Tue, 16 Jun 2026 17:08:05 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:

> Introduce a TYPE_MEMORY_DEVICE subclass `sp-mem` for boot-time
> SOFT_RESERVED memory exposed to the guest with a per-device NUMA
> proximity domain.
> 
> The device targets accelerator memory (HBM and similar) that the
> firmware hands to the guest OS as SOFT_RESERVED memory, so a driver
> in the guest -- rather than the kernel's general allocator -- owns
> the range.
> 
> Usage:
> 
>     -object memory-backend-ram,id=spm0,size=$SIZE
>     -numa node,nodeid=$N
>     -device sp-mem,id=dev0,memdev=spm0,node=$N[,addr=$GPA]
> 
> The device is boot-time only (no hotplug).

Modulo nitpicking/patch splitting and a migration question LGTM 

> 
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
> ---
>  qapi/machine.json          |  43 +++++++++++-
>  include/hw/mem/sp-mem.h    |  33 +++++++++
>  hw/core/machine-hmp-cmds.c |  11 +++
>  hw/mem/sp-mem.c            | 136 +++++++++++++++++++++++++++++++++++++
>  hw/mem/Kconfig             |   4 ++
>  hw/mem/meson.build         |   1 +
>  6 files changed, 226 insertions(+), 2 deletions(-)
>  create mode 100644 include/hw/mem/sp-mem.h
>  create mode 100644 hw/mem/sp-mem.c
> 
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 685e4e29b8..777cfc81e1 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -1413,6 +1413,32 @@
>            }
>  }
>  
> +##
> +# @SpMemDeviceInfo:
> +#
> +# sp-mem device state information
> +#
> +# @id: device's ID
> +#
> +# @addr: physical address, where device is mapped
> +#
> +# @size: size of memory that the device provides
> +#
> +# @node: NUMA proximity domain to which the device is assigned
> +#
> +# @memdev: memory backend linked with device
> +#
> +# Since: 11.1
> +##
> +{ 'struct': 'SpMemDeviceInfo',
> +  'data': { '*id': 'str',
> +            'addr': 'size',
> +            'size': 'size',
> +            'node': 'int',
> +            'memdev': 'str'
> +          }
> +}
> +
>  ##
>  # @MemoryDeviceInfoKind:
>  #
> @@ -1426,11 +1452,13 @@
>  #
>  # @hv-balloon: since 8.2.
>  #
> +# @sp-mem: since 11.1.
> +#
>  # Since: 2.1
>  ##
>  { 'enum': 'MemoryDeviceInfoKind',
>    'data': [ 'dimm', 'nvdimm', 'virtio-pmem', 'virtio-mem', 'sgx-epc',
> -            'hv-balloon' ] }
> +            'hv-balloon', 'sp-mem' ] }
>  
>  ##
>  # @PCDIMMDeviceInfoWrapper:
> @@ -1482,6 +1510,16 @@
>  { 'struct': 'HvBalloonDeviceInfoWrapper',
>    'data': { 'data': 'HvBalloonDeviceInfo' } }
>  
> +##
> +# @SpMemDeviceInfoWrapper:
> +#
> +# @data: sp-mem device state information
> +#
> +# Since: 11.1
> +##
> +{ 'struct': 'SpMemDeviceInfoWrapper',
> +  'data': { 'data': 'SpMemDeviceInfo' } }
> +
>  ##
>  # @MemoryDeviceInfo:
>  #
> @@ -1499,7 +1537,8 @@
>              'virtio-pmem': 'VirtioPMEMDeviceInfoWrapper',
>              'virtio-mem': 'VirtioMEMDeviceInfoWrapper',
>              'sgx-epc': 'SgxEPCDeviceInfoWrapper',
> -            'hv-balloon': 'HvBalloonDeviceInfoWrapper'
> +            'hv-balloon': 'HvBalloonDeviceInfoWrapper',
> +            'sp-mem': 'SpMemDeviceInfoWrapper'
>            }
>  }
>  
> diff --git a/include/hw/mem/sp-mem.h b/include/hw/mem/sp-mem.h
> new file mode 100644
> index 0000000000..a8951b49e6
> --- /dev/null
> +++ b/include/hw/mem/sp-mem.h
> @@ -0,0 +1,33 @@
> +/*
> + * Specific Purpose Memory (SPM) device
> + *
> + * TYPE_MEMORY_DEVICE subclass for boot-time-only memory exposed to the
> + * guest as an E820 SOFT_RESERVED range with a SRAT memory-affinity entry.
> + *
> + * Copyright (c) 2026 Advanced Micro Devices, Inc.
> + *
> + * Authors:
> + *  FangSheng Huang <FangSheng.Huang@amd.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef QEMU_SP_MEM_H
> +#define QEMU_SP_MEM_H
> +
> +#include "hw/core/qdev.h"
> +#include "qom/object.h"
> +
> +#define TYPE_SP_MEM "sp-mem"
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(SpMemDevice, SP_MEM)
> +
> +struct SpMemDevice {
> +    DeviceState parent_obj;
> +
> +    HostMemoryBackend *hostmem;
> +    uint32_t node;
> +    uint64_t addr;
> +};
> +
> +#endif /* QEMU_SP_MEM_H */
> diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
> index 46846f741a..686304bafa 100644
> --- a/hw/core/machine-hmp-cmds.c
> +++ b/hw/core/machine-hmp-cmds.c
> @@ -279,6 +279,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
>      PCDIMMDeviceInfo *di;
>      SgxEPCDeviceInfo *se;
>      HvBalloonDeviceInfo *hi;
> +    SpMemDeviceInfo *spmi;
>  
>      for (info = info_list; info; info = info->next) {
>          value = info->value;
> @@ -350,6 +351,16 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
>                      monitor_printf(mon, "  memdev: %s\n", hi->memdev);
>                  }
>                  break;
> +            case MEMORY_DEVICE_INFO_KIND_SP_MEM:
> +                spmi = value->u.sp_mem.data;
> +                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
> +                               MemoryDeviceInfoKind_str(value->type),
> +                               spmi->id ? spmi->id : "");
> +                monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", spmi->addr);
> +                monitor_printf(mon, "  node: %" PRId64 "\n", spmi->node);
> +                monitor_printf(mon, "  size: %" PRIu64 "\n", spmi->size);
> +                monitor_printf(mon, "  memdev: %s\n", spmi->memdev);
> +                break;
>              default:
>                  g_assert_not_reached();
>              }

hmp could be a separate patch.

> diff --git a/hw/mem/sp-mem.c b/hw/mem/sp-mem.c
> new file mode 100644
> index 0000000000..3b46cabc46
> --- /dev/null
> +++ b/hw/mem/sp-mem.c
> @@ -0,0 +1,136 @@
> +/*
> + * Specific Purpose Memory (SPM) device
> + *
> + * Copyright (c) 2026 Advanced Micro Devices, Inc.
> + *
> + * Authors:
> + *  FangSheng Huang <FangSheng.Huang@amd.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/module.h"
> +#include "qapi/error.h"
> +#include "hw/core/qdev-properties.h"
> +#include "hw/core/qdev.h"
> +#include "hw/mem/sp-mem.h"
> +#include "hw/mem/memory-device.h"
> +#include "migration/vmstate.h"
> +#include "system/hostmem.h"
> +
> +#define SP_MEM_MEMDEV_PROP    "memdev"
> +#define SP_MEM_NODE_PROP      "node"
> +#define SP_MEM_ADDR_PROP      "addr"
> +
> +static const Property sp_mem_properties[] = {
> +    DEFINE_PROP_LINK(SP_MEM_MEMDEV_PROP, SpMemDevice, hostmem,
> +                     TYPE_MEMORY_BACKEND, HostMemoryBackend *),
> +    DEFINE_PROP_UINT32(SP_MEM_NODE_PROP, SpMemDevice, node, 0),
> +    DEFINE_PROP_UINT64(SP_MEM_ADDR_PROP, SpMemDevice, addr, 0),
> +};
> +
> +static uint64_t sp_mem_get_addr(const MemoryDeviceState *md)
> +{
> +    return object_property_get_uint(OBJECT(md), SP_MEM_ADDR_PROP,
> +                                    &error_abort);
> +}
> +
> +static void sp_mem_set_addr(MemoryDeviceState *md, uint64_t addr,
> +                            Error **errp)
> +{
> +    object_property_set_uint(OBJECT(md), SP_MEM_ADDR_PROP, addr, errp);
> +}
> +
> +static MemoryRegion *sp_mem_get_memory_region(MemoryDeviceState *md,
> +                                              Error **errp)
> +{
> +    SpMemDevice *spm = SP_MEM(md);
> +
> +    if (!spm->hostmem) {
> +        error_setg(errp, "'%s' property must be set", SP_MEM_MEMDEV_PROP);
> +        return NULL;
> +    }
> +    return host_memory_backend_get_memory(spm->hostmem);
> +}
> +

> +static void sp_mem_fill_device_info(const MemoryDeviceState *md,
> +                                    MemoryDeviceInfo *info)
> +{
> +    SpMemDeviceInfo *di = g_new0(SpMemDeviceInfo, 1);
> +    SpMemDevice *spm = SP_MEM(md);
> +    DeviceState *dev = DEVICE(md);
> +
> +    di->id = dev->id ? g_strdup(dev->id) : NULL;
> +    di->addr = spm->addr;
> +    di->size = memory_region_size(
> +                   host_memory_backend_get_memory(spm->hostmem));
> +    di->node = spm->node;
> +    di->memdev = object_get_canonical_path(OBJECT(spm->hostmem));
> +
> +    info->u.sp_mem.data = di;
> +    info->type = MEMORY_DEVICE_INFO_KIND_SP_MEM;
> +}

if missing this doesn't break anything, I'd bundle it together with hmp patch


> +
> +static void sp_mem_realize(DeviceState *dev, Error **errp)
> +{
> +    SpMemDevice *spm = SP_MEM(dev);
> +
> +    if (!spm->hostmem) {
> +        error_setg(errp, "'%s' property is required", SP_MEM_MEMDEV_PROP);
> +        return;
> +    }
> +    if (host_memory_backend_is_mapped(spm->hostmem)) {
> +        error_setg(errp, "memory backend '%s' is already in use",
> +                   object_get_canonical_path_component(OBJECT(spm->hostmem)));
> +        return;
> +    }
> +    host_memory_backend_set_mapped(spm->hostmem, true);
> +}
> +
> +static void sp_mem_unrealize(DeviceState *dev)
> +{
> +    SpMemDevice *spm = SP_MEM(dev);
> +
> +    host_memory_backend_set_mapped(spm->hostmem, false);
> +}
> +
> +static const VMStateDescription vmstate_sp_mem = {
> +    .name = TYPE_SP_MEM,
> +    /* boot-time only; no plug/unplug state to migrate */
> +    .unmigratable = 1,

this is explicit migration blocker, isn't it?
are we sure about setting it un-migratable, if yes/no than why?

I don't see how plug/unplug is involved here,
but I'd speculate that we would want to migrate memory content itself.

CCing Peter,
 for a look from migration pov


> +};
> +
> +static void sp_mem_class_init(ObjectClass *oc, const void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +    MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
> +
> +    dc->desc = "SPM (Specific Purpose Memory) device";
> +    dc->hotpluggable = false;
> +    dc->realize = sp_mem_realize;
> +    dc->unrealize = sp_mem_unrealize;
> +    dc->vmsd = &vmstate_sp_mem;
> +    device_class_set_props(dc, sp_mem_properties);
> +
> +    mdc->get_addr            = sp_mem_get_addr;
> +    mdc->set_addr            = sp_mem_set_addr;
> +    mdc->get_memory_region   = sp_mem_get_memory_region;
> +    mdc->get_plugged_size    = memory_device_get_region_size;
> +    mdc->fill_device_info    = sp_mem_fill_device_info;
> +}
> +
> +static const TypeInfo sp_mem_types[] = {
> +    {
> +        .name          = TYPE_SP_MEM,
> +        .parent        = TYPE_DEVICE,
> +        .class_init    = sp_mem_class_init,
> +        .instance_size = sizeof(SpMemDevice),
> +        .interfaces    = (InterfaceInfo[]) {
> +            { TYPE_MEMORY_DEVICE },
> +            { }
> +        },
> +    },
> +};
> +
> +DEFINE_TYPES(sp_mem_types)
> diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig
> index 73c5ae8ad9..39ddb36710 100644
> --- a/hw/mem/Kconfig
> +++ b/hw/mem/Kconfig
> @@ -16,3 +16,7 @@ config CXL_MEM_DEVICE
>      bool
>      default y if CXL
>      select MEM_DEVICE
> +
> +config SP_MEM
> +    bool
> +    select MEM_DEVICE
> diff --git a/hw/mem/meson.build b/hw/mem/meson.build
> index 8c2beeb7d4..f410d75475 100644
> --- a/hw/mem/meson.build
> +++ b/hw/mem/meson.build
> @@ -4,6 +4,7 @@ mem_ss.add(when: 'CONFIG_DIMM', if_true: files('pc-dimm.c'))
>  mem_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_mc.c'))
>  mem_ss.add(when: 'CONFIG_NVDIMM', if_true: files('nvdimm.c'))
>  mem_ss.add(when: 'CONFIG_CXL_MEM_DEVICE', if_true: files('cxl_type3.c'))
> +mem_ss.add(when: 'CONFIG_SP_MEM', if_true: files('sp-mem.c'))
>  stub_ss.add(files('cxl_type3_stubs.c'))
>  
>  stub_ss.add(files('memory-device-stubs.c'))



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v12 1/4] hw/mem: add sp-mem device for Specific Purpose Memory
  2026-06-17  9:16   ` Igor Mammedov
@ 2026-06-17 10:00     ` Huang, FangSheng (Jerry)
  0 siblings, 0 replies; 10+ messages in thread
From: Huang, FangSheng (Jerry) @ 2026-06-17 10:00 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: qemu-devel, david, gourry, philmd, Zhigang.Luo, Lianjie.Shi,
	Peter Xu



On 6/17/2026 5:16 PM, Igor Mammedov wrote:
> On Tue, 16 Jun 2026 17:08:05 +0800
> fanhuang <FangSheng.Huang@amd.com> wrote:
> 
>> Introduce a TYPE_MEMORY_DEVICE subclass `sp-mem` for boot-time
>> SOFT_RESERVED memory exposed to the guest with a per-device NUMA
>> proximity domain.
>>
>> The device targets accelerator memory (HBM and similar) that the
>> firmware hands to the guest OS as SOFT_RESERVED memory, so a driver
>> in the guest -- rather than the kernel's general allocator -- owns
>> the range.
>>
>> Usage:
>>
>>      -object memory-backend-ram,id=spm0,size=$SIZE
>>      -numa node,nodeid=$N
>>      -device sp-mem,id=dev0,memdev=spm0,node=$N[,addr=$GPA]
>>
>> The device is boot-time only (no hotplug).
> 
> Modulo nitpicking/patch splitting and a migration question LGTM
> 
>> +            case MEMORY_DEVICE_INFO_KIND_SP_MEM:
>> +                spmi = value->u.sp_mem.data;
>> +                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
>> +                               MemoryDeviceInfoKind_str(value->type),
>> +                               spmi->id ? spmi->id : "");
>> +                monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", spmi->addr);
>> +                monitor_printf(mon, "  node: %" PRId64 "\n", spmi->node);
>> +                monitor_printf(mon, "  size: %" PRIu64 "\n", spmi->size);
>> +                monitor_printf(mon, "  memdev: %s\n", spmi->memdev);
>> +                break;
>>               default:
>>                   g_assert_not_reached();
>>               }
> 
> hmp could be a separate patch.
> 
> 
>> +static void sp_mem_fill_device_info(const MemoryDeviceState *md,
>> +                                    MemoryDeviceInfo *info)
>> +{
>> +    SpMemDeviceInfo *di = g_new0(SpMemDeviceInfo, 1);
>> +    SpMemDevice *spm = SP_MEM(md);
>> +    DeviceState *dev = DEVICE(md);
>> +
>> +    di->id = dev->id ? g_strdup(dev->id) : NULL;
>> +    di->addr = spm->addr;
>> +    di->size = memory_region_size(
>> +                   host_memory_backend_get_memory(spm->hostmem));
>> +    di->node = spm->node;
>> +    di->memdev = object_get_canonical_path(OBJECT(spm->hostmem));
>> +
>> +    info->u.sp_mem.data = di;
>> +    info->type = MEMORY_DEVICE_INFO_KIND_SP_MEM;
>> +}
> 
> if missing this doesn't break anything, I'd bundle it together with hmp patch
> 
>

Will split the introspection bits (fill_device_info + the HMP
printer) into their own patch in the next respin.

>> +
>> +static void sp_mem_realize(DeviceState *dev, Error **errp)
>> +{
>> +    SpMemDevice *spm = SP_MEM(dev);
>> +
>> +    if (!spm->hostmem) {
>> +        error_setg(errp, "'%s' property is required", SP_MEM_MEMDEV_PROP);
>> +        return;
>> +    }
>> +    if (host_memory_backend_is_mapped(spm->hostmem)) {
>> +        error_setg(errp, "memory backend '%s' is already in use",
>> +                   object_get_canonical_path_component(OBJECT(spm->hostmem)));
>> +        return;
>> +    }
>> +    host_memory_backend_set_mapped(spm->hostmem, true);
>> +}
>> +
>> +static void sp_mem_unrealize(DeviceState *dev)
>> +{
>> +    SpMemDevice *spm = SP_MEM(dev);
>> +
>> +    host_memory_backend_set_mapped(spm->hostmem, false);
>> +}
>> +
>> +static const VMStateDescription vmstate_sp_mem = {
>> +    .name = TYPE_SP_MEM,
>> +    /* boot-time only; no plug/unplug state to migrate */
>> +    .unmigratable = 1,
> 
> this is explicit migration blocker, isn't it?
> are we sure about setting it un-migratable, if yes/no than why?
> 
> I don't see how plug/unplug is involved here,
> but I'd speculate that we would want to migrate memory content itself.
> 
> CCing Peter,
>   for a look from migration pov
> 
> 

You're right that the "plug/unplug" wording is off.

The device carries no per-device migration state, so with a normal
RAM backend it would migrate like pc-dimm. I'd originally marked it
unmigratable out of caution, being unsure whether the backend could
be migrated -- but on reflection that's a property of the backend,
not of sp-mem: a backend that can't be migrated can express that
itself, independently of this device. So dropping the flag and
letting sp-mem migrate like pc-dimm, leaving any restriction to the
backend, looks like the more flexible choice.

Peter, does that match your view, or is there a reason to keep a gate
at the device?

Best regards,
FangSheng Huang (Jerry)
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v12 2/4] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem
  2026-06-16  9:08 ` [PATCH v12 2/4] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem fanhuang
@ 2026-06-17 11:04   ` Igor Mammedov
  0 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2026-06-17 11:04 UTC (permalink / raw)
  To: fanhuang; +Cc: qemu-devel, david, gourry, philmd, Zhigang.Luo, Lianjie.Shi

On Tue, 16 Jun 2026 17:08:06 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:

> Restructure the device_memory SRAT umbrella entry into a per-kind
> partition: each TYPE_SP_MEM device gets an ENABLED entry at its own
> proximity_domain; the remaining sub-ranges get HOTPLUGGABLE | ENABLED
> placeholders at the highest PXM, preserving the existing umbrella
> convention.
> 
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>

LGTM, but i haven't really tested it.
please add test case for this, see tests/qtest/bios-tables-test.c
for examples and process.

With condition adding test to cover it:
Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  hw/i386/acpi-build.c | 96 ++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 92 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 0d7c83d5e9..db144b5706 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -52,6 +52,7 @@
>  #include "migration/vmstate.h"
>  #include "hw/mem/memory-device.h"
>  #include "hw/mem/nvdimm.h"
> +#include "hw/mem/sp-mem.h"
>  #include "system/numa.h"
>  #include "system/reset.h"
>  #include "hw/hyperv/vmbus-bridge.h"
> @@ -1346,6 +1347,96 @@ build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
>  }
>  #endif
>  
> +typedef struct {
> +    uint64_t addr;
> +    uint64_t size;
> +    uint32_t node;
> +} SpMemRange;
> +
> +static int sp_mem_collect_ranges_cb(Object *obj, void *opaque)
> +{
> +    GArray *ranges = opaque;
> +    SpMemDevice *spm;
> +    MemoryDeviceClass *mdc;
> +    SpMemRange r;
> +
> +    if (!object_dynamic_cast(obj, TYPE_SP_MEM)) {
> +        return 0;
> +    }
> +    spm = SP_MEM(obj);
> +    mdc = MEMORY_DEVICE_GET_CLASS(MEMORY_DEVICE(spm));
> +    r.addr = mdc->get_addr(MEMORY_DEVICE(spm));
> +    r.size = memory_region_size(
> +                 host_memory_backend_get_memory(spm->hostmem));
> +    r.node = spm->node;
> +    g_array_append_val(ranges, r);
> +    return 0;
> +}
> +
> +static gint sp_mem_range_compare(gconstpointer a, gconstpointer b)
> +{
> +    const SpMemRange *range_a = a;
> +    const SpMemRange *range_b = b;
> +
> +    if (range_a->addr < range_b->addr) {
> +        return -1;
> +    }
> +    if (range_a->addr > range_b->addr) {
> +        return 1;
> +    }
> +    return 0;
> +}
> +
> +/*
> + * Emit SRAT memory-affinity entries covering the device_memory region.
> + *
> + * For each plugged TYPE_SP_MEM device, emit an ENABLED entry at the
> + * device's own proximity_domain.  All remaining sub-ranges (gaps
> + * between sp-mem devices, leading and trailing padding, and ranges
> + * occupied by other memory devices) are covered by HOTPLUGGABLE |
> + * ENABLED placeholder entries at PXM = nb_numa_nodes - 1.
> + */
> +static void build_srat_device_memory(GArray *table_data, MachineState *ms)
> +{
> +    g_autoptr(GArray) ranges = g_array_new(FALSE, TRUE, sizeof(SpMemRange));
> +    uint32_t hotplug_pxm = ms->numa_state->num_nodes - 1;
> +    uint64_t region_start, region_end;
> +    guint i;
> +
> +    region_start = ms->device_memory->base;
> +    region_end = region_start + memory_region_size(&ms->device_memory->mr);
> +
> +    object_child_foreach_recursive(qdev_get_machine(),
> +                                   sp_mem_collect_ranges_cb, ranges);
> +    g_array_sort(ranges, sp_mem_range_compare);
> +
> +    for (i = 0; i < ranges->len; i++) {
> +        SpMemRange *r = &g_array_index(ranges, SpMemRange, i);
> +
> +        if (region_start < r->addr) {
> +            build_srat_memory(table_data, region_start, r->addr - region_start,
> +                              hotplug_pxm,
> +                              MEM_AFFINITY_HOTPLUGGABLE |
> +                              MEM_AFFINITY_ENABLED);
> +        }
> +        build_srat_memory(table_data, r->addr, r->size, r->node,
> +                          MEM_AFFINITY_ENABLED);
> +        region_start = r->addr + r->size;
> +    }
> +
> +    /*
> +     * Cover the rest of the device_memory window that no sp-mem device
> +     * occupies. Keeping it HOTPLUGGABLE preserves the umbrella entry's
> +     * role for future pc-dimm / virtio-mem hot-add into this window.
> +     */
> +    if (region_start < region_end) {
> +        build_srat_memory(table_data, region_start, region_end - region_start,
> +                          hotplug_pxm,
> +                          MEM_AFFINITY_HOTPLUGGABLE |
> +                          MEM_AFFINITY_ENABLED);
> +    }
> +}
> +
>  #define HOLE_640K_START  (640 * KiB)
>  #define HOLE_640K_END   (1 * MiB)
>  
> @@ -1482,10 +1573,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
>       * providing _PXM method if necessary.
>       */
>      if (machine->device_memory) {
> -        build_srat_memory(table_data, machine->device_memory->base,
> -                          memory_region_size(&machine->device_memory->mr),
> -                          nb_numa_nodes - 1,
> -                          MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
> +        build_srat_device_memory(table_data, machine);
>      }
>  
>      acpi_table_end(linker, &table);



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v12 3/4] hw/i386: hook sp-mem into the pc machine plug path
  2026-06-16  9:08 ` [PATCH v12 3/4] hw/i386: hook sp-mem into the pc machine plug path fanhuang
@ 2026-06-17 11:14   ` Igor Mammedov
  0 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2026-06-17 11:14 UTC (permalink / raw)
  To: fanhuang; +Cc: qemu-devel, david, gourry, philmd, Zhigang.Luo, Lianjie.Shi

On Tue, 16 Jun 2026 17:08:07 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:

> Add the pc machine hookup for TYPE_SP_MEM so each sp-mem instance is
> placed by the memory-device framework and reported to the guest as
> E820_SOFT_RESERVED.
> 
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>

see below comment below wrt testing but otherwise:

Reviewed-by: Igor Mammedov <imammedo@redhat.com>


> ---
>  hw/i386/e820_memory_layout.h | 11 ++++++-----
>  hw/i386/pc.c                 | 36 ++++++++++++++++++++++++++++++++++++
>  hw/i386/Kconfig              |  2 ++
>  3 files changed, 44 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/i386/e820_memory_layout.h b/hw/i386/e820_memory_layout.h
> index b50acfa201..6ef169db9c 100644
> --- a/hw/i386/e820_memory_layout.h
> +++ b/hw/i386/e820_memory_layout.h
> @@ -10,11 +10,12 @@
>  #define HW_I386_E820_MEMORY_LAYOUT_H
>  
>  /* e820 types */
> -#define E820_RAM        1
> -#define E820_RESERVED   2
> -#define E820_ACPI       3
> -#define E820_NVS        4
> -#define E820_UNUSABLE   5
> +#define E820_RAM           1
> +#define E820_RESERVED      2
> +#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 7b6ad97e5a..ec3459389b 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -63,6 +63,7 @@
>  #include "hw/i386/kvm/xen_gnttab.h"
>  #include "hw/i386/kvm/xen_xenstore.h"
>  #include "hw/mem/memory-device.h"
> +#include "hw/mem/sp-mem.h"
>  #include "e820_memory_layout.h"
>  #include "trace.h"
>  #include "sev.h"
> @@ -1283,11 +1284,43 @@ static void pc_hv_balloon_plug(HotplugHandler *hotplug_dev,
>      memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
>  }
>  
> +static void pc_sp_mem_pre_plug(HotplugHandler *hotplug_dev,
> +                               DeviceState *dev, Error **errp)
> +{
> +    MachineState *ms = MACHINE(hotplug_dev);
> +    SpMemDevice *spm = SP_MEM(dev);
> +
> +    if (ms->numa_state && spm->node >= ms->numa_state->num_nodes) {
> +        error_setg(errp,
> +                   "'node' property value %" PRIu32
> +                   " exceeds the number of NUMA nodes (%d)",
> +                   spm->node, ms->numa_state->num_nodes);
> +        return;
> +    }
> +    memory_device_pre_plug(MEMORY_DEVICE(dev), ms, errp);
> +}
> +
> +static void pc_sp_mem_plug(HotplugHandler *hotplug_dev,
> +                               DeviceState *dev, Error **errp)
> +{
> +    SpMemDevice *spm = SP_MEM(dev);
> +    MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(MEMORY_DEVICE(dev));
> +    uint64_t addr, size;
> +
> +    memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
> +
> +    addr = mdc->get_addr(MEMORY_DEVICE(dev));
> +    size = memory_region_size(host_memory_backend_get_memory(spm->hostmem));
> +    e820_add_entry(addr, size, E820_SOFT_RESERVED);

We haven't been testing e820 (lack of coverage mostly historical due to
it being mostly static not touched code).
But I think we should add tests for it. (something similar to bios-tables-test)
 
1st add clean slate test before your change, and then build/add on top to
make sure we do not regress, whatever existed before.

> +}
> +
>  static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
>                                            DeviceState *dev, Error **errp)
>  {
>      if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>          pc_memory_pre_plug(hotplug_dev, dev, errp);
> +    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM)) {
> +        pc_sp_mem_pre_plug(hotplug_dev, dev, errp);
>      } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>          x86_cpu_pre_plug(hotplug_dev, dev, errp);
>      } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
> @@ -1324,6 +1357,8 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
>  {
>      if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>          pc_memory_plug(hotplug_dev, dev, errp);
> +    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM)) {
> +        pc_sp_mem_plug(hotplug_dev, dev, errp);
>      } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>          x86_cpu_plug(hotplug_dev, dev, errp);
>      } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
> @@ -1368,6 +1403,7 @@ static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,
>                                               DeviceState *dev)
>  {
>      if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
> +        object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM) ||
>          object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||
>          object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI) ||
>          object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
> diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
> index 12473acaa7..e27d8816e5 100644
> --- a/hw/i386/Kconfig
> +++ b/hw/i386/Kconfig
> @@ -84,6 +84,7 @@ config I440FX
>      select PCI_I440FX
>      select PIIX
>      select DIMM
> +    select SP_MEM
>      select SMBIOS
>      select SMBIOS_LEGACY
>      select FW_CFG_DMA
> @@ -113,6 +114,7 @@ config Q35
>      select LPC_ICH9
>      select AHCI_ICH9
>      select DIMM
> +    select SP_MEM
>      select SMBIOS
>      select FW_CFG_DMA
>  



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory
  2026-06-16  9:08 [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
                   ` (3 preceding siblings ...)
  2026-06-16  9:08 ` [PATCH v12 4/4] MAINTAINERS: cover sp-mem under Memory devices, add R: tag fanhuang
@ 2026-06-17 11:19 ` Igor Mammedov
  4 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2026-06-17 11:19 UTC (permalink / raw)
  To: fanhuang; +Cc: qemu-devel, david, gourry, philmd, Zhigang.Luo, Lianjie.Shi

On Tue, 16 Jun 2026 17:08:04 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:

> This series adds a TYPE_MEMORY_DEVICE subclass `sp-mem` for boot-time
> SOFT_RESERVED guest memory, following the direction from the v7
> thread [1] and the v8 / v9 / v10 / v11 reviews [2][3][4][5].

review is done, modulo cosmetic patch restructuring and missing tests
LGTM.

as for adding duplication, I'm expecting cleanup/consolidation
refactoring on top, that I've asked for in earlier reviews. 

> 
> Background
> ----------
> 
> This series targets coherent CPU + accelerator shared-address-space
> systems, where the accelerator's HBM is not a device-private
> framebuffer behind a PCIe BAR but a tier of host system memory:
> visible to the CPU in the platform physical address space, shared
> coherently with the accelerator over the platform fabric, and bound
> to a NUMA proximity domain set by platform firmware at boot fabric
> training.
> 
> For such a region to function correctly in the guest, two things
> must hold simultaneously: the CPU memory subsystem has to see it in
> the system memory map (so the CPU side can address it), and it has
> to be reserved exclusively for the accelerator's driver (so the
> kernel's general allocator does not hand SPM pages to unrelated
> workloads). The SOFT_RESERVED memory type in E820 plus a matching
> SRAT memory-affinity entry is the mechanism that delivers both: a
> firmware-produced topology that the CPU memory subsystem honors and
> the accelerator's driver consumes for its own range.
> 
> Approach
> --------
> 
> The series introduces a new TYPE_MEMORY_DEVICE subclass `sp-mem`.
> Each instance binds one host memory backend to a single NUMA
> proximity domain and is boot-time only; placement, mapped-state
> enforcement, and QMP introspection come from the existing
> memory-device framework.
> 
> Testing
> -------
> 
> Verified end-to-end on q35 + KVM, with both SeaBIOS and OVMF, for:
> 
> - single sp-mem instance
> - two sp-mem instances on different NUMA nodes
> 
> Guest observations: /proc/iomem shows one SOFT_RESERVED entry per
> sp-mem device, dmesg SRAT parsing reports the matching
> memory_affinity entries with correct PXM, and the umbrella
> HOTPLUGGABLE entry covers the remaining hotplug-memory window
> without overlapping the sp-mem ranges.
> 
> Changes since v11
> -----------------
> 
>   - Drop the unneeded memory-device.h and system/hostmem.h includes
>     from sp-mem.h (HostMemoryBackend is forward-declared).
>   - Use SP_MEM_MEMDEV_PROP in sp_mem_get_memory_region()'s error
>     message, matching realize().
>   - Move the .unmigratable comment next to the field it documents.
> 
> All v11 patch-1 review comments from Philippe; patches 2-4 unchanged.
> Patch 4 (MAINTAINERS) retains the Acked-by from Igor and David.
> 
> Previous versions
> -----------------
> 
>   v1: https://lore.kernel.org/qemu-devel/20250924103324.2074819-1-FangSheng.Huang@amd.com/
>   v2: https://lore.kernel.org/qemu-devel/20251020090701.4036748-1-FangSheng.Huang@amd.com/
>   v3: https://lore.kernel.org/qemu-devel/20251208105137.2058928-1-FangSheng.Huang@amd.com/
>   v4: https://lore.kernel.org/qemu-devel/20251209093841.2250527-1-FangSheng.Huang@amd.com/
>   v5: https://lore.kernel.org/qemu-devel/20260123024312.1601732-1-FangSheng.Huang@amd.com/
>   v6: https://lore.kernel.org/qemu-devel/20260226105023.256568-1-FangSheng.Huang@amd.com/
>   v7: https://lore.kernel.org/qemu-devel/20260306082735.1106690-1-FangSheng.Huang@amd.com/
>   v8: https://lore.kernel.org/qemu-devel/20260527074215.229119-1-FangSheng.Huang@amd.com/
>   v9: https://lore.kernel.org/qemu-devel/20260602084447.1100554-1-FangSheng.Huang@amd.com/
>   v10: https://lore.kernel.org/qemu-devel/20260605104609.1739911-1-FangSheng.Huang@amd.com/
>   v11: https://lore.kernel.org/qemu-devel/20260611100637.2460507-1-FangSheng.Huang@amd.com/
> 
>   [1] v7 thread closeout:
>       https://lore.kernel.org/qemu-devel/666a7ba1-5d3a-4732-b872-0d9fb2fe8461@amd.com/
>   [2] v8 review:
>       https://lore.kernel.org/qemu-devel/20260601105057.2d764e55@imammedo/
>   [3] v9 review:
>       https://lore.kernel.org/qemu-devel/20260602084447.1100554-1-FangSheng.Huang@amd.com/T/
>   [4] v10 review:
>       https://lore.kernel.org/qemu-devel/20260605104609.1739911-1-FangSheng.Huang@amd.com/T/
>   [5] v11 review:
>       https://lore.kernel.org/qemu-devel/20260611100637.2460507-1-FangSheng.Huang@amd.com/T/
> 
> fanhuang (4):
>   hw/mem: add sp-mem device for Specific Purpose Memory
>   i386/acpi-build: partition device_memory SRAT umbrella for sp-mem
>   hw/i386: hook sp-mem into the pc machine plug path
>   MAINTAINERS: cover sp-mem under Memory devices, add R: tag
> 
>  MAINTAINERS                  |   3 +
>  qapi/machine.json            |  43 ++++++++++-
>  hw/i386/e820_memory_layout.h |  11 +--
>  include/hw/mem/sp-mem.h      |  33 +++++++++
>  hw/core/machine-hmp-cmds.c   |  11 +++
>  hw/i386/acpi-build.c         |  96 +++++++++++++++++++++++--
>  hw/i386/pc.c                 |  36 ++++++++++
>  hw/mem/sp-mem.c              | 136 +++++++++++++++++++++++++++++++++++
>  hw/i386/Kconfig              |   2 +
>  hw/mem/Kconfig               |   4 ++
>  hw/mem/meson.build           |   1 +
>  11 files changed, 365 insertions(+), 11 deletions(-)
>  create mode 100644 include/hw/mem/sp-mem.h
>  create mode 100644 hw/mem/sp-mem.c
> 
> 
> base-commit: 2f28d34ea0aead9830478cd1d3d0dd9d9191d82e
> --
> 2.34.1
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-06-17 11:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16  9:08 [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
2026-06-16  9:08 ` [PATCH v12 1/4] " fanhuang
2026-06-17  9:16   ` Igor Mammedov
2026-06-17 10:00     ` Huang, FangSheng (Jerry)
2026-06-16  9:08 ` [PATCH v12 2/4] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem fanhuang
2026-06-17 11:04   ` Igor Mammedov
2026-06-16  9:08 ` [PATCH v12 3/4] hw/i386: hook sp-mem into the pc machine plug path fanhuang
2026-06-17 11:14   ` Igor Mammedov
2026-06-16  9:08 ` [PATCH v12 4/4] MAINTAINERS: cover sp-mem under Memory devices, add R: tag fanhuang
2026-06-17 11:19 ` [PATCH v12 0/4] hw/mem: add sp-mem device for Specific Purpose Memory Igor Mammedov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.