]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: Introduce virtio options for virtio memory models
authorMichal Privoznik <mprivozn@redhat.com>
Mon, 27 Oct 2025 10:38:57 +0000 (11:38 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 29 Oct 2025 11:09:28 +0000 (12:09 +0100)
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>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/domain_validate.c
src/conf/schemas/domaincommon.rng
tests/qemuxmlconfdata/virtio-options.x86_64-latest.args
tests/qemuxmlconfdata/virtio-options.xml

index d430101dce4b9532196cfafb987f507de59e0473..c09f026a1c20f27eee532c15f168679cde4b4475 100644 (file)
@@ -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);
index a279fdd43cca6bee9b14088d4904cf0913125dc9..b265bf224b54514cfcb1553ef41a8a6a54b35368 100644 (file)
@@ -2801,6 +2801,7 @@ struct _virDomainMemoryDef {
     } target;
 
     virDomainDeviceInfo info;
+    virDomainVirtioOptions *virtio;
 };
 
 virDomainMemoryDef *virDomainMemoryDefNew(virDomainMemoryModel model);
index eea9b38b21ae2527a3262f55d8e41914c0aab168..17955decc02edaed8a59ed3b4dcfc96ed1acb033 100644 (file)
@@ -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;
 }
 
index ace74fee0830c8f5a3c9680de427ab98bc75d6fe..110f6cbc69a9f8cced903a3fb1c51e6f4e1968af 100644 (file)
             <ref name="UUID"/>
           </element>
         </optional>
+        <optional>
+          <element name="driver">
+            <ref name="virtioOptions"/>
+          </element>
+        </optional>
         <optional>
           <ref name="memorydev-source"/>
         </optional>
index 03b3dd969161609695bb23d6c8ad061db0137fac..f2b9ee2afe74fc718659cd2b6c1bf76facae8673 100644 (file)
@@ -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 \
index 486bc453a1296bce0272ecad8503517b2f42c953..05eaae35a94af2a834d4fbb065a7fefb659aaf2f 100644 (file)
@@ -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>
       <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>