]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: add IOMMU model amd
authorJán Tomko <jtomko@redhat.com>
Fri, 14 Mar 2025 16:13:09 +0000 (17:13 +0100)
committerJán Tomko <jtomko@redhat.com>
Tue, 24 Jun 2025 10:14:04 +0000 (12:14 +0200)
Introduce a new IOMMU device model 'amd', both the parser
and the formatter for QEMU because of our enum warnings.

https://issues.redhat.com/browse/RHEL-50560

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
12 files changed:
docs/formatdomain.rst
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/domain_validate.c
src/conf/schemas/domaincommon.rng
src/qemu/qemu_command.c
src/qemu/qemu_domain_address.c
src/qemu/qemu_validate.c
tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args [new file with mode: 0644]
tests/qemuxmlconfdata/amd-iommu.x86_64-latest.xml [new symlink]
tests/qemuxmlconfdata/amd-iommu.xml [new file with mode: 0644]
tests/qemuxmlconftest.c

index 0ba31cfaa693d83c819bd83ef2528ea09e5a6671..7ebb4c3e9e08c52edceaee52b383754fd49d6a33 100644 (file)
@@ -9060,8 +9060,9 @@ Example:
 
 ``model``
    Supported values are ``intel`` (for Q35 guests) ``smmuv3``
-   (:since:`since 5.5.0`, for ARM virt guests), and ``virtio``
-   (:since:`since 8.3.0`, for Q35 and ARM virt guests).
+   (:since:`since 5.5.0`, for ARM virt guests), ``virtio``
+   (:since:`since 8.3.0`, for Q35 and ARM virt guests) and
+   ``amd`` (:since:`since 11.5.0`).
 
 ``driver``
    The ``driver`` subelement can be used to configure additional options, some
index 1a6c8afb1ddde63cfdd84c4ccb063f4220d64330..12882291a6e7e017afb10155dd2ad6bdee24e682 100644 (file)
@@ -1352,6 +1352,7 @@ VIR_ENUM_IMPL(virDomainIOMMUModel,
               "intel",
               "smmuv3",
               "virtio",
+              "amd",
 );
 
 VIR_ENUM_IMPL(virDomainVsockModel,
index 3d380073cf22a47b1f663a48633242735cf69928..051037eff994ddde01b644a698fdc02cfa2c33d8 100644 (file)
@@ -3011,6 +3011,7 @@ typedef enum {
     VIR_DOMAIN_IOMMU_MODEL_INTEL,
     VIR_DOMAIN_IOMMU_MODEL_SMMUV3,
     VIR_DOMAIN_IOMMU_MODEL_VIRTIO,
+    VIR_DOMAIN_IOMMU_MODEL_AMD,
 
     VIR_DOMAIN_IOMMU_MODEL_LAST
 } virDomainIOMMUModel;
index 96f76f2f7bba964ada6c96af7bf05f4b5648dc90..b9a6740437ecf9f912900eafb76d979b4301a00f 100644 (file)
@@ -3082,6 +3082,18 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
         }
         break;
 
+    case VIR_DOMAIN_IOMMU_MODEL_AMD:
+        if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->eim != VIR_TRISTATE_SWITCH_ABSENT ||
+            iommu->aw_bits != 0 ||
+            iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("iommu model '%1$s' doesn't support some additional attributes"),
+                           virDomainIOMMUModelTypeToString(iommu->model));
+            return -1;
+        }
+        break;
+
     case VIR_DOMAIN_IOMMU_MODEL_INTEL:
     case VIR_DOMAIN_IOMMU_MODEL_LAST:
         break;
@@ -3099,6 +3111,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
         break;
 
     case VIR_DOMAIN_IOMMU_MODEL_VIRTIO:
+    case VIR_DOMAIN_IOMMU_MODEL_AMD:
     case VIR_DOMAIN_IOMMU_MODEL_LAST:
         break;
     }
index b1fe51f5190e6154d83f0c2567b1bf747682a4bf..92b9ba3cc720cd8b738ca2f74c49d1bddffe8506 100644 (file)
           <value>intel</value>
           <value>smmuv3</value>
           <value>virtio</value>
+          <value>amd</value>
         </choice>
       </attribute>
       <interleave>
index 4de60167840507a6a59483273d1e13fcbfe003be..6fae9b1f5aaa720c50fb847ad434c0df3e8d75d1 100644 (file)
@@ -6165,6 +6165,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
                           virQEMUCaps *qemuCaps)
 {
     g_autoptr(virJSONValue) props = NULL;
+    g_autoptr(virJSONValue) wrapperProps = NULL;
     const virDomainIOMMUDef *iommu = def->iommu;
 
     if (!iommu)
@@ -6209,6 +6210,32 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
         /* There is no -device for SMMUv3, so nothing to be done here */
         return 0;
 
+    case VIR_DOMAIN_IOMMU_MODEL_AMD:
+        if (virJSONValueObjectAdd(&wrapperProps,
+                                  "s:driver", "AMDVI-PCI",
+                                  "s:id", iommu->info.alias,
+                                  NULL) < 0)
+            return -1;
+
+        if (qemuBuildDeviceAddressProps(wrapperProps, def, &iommu->info) < 0)
+            return -1;
+
+        if (qemuBuildDeviceCommandlineFromJSON(cmd, wrapperProps, def, qemuCaps) < 0)
+            return -1;
+
+        if (virJSONValueObjectAdd(&props,
+                                  "s:driver", "amd-iommu",
+                                  "s:pci-id", iommu->info.alias,
+                                  "S:intremap", qemuOnOffAuto(iommu->intremap),
+                                  "T:device-iotlb", iommu->iotlb,
+                                  NULL) < 0)
+            return -1;
+
+        if (qemuBuildDeviceCommandlineFromJSON(cmd, props, def, qemuCaps) < 0)
+            return -1;
+
+        return 0;
+
     case VIR_DOMAIN_IOMMU_MODEL_LAST:
     default:
         virReportEnumRangeError(virDomainIOMMUModel, iommu->model);
@@ -7041,6 +7068,7 @@ qemuBuildMachineCommandLine(virCommand *cmd,
 
         case VIR_DOMAIN_IOMMU_MODEL_INTEL:
         case VIR_DOMAIN_IOMMU_MODEL_VIRTIO:
+        case VIR_DOMAIN_IOMMU_MODEL_AMD:
             /* These IOMMUs are formatted in qemuBuildIOMMUCommandLine */
             break;
 
index bb86cfa0c3f31b6fbbc81754d77f160f6d51dd32..bf77af62d0afe36cdc67084e1703e7f3ce6bce84 100644 (file)
@@ -945,6 +945,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev,
             case VIR_DOMAIN_IOMMU_MODEL_VIRTIO:
                 return virtioFlags | VIR_PCI_CONNECT_INTEGRATED;
 
+            case VIR_DOMAIN_IOMMU_MODEL_AMD:
+                return pciFlags | VIR_PCI_CONNECT_INTEGRATED;
+
             case VIR_DOMAIN_IOMMU_MODEL_INTEL:
             case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
             case VIR_DOMAIN_IOMMU_MODEL_LAST:
@@ -2364,6 +2367,7 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def,
 
         switch (iommu->model) {
         case VIR_DOMAIN_IOMMU_MODEL_VIRTIO:
+        case VIR_DOMAIN_IOMMU_MODEL_AMD:
             if (virDeviceInfoPCIAddressIsWanted(&iommu->info) &&
                 qemuDomainPCIAddressReserveNextAddr(addrs, &iommu->info) < 0) {
                 return -1;
index b2faf43002048f19109ddaaa27bc94528c4e4d6d..bf7079d109d891542851455a5e7e61261fca1278 100644 (file)
@@ -5314,6 +5314,28 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu,
         }
         break;
 
+    case VIR_DOMAIN_IOMMU_MODEL_AMD:
+        if (!qemuDomainIsQ35(def)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("IOMMU device: '%1$s' is only supported with Q35 machines"),
+                           virDomainIOMMUModelTypeToString(iommu->model));
+            return -1;
+        }
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_AMD_IOMMU_PCI_ID)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("IOMMU device: '%1$s' is not supported with this QEMU binary"),
+                           virDomainIOMMUModelTypeToString(iommu->model));
+            return -1;
+        }
+        if (iommu->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+            iommu->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("IOMMU device: '%1$s' needs a PCI address"),
+                           virDomainIOMMUModelTypeToString(iommu->model));
+            return -1;
+        }
+        break;
+
     case VIR_DOMAIN_IOMMU_MODEL_LAST:
     default:
         virReportEnumRangeError(virDomainIOMMUModel, iommu->model);
diff --git a/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args
new file mode 100644 (file)
index 0000000..36244ed
--- /dev/null
@@ -0,0 +1,35 @@
+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=on \
+-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":"AMDVI-PCI","id":"iommu0","bus":"pcie.0","addr":"0x1"}' \
+-device '{"driver":"amd-iommu","pci-id":"iommu0","intremap":"on","device-iotlb":true}' \
+-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/amd-iommu.x86_64-latest.xml b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.xml
new file mode 120000 (symlink)
index 0000000..5ba3d4b
--- /dev/null
@@ -0,0 +1 @@
+amd-iommu.xml
\ No newline at end of file
diff --git a/tests/qemuxmlconfdata/amd-iommu.xml b/tests/qemuxmlconfdata/amd-iommu.xml
new file mode 100644 (file)
index 0000000..0668ed4
--- /dev/null
@@ -0,0 +1,39 @@
+<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>
+    <acpi/>
+    <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='amd'>
+      <driver intremap='on' iotlb='on'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+    </iommu>
+  </devices>
+</domain>
index 3f99026a3160bce38569fe4e9c21dbfd635a3a97..f74bd2bb7a1aedcf9491df3b0b5fa47b02b13760 100644 (file)
@@ -2750,6 +2750,8 @@ mymain(void)
     DO_TEST_CAPS_LATEST("acpi-table");
     DO_TEST_CAPS_LATEST("acpi-table-many");
 
+    DO_TEST_CAPS_LATEST("amd-iommu");
+
     DO_TEST_CAPS_LATEST("intel-iommu");
     DO_TEST_CAPS_LATEST("intel-iommu-caching-mode");
     DO_TEST_CAPS_LATEST("intel-iommu-eim");