]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: add dma_translation attribute to iommu
authorSandesh Patel <sandesh.patel@nutanix.com>
Wed, 7 Aug 2024 07:37:50 +0000 (07:37 +0000)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 9 Aug 2024 08:05:56 +0000 (10:05 +0200)
Add dma_translation attribute to iommu to enable/disable dma traslation
for intel-iommu

Signed-off-by: Sandesh Patel <sandesh.patel@nutanix.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
docs/formatdomain.rst
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/schemas/domaincommon.rng
src/qemu/qemu_validate.c
tests/qemuxmlconfdata/intel-iommu-dma-translation.x86_64-latest.args [new file with mode: 0644]
tests/qemuxmlconfdata/intel-iommu-dma-translation.x86_64-latest.xml [new symlink]
tests/qemuxmlconfdata/intel-iommu-dma-translation.xml [new file with mode: 0644]
tests/qemuxmlconftest.c

index c56b739b235f9bbe3c4533724fcb74709438d5b4..e1e219bcb5c51a1161273eb19ace3443f3fc2964 100644 (file)
@@ -8611,6 +8611,13 @@ Example:
       mapping larger iova addresses in the guest. :since:`Since 6.5.0` (QEMU/KVM
       only)
 
+   ``dma_translation``
+      The ``dma_translation`` attribute with possible values ``on`` and ``off`` can
+      be used to turn off the dma translation for IOMMU. It is useful when only
+      interrupt remapping is required but dma translation overhead is unwanted, for
+      example to efficiently enable more than 255 vCPUs.
+      :since:`Since 10.7.0` (QEMU/KVM only)
+
 The ``virtio`` IOMMU devices can further have ``address`` element as described
 in `Device addresses`_ (address has to by type of ``pci``).
 
index 86b563fbfb78bc63f9f3ca4e7891b9b2cdf4af03..d950921667a2afca4d6a13a36f4f2ee195361c0e 100644 (file)
@@ -13931,6 +13931,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt,
         if (virXMLPropUInt(driver, "aw_bits", 10, VIR_XML_PROP_NONE,
                            &iommu->aw_bits) < 0)
             return NULL;
+
+        if (virXMLPropTristateSwitch(driver, "dma_translation", VIR_XML_PROP_NONE,
+                                     &iommu->dma_translation) < 0)
+            return NULL;
     }
 
     if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt,
@@ -21467,6 +21471,13 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src,
                        dst->aw_bits, src->aw_bits);
         return false;
     }
+    if (src->dma_translation != dst->dma_translation) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain IOMMU device dma translation '%1$s' does not match source '%2$s'"),
+                       virTristateSwitchTypeToString(dst->dma_translation),
+                       virTristateSwitchTypeToString(src->dma_translation));
+        return false;
+    }
 
     return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
 }
@@ -27451,6 +27462,10 @@ virDomainIOMMUDefFormat(virBuffer *buf,
         virBufferAsprintf(&driverAttrBuf, " aw_bits='%d'",
                           iommu->aw_bits);
     }
+    if (iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT) {
+        virBufferAsprintf(&driverAttrBuf, " dma_translation='%s'",
+                          virTristateSwitchTypeToString(iommu->dma_translation));
+    }
 
     virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
 
index 95ddf5470e5d258506a32d95b9dc1dc6c66fe28b..eae621f900b98f86d4c0c34e6f751aa5a7e8ca16 100644 (file)
@@ -2928,6 +2928,7 @@ struct _virDomainIOMMUDef {
     virTristateSwitch iotlb;
     unsigned int aw_bits;
     virDomainDeviceInfo info;
+    virTristateSwitch dma_translation;
 };
 
 typedef enum {
index 7d58dce46544f48d40c2508f7f0ec3837567bedc..05ba697924701ee5d2ed8bee4293daac477e2f35 100644 (file)
                 <ref name="uint8"/>
               </attribute>
             </optional>
+            <optional>
+              <attribute name="dma_translation">
+                <ref name="virOnOff"/>
+              </attribute>
+            </optional>
           </element>
         </optional>
         <optional>
index 0e8f0f977f848fc4e8ed988dc354927a3fec9fc0..b885fe7c773a78d3d8ff40fed2f9ffc515163ef1 100644 (file)
@@ -5094,6 +5094,12 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu,
                        _("iommu: aw_bits is not supported with this QEMU binary"));
         return -1;
     }
+    if (iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT &&
+        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION))  {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("iommu: updating dma translation is not supported with this QEMU binary"));
+        return -1;
+    }
 
     return 0;
 }
diff --git a/tests/qemuxmlconfdata/intel-iommu-dma-translation.x86_64-latest.args b/tests/qemuxmlconfdata/intel-iommu-dma-translation.x86_64-latest.args
new file mode 100644 (file)
index 0000000..41f30d7
--- /dev/null
@@ -0,0 +1,34 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-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 q35,usb=off,kernel_irqchip=split,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel kvm \
+-cpu qemu64 \
+-m size=219136k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"intel-iommu","id":"iommu0","intremap":"on"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-global ICH9-LPC.noreboot=off \
+-watchdog-action reset \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/intel-iommu-dma-translation.x86_64-latest.xml b/tests/qemuxmlconfdata/intel-iommu-dma-translation.x86_64-latest.xml
new file mode 120000 (symlink)
index 0000000..a35a254
--- /dev/null
@@ -0,0 +1 @@
+intel-iommu-dma-translation.xml
\ No newline at end of file
diff --git a/tests/qemuxmlconfdata/intel-iommu-dma-translation.xml b/tests/qemuxmlconfdata/intel-iommu-dma-translation.xml
new file mode 100644 (file)
index 0000000..9b4debc
--- /dev/null
@@ -0,0 +1,37 @@
+<domain type='kvm'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='q35'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <ioapic driver='qemu'/>
+  </features>
+  <cpu mode='custom' match='exact' check='none'>
+    <model fallback='forbid'>qemu64</model>
+  </cpu>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <controller type='usb' index='0' model='none'/>
+    <controller type='sata' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+    </controller>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <audio id='1' type='none'/>
+    <watchdog model='itco' action='reset'/>
+    <memballoon model='none'/>
+    <iommu model='intel'>
+      <driver intremap='on' dma_translation='off'/>
+    </iommu>
+  </devices>
+</domain>
index 8aa8efea13417676e632cb8775b5d4299a2f2e33..7e47c781504f54b04057cca6121276b46f8995d1 100644 (file)
@@ -2729,6 +2729,7 @@ mymain(void)
     DO_TEST_CAPS_LATEST("intel-iommu-eim");
     DO_TEST_CAPS_LATEST("intel-iommu-device-iotlb");
     DO_TEST_CAPS_LATEST("intel-iommu-aw-bits");
+    DO_TEST_CAPS_LATEST("intel-iommu-dma-translation");
     DO_TEST_CAPS_LATEST_PARSE_ERROR("intel-iommu-wrong-machine");
     DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64");
     DO_TEST_CAPS_LATEST("virtio-iommu-x86_64");