* [PATCH v13 01/10] hw/mem: add sp-mem device for Specific Purpose Memory
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-22 12:49 ` Igor Mammedov
2026-06-19 11:11 ` [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device fanhuang
` (8 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, 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>
---
include/hw/mem/sp-mem.h | 33 ++++++++++++
hw/mem/sp-mem.c | 109 ++++++++++++++++++++++++++++++++++++++++
hw/mem/Kconfig | 4 ++
hw/mem/meson.build | 1 +
4 files changed, 147 insertions(+)
create mode 100644 include/hw/mem/sp-mem.h
create mode 100644 hw/mem/sp-mem.c
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/mem/sp-mem.c b/hw/mem/sp-mem.c
new file mode 100644
index 0000000000..d088222f54
--- /dev/null
+++ b/hw/mem/sp-mem.c
@@ -0,0 +1,109 @@
+/*
+ * 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 "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_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 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;
+ 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;
+}
+
+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] 22+ messages in thread* Re: [PATCH v13 01/10] hw/mem: add sp-mem device for Specific Purpose Memory
2026-06-19 11:11 ` [PATCH v13 01/10] " fanhuang
@ 2026-06-22 12:49 ` Igor Mammedov
0 siblings, 0 replies; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 12:49 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, mst, gourry, philmd, peterx, Zhigang.Luo,
Lianjie.Shi
On Fri, 19 Jun 2026 19:11:27 +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).
>
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> ---
> include/hw/mem/sp-mem.h | 33 ++++++++++++
> hw/mem/sp-mem.c | 109 ++++++++++++++++++++++++++++++++++++++++
> hw/mem/Kconfig | 4 ++
> hw/mem/meson.build | 1 +
> 4 files changed, 147 insertions(+)
> create mode 100644 include/hw/mem/sp-mem.h
> create mode 100644 hw/mem/sp-mem.c
>
> 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/mem/sp-mem.c b/hw/mem/sp-mem.c
> new file mode 100644
> index 0000000000..d088222f54
> --- /dev/null
> +++ b/hw/mem/sp-mem.c
> @@ -0,0 +1,109 @@
> +/*
> + * 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 "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_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 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;
> + 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;
> +}
> +
> +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] 22+ messages in thread
* [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
2026-06-19 11:11 ` [PATCH v13 01/10] " fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-22 12:52 ` Igor Mammedov
2026-06-22 12:55 ` Daniel P. Berrangé
2026-06-19 11:11 ` [PATCH v13 03/10] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem fanhuang
` (7 subsequent siblings)
9 siblings, 2 replies; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, Zhigang.Luo, Lianjie.Shi, fanhuang
Add a SpMemDeviceInfo variant to MemoryDeviceInfo so `query-memory-devices`
reports each sp-mem instance (id, addr, size, node, memdev), and print it
from HMP `info memory-devices`.
Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
qapi/machine.json | 43 ++++++++++++++++++++++++++++++++++++--
hw/core/machine-hmp-cmds.c | 11 ++++++++++
hw/mem/sp-mem.c | 19 +++++++++++++++++
3 files changed, 71 insertions(+), 2 deletions(-)
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/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
index d088222f54..962d0f937e 100644
--- a/hw/mem/sp-mem.c
+++ b/hw/mem/sp-mem.c
@@ -53,6 +53,24 @@ static MemoryRegion *sp_mem_get_memory_region(MemoryDeviceState *md,
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);
@@ -91,6 +109,7 @@ static void sp_mem_class_init(ObjectClass *oc, const void *data)
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[] = {
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device
2026-06-19 11:11 ` [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device fanhuang
@ 2026-06-22 12:52 ` Igor Mammedov
2026-06-22 12:55 ` Daniel P. Berrangé
1 sibling, 0 replies; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 12:52 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, mst, gourry, philmd, peterx, Zhigang.Luo,
Lianjie.Shi
On Fri, 19 Jun 2026 19:11:28 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:
> Add a SpMemDeviceInfo variant to MemoryDeviceInfo so `query-memory-devices`
> reports each sp-mem instance (id, addr, size, node, memdev), and print it
> from HMP `info memory-devices`.
>
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> ---
> qapi/machine.json | 43 ++++++++++++++++++++++++++++++++++++--
> hw/core/machine-hmp-cmds.c | 11 ++++++++++
> hw/mem/sp-mem.c | 19 +++++++++++++++++
> 3 files changed, 71 insertions(+), 2 deletions(-)
>
> 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/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
> index d088222f54..962d0f937e 100644
> --- a/hw/mem/sp-mem.c
> +++ b/hw/mem/sp-mem.c
> @@ -53,6 +53,24 @@ static MemoryRegion *sp_mem_get_memory_region(MemoryDeviceState *md,
> 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);
> @@ -91,6 +109,7 @@ static void sp_mem_class_init(ObjectClass *oc, const void *data)
> 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[] = {
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device
2026-06-19 11:11 ` [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device fanhuang
2026-06-22 12:52 ` Igor Mammedov
@ 2026-06-22 12:55 ` Daniel P. Berrangé
2026-06-22 13:07 ` Igor Mammedov
1 sibling, 1 reply; 22+ messages in thread
From: Daniel P. Berrangé @ 2026-06-22 12:55 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, imammedo, mst, gourry, philmd, peterx,
Zhigang.Luo, Lianjie.Shi
On Fri, Jun 19, 2026 at 07:11:28PM +0800, fanhuang wrote:
> Add a SpMemDeviceInfo variant to MemoryDeviceInfo so `query-memory-devices`
> reports each sp-mem instance (id, addr, size, node, memdev), and print it
> from HMP `info memory-devices`.
>
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
> ---
> qapi/machine.json | 43 ++++++++++++++++++++++++++++++++++++--
> hw/core/machine-hmp-cmds.c | 11 ++++++++++
> hw/mem/sp-mem.c | 19 +++++++++++++++++
> 3 files changed, 71 insertions(+), 2 deletions(-)
>
> 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
Is this bytes ? Please include the units in the comment.
> +#
> +# @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'
> + }
> +}
> +
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device
2026-06-22 12:55 ` Daniel P. Berrangé
@ 2026-06-22 13:07 ` Igor Mammedov
2026-06-22 13:22 ` Daniel P. Berrangé
0 siblings, 1 reply; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 13:07 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: fanhuang, qemu-devel, david, mst, gourry, philmd, peterx,
Zhigang.Luo, Lianjie.Shi
On Mon, 22 Jun 2026 13:55:10 +0100
Daniel P. Berrangé <berrange@redhat.com> wrote:
> On Fri, Jun 19, 2026 at 07:11:28PM +0800, fanhuang wrote:
> > Add a SpMemDeviceInfo variant to MemoryDeviceInfo so `query-memory-devices`
> > reports each sp-mem instance (id, addr, size, node, memdev), and print it
> > from HMP `info memory-devices`.
> >
> > Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
> > ---
> > qapi/machine.json | 43 ++++++++++++++++++++++++++++++++++++--
> > hw/core/machine-hmp-cmds.c | 11 ++++++++++
> > hw/mem/sp-mem.c | 19 +++++++++++++++++
> > 3 files changed, 71 insertions(+), 2 deletions(-)
> >
> > 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
>
> Is this bytes ? Please include the units in the comment.
we don't do that with any of memory devices,
given it's QAPI - I guess bytes are implied for 'size' type
(i.e. no suffix massaging)
> > +#
> > +# @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'
> > + }
> > +}
> > +
>
> With regards,
> Daniel
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device
2026-06-22 13:07 ` Igor Mammedov
@ 2026-06-22 13:22 ` Daniel P. Berrangé
0 siblings, 0 replies; 22+ messages in thread
From: Daniel P. Berrangé @ 2026-06-22 13:22 UTC (permalink / raw)
To: Igor Mammedov
Cc: fanhuang, qemu-devel, david, mst, gourry, philmd, peterx,
Zhigang.Luo, Lianjie.Shi
On Mon, Jun 22, 2026 at 03:07:54PM +0200, Igor Mammedov wrote:
> On Mon, 22 Jun 2026 13:55:10 +0100
> Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> > On Fri, Jun 19, 2026 at 07:11:28PM +0800, fanhuang wrote:
> > > Add a SpMemDeviceInfo variant to MemoryDeviceInfo so `query-memory-devices`
> > > reports each sp-mem instance (id, addr, size, node, memdev), and print it
> > > from HMP `info memory-devices`.
> > >
> > > Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
> > > ---
> > > qapi/machine.json | 43 ++++++++++++++++++++++++++++++++++++--
> > > hw/core/machine-hmp-cmds.c | 11 ++++++++++
> > > hw/mem/sp-mem.c | 19 +++++++++++++++++
> > > 3 files changed, 71 insertions(+), 2 deletions(-)
> > >
> > > 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
> >
> > Is this bytes ? Please include the units in the comment.
>
> we don't do that with any of memory devices,
> given it's QAPI - I guess bytes are implied for 'size' type
> (i.e. no suffix massaging)
The trouble with "implied" is that it relies on the reader being
familiar with QEMU's normal practice. Perhaps passable for regular
QEMU maintainers, but not good for app developers/users consuming
QEMU. It doesn't take much to add "in bytes" to these comments to
make it clear.
Although we don't do it universally/consistently, we do have
quite a few examples:
$ git grep 'in bytes' | wc -l
95
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v13 03/10] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
2026-06-19 11:11 ` [PATCH v13 01/10] " fanhuang
2026-06-19 11:11 ` [PATCH v13 02/10] qapi, hmp: introspection for the sp-mem device fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-19 11:11 ` [PATCH v13 04/10] hw/i386: hook sp-mem into the pc machine plug path fanhuang
` (6 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, 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>
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 2ee061558c..8837b69687 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"
@@ -1351,6 +1352,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)
@@ -1487,10 +1578,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] 22+ messages in thread* [PATCH v13 04/10] hw/i386: hook sp-mem into the pc machine plug path
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
` (2 preceding siblings ...)
2026-06-19 11:11 ` [PATCH v13 03/10] i386/acpi-build: partition device_memory SRAT umbrella for sp-mem fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-22 12:44 ` Igor Mammedov
2026-06-19 11:11 ` [PATCH v13 05/10] MAINTAINERS: cover sp-mem under Memory devices, add R: tag fanhuang
` (5 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, 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>
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 73a625327c..782122f7be 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"
@@ -1285,11 +1286,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)) {
@@ -1326,6 +1359,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)) {
@@ -1370,6 +1405,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] 22+ messages in thread* Re: [PATCH v13 04/10] hw/i386: hook sp-mem into the pc machine plug path
2026-06-19 11:11 ` [PATCH v13 04/10] hw/i386: hook sp-mem into the pc machine plug path fanhuang
@ 2026-06-22 12:44 ` Igor Mammedov
0 siblings, 0 replies; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 12:44 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, mst, gourry, philmd, peterx, Zhigang.Luo,
Lianjie.Shi
On Fri, 19 Jun 2026 19:11:30 +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>
> 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 73a625327c..782122f7be 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"
> @@ -1285,11 +1286,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)
^^^ fix indent
> +{
> + 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)) {
> @@ -1326,6 +1359,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)) {
> @@ -1370,6 +1405,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] 22+ messages in thread
* [PATCH v13 05/10] MAINTAINERS: cover sp-mem under Memory devices, add R: tag
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
` (3 preceding siblings ...)
2026-06-19 11:11 ` [PATCH v13 04/10] hw/i386: hook sp-mem into the pc machine plug path fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-19 11:11 ` [PATCH v13 06/10] tests/acpi: add empty expected blobs for sp-mem SRAT test fanhuang
` (4 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, 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 93df53d87f..08f0d11a74 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3364,13 +3364,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] 22+ messages in thread* [PATCH v13 06/10] tests/acpi: add empty expected blobs for sp-mem SRAT test
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
` (4 preceding siblings ...)
2026-06-19 11:11 ` [PATCH v13 05/10] MAINTAINERS: cover sp-mem under Memory devices, add R: tag fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-22 12:53 ` Igor Mammedov
2026-06-19 11:11 ` [PATCH v13 07/10] tests/acpi: add bios-tables-test case for sp-mem fanhuang
` (3 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, Zhigang.Luo, Lianjie.Shi, fanhuang
Add empty SRAT.spmem and DSDT.spmem stubs and list them in
bios-tables-test-allowed-diff.h.
Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
tests/data/acpi/x86/q35/DSDT.spmem | 0
tests/data/acpi/x86/q35/SRAT.spmem | 0
3 files changed, 2 insertions(+)
create mode 100644 tests/data/acpi/x86/q35/DSDT.spmem
create mode 100644 tests/data/acpi/x86/q35/SRAT.spmem
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..188003fa90 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,3 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/x86/q35/DSDT.spmem",
+"tests/data/acpi/x86/q35/SRAT.spmem",
diff --git a/tests/data/acpi/x86/q35/DSDT.spmem b/tests/data/acpi/x86/q35/DSDT.spmem
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/data/acpi/x86/q35/SRAT.spmem b/tests/data/acpi/x86/q35/SRAT.spmem
new file mode 100644
index 0000000000..e69de29bb2
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v13 06/10] tests/acpi: add empty expected blobs for sp-mem SRAT test
2026-06-19 11:11 ` [PATCH v13 06/10] tests/acpi: add empty expected blobs for sp-mem SRAT test fanhuang
@ 2026-06-22 12:53 ` Igor Mammedov
0 siblings, 0 replies; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 12:53 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, mst, gourry, philmd, peterx, Zhigang.Luo,
Lianjie.Shi
On Fri, 19 Jun 2026 19:11:32 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:
> Add empty SRAT.spmem and DSDT.spmem stubs and list them in
> bios-tables-test-allowed-diff.h.
>
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
Acked-by: Igor Mammedov <imammedo@redhat.com>
> ---
> tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
> tests/data/acpi/x86/q35/DSDT.spmem | 0
> tests/data/acpi/x86/q35/SRAT.spmem | 0
> 3 files changed, 2 insertions(+)
> create mode 100644 tests/data/acpi/x86/q35/DSDT.spmem
> create mode 100644 tests/data/acpi/x86/q35/SRAT.spmem
>
> diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
> index dfb8523c8b..188003fa90 100644
> --- a/tests/qtest/bios-tables-test-allowed-diff.h
> +++ b/tests/qtest/bios-tables-test-allowed-diff.h
> @@ -1 +1,3 @@
> /* List of comma-separated changed AML files to ignore */
> +"tests/data/acpi/x86/q35/DSDT.spmem",
> +"tests/data/acpi/x86/q35/SRAT.spmem",
> diff --git a/tests/data/acpi/x86/q35/DSDT.spmem b/tests/data/acpi/x86/q35/DSDT.spmem
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/data/acpi/x86/q35/SRAT.spmem b/tests/data/acpi/x86/q35/SRAT.spmem
> new file mode 100644
> index 0000000000..e69de29bb2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v13 07/10] tests/acpi: add bios-tables-test case for sp-mem
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
` (5 preceding siblings ...)
2026-06-19 11:11 ` [PATCH v13 06/10] tests/acpi: add empty expected blobs for sp-mem SRAT test fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-22 13:00 ` Igor Mammedov
2026-06-19 11:11 ` [PATCH v13 08/10] tests/acpi: generate expected blobs for sp-mem SRAT test fanhuang
` (2 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, Zhigang.Luo, Lianjie.Shi, fanhuang
Add a q35 bios-tables-test case that boots two sp-mem devices on
distinct NUMA nodes within the device_memory window, exercising the
per-kind SRAT partition (per-device ENABLED entries plus HOTPLUGGABLE
placeholders for the remaining sub-ranges).
Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
tests/qtest/bios-tables-test.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index af6d9b5136..45abd8bd8c 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1416,6 +1416,26 @@ static void test_acpi_q35_tcg_numamem(void)
free_test_data(&data);
}
+static void test_acpi_q35_tcg_sp_mem(void)
+{
+ test_data data = {};
+
+ data.machine = MACHINE_Q35;
+ data.arch = "x86",
+ data.variant = ".spmem";
+ test_acpi_one(" -m 128M,slots=4,maxmem=1G"
+ " -object memory-backend-ram,id=ram0,size=128M"
+ " -numa node,nodeid=0,memdev=ram0"
+ " -numa node,nodeid=1"
+ " -numa node,nodeid=2"
+ " -object memory-backend-ram,id=spm0,size=128M"
+ " -object memory-backend-ram,id=spm1,size=128M"
+ " -device sp-mem,id=sp0,memdev=spm0,node=1"
+ " -device sp-mem,id=sp1,memdev=spm1,node=2",
+ &data);
+ free_test_data(&data);
+}
+
static void test_acpi_q35_kvm_xapic(void)
{
test_data data = {};
@@ -2807,6 +2827,7 @@ int main(int argc, char *argv[])
if (strcmp(arch, "i386")) {
qtest_add_func("acpi/q35/memhp", test_acpi_q35_tcg_memhp);
qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
+ qtest_add_func("acpi/q35/sp-mem", test_acpi_q35_tcg_sp_mem);
qtest_add_func("acpi/q35/acpihmat",
test_acpi_q35_tcg_acpi_hmat);
qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v13 07/10] tests/acpi: add bios-tables-test case for sp-mem
2026-06-19 11:11 ` [PATCH v13 07/10] tests/acpi: add bios-tables-test case for sp-mem fanhuang
@ 2026-06-22 13:00 ` Igor Mammedov
0 siblings, 0 replies; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 13:00 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, mst, gourry, philmd, peterx, Zhigang.Luo,
Lianjie.Shi
On Fri, 19 Jun 2026 19:11:33 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:
> Add a q35 bios-tables-test case that boots two sp-mem devices on
> distinct NUMA nodes within the device_memory window, exercising the
> per-kind SRAT partition (per-device ENABLED entries plus HOTPLUGGABLE
> placeholders for the remaining sub-ranges).
>
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> ---
> tests/qtest/bios-tables-test.c | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
> index af6d9b5136..45abd8bd8c 100644
> --- a/tests/qtest/bios-tables-test.c
> +++ b/tests/qtest/bios-tables-test.c
> @@ -1416,6 +1416,26 @@ static void test_acpi_q35_tcg_numamem(void)
> free_test_data(&data);
> }
>
> +static void test_acpi_q35_tcg_sp_mem(void)
> +{
> + test_data data = {};
> +
> + data.machine = MACHINE_Q35;
> + data.arch = "x86",
> + data.variant = ".spmem";
> + test_acpi_one(" -m 128M,slots=4,maxmem=1G"
> + " -object memory-backend-ram,id=ram0,size=128M"
> + " -numa node,nodeid=0,memdev=ram0"
> + " -numa node,nodeid=1"
> + " -numa node,nodeid=2"
> + " -object memory-backend-ram,id=spm0,size=128M"
> + " -object memory-backend-ram,id=spm1,size=128M"
> + " -device sp-mem,id=sp0,memdev=spm0,node=1"
> + " -device sp-mem,id=sp1,memdev=spm1,node=2",
> + &data);
> + free_test_data(&data);
> +}
> +
> static void test_acpi_q35_kvm_xapic(void)
> {
> test_data data = {};
> @@ -2807,6 +2827,7 @@ int main(int argc, char *argv[])
> if (strcmp(arch, "i386")) {
> qtest_add_func("acpi/q35/memhp", test_acpi_q35_tcg_memhp);
> qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
> + qtest_add_func("acpi/q35/sp-mem", test_acpi_q35_tcg_sp_mem);
> qtest_add_func("acpi/q35/acpihmat",
> test_acpi_q35_tcg_acpi_hmat);
> qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v13 08/10] tests/acpi: generate expected blobs for sp-mem SRAT test
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
` (6 preceding siblings ...)
2026-06-19 11:11 ` [PATCH v13 07/10] tests/acpi: add bios-tables-test case for sp-mem fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-22 13:09 ` Igor Mammedov
2026-06-19 11:11 ` [PATCH v13 09/10] tests/qtest: add e820 fw_cfg test fanhuang
2026-06-19 11:11 ` [PATCH v13 10/10] tests/qtest: cover sp-mem SOFT_RESERVED e820 entry fanhuang
9 siblings, 1 reply; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, Zhigang.Luo, Lianjie.Shi, fanhuang
Populate the expected ACPI blobs for the sp-mem test and clear the
allowed-diff list.
SRAT memory-affinity entries for the device_memory window (q35,
-m 128M,maxmem=1G, sp0 on node 1 and sp1 on node 2, each 128M):
Proximity Domain : 1 Base : 0x100000000 Length : 0x08000000 (Enabled)
Proximity Domain : 2 Base : 0x108000000 Length : 0x08000000 (Enabled)
Proximity Domain : 2 Base : 0x110000000 Length : 0x128000000 (Hot Pluggable)
Each sp-mem device gets an ENABLED entry at its own proximity domain;
the remaining device_memory window is covered by a HOTPLUGGABLE
placeholder at the highest proximity domain.
(DSDT.spmem differs from the base only by the memory-hotplug AML
enabled by -m,maxmem.)
Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
tests/data/acpi/x86/q35/DSDT.spmem | Bin 0 -> 9910 bytes
tests/data/acpi/x86/q35/SRAT.spmem | Bin 0 -> 384 bytes
3 files changed, 2 deletions(-)
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index 188003fa90..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,3 +1 @@
/* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/x86/q35/DSDT.spmem",
-"tests/data/acpi/x86/q35/SRAT.spmem",
diff --git a/tests/data/acpi/x86/q35/DSDT.spmem b/tests/data/acpi/x86/q35/DSDT.spmem
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7e6f850e7a25aaa3cb7abc0ff2aeab4ca7fdb716 100644
GIT binary patch
literal 9910
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
MvBJ}12_H=T4{{!rhyVZp
literal 0
HcmV?d00001
diff --git a/tests/data/acpi/x86/q35/SRAT.spmem b/tests/data/acpi/x86/q35/SRAT.spmem
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9ecd266eda68d035f72f170cb1346b97da623c28 100644
GIT binary patch
literal 384
zcmWFzatvu;WME+AbMklg2v%^42yj*a0-z8Bhz+7a7!Cwb`HUKH87PAbE`Y2Lp$=#O
z7<^!dDa5W0CX1a$n1@{+CQ7_Ige#yd4!9XG29RddV1n^Dh*T#4Ri^>7ff;53kOlxB
Ct_cAE
literal 0
HcmV?d00001
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v13 08/10] tests/acpi: generate expected blobs for sp-mem SRAT test
2026-06-19 11:11 ` [PATCH v13 08/10] tests/acpi: generate expected blobs for sp-mem SRAT test fanhuang
@ 2026-06-22 13:09 ` Igor Mammedov
0 siblings, 0 replies; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 13:09 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, mst, gourry, philmd, peterx, Zhigang.Luo,
Lianjie.Shi
On Fri, 19 Jun 2026 19:11:34 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:
> Populate the expected ACPI blobs for the sp-mem test and clear the
> allowed-diff list.
>
> SRAT memory-affinity entries for the device_memory window (q35,
> -m 128M,maxmem=1G, sp0 on node 1 and sp1 on node 2, each 128M):
>
> Proximity Domain : 1 Base : 0x100000000 Length : 0x08000000 (Enabled)
> Proximity Domain : 2 Base : 0x108000000 Length : 0x08000000 (Enabled)
> Proximity Domain : 2 Base : 0x110000000 Length : 0x128000000 (Hot Pluggable)
>
> Each sp-mem device gets an ENABLED entry at its own proximity domain;
> the remaining device_memory window is covered by a HOTPLUGGABLE
> placeholder at the highest proximity domain.
>
> (DSDT.spmem differs from the base only by the memory-hotplug AML
> enabled by -m,maxmem.)
>
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
Acked-by: Igor Mammedov <imammedo@redhat.com>
> ---
> tests/qtest/bios-tables-test-allowed-diff.h | 2 --
> tests/data/acpi/x86/q35/DSDT.spmem | Bin 0 -> 9910 bytes
> tests/data/acpi/x86/q35/SRAT.spmem | Bin 0 -> 384 bytes
> 3 files changed, 2 deletions(-)
>
> diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
> index 188003fa90..dfb8523c8b 100644
> --- a/tests/qtest/bios-tables-test-allowed-diff.h
> +++ b/tests/qtest/bios-tables-test-allowed-diff.h
> @@ -1,3 +1 @@
> /* List of comma-separated changed AML files to ignore */
> -"tests/data/acpi/x86/q35/DSDT.spmem",
> -"tests/data/acpi/x86/q35/SRAT.spmem",
> diff --git a/tests/data/acpi/x86/q35/DSDT.spmem b/tests/data/acpi/x86/q35/DSDT.spmem
> index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7e6f850e7a25aaa3cb7abc0ff2aeab4ca7fdb716 100644
> GIT binary patch
> literal 9910
> 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
> MvBJ}12_H=T4{{!rhyVZp
>
> literal 0
> HcmV?d00001
>
> diff --git a/tests/data/acpi/x86/q35/SRAT.spmem b/tests/data/acpi/x86/q35/SRAT.spmem
> index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9ecd266eda68d035f72f170cb1346b97da623c28 100644
> GIT binary patch
> literal 384
> zcmWFzatvu;WME+AbMklg2v%^42yj*a0-z8Bhz+7a7!Cwb`HUKH87PAbE`Y2Lp$=#O
> z7<^!dDa5W0CX1a$n1@{+CQ7_Ige#yd4!9XG29RddV1n^Dh*T#4Ri^>7ff;53kOlxB
> Ct_cAE
>
> literal 0
> HcmV?d00001
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v13 09/10] tests/qtest: add e820 fw_cfg test
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
` (7 preceding siblings ...)
2026-06-19 11:11 ` [PATCH v13 08/10] tests/acpi: generate expected blobs for sp-mem SRAT test fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-22 14:09 ` Igor Mammedov
2026-06-19 11:11 ` [PATCH v13 10/10] tests/qtest: cover sp-mem SOFT_RESERVED e820 entry fanhuang
9 siblings, 1 reply; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, Zhigang.Luo, Lianjie.Shi, fanhuang
Add a qtest that reads the "etc/e820" fw_cfg table and checks its
structural invariants: the file is a whole number of e820 entries and
every entry has a non-zero length. The baseline q35 case asserts the
guest sees RAM and, with no sp-mem device, no SOFT_RESERVED range.
Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
tests/qtest/e820-test.c | 95 +++++++++++++++++++++++++++++++++++++++++
tests/qtest/meson.build | 1 +
2 files changed, 96 insertions(+)
create mode 100644 tests/qtest/e820-test.c
diff --git a/tests/qtest/e820-test.c b/tests/qtest/e820-test.c
new file mode 100644
index 0000000000..1db0744c08
--- /dev/null
+++ b/tests/qtest/e820-test.c
@@ -0,0 +1,95 @@
+/*
+ * qtest e820 fw_cfg test case
+ *
+ * Validate the "etc/e820" fw_cfg table that QEMU hands to the firmware.
+ *
+ * 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 "libqtest.h"
+#include "libqos/fw_cfg.h"
+#include "qemu/bswap.h"
+
+/* e820 entry layout and types (cf. hw/i386/e820_memory_layout.h) */
+#define E820_RAM 1
+#define E820_SOFT_RESERVED 0xefffffff
+
+struct e820_entry {
+ uint64_t address;
+ uint64_t length;
+ uint32_t type;
+} QEMU_PACKED;
+
+#define E820_MAX_ENTRIES 128
+
+/*
+ * Read and structurally validate "etc/e820": the file is a packed array
+ * of struct e820_entry, so its size must be a whole multiple of the entry
+ * size and every entry must have a non-zero length. Returns the entry
+ * count and fills @table.
+ */
+static size_t get_e820_table(QFWCFG *fw_cfg, struct e820_entry *table)
+{
+ size_t filesize, n, i;
+
+ filesize = qfw_cfg_get_file(fw_cfg, "etc/e820", table,
+ E820_MAX_ENTRIES * sizeof(*table));
+ g_assert_cmpint(filesize, >, 0);
+ g_assert_cmpint(filesize % sizeof(struct e820_entry), ==, 0);
+
+ n = filesize / sizeof(struct e820_entry);
+ g_assert_cmpint(n, <=, E820_MAX_ENTRIES);
+
+ for (i = 0; i < n; i++) {
+ g_assert_cmpint(le64_to_cpu(table[i].length), >, 0);
+ }
+
+ return n;
+}
+
+static void test_e820_basic(void)
+{
+ struct e820_entry table[E820_MAX_ENTRIES];
+ QFWCFG *fw_cfg;
+ QTestState *s;
+ size_t n, i;
+ bool found_ram = false, found_soft_reserved = false;
+
+ s = qtest_init("-machine q35 -m 256M");
+ fw_cfg = pc_fw_cfg_init(s);
+
+ n = get_e820_table(fw_cfg, table);
+ for (i = 0; i < n; i++) {
+ switch (le32_to_cpu(table[i].type)) {
+ case E820_RAM:
+ found_ram = true;
+ break;
+ case E820_SOFT_RESERVED:
+ found_soft_reserved = true;
+ break;
+ }
+ }
+
+ /* baseline: RAM present, no SOFT_RESERVED range */
+ g_assert_true(found_ram);
+ g_assert_false(found_soft_reserved);
+
+ pc_fw_cfg_uninit(fw_cfg);
+ qtest_quit(s);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_func("e820/basic", test_e820_basic);
+
+ return g_test_run();
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 4897325d84..d69ee27fa4 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -58,6 +58,7 @@ qtests_i386 = \
(config_all_devices.has_key('CONFIG_AHCI_ICH9') ? ['tco-test'] : []) + \
(config_all_devices.has_key('CONFIG_FDC_ISA') ? ['fdc-test'] : []) + \
(config_all_devices.has_key('CONFIG_I440FX') ? ['fw_cfg-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_Q35') ? ['e820-test'] : []) + \
(config_all_devices.has_key('CONFIG_FW_CFG_DMA') ? ['vmcoreinfo-test'] : []) + \
(config_all_devices.has_key('CONFIG_I440FX') ? ['i440fx-test'] : []) + \
(config_all_devices.has_key('CONFIG_I440FX') ? ['ide-test'] : []) + \
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v13 09/10] tests/qtest: add e820 fw_cfg test
2026-06-19 11:11 ` [PATCH v13 09/10] tests/qtest: add e820 fw_cfg test fanhuang
@ 2026-06-22 14:09 ` Igor Mammedov
0 siblings, 0 replies; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 14:09 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, mst, gourry, philmd, peterx, Zhigang.Luo,
Lianjie.Shi
On Fri, 19 Jun 2026 19:11:35 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:
> Add a qtest that reads the "etc/e820" fw_cfg table and checks its
> structural invariants: the file is a whole number of e820 entries and
> every entry has a non-zero length. The baseline q35 case asserts the
> guest sees RAM and, with no sp-mem device, no SOFT_RESERVED range.
>
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
Acked-by: Igor Mammedov <imammedo@redhat.com>
> ---
> tests/qtest/e820-test.c | 95 +++++++++++++++++++++++++++++++++++++++++
> tests/qtest/meson.build | 1 +
> 2 files changed, 96 insertions(+)
> create mode 100644 tests/qtest/e820-test.c
>
> diff --git a/tests/qtest/e820-test.c b/tests/qtest/e820-test.c
> new file mode 100644
> index 0000000000..1db0744c08
> --- /dev/null
> +++ b/tests/qtest/e820-test.c
> @@ -0,0 +1,95 @@
> +/*
> + * qtest e820 fw_cfg test case
> + *
> + * Validate the "etc/e820" fw_cfg table that QEMU hands to the firmware.
> + *
> + * 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 "libqtest.h"
> +#include "libqos/fw_cfg.h"
> +#include "qemu/bswap.h"
> +
> +/* e820 entry layout and types (cf. hw/i386/e820_memory_layout.h) */
> +#define E820_RAM 1
> +#define E820_SOFT_RESERVED 0xefffffff
> +
> +struct e820_entry {
> + uint64_t address;
> + uint64_t length;
> + uint32_t type;
> +} QEMU_PACKED;
> +
> +#define E820_MAX_ENTRIES 128
> +
> +/*
> + * Read and structurally validate "etc/e820": the file is a packed array
> + * of struct e820_entry, so its size must be a whole multiple of the entry
> + * size and every entry must have a non-zero length. Returns the entry
> + * count and fills @table.
> + */
> +static size_t get_e820_table(QFWCFG *fw_cfg, struct e820_entry *table)
> +{
> + size_t filesize, n, i;
> +
> + filesize = qfw_cfg_get_file(fw_cfg, "etc/e820", table,
> + E820_MAX_ENTRIES * sizeof(*table));
> + g_assert_cmpint(filesize, >, 0);
> + g_assert_cmpint(filesize % sizeof(struct e820_entry), ==, 0);
> +
> + n = filesize / sizeof(struct e820_entry);
> + g_assert_cmpint(n, <=, E820_MAX_ENTRIES);
> +
> + for (i = 0; i < n; i++) {
> + g_assert_cmpint(le64_to_cpu(table[i].length), >, 0);
> + }
> +
> + return n;
> +}
> +
> +static void test_e820_basic(void)
> +{
> + struct e820_entry table[E820_MAX_ENTRIES];
> + QFWCFG *fw_cfg;
> + QTestState *s;
> + size_t n, i;
> + bool found_ram = false, found_soft_reserved = false;
> +
> + s = qtest_init("-machine q35 -m 256M");
> + fw_cfg = pc_fw_cfg_init(s);
> +
> + n = get_e820_table(fw_cfg, table);
> + for (i = 0; i < n; i++) {
> + switch (le32_to_cpu(table[i].type)) {
> + case E820_RAM:
> + found_ram = true;
> + break;
> + case E820_SOFT_RESERVED:
> + found_soft_reserved = true;
> + break;
> + }
> + }
> +
> + /* baseline: RAM present, no SOFT_RESERVED range */
> + g_assert_true(found_ram);
> + g_assert_false(found_soft_reserved);
> +
> + pc_fw_cfg_uninit(fw_cfg);
> + qtest_quit(s);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + g_test_init(&argc, &argv, NULL);
> +
> + qtest_add_func("e820/basic", test_e820_basic);
> +
> + return g_test_run();
> +}
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 4897325d84..d69ee27fa4 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -58,6 +58,7 @@ qtests_i386 = \
> (config_all_devices.has_key('CONFIG_AHCI_ICH9') ? ['tco-test'] : []) + \
> (config_all_devices.has_key('CONFIG_FDC_ISA') ? ['fdc-test'] : []) + \
> (config_all_devices.has_key('CONFIG_I440FX') ? ['fw_cfg-test'] : []) + \
> + (config_all_devices.has_key('CONFIG_Q35') ? ['e820-test'] : []) + \
> (config_all_devices.has_key('CONFIG_FW_CFG_DMA') ? ['vmcoreinfo-test'] : []) + \
> (config_all_devices.has_key('CONFIG_I440FX') ? ['i440fx-test'] : []) + \
> (config_all_devices.has_key('CONFIG_I440FX') ? ['ide-test'] : []) + \
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v13 10/10] tests/qtest: cover sp-mem SOFT_RESERVED e820 entry
2026-06-19 11:11 [PATCH v13 00/10] hw/mem: add sp-mem device for Specific Purpose Memory fanhuang
` (8 preceding siblings ...)
2026-06-19 11:11 ` [PATCH v13 09/10] tests/qtest: add e820 fw_cfg test fanhuang
@ 2026-06-19 11:11 ` fanhuang
2026-06-22 14:09 ` Igor Mammedov
9 siblings, 1 reply; 22+ messages in thread
From: fanhuang @ 2026-06-19 11:11 UTC (permalink / raw)
To: qemu-devel, david, imammedo, mst, gourry, philmd
Cc: peterx, Zhigang.Luo, Lianjie.Shi, fanhuang
Boot one sp-mem device and assert the guest's e820 table gains exactly
one E820_SOFT_RESERVED range whose length matches the device's backend
size.
Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
---
tests/qtest/e820-test.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/tests/qtest/e820-test.c b/tests/qtest/e820-test.c
index 1db0744c08..aafa3c1aa2 100644
--- a/tests/qtest/e820-test.c
+++ b/tests/qtest/e820-test.c
@@ -16,6 +16,7 @@
#include "libqtest.h"
#include "libqos/fw_cfg.h"
#include "qemu/bswap.h"
+#include "qemu/units.h"
/* e820 entry layout and types (cf. hw/i386/e820_memory_layout.h) */
#define E820_RAM 1
@@ -85,11 +86,44 @@ static void test_e820_basic(void)
qtest_quit(s);
}
+static void test_e820_sp_mem(void)
+{
+ struct e820_entry table[E820_MAX_ENTRIES];
+ QFWCFG *fw_cfg;
+ QTestState *s;
+ size_t n, i;
+ int soft_reserved = 0;
+ uint64_t soft_reserved_len = 0;
+
+ s = qtest_init("-machine q35 -m 256M,slots=2,maxmem=2G "
+ "-object memory-backend-ram,id=ram0,size=256M "
+ "-numa node,nodeid=0,memdev=ram0 "
+ "-object memory-backend-ram,id=spm0,size=128M "
+ "-device sp-mem,id=sp0,memdev=spm0,node=0");
+ fw_cfg = pc_fw_cfg_init(s);
+
+ n = get_e820_table(fw_cfg, table);
+ for (i = 0; i < n; i++) {
+ if (le32_to_cpu(table[i].type) == E820_SOFT_RESERVED) {
+ soft_reserved++;
+ soft_reserved_len = le64_to_cpu(table[i].length);
+ }
+ }
+
+ /* exactly one SOFT_RESERVED range, sized to the backend */
+ g_assert_cmpint(soft_reserved, ==, 1);
+ g_assert_cmpint(soft_reserved_len, ==, 128 * MiB);
+
+ pc_fw_cfg_uninit(fw_cfg);
+ qtest_quit(s);
+}
+
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
qtest_add_func("e820/basic", test_e820_basic);
+ qtest_add_func("e820/sp-mem", test_e820_sp_mem);
return g_test_run();
}
--
2.34.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH v13 10/10] tests/qtest: cover sp-mem SOFT_RESERVED e820 entry
2026-06-19 11:11 ` [PATCH v13 10/10] tests/qtest: cover sp-mem SOFT_RESERVED e820 entry fanhuang
@ 2026-06-22 14:09 ` Igor Mammedov
0 siblings, 0 replies; 22+ messages in thread
From: Igor Mammedov @ 2026-06-22 14:09 UTC (permalink / raw)
To: fanhuang
Cc: qemu-devel, david, mst, gourry, philmd, peterx, Zhigang.Luo,
Lianjie.Shi
On Fri, 19 Jun 2026 19:11:36 +0800
fanhuang <FangSheng.Huang@amd.com> wrote:
> Boot one sp-mem device and assert the guest's e820 table gains exactly
> one E820_SOFT_RESERVED range whose length matches the device's backend
> size.
>
> Signed-off-by: FangSheng Huang <FangSheng.Huang@amd.com>
Acked-by: Igor Mammedov <imammedo@redhat.com>
> ---
> tests/qtest/e820-test.c | 34 ++++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/tests/qtest/e820-test.c b/tests/qtest/e820-test.c
> index 1db0744c08..aafa3c1aa2 100644
> --- a/tests/qtest/e820-test.c
> +++ b/tests/qtest/e820-test.c
> @@ -16,6 +16,7 @@
> #include "libqtest.h"
> #include "libqos/fw_cfg.h"
> #include "qemu/bswap.h"
> +#include "qemu/units.h"
>
> /* e820 entry layout and types (cf. hw/i386/e820_memory_layout.h) */
> #define E820_RAM 1
> @@ -85,11 +86,44 @@ static void test_e820_basic(void)
> qtest_quit(s);
> }
>
> +static void test_e820_sp_mem(void)
> +{
> + struct e820_entry table[E820_MAX_ENTRIES];
> + QFWCFG *fw_cfg;
> + QTestState *s;
> + size_t n, i;
> + int soft_reserved = 0;
> + uint64_t soft_reserved_len = 0;
> +
> + s = qtest_init("-machine q35 -m 256M,slots=2,maxmem=2G "
> + "-object memory-backend-ram,id=ram0,size=256M "
> + "-numa node,nodeid=0,memdev=ram0 "
> + "-object memory-backend-ram,id=spm0,size=128M "
> + "-device sp-mem,id=sp0,memdev=spm0,node=0");
> + fw_cfg = pc_fw_cfg_init(s);
> +
> + n = get_e820_table(fw_cfg, table);
> + for (i = 0; i < n; i++) {
> + if (le32_to_cpu(table[i].type) == E820_SOFT_RESERVED) {
> + soft_reserved++;
> + soft_reserved_len = le64_to_cpu(table[i].length);
> + }
> + }
> +
> + /* exactly one SOFT_RESERVED range, sized to the backend */
> + g_assert_cmpint(soft_reserved, ==, 1);
> + g_assert_cmpint(soft_reserved_len, ==, 128 * MiB);
> +
> + pc_fw_cfg_uninit(fw_cfg);
> + qtest_quit(s);
> +}
> +
> int main(int argc, char **argv)
> {
> g_test_init(&argc, &argv, NULL);
>
> qtest_add_func("e820/basic", test_e820_basic);
> + qtest_add_func("e820/sp-mem", test_e820_sp_mem);
>
> return g_test_run();
> }
^ permalink raw reply [flat|nested] 22+ messages in thread