- conf: Support EGM memory device model (VOYAGER-13) - qemu: Add cgroup, namespace, and seclabel setup for EGM memory device model (VOYAGER-13) - qemu: Add qemu CLI support for EGM (VOYAGER-13) - tests: Add qemuxmlconftest for ACPI EGM memory device (VOYAGER-13) Resolves: VOYAGER-13
529 lines
21 KiB
Diff
529 lines
21 KiB
Diff
From 9965f1b7b0fb1810fe32498f7892aa549a754d19 Mon Sep 17 00:00:00 2001
|
|
Message-ID: <9965f1b7b0fb1810fe32498f7892aa549a754d19.1779098642.git.phrdina@redhat.com>
|
|
From: Pavel Hrdina <phrdina@redhat.com>
|
|
Date: Tue, 25 Nov 2025 11:17:03 -0800
|
|
Subject: [PATCH] qemu: Add qemu CLI support for EGM
|
|
|
|
From: Nathan Chen via Devel <devel@lists.libvirt.org>
|
|
|
|
Add qemu CLI support for EGM memory device model:
|
|
- Specify EGM device path to memory-backend-file object
|
|
- Support acpi-egm-memory object with id, pci-dev, and
|
|
node attributes
|
|
- Consolidate all acpi-egm-memory objects' memory into
|
|
a single memory-backend-file per EGM chardev
|
|
specified.
|
|
|
|
Signed-off-by: Ian May <ianm@nvidia.com>
|
|
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
|
|
|
|
Resolves: https://redhat.atlassian.net/browse/VOYAGER-13
|
|
---
|
|
src/qemu/qemu_alias.c | 7 +-
|
|
src/qemu/qemu_capabilities.c | 2 +
|
|
src/qemu/qemu_capabilities.h | 1 +
|
|
src/qemu/qemu_command.c | 158 ++++++++++++++++++++++++++++++---
|
|
src/qemu/qemu_domain.c | 13 ++-
|
|
src/qemu/qemu_domain_address.c | 3 +
|
|
src/qemu/qemu_driver.c | 1 +
|
|
src/qemu/qemu_hotplug.c | 1 +
|
|
src/qemu/qemu_monitor_json.c | 1 +
|
|
src/qemu/qemu_postparse.c | 1 +
|
|
src/qemu/qemu_process.c | 2 +
|
|
src/qemu/qemu_validate.c | 6 ++
|
|
12 files changed, 180 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
|
|
index 400ce73283..719224e1ba 100644
|
|
--- a/src/qemu/qemu_alias.c
|
|
+++ b/src/qemu/qemu_alias.c
|
|
@@ -504,7 +504,8 @@ qemuDeviceMemoryGetAliasID(virDomainDef *def,
|
|
* valid */
|
|
if (mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM &&
|
|
mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM &&
|
|
- mem->model != VIR_DOMAIN_MEMORY_MODEL_SGX_EPC)
|
|
+ mem->model != VIR_DOMAIN_MEMORY_MODEL_SGX_EPC &&
|
|
+ mem->model != VIR_DOMAIN_MEMORY_MODEL_EGM)
|
|
return mem->info.addr.dimm.slot;
|
|
|
|
for (i = 0; i < def->nmems; i++) {
|
|
@@ -553,6 +554,10 @@ qemuAssignDeviceMemoryAlias(virDomainDef *def,
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
prefix = "epc";
|
|
break;
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM: {
|
|
+ prefix = "egm";
|
|
+ break;
|
|
+ }
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
default:
|
|
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|
index ed6aa86da2..010933bc4e 100644
|
|
--- a/src/qemu/qemu_capabilities.c
|
|
+++ b/src/qemu/qemu_capabilities.c
|
|
@@ -760,6 +760,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
|
|
|
|
/* 490 */
|
|
"iommufd", /* QEMU_CAPS_OBJECT_IOMMUFD */
|
|
+ "acpi-egm-memory", /* QEMU_CAPS_DEVICE_ACPI_EGM_MEMORY */
|
|
);
|
|
|
|
|
|
@@ -1468,6 +1469,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
|
|
{ "tpm-passthrough", QEMU_CAPS_DEVICE_TPM_PASSTHROUGH },
|
|
{ "acpi-generic-initiator", QEMU_CAPS_ACPI_GENERIC_INITIATOR },
|
|
{ "iommufd", QEMU_CAPS_OBJECT_IOMMUFD },
|
|
+ { "acpi-egm-memory", QEMU_CAPS_DEVICE_ACPI_EGM_MEMORY },
|
|
};
|
|
|
|
|
|
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
|
index f7c8680f94..85615b4524 100644
|
|
--- a/src/qemu/qemu_capabilities.h
|
|
+++ b/src/qemu/qemu_capabilities.h
|
|
@@ -734,6 +734,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
|
|
|
|
/* 490 */
|
|
QEMU_CAPS_OBJECT_IOMMUFD, /* -object iommufd */
|
|
+ QEMU_CAPS_DEVICE_ACPI_EGM_MEMORY, /* For using extended GPU memory */
|
|
|
|
QEMU_CAPS_LAST /* this must always be the last item */
|
|
} virQEMUCapsFlags;
|
|
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
index a76f504e6f..63fd9885b7 100644
|
|
--- a/src/qemu/qemu_command.c
|
|
+++ b/src/qemu/qemu_command.c
|
|
@@ -135,6 +135,21 @@ VIR_ENUM_IMPL(qemuACPITableSIG,
|
|
"SLIC",
|
|
"MSDM");
|
|
|
|
+typedef struct _qemuEGMBackendInfo {
|
|
+ char *alias;
|
|
+ unsigned long long totalSize;
|
|
+ bool created;
|
|
+ virDomainMemoryDef *firstMem; /* Pointer to first device for this path */
|
|
+} qemuEGMBackendInfo;
|
|
+
|
|
+static void
|
|
+qemuEGMBackendInfoFree(qemuEGMBackendInfo *info)
|
|
+{
|
|
+ if (!info)
|
|
+ return;
|
|
+ g_free(info->alias);
|
|
+ g_free(info);
|
|
+}
|
|
|
|
const char *
|
|
qemuAudioDriverTypeToString(virDomainAudioType type)
|
|
@@ -992,6 +1007,7 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device,
|
|
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_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -3166,6 +3182,7 @@ qemuBuildMemoryGetPagesize(virQEMUDriverConfig *cfg,
|
|
nvdimmPath = mem->source.virtio_pmem.path;
|
|
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;
|
|
@@ -3366,6 +3383,9 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
nvdimmPath = mem->source.virtio_pmem.path;
|
|
break;
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ nvdimmPath = mem->source.egm.path;
|
|
+ break;
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -3577,12 +3597,17 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd,
|
|
virDomainMemoryDef *mem,
|
|
virDomainDef *def,
|
|
virQEMUDriverConfig *cfg,
|
|
- qemuDomainObjPrivate *priv)
|
|
+ qemuDomainObjPrivate *priv,
|
|
+ GHashTable *egmBackends)
|
|
{
|
|
g_autoptr(virJSONValue) props = NULL;
|
|
g_autoptr(virJSONValue) tcProps = NULL;
|
|
virBitmap *nodemask = NULL;
|
|
g_autofree char *alias = NULL;
|
|
+ unsigned long long originalSize = 0;
|
|
+ bool isEGM = (mem->model == VIR_DOMAIN_MEMORY_MODEL_EGM);
|
|
+ bool shouldCreateBackend = true;
|
|
+ qemuEGMBackendInfo *egmInfo = NULL;
|
|
|
|
if (!mem->info.alias) {
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
@@ -3592,19 +3617,65 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd,
|
|
|
|
alias = g_strdup_printf("mem%s", mem->info.alias);
|
|
|
|
- if (qemuBuildMemoryBackendProps(&props, alias, cfg, priv,
|
|
- def, mem, true, false, &nodemask) < 0)
|
|
- return -1;
|
|
+ /* Handle EGM shared backend logic */
|
|
+ if (isEGM && egmBackends) {
|
|
+ const char *egmPath = mem->source.egm.path;
|
|
+ egmInfo = g_hash_table_lookup(egmBackends, egmPath);
|
|
|
|
- if (qemuBuildThreadContextProps(&tcProps, &props, def, priv, nodemask) < 0)
|
|
- return -1;
|
|
+ if (egmInfo) {
|
|
+ alias = g_strdup(egmInfo->alias);
|
|
+ if (egmInfo->created) {
|
|
+ /* Backend already created, skip backend creation */
|
|
+ shouldCreateBackend = false;
|
|
+ } else {
|
|
+ /* First device for this path - temporarily use accumulated size */
|
|
+ originalSize = mem->size;
|
|
+ mem->size = egmInfo->totalSize;
|
|
+ egmInfo->created = true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
|
|
- if (tcProps &&
|
|
- qemuBuildObjectCommandlineFromJSON(cmd, tcProps) < 0)
|
|
- return -1;
|
|
+ if (shouldCreateBackend) {
|
|
+ /* Use existing function unchanged */
|
|
+ if (qemuBuildMemoryBackendProps(&props, alias, cfg, priv,
|
|
+ def, mem, true, false, &nodemask) < 0) {
|
|
+ if (originalSize > 0)
|
|
+ mem->size = originalSize; /* Restore on error */
|
|
+ return -1;
|
|
+ }
|
|
|
|
- if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
|
|
- return -1;
|
|
+ /* Restore original size after backend props are built */
|
|
+ if (originalSize > 0)
|
|
+ mem->size = originalSize;
|
|
+
|
|
+ if (qemuBuildThreadContextProps(&tcProps, &props, def, priv, nodemask) < 0)
|
|
+ return -1;
|
|
+
|
|
+ if (tcProps &&
|
|
+ qemuBuildObjectCommandlineFromJSON(cmd, tcProps) < 0)
|
|
+ return -1;
|
|
+
|
|
+ if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (isEGM) {
|
|
+ g_autofree char *egmObjStr = NULL;
|
|
+ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
|
|
+
|
|
+ virBufferAsprintf(&buf, "acpi-egm-memory,id=%s", mem->info.alias);
|
|
+
|
|
+ if (mem->target.egm.pciDev)
|
|
+ virBufferAsprintf(&buf, ",pci-dev=%s", mem->target.egm.pciDev);
|
|
+
|
|
+ if (mem->targetNode >= 0)
|
|
+ virBufferAsprintf(&buf, ",node=%d", mem->targetNode);
|
|
+
|
|
+ egmObjStr = virBufferContentAndReset(&buf);
|
|
+
|
|
+ virCommandAddArgList(cmd, "-object", egmObjStr, NULL);
|
|
+ }
|
|
|
|
return 0;
|
|
}
|
|
@@ -3675,6 +3746,7 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg,
|
|
dynamicMemslots = mem->target.virtio_mem.dynamicMemslots;
|
|
break;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
@@ -7193,6 +7265,7 @@ qemuAppendDomainMemoryMachineParams(virBuffer *buf,
|
|
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
@@ -7910,6 +7983,8 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
|
|
size_t ncells = virDomainNumaGetNodeCount(def->numa);
|
|
ssize_t masterInitiator = -1;
|
|
int rc;
|
|
+ g_autoptr(GHashTable) egmBackends = NULL;
|
|
+ size_t egmBackendCount = 0;
|
|
|
|
if (!virDomainNumatuneNodesetIsAvailable(def->numa, priv->autoNodeset))
|
|
goto cleanup;
|
|
@@ -7924,6 +7999,37 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
|
|
hmat = true;
|
|
}
|
|
|
|
+ /* Pre-scan EGM devices to group by path and calculate total sizes */
|
|
+ egmBackends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
|
|
+ (GDestroyNotify)qemuEGMBackendInfoFree);
|
|
+
|
|
+ for (i = 0; i < def->nmems; i++) {
|
|
+ if (def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_EGM) {
|
|
+ const char *egmPath = def->mems[i]->source.egm.path;
|
|
+ qemuEGMBackendInfo *info = g_hash_table_lookup(egmBackends, egmPath);
|
|
+
|
|
+ if (!info) {
|
|
+ info = g_new0(qemuEGMBackendInfo, 1);
|
|
+ info->alias = g_strdup_printf("memegm%zu", egmBackendCount);
|
|
+ egmBackendCount++;
|
|
+ info->totalSize = def->mems[i]->size;
|
|
+ info->created = false;
|
|
+ info->firstMem = def->mems[i];
|
|
+ g_hash_table_insert(egmBackends, g_strdup(egmPath), info);
|
|
+ } else {
|
|
+ info->totalSize += def->mems[i]->size;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Build the actual backend and device objects */
|
|
+ for (i = 0; i < def->nmems; i++) {
|
|
+ if (def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_EGM) {
|
|
+ if (qemuBuildMemoryDimmBackendStr(cmd, def->mems[i], def, cfg, priv, egmBackends) < 0)
|
|
+ goto cleanup;
|
|
+ }
|
|
+ }
|
|
+
|
|
nodeBackends = g_new0(virJSONValue *, ncells);
|
|
nodemask = g_new0(virBitmap *, ncells);
|
|
|
|
@@ -7959,8 +8065,18 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
|
|
for (i = 0; i < ncells; i++) {
|
|
ssize_t initiator = virDomainNumaGetNodeInitiator(def->numa, i);
|
|
unsigned long long memSize = virDomainNumaGetNodeMemorySize(def->numa, i);
|
|
+ bool egmBacked = false;
|
|
+ size_t k;
|
|
|
|
- if (needBackend && memSize > 0) {
|
|
+ for (k = 0; k < def->nmems; k++) {
|
|
+ if (def->mems[k]->model == VIR_DOMAIN_MEMORY_MODEL_EGM &&
|
|
+ def->mems[k]->targetNode == (int)i) {
|
|
+ egmBacked = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (needBackend && memSize > 0 && !egmBacked) {
|
|
g_autoptr(virJSONValue) tcProps = NULL;
|
|
|
|
if (qemuBuildThreadContextProps(&tcProps, &nodeBackends[i],
|
|
@@ -7990,7 +8106,15 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg,
|
|
|
|
if (memSize > 0) {
|
|
if (needBackend) {
|
|
- virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
|
|
+ if (egmBacked) {
|
|
+ /* Look up the actual backend alias for EGM */
|
|
+ const char *egmPath = def->mems[k]->source.egm.path;
|
|
+ qemuEGMBackendInfo *egmInfo = g_hash_table_lookup(egmBackends, egmPath);
|
|
+ const char *backendAlias = egmInfo ? egmInfo->alias : def->mems[k]->info.alias;
|
|
+ virBufferAsprintf(&buf, ",memdev=%s", backendAlias);
|
|
+ } else {
|
|
+ virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
|
|
+ }
|
|
} else {
|
|
virBufferAsprintf(&buf, ",mem=%llu", memSize / 1024);
|
|
}
|
|
@@ -8054,7 +8178,10 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd,
|
|
for (i = 0; i < def->nmems; i++) {
|
|
g_autoptr(virJSONValue) props = NULL;
|
|
|
|
- if (qemuBuildMemoryDimmBackendStr(cmd, def->mems[i], def, cfg, priv) < 0)
|
|
+ if (def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_EGM)
|
|
+ continue;
|
|
+
|
|
+ if (qemuBuildMemoryDimmBackendStr(cmd, def->mems[i], def, cfg, priv, NULL) < 0)
|
|
return -1;
|
|
|
|
switch (def->mems[i]->model) {
|
|
@@ -8074,6 +8201,9 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd,
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
break;
|
|
|
|
+ /* EGM memory backing is via memory-backend-file object */
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ break;
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|
index 495cbd4f7d..c5e3d09360 100644
|
|
--- a/src/qemu/qemu_domain.c
|
|
+++ b/src/qemu/qemu_domain.c
|
|
@@ -7266,6 +7266,7 @@ qemuDomainUpdateMemoryDeviceInfo(virDomainObj *vm,
|
|
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;
|
|
@@ -7500,7 +7501,8 @@ qemuDomainAlignMemorySizes(virDomainDef *def)
|
|
def->mems[i]->size = VIR_ROUND_UP(def->mems[i]->size, align);
|
|
}
|
|
|
|
- hotplugmem += def->mems[i]->size;
|
|
+ if (def->mems[i]->model != VIR_DOMAIN_MEMORY_MODEL_EGM)
|
|
+ hotplugmem += def->mems[i]->size;
|
|
|
|
if (def->mems[i]->size > maxmemkb) {
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
@@ -7988,6 +7990,12 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem,
|
|
virDomainMemoryModelTypeToString(mem->model));
|
|
return -1;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
+ _("hotplug is not supported for the %1$s device"),
|
|
+ virDomainMemoryModelTypeToString(mem->model));
|
|
+ return -1;
|
|
+
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
return -1;
|
|
@@ -8046,6 +8054,7 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
break;
|
|
@@ -8093,6 +8102,8 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
|
|
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
/* sgx epc memory does not support hotplug, skip this check */
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ /* egm memory does not support hotplug, skip this check */
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
break;
|
|
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
|
|
index 7233df888c..97e533bf9a 100644
|
|
--- a/src/qemu/qemu_domain_address.c
|
|
+++ b/src/qemu/qemu_domain_address.c
|
|
@@ -3124,6 +3124,7 @@ qemuDomainAssignMemoryDeviceSlot(virDomainObj *vm,
|
|
return qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev);
|
|
|
|
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;
|
|
@@ -3151,6 +3152,7 @@ qemuDomainReleaseMemoryDeviceSlot(virDomainObj *vm,
|
|
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;
|
|
@@ -3185,6 +3187,7 @@ qemuDomainAssignMemorySlots(virDomainDef *def)
|
|
/* handled in qemuDomainAssignPCIAddresses() */
|
|
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;
|
|
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
index 5e63614b4a..247c98d84e 100644
|
|
--- a/src/qemu/qemu_driver.c
|
|
+++ b/src/qemu/qemu_driver.c
|
|
@@ -6712,6 +6712,7 @@ qemuDomainAttachMemoryConfig(virDomainDef *vmdef,
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
break;
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|
index 8944062aa4..de47702bc5 100644
|
|
--- a/src/qemu/qemu_hotplug.c
|
|
+++ b/src/qemu/qemu_hotplug.c
|
|
@@ -7417,6 +7417,7 @@ qemuDomainChangeMemoryLiveValidateChange(const virDomainMemoryDef *oldDef,
|
|
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
_("cannot modify memory of model '%1$s'"),
|
|
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
|
|
index 45f690d9e2..2bf9bb885e 100644
|
|
--- a/src/qemu/qemu_monitor_json.c
|
|
+++ b/src/qemu/qemu_monitor_json.c
|
|
@@ -7285,6 +7285,7 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
|
|
switch ((virDomainMemoryModel) model) {
|
|
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
/* While 'id' attribute is marked as optional in QEMU's QAPI
|
|
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
|
|
index 840d6a1174..c74824322a 100644
|
|
--- a/src/qemu/qemu_postparse.c
|
|
+++ b/src/qemu/qemu_postparse.c
|
|
@@ -1839,6 +1839,7 @@ qemuDomainDefNumaAutoAdd(virDomainDef *def,
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
}
|
|
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
index 10a4a70f1c..8132f13791 100644
|
|
--- a/src/qemu/qemu_process.c
|
|
+++ b/src/qemu/qemu_process.c
|
|
@@ -4158,6 +4158,7 @@ qemuProcessDomainMemoryDefNeedHugepagesPath(const virDomainMemoryDef *mem,
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
|
|
pagesize = mem->source.virtio_mem.pagesize;
|
|
break;
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
@@ -4247,6 +4248,7 @@ qemuProcessNeedMemoryBackingPath(virDomainDef *def,
|
|
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
/* Backed by user provided path. Not stored in memory
|
|
* backing dir anyway. */
|
|
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
|
|
index c39d8c869f..e03da3e27e 100644
|
|
--- a/src/qemu/qemu_validate.c
|
|
+++ b/src/qemu/qemu_validate.c
|
|
@@ -5892,6 +5892,12 @@ qemuValidateDomainDeviceDefMemory(const virDomainMemoryDef *mem,
|
|
|
|
break;
|
|
|
|
+ case VIR_DOMAIN_MEMORY_MODEL_EGM:
|
|
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ACPI_EGM_MEMORY)) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("ACPI EGM memory device is not supported with this QEMU binary"));
|
|
+ return -1;
|
|
+ }
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
break;
|
|
--
|
|
2.54.0
|