- Rebased to libvirt-12.5.0 (VOYAGER-1356) - The rebase also fixes the following bugs: VOYAGER-1351 - conf: Include check for pci_bus in virDomainIOMMUDefEquals() (VOYAGER-1043) - qemu: introduce QEMU_CAPS_DEVICE_ARM_SMMUV3 (VOYAGER-1043) - qemu: introduce QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS (VOYAGER-1043) - qemu: introduce QEMU_CAPS_ARM_SMMUV3_ACCEL (VOYAGER-1043) - qemu: Add support for HW-accelerated nested SMMUv3 (VOYAGER-1043) - tests: qemuxmlconfdata: provide HW-accel smmuv3 sample XML and CLI args (VOYAGER-1043) - qemu: Support NVIDIA Tegra241 CMDQV for SMMUv3 (VOYAGER-1045) - tests: qemuxmlconfdata: provide cmdqv sample XML and CLI args (VOYAGER-1045) - conf: Support EGM memory device model (VOYAGER-1109) - qemu: Add cgroup, namespace, and seclabel setup for EGM memory device model (VOYAGER-1109) - qemu: Add qemu CLI support for EGM (VOYAGER-1109) - tests: Add qemuxmlconftest for ACPI EGM memory device (VOYAGER-1109) Resolves: VOYAGER-1043, VOYAGER-1045, VOYAGER-1109, VOYAGER-1351, VOYAGER-1356
276 lines
9.2 KiB
Diff
276 lines
9.2 KiB
Diff
From 7f6076eef8f66e5252cf1ecaa25446c26288a4aa Mon Sep 17 00:00:00 2001
|
|
Message-ID: <7f6076eef8f66e5252cf1ecaa25446c26288a4aa.1786096789.git.phrdina@redhat.com>
|
|
From: Pavel Hrdina <phrdina@redhat.com>
|
|
Date: Tue, 25 Nov 2025 11:17:01 -0800
|
|
Subject: [PATCH] conf: Support EGM memory device model
|
|
|
|
From: Nathan Chen via Devel <devel@lists.libvirt.org>
|
|
|
|
Add support for EGM memory device model with
|
|
'path' source attribute and 'pciDev' target
|
|
attribute to denote host EGM device backing path
|
|
and PCI device alias to associate the vEGM with,
|
|
respectively.
|
|
|
|
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
|
|
|
|
Resolves: https://redhat.atlassian.net/browse/VOYAGER-1109
|
|
---
|
|
docs/formatdomain.rst | 18 +++++++++++++++++-
|
|
src/conf/domain_conf.c | 29 +++++++++++++++++++++++++++++
|
|
src/conf/domain_conf.h | 7 +++++++
|
|
src/conf/domain_postparse.c | 1 +
|
|
src/conf/domain_validate.c | 15 +++++++++++++++
|
|
src/conf/schemas/domaincommon.rng | 6 ++++++
|
|
6 files changed, 75 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
|
|
index f7b35d31fa..b1500ba718 100644
|
|
--- a/docs/formatdomain.rst
|
|
+++ b/docs/formatdomain.rst
|
|
@@ -9193,6 +9193,16 @@ Example: usage of the memory devices
|
|
<size unit='KiB'>16384</size>
|
|
</target>
|
|
</memory>
|
|
+ <memory model='egm' access='shared'>
|
|
+ <source>
|
|
+ <path>/dev/egm0</path>
|
|
+ </source>
|
|
+ <target>
|
|
+ <size unit='KiB'>524288</size>
|
|
+ <node>0</node>
|
|
+ <pciDev>ua-hostdev0</pciDev>
|
|
+ </target>
|
|
+ </memory>
|
|
</devices>
|
|
...
|
|
|
|
@@ -9204,7 +9214,8 @@ Example: usage of the memory devices
|
|
persistent memory device. :since:`Since 7.1.0` Provide ``virtio-mem`` model
|
|
to add paravirtualized memory device. :since:`Since 7.9.0` Provide
|
|
``sgx-epc`` model to add a SGX enclave page cache (EPC) memory to the guest.
|
|
- :since:`Since 8.10.0 and QEMU 7.0.0`
|
|
+ :since:`Since 8.10.0 and QEMU 7.0.0` Provide ``egm`` model to add a EGM
|
|
+ (Extended GPU Memory) device.
|
|
|
|
``access``
|
|
An optional attribute ``access`` ( :since:`since 3.2.0` ) that provides
|
|
@@ -9339,6 +9350,11 @@ Example: usage of the memory devices
|
|
The physical address in memory, where device is mapped.
|
|
:since:`Since 9.4.0`
|
|
|
|
+ ``pciDev``
|
|
+ For ``egm`` only.
|
|
+ The PCI device that is enabled to access the system memory via
|
|
+ association with the EGM device.
|
|
+
|
|
|
|
IOMMU devices
|
|
~~~~~~~~~~~~~
|
|
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
index 974746bb5c..74b07ad88e 100644
|
|
--- a/src/conf/domain_conf.c
|
|
+++ b/src/conf/domain_conf.c
|
|
@@ -1535,6 +1535,7 @@ VIR_ENUM_IMPL(virDomainMemoryModel,
|
|
"virtio-pmem",
|
|
"virtio-mem",
|
|
"sgx-epc",
|
|
+ "egm",
|
|
);
|
|
|
|
VIR_ENUM_IMPL(virDomainShmemModel,
|
|
@@ -3682,6 +3683,9 @@ void virDomainMemoryDefFree(virDomainMemoryDef *def)
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
virBitmapFree(def->source.sgx_epc.nodes);
|
|
break;
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ g_free(def->source.egm.path);
|
|
+ g_free(def->target.egm.pciDev);
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -14320,6 +14324,10 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node,
|
|
}
|
|
break;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ def->source.egm.path = virXPathString("string(./path)", ctxt);
|
|
+ break;
|
|
+
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -14396,6 +14404,10 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
|
|
addr = &def->target.virtio_pmem.address;
|
|
break;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ def->target.egm.pciDev = virXPathString("string(./pciDev)", ctxt);
|
|
+ break;
|
|
+
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
@@ -14617,6 +14629,7 @@ virDomainMemoryIsVirtioModel(const virDomainMemoryDef *def)
|
|
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
}
|
|
@@ -16561,6 +16574,12 @@ virDomainMemoryFindByDefInternal(virDomainDef *def,
|
|
continue;
|
|
break;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ if (STRNEQ(tmp->source.egm.path, mem->source.egm.path))
|
|
+ continue;
|
|
+ if (STRNEQ(tmp->target.egm.pciDev, mem->target.egm.pciDev))
|
|
+ continue;
|
|
+
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -22705,6 +22724,7 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDef *src,
|
|
|
|
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -27306,6 +27326,10 @@ virDomainMemorySourceDefFormat(virBuffer *buf,
|
|
}
|
|
break;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ virBufferEscapeString(&childBuf, "<path>%s</path>\n", def->source.egm.path);
|
|
+ break;
|
|
+
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -27368,6 +27392,11 @@ virDomainMemoryTargetDefFormat(virBuffer *buf,
|
|
}
|
|
break;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ if (def->target.egm.pciDev)
|
|
+ virBufferAsprintf(&childBuf, "<pciDev>%s</pciDev>\n", def->target.egm.pciDev);
|
|
+ break;
|
|
+
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
|
index 9a65a12e2c..2e49fa837d 100644
|
|
--- a/src/conf/domain_conf.h
|
|
+++ b/src/conf/domain_conf.h
|
|
@@ -2787,6 +2787,7 @@ typedef enum {
|
|
VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM, /* virtio-pmem memory device */
|
|
VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM, /* virtio-mem memory device */
|
|
VIR_DOMAIN_MEMORY_MODEL_SGX_EPC, /* SGX enclave page cache */
|
|
+ VIR_DOMAIN_MEMORY_MODEL_EGM, /* Extended GPU memory */
|
|
|
|
VIR_DOMAIN_MEMORY_MODEL_LAST
|
|
} virDomainMemoryModel;
|
|
@@ -2819,6 +2820,9 @@ struct _virDomainMemoryDef {
|
|
struct {
|
|
virBitmap *nodes; /* source NUMA nodes */
|
|
} sgx_epc;
|
|
+ struct {
|
|
+ char *path;
|
|
+ } egm;
|
|
} source;
|
|
|
|
union {
|
|
@@ -2844,6 +2848,9 @@ struct _virDomainMemoryDef {
|
|
} virtio_mem;
|
|
struct {
|
|
} sgx_epc;
|
|
+ struct {
|
|
+ char *pciDev;
|
|
+ } egm;
|
|
} target;
|
|
|
|
virDomainDeviceInfo info;
|
|
diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c
|
|
index cbaae75c02..2c21e06910 100644
|
|
--- a/src/conf/domain_postparse.c
|
|
+++ b/src/conf/domain_postparse.c
|
|
@@ -616,6 +616,7 @@ virDomainMemoryDefPostParse(virDomainMemoryDef *mem,
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
|
|
index 1cd407bedc..9ddb4e319c 100644
|
|
--- a/src/conf/domain_validate.c
|
|
+++ b/src/conf/domain_validate.c
|
|
@@ -2564,6 +2564,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
|
|
}
|
|
break;
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -2610,6 +2611,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
|
|
switch (other->model) {
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
continue;
|
|
break;
|
|
@@ -2790,6 +2792,19 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
|
|
}
|
|
break;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ if (!mem->source.egm.path) {
|
|
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
|
|
+ _("path is required for model 'egm'"));
|
|
+ return -1;
|
|
+ }
|
|
+ if (!mem->target.egm.pciDev) {
|
|
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
|
|
+ _("pciDev is required for model 'egm'"));
|
|
+ return -1;
|
|
+ }
|
|
+ break;
|
|
+
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
default:
|
|
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
|
|
index ea7c177a68..ec0bca1a84 100644
|
|
--- a/src/conf/schemas/domaincommon.rng
|
|
+++ b/src/conf/schemas/domaincommon.rng
|
|
@@ -7664,6 +7664,7 @@
|
|
<value>virtio-pmem</value>
|
|
<value>virtio-mem</value>
|
|
<value>sgx-epc</value>
|
|
+ <value>egm</value>
|
|
</choice>
|
|
</attribute>
|
|
<optional>
|
|
@@ -7795,6 +7796,11 @@
|
|
</attribute>
|
|
</element>
|
|
</optional>
|
|
+ <optional>
|
|
+ <element name="pciDev">
|
|
+ <data type="string"/>
|
|
+ </element>
|
|
+ </optional>
|
|
</interleave>
|
|
</element>
|
|
</define>
|
|
--
|
|
2.55.0
|