[libvirt PATCH 3/7] qemu: add IOMMU model amd

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 docs/formatdomain.rst                         |  5 ++-
 src/conf/domain_conf.c                        |  1 +
 src/conf/domain_conf.h                        |  1 +
 src/conf/domain_validate.c                    | 13 +++++++
 src/conf/schemas/domaincommon.rng             |  1 +
 src/qemu/qemu_command.c                       | 28 +++++++++++++
 src/qemu/qemu_domain_address.c                |  4 ++
 src/qemu/qemu_validate.c                      | 29 ++++++++++++++
 .../amd-iommu.x86_64-latest.args              | 35 +++++++++++++++++
 .../amd-iommu.x86_64-latest.xml               |  1 +
 tests/qemuxmlconfdata/amd-iommu.xml           | 39 +++++++++++++++++++
 tests/qemuxmlconftest.c                       |  2 +
 12 files changed, 157 insertions(+), 2 deletions(-)
 create mode 100644 tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args
 create mode 120000 tests/qemuxmlconfdata/amd-iommu.x86_64-latest.xml
 create mode 100644 tests/qemuxmlconfdata/amd-iommu.xml

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 9c6bb08726..c5708000b8 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8904,8 +8904,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.2.0`).
 
 ``driver``
    The ``driver`` subelement can be used to configure additional options, some
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d05e68dd41..961ef08ba1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1350,6 +1350,7 @@ VIR_ENUM_IMPL(virDomainIOMMUModel,
               "intel",
               "smmuv3",
               "virtio",
+              "amd",
 );
 
 VIR_ENUM_IMPL(virDomainVsockModel,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cbad1b7f7d..1ec16d3824 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2989,6 +2989,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;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 7b901da593..be91caee65 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -3016,6 +3016,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;
@@ -3033,6 +3045,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;
     }
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 7ef45a1731..71b68d6687 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6178,6 +6178,7 @@
           <value>intel</value>
           <value>smmuv3</value>
           <value>virtio</value>
+          <value>amd</value>
         </choice>
       </attribute>
       <interleave>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 84ff62cd6c..269455ff3b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6039,6 +6039,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd,
                           virQEMUCaps *qemuCaps)
 {
     g_autoptr(virJSONValue) props = NULL;
+    g_autoptr(virJSONValue) wrapperProps = NULL;
     const virDomainIOMMUDef *iommu = def->iommu;
 
     if (!iommu)
@@ -6083,6 +6084,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);
@@ -6914,6 +6941,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;
 
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index e89cdee487..7b65abac82 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -941,6 +941,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:
@@ -2359,6 +2362,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;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 19af0f0209..b1a798802d 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -5209,6 +5209,35 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu,
         }
         break;
 
+    case VIR_DOMAIN_IOMMU_MODEL_AMD:
+        /* TODO: is this true? */
+        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 (def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("IOMMU device: '%1$s' requires ACPI"),
+                           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
index 0000000000..36244edb3a
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args
@@ -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
index 0000000000..5ba3d4b91b
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.xml
@@ -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
index 0000000000..0668ed4237
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu.xml
@@ -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>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 17efed1379..389d885898 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2745,6 +2745,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");
-- 
2.48.1




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux