hw/i386: hook sp-mem into the pc machine plug path
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> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20260623075051.3797975-5-FangSheng.Huang@amd.com>
fanhuang committed
Jun 23, 2026 at 15:50 UTC
a597e6791f6ebf2b012f54462d0c44c33a781334
3 files changed
+44
-5
hw/i386/Kconfig
+2
@@ -84,6 +84,7 @@ config I440FX
84
select PCI_I440FX
85
select PIIX
86
select DIMM
87
+ select SP_MEM
88
select SMBIOS
89
select SMBIOS_LEGACY
90
select FW_CFG_DMA
@@ -113,6 +114,7 @@ config Q35
114
select LPC_ICH9
115
select AHCI_ICH9
116
select DIMM
117
+ select SP_MEM
118
select SMBIOS
119
select FW_CFG_DMA
120
hw/i386/e820_memory_layout.h
+6
-5
@@ -10,11 +10,12 @@
10
#define HW_I386_E820_MEMORY_LAYOUT_H
11
12
/* e820 types */
13
-#define E820_RAM 1
14
-#define E820_RESERVED 2
15
-#define E820_ACPI 3
16
-#define E820_NVS 4
17
-#define E820_UNUSABLE 5
13
+#define E820_RAM 1
14
+#define E820_RESERVED 2
15
+#define E820_ACPI 3
16
+#define E820_NVS 4
17
+#define E820_UNUSABLE 5
18
+#define E820_SOFT_RESERVED 0xefffffff
19
20
struct e820_entry {
21
uint64_t address;
hw/i386/pc.c
+36
@@ -63,6 +63,7 @@
63
#include "hw/i386/kvm/xen_gnttab.h"
64
#include "hw/i386/kvm/xen_xenstore.h"
65
#include "hw/mem/memory-device.h"
66
+#include "hw/mem/sp-mem.h"
67
#include "e820_memory_layout.h"
68
#include "trace.h"
69
#include "sev.h"
@@ -1285,11 +1286,43 @@ static void pc_hv_balloon_plug(HotplugHandler *hotplug_dev,
1286
memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
1287
}
1288
1289
+static void pc_sp_mem_pre_plug(HotplugHandler *hotplug_dev,
1290
+ DeviceState *dev, Error **errp)
1291
+{
1292
+ MachineState *ms = MACHINE(hotplug_dev);
1293
+ SpMemDevice *spm = SP_MEM(dev);
1294
+
1295
+ if (ms->numa_state && spm->node >= ms->numa_state->num_nodes) {
1296
+ error_setg(errp,
1297
+ "'node' property value %" PRIu32
1298
+ " exceeds the number of NUMA nodes (%d)",
1299
+ spm->node, ms->numa_state->num_nodes);
1300
+ return;
1301
+ }
1302
+ memory_device_pre_plug(MEMORY_DEVICE(dev), ms, errp);
1303
+}
1304
+
1305
+static void pc_sp_mem_plug(HotplugHandler *hotplug_dev,
1306
+ DeviceState *dev, Error **errp)
1307
+{
1308
+ SpMemDevice *spm = SP_MEM(dev);
1309
+ MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(MEMORY_DEVICE(dev));
1310
+ uint64_t addr, size;
1311
+
1312
+ memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
1313
+
1314
+ addr = mdc->get_addr(MEMORY_DEVICE(dev));
1315
+ size = memory_region_size(host_memory_backend_get_memory(spm->hostmem));
1316
+ e820_add_entry(addr, size, E820_SOFT_RESERVED);
1317
+}
1318
+
1319
static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
1320
DeviceState *dev, Error **errp)
1321
{
1322
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
1323
pc_memory_pre_plug(hotplug_dev, dev, errp);
1324
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM)) {
1325
+ pc_sp_mem_pre_plug(hotplug_dev, dev, errp);
1326
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
1327
x86_cpu_pre_plug(hotplug_dev, dev, errp);
1328
} 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,
1359
{
1360
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
1361
pc_memory_plug(hotplug_dev, dev, errp);
1362
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM)) {
1363
+ pc_sp_mem_plug(hotplug_dev, dev, errp);
1364
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
1365
x86_cpu_plug(hotplug_dev, dev, errp);
1366
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
@@ -1370,6 +1405,7 @@ static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,
1405
DeviceState *dev)
1406
{
1407
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
1408
+ object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM) ||
1409
object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||
1410
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI) ||
1411
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||