[PATCH 0/7] conf: Introduce virtio options for virtio memory models
*** BLURB HERE *** Michal Prívozník (7): domain_conf: Make virDomainMemoryDefFormat() return void domain_cof: Switch to virXMLFormatElement() in virDomainMemoryDefFormat() conf: Introduce virDomainMemoryIsVirtioModel() qemu: Use virDomainMemoryIsVirtioModel() conf: Introduce virtio options for virtio memory models qemu_command: Generate virtio options for memory device NEWS: Document virtio options for memory models NEWS.rst | 6 ++ src/conf/domain_conf.c | 64 +++++++++++++------ src/conf/domain_conf.h | 2 + src/conf/domain_validate.c | 5 ++ src/conf/schemas/domaincommon.rng | 5 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 2 + src/qemu/qemu_domain_address.c | 44 +++---------- .../virtio-options.x86_64-latest.args | 9 ++- tests/qemuxmlconfdata/virtio-options.xml | 23 ++++++- 10 files changed, 102 insertions(+), 59 deletions(-) -- 2.51.0
From: Michal Privoznik <mprivozn@redhat.com> The only thing that's possibly making virDomainMemoryDefFormat() fail is call to virDomainMemorySourceDefFormat() but that always returns zero. Make both functions return void so callers are not confused. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0223fc1d88..0a647a1b44 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26472,7 +26472,7 @@ virDomainCryptoDefFree(virDomainCryptoDef *def) } -static int +static void virDomainMemorySourceDefFormat(virBuffer *buf, virDomainMemoryDef *def) { @@ -26532,8 +26532,6 @@ virDomainMemorySourceDefFormat(virBuffer *buf, } virXMLFormatElement(buf, "source", NULL, &childBuf); - - return 0; } @@ -26600,7 +26598,7 @@ virDomainMemoryTargetDefFormat(virBuffer *buf, virXMLFormatElement(buf, "target", &attrBuf, &childBuf); } -static int +static void virDomainMemoryDefFormat(virBuffer *buf, virDomainMemoryDef *def, unsigned int flags) @@ -26625,8 +26623,7 @@ virDomainMemoryDefFormat(virBuffer *buf, virBufferAsprintf(buf, "<uuid>%s</uuid>\n", uuidstr); } - if (virDomainMemorySourceDefFormat(buf, def) < 0) - return -1; + virDomainMemorySourceDefFormat(buf, def); virDomainMemoryTargetDefFormat(buf, def, flags); @@ -26634,7 +26631,6 @@ virDomainMemoryDefFormat(virBuffer *buf, virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</memory>\n"); - return 0; } static void @@ -29462,8 +29458,7 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def, virDomainShmemDefFormat(buf, def->shmems[n], flags); for (n = 0; n < def->nmems; n++) { - if (virDomainMemoryDefFormat(buf, def->mems[n], flags) < 0) - return -1; + virDomainMemoryDefFormat(buf, def->mems[n], flags); } for (n = 0; n < def->ncryptos; n++) { -- 2.51.0
On Wed, Oct 29, 2025 at 08:53:01 +0100, Michal Privoznik wrote:
From: Michal Privoznik <mprivozn@redhat.com>
The only thing that's possibly making virDomainMemoryDefFormat() fail is call to virDomainMemorySourceDefFormat() but that always returns zero. Make both functions return void so callers are not confused.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com> SSIA Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0a647a1b44..0d32bcad47 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26604,33 +26604,32 @@ virDomainMemoryDefFormat(virBuffer *buf, unsigned int flags) { const char *model = virDomainMemoryModelTypeToString(def->model); + g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf); - virBufferAsprintf(buf, "<memory model='%s'", model); + virBufferAsprintf(&attrBuf, " model='%s'", model); if (def->access) - virBufferAsprintf(buf, " access='%s'", + virBufferAsprintf(&attrBuf, " access='%s'", virDomainMemoryAccessTypeToString(def->access)); if (def->discard) - virBufferAsprintf(buf, " discard='%s'", + virBufferAsprintf(&attrBuf, " discard='%s'", virTristateBoolTypeToString(def->discard)); - virBufferAddLit(buf, ">\n"); - virBufferAdjustIndent(buf, 2); if (def->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM && def->target.nvdimm.uuid) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(def->target.nvdimm.uuid, uuidstr); - virBufferAsprintf(buf, "<uuid>%s</uuid>\n", uuidstr); + virBufferAsprintf(&childBuf, "<uuid>%s</uuid>\n", uuidstr); } - virDomainMemorySourceDefFormat(buf, def); + virDomainMemorySourceDefFormat(&childBuf, def); - virDomainMemoryTargetDefFormat(buf, def, flags); + virDomainMemoryTargetDefFormat(&childBuf, def, flags); - virDomainDeviceInfoFormat(buf, &def->info, flags); + virDomainDeviceInfoFormat(&childBuf, &def->info, flags); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</memory>\n"); + virXMLFormatElement(buf, "memory", &attrBuf, &childBuf); } static void -- 2.51.0
On Wed, Oct 29, 2025 at 08:53:02 +0100, Michal Privoznik wrote:
From: Michal Privoznik <mprivozn@redhat.com>
SSIA
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
On a Wednesday in 2025, Michal Privoznik via Devel wrote:
From: Michal Privoznik <mprivozn@redhat.com>
SSIA
Instead of obscure acronyms, just leave the commit message blank Also, s/cof/conf/ in the summary Or s/domain_cof/conf/ Jano
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
From: Michal Privoznik <mprivozn@redhat.com> The aim is to return true for memory models that are virtio devices (virtio-mem and virtio-pmem) and false for everything else. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 20 ++++++++++++++++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + 3 files changed, 22 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0d32bcad47..d430101dce 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14333,6 +14333,26 @@ virDomainMemoryDefNew(virDomainMemoryModel model) } +bool +virDomainMemoryIsVirtioModel(const virDomainMemoryDef *def) +{ + switch (def->model) { + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + return true; + + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + break; + } + + return false; +} + + static virDomainMemoryDef * virDomainMemoryDefParseXML(virDomainXMLOption *xmlopt, xmlNodePtr memdevNode, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a63d922853..a279fdd43c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2806,6 +2806,7 @@ struct _virDomainMemoryDef { virDomainMemoryDef *virDomainMemoryDefNew(virDomainMemoryModel model); void virDomainMemoryDefFree(virDomainMemoryDef *def); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainMemoryDef, virDomainMemoryDefFree); +bool virDomainMemoryIsVirtioModel(const virDomainMemoryDef *def); typedef enum { diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 26776dff2a..7269dd3786 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -529,6 +529,7 @@ virDomainMemoryFindByDeviceAlias; virDomainMemoryFindByDeviceInfo; virDomainMemoryFindInactiveByDef; virDomainMemoryInsert; +virDomainMemoryIsVirtioModel; virDomainMemoryModelTypeFromString; virDomainMemoryModelTypeToString; virDomainMemoryRemove; -- 2.51.0
On Wed, Oct 29, 2025 at 08:53:03 +0100, Michal Privoznik wrote:
From: Michal Privoznik <mprivozn@redhat.com>
The aim is to return true for memory models that are virtio devices (virtio-mem and virtio-pmem) and false for everything else.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 20 ++++++++++++++++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + 3 files changed, 22 insertions(+)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com> Instead of having these big switch()-es that enumerate all memory models (but act only on virtio models), let's use virDomainMemoryIsVirtioModel() helper instead. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_domain_address.c | 44 +++++++--------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 774541ca06..6d5c4785e8 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -293,18 +293,9 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDef *def, } for (i = 0; i < def->nmems; i++) { - switch (def->mems[i]->model) { - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: - if (def->mems[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) - def->mems[i]->info.type = type; - break; - case VIR_DOMAIN_MEMORY_MODEL_NONE: - case VIR_DOMAIN_MEMORY_MODEL_DIMM: - case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: - case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: - case VIR_DOMAIN_MEMORY_MODEL_LAST: - break; + if (virDomainMemoryIsVirtioModel(def->mems[i]) && + def->mems[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + def->mems[i]->info.type = type; } } @@ -1024,18 +1015,10 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, break; case VIR_DOMAIN_DEVICE_MEMORY: - switch (dev->data.memory->model) { - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + if (virDomainMemoryIsVirtioModel(dev->data.memory)) return virtioFlags; - case VIR_DOMAIN_MEMORY_MODEL_NONE: - case VIR_DOMAIN_MEMORY_MODEL_DIMM: - case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: - case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: - case VIR_DOMAIN_MEMORY_MODEL_LAST: - return 0; - } + return 0; break; case VIR_DOMAIN_DEVICE_CRYPTO: @@ -2444,19 +2427,10 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, for (i = 0; i < def->nmems; i++) { virDomainMemoryDef *mem = def->mems[i]; - switch (mem->model) { - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: - if (virDeviceInfoPCIAddressIsWanted(&mem->info) && - qemuDomainPCIAddressReserveNextAddr(addrs, &mem->info) < 0) - return -1; - break; - case VIR_DOMAIN_MEMORY_MODEL_NONE: - case VIR_DOMAIN_MEMORY_MODEL_DIMM: - case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: - case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: - case VIR_DOMAIN_MEMORY_MODEL_LAST: - break; + if (virDomainMemoryIsVirtioModel(mem) && + virDeviceInfoPCIAddressIsWanted(&mem->info) && + qemuDomainPCIAddressReserveNextAddr(addrs, &mem->info) < 0) { + return -1; } } -- 2.51.0
On Wed, Oct 29, 2025 at 08:53:04 +0100, Michal Privoznik wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Instead of having these big switch()-es that enumerate all memory models (but act only on virtio models), let's use virDomainMemoryIsVirtioModel() helper instead.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_domain_address.c | 44 +++++++--------------------------- 1 file changed, 9 insertions(+), 35 deletions(-)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com> Both virtio-mem and virtio-pmem memory models are virtio devices and as such support setting various virtio knobs (iommu, ats, packed, page_per_vq) common to other virtio devices. Introduce <driver/> element as a child to <memory/> element, just like we do for other virtio devices, where aforementioned knobs live. NB, this is without docs changes, since we do not document which virtio devices support these knobs and each one is already documented. Also, the virtio-options.xml test needed some additional adjustment (apart from adding virtio-mem device) to enable memory hotplug. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 12 ++++++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 5 ++++ src/conf/schemas/domaincommon.rng | 5 ++++ .../virtio-options.x86_64-latest.args | 9 +++++--- tests/qemuxmlconfdata/virtio-options.xml | 23 +++++++++++++++++-- 6 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d430101dce..c09f026a1c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14413,6 +14413,10 @@ virDomainMemoryDefParseXML(virDomainXMLOption *xmlopt, &def->info, flags) < 0) return NULL; + if (virDomainVirtioOptionsParseXML(virXPathNode("./driver", ctxt), + &def->virtio) < 0) + return NULL; + return g_steal_pointer(&def); } @@ -22073,6 +22077,9 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDef *src, break; } + if (!virDomainVirtioOptionsCheckABIStability(src->virtio, dst->virtio)) + return false; + return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); } @@ -26626,6 +26633,7 @@ virDomainMemoryDefFormat(virBuffer *buf, const char *model = virDomainMemoryModelTypeToString(def->model); g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf); + g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER; virBufferAsprintf(&attrBuf, " model='%s'", model); if (def->access) @@ -26643,6 +26651,10 @@ virDomainMemoryDefFormat(virBuffer *buf, virBufferAsprintf(&childBuf, "<uuid>%s</uuid>\n", uuidstr); } + virDomainVirtioOptionsFormat(&driverAttrBuf, def->virtio); + + virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL); + virDomainMemorySourceDefFormat(&childBuf, def); virDomainMemoryTargetDefFormat(&childBuf, def, flags); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a279fdd43c..b265bf224b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2801,6 +2801,7 @@ struct _virDomainMemoryDef { } target; virDomainDeviceInfo info; + virDomainVirtioOptions *virtio; }; virDomainMemoryDef *virDomainMemoryDefNew(virDomainMemoryModel model); diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index eea9b38b21..17955decc0 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -2723,6 +2723,11 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem, if (virDomainMemoryDefCheckConflict(mem, def) < 0) return -1; + if (!virDomainMemoryIsVirtioModel(mem) && + virDomainCheckVirtioOptionsAreAbsent(mem->virtio) < 0) { + return -1; + } + return 0; } diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index ace74fee08..110f6cbc69 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -7502,6 +7502,11 @@ <ref name="UUID"/> </element> </optional> + <optional> + <element name="driver"> + <ref name="virtioOptions"/> + </element> + </optional> <optional> <ref name="memorydev-source"/> </optional> diff --git a/tests/qemuxmlconfdata/virtio-options.x86_64-latest.args b/tests/qemuxmlconfdata/virtio-options.x86_64-latest.args index 03b3dd9691..f2b9ee2afe 100644 --- a/tests/qemuxmlconfdata/virtio-options.x86_64-latest.args +++ b/tests/qemuxmlconfdata/virtio-options.x86_64-latest.args @@ -10,13 +10,14 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -name guest=QEMUGuest1,debug-threads=on \ -S \ -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ --machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ +-machine pc,usb=off,dump-guest-core=off,acpi=off \ -accel tcg \ -cpu qemu64 \ --m size=219136k \ --object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ +-m size=2316288k,maxmem=1099511627776k \ -overcommit mem-lock=off \ -smp 1,sockets=1,cores=1,threads=1 \ +-object '{"qom-type":"memory-backend-ram","id":"ram-node0","size":2371878912}' \ +-numa node,nodeid=0,cpus=0,memdev=ram-node0 \ -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ -display none \ -no-user-config \ @@ -29,6 +30,8 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ -device '{"driver":"virtio-scsi-pci","iommu_platform":true,"ats":true,"packed":true,"page-per-vq":true,"id":"scsi0","bus":"pci.0","addr":"0x8"}' \ -device '{"driver":"virtio-serial-pci","iommu_platform":true,"ats":true,"packed":true,"page-per-vq":true,"id":"virtio-serial0","bus":"pci.0","addr":"0x9"}' \ +-object '{"qom-type":"memory-backend-file","id":"memvirtiomem0","mem-path":"/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1","reserve":false,"size":2147483648,"host-nodes":[1,2,3],"policy":"bind"}' \ +-device '{"driver":"virtio-mem-pci","node":0,"block-size":2097152,"requested-size":1073741824,"memdev":"memvirtiomem0","prealloc":true,"memaddr":5637144576,"dynamic-memslots":true,"id":"virtiomem0","bus":"pci.0","addr":"0x5"}' \ -blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/img1","node-name":"libvirt-1-storage","read-only":false}' \ -device '{"driver":"virtio-blk-pci","iommu_platform":true,"ats":true,"packed":true,"page-per-vq":true,"bus":"pci.0","addr":"0xa","drive":"libvirt-1-storage","id":"virtio-disk0","bootindex":1}' \ -fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/fs1 \ diff --git a/tests/qemuxmlconfdata/virtio-options.xml b/tests/qemuxmlconfdata/virtio-options.xml index 486bc453a1..05eaae35a9 100644 --- a/tests/qemuxmlconfdata/virtio-options.xml +++ b/tests/qemuxmlconfdata/virtio-options.xml @@ -1,8 +1,9 @@ <domain type='qemu'> <name>QEMUGuest1</name> <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> - <memory unit='KiB'>219136</memory> - <currentMemory unit='KiB'>219136</currentMemory> + <maxMemory unit='KiB'>1099511627776</maxMemory> + <memory unit='KiB'>2316288</memory> + <currentMemory unit='KiB'>2316288</currentMemory> <vcpu placement='static'>1</vcpu> <os> <type arch='x86_64' machine='pc'>hvm</type> @@ -10,6 +11,9 @@ </os> <cpu mode='custom' match='exact' check='none'> <model fallback='forbid'>qemu64</model> + <numa> + <cell id='0' cpus='0' memory='2316288' unit='KiB'/> + </numa> </cpu> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> @@ -92,5 +96,20 @@ <driver iommu='on' ats='on' packed='on' page_per_vq='on'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> </rng> + <memory model='virtio-mem'> + <driver iommu='on' ats='on' packed='on' page_per_vq='on'/> + <source> + <nodemask>1-3</nodemask> + <pagesize unit='KiB'>2048</pagesize> + </source> + <target dynamicMemslots='yes'> + <size unit='KiB'>2097152</size> + <node>0</node> + <block unit='KiB'>2048</block> + <requested unit='KiB'>1048576</requested> + <address base='0x150000000'/> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </memory> </devices> </domain> -- 2.51.0
On Wed, Oct 29, 2025 at 08:53:05 +0100, Michal Privoznik wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Both virtio-mem and virtio-pmem memory models are virtio devices and as such support setting various virtio knobs (iommu, ats, packed, page_per_vq) common to other virtio devices.
Introduce <driver/> element as a child to <memory/> element, just like we do for other virtio devices, where aforementioned knobs live.
NB, this is without docs changes, since we do not document which virtio devices support these knobs and each one is already documented.
Also, the virtio-options.xml test needed some additional adjustment (apart from adding virtio-mem device) to enable memory hotplug.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 12 ++++++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 5 ++++ src/conf/schemas/domaincommon.rng | 5 ++++ .../virtio-options.x86_64-latest.args | 9 +++++--- tests/qemuxmlconfdata/virtio-options.xml | 23 +++++++++++++++++-- 6 files changed, 50 insertions(+), 5 deletions(-)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com> Thanks to previous refactors (namely v11.1.0-rc1~142) this is trivial. There's all the infrastructure needed to generate virtio options onto cmd line, all that's left to do is set a pointer to appropriate struct member. Resolves: https://issues.redhat.com/browse/RHEL-7493 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 2 ++ tests/qemuxmlconfdata/virtio-options.x86_64-latest.args | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fcf5fc1935..c538a9fb2f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -983,9 +983,11 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device, switch (device->data.memory->model) { case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: *baseName = "virtio-pmem"; + *virtioOptions = device->data.memory->virtio; break; case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: *baseName = "virtio-mem"; + *virtioOptions = device->data.memory->virtio; break; case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: diff --git a/tests/qemuxmlconfdata/virtio-options.x86_64-latest.args b/tests/qemuxmlconfdata/virtio-options.x86_64-latest.args index f2b9ee2afe..0f65cefd57 100644 --- a/tests/qemuxmlconfdata/virtio-options.x86_64-latest.args +++ b/tests/qemuxmlconfdata/virtio-options.x86_64-latest.args @@ -31,7 +31,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"virtio-scsi-pci","iommu_platform":true,"ats":true,"packed":true,"page-per-vq":true,"id":"scsi0","bus":"pci.0","addr":"0x8"}' \ -device '{"driver":"virtio-serial-pci","iommu_platform":true,"ats":true,"packed":true,"page-per-vq":true,"id":"virtio-serial0","bus":"pci.0","addr":"0x9"}' \ -object '{"qom-type":"memory-backend-file","id":"memvirtiomem0","mem-path":"/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1","reserve":false,"size":2147483648,"host-nodes":[1,2,3],"policy":"bind"}' \ --device '{"driver":"virtio-mem-pci","node":0,"block-size":2097152,"requested-size":1073741824,"memdev":"memvirtiomem0","prealloc":true,"memaddr":5637144576,"dynamic-memslots":true,"id":"virtiomem0","bus":"pci.0","addr":"0x5"}' \ +-device '{"driver":"virtio-mem-pci","iommu_platform":true,"ats":true,"packed":true,"page-per-vq":true,"node":0,"block-size":2097152,"requested-size":1073741824,"memdev":"memvirtiomem0","prealloc":true,"memaddr":5637144576,"dynamic-memslots":true,"id":"virtiomem0","bus":"pci.0","addr":"0x5"}' \ -blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/img1","node-name":"libvirt-1-storage","read-only":false}' \ -device '{"driver":"virtio-blk-pci","iommu_platform":true,"ats":true,"packed":true,"page-per-vq":true,"bus":"pci.0","addr":"0xa","drive":"libvirt-1-storage","id":"virtio-disk0","bootindex":1}' \ -fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/fs1 \ -- 2.51.0
On Wed, Oct 29, 2025 at 08:53:06 +0100, Michal Privoznik wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Thanks to previous refactors (namely v11.1.0-rc1~142) this is trivial. There's all the infrastructure needed to generate virtio options onto cmd line, all that's left to do is set a pointer to appropriate struct member.
Resolves: https://issues.redhat.com/browse/RHEL-7493 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 2 ++ tests/qemuxmlconfdata/virtio-options.x86_64-latest.args | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- NEWS.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index afdb26cebf..ee11435e0e 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -50,6 +50,12 @@ v11.9.0 (unreleased) Some Hyper-V enlightenments may require some other enlightenments to be turned on. Libvirt now validates these for new domains. + * qemu: Introduce virtio options for virtio memory models + + Both virtio-mem and virtio-pmem memory models are virtio devices and as + such now support setting various virtio knobs (iommu, ats, packed, + page_per_vq) common to other virtio devices. + * **Bug fixes** -- 2.51.0
On Wed, Oct 29, 2025 at 08:53:07 +0100, Michal Privoznik wrote:
From: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- NEWS.rst | 6 ++++++ 1 file changed, 6 insertions(+)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
participants (3)
-
Jiri Denemark -
Ján Tomko -
Michal Privoznik