Fixes: https://issues.redhat.com/browse/RHEL-50560
Signed-off-by: Han Han <hhan@redhat.com>
---
docs/formatdomain.rst | 20 +++++++++-
src/conf/domain_conf.c | 16 ++++++++
src/conf/domain_conf.h | 2 +
src/conf/domain_validate.c | 39 ++++++++++++++++++-
src/conf/schemas/domaincommon.rng | 6 +++
src/qemu/qemu_command.c | 15 +++++++
src/qemu/qemu_domain_address.c | 2 +
src/qemu/qemu_validate.c | 1 +
tests/qemuxmlconfdata/amd-iommu-aw-bits.err | 1 +
tests/qemuxmlconfdata/amd-iommu-aw-bits.xml | 32 +++++++++++++++
.../amd-iommu-caching-mode.err | 1 +
.../amd-iommu-caching-mode.xml | 32 +++++++++++++++
.../amd-iommu-device-iotlb.x86_64-latest.args | 34 ++++++++++++++++
.../amd-iommu-device-iotlb.xml | 37 ++++++++++++++++++
.../amd-iommu-dma-translation.err | 1 +
.../amd-iommu-dma-translation.xml | 32 +++++++++++++++
tests/qemuxmlconfdata/amd-iommu-eim.err | 1 +
tests/qemuxmlconfdata/amd-iommu-eim.xml | 32 +++++++++++++++
.../amd-iommu-xtsup.x86_64-latest.args | 34 ++++++++++++++++
tests/qemuxmlconfdata/amd-iommu-xtsup.xml | 32 +++++++++++++++
.../amd-iommu.x86_64-latest.args | 34 ++++++++++++++++
tests/qemuxmlconfdata/amd-iommu.xml | 32 +++++++++++++++
tests/qemuxmlconfdata/intel-iommu-xtsup.err | 1 +
tests/qemuxmlconfdata/intel-iommu-xtsup.xml | 38 ++++++++++++++++++
tests/qemuxmlconftest.c | 8 ++++
25 files changed, 480 insertions(+), 3 deletions(-)
create mode 100644 tests/qemuxmlconfdata/amd-iommu-aw-bits.err
create mode 100644 tests/qemuxmlconfdata/amd-iommu-aw-bits.xml
create mode 100644 tests/qemuxmlconfdata/amd-iommu-caching-mode.err
create mode 100644 tests/qemuxmlconfdata/amd-iommu-caching-mode.xml
create mode 100644 tests/qemuxmlconfdata/amd-iommu-device-iotlb.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/amd-iommu-device-iotlb.xml
create mode 100644 tests/qemuxmlconfdata/amd-iommu-dma-translation.err
create mode 100644 tests/qemuxmlconfdata/amd-iommu-dma-translation.xml
create mode 100644 tests/qemuxmlconfdata/amd-iommu-eim.err
create mode 100644 tests/qemuxmlconfdata/amd-iommu-eim.xml
create mode 100644 tests/qemuxmlconfdata/amd-iommu-xtsup.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/amd-iommu-xtsup.xml
create mode 100644 tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/amd-iommu.xml
create mode 100644 tests/qemuxmlconfdata/intel-iommu-xtsup.err
create mode 100644 tests/qemuxmlconfdata/intel-iommu-xtsup.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 4336cff3ac..866dbf4bd4 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8587,10 +8587,20 @@ Example:
</devices>
...
+::
+
+ ...
+ <devices>
+ <iommu model='amd'>
+ <driver xtsup='on'/>
+ </iommu>
+ </devices>
+
``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 10.9.0`,
+ for Q35 guests ).
``driver``
The ``driver`` subelement can be used to configure additional options, some
@@ -8631,6 +8641,12 @@ Example:
example to efficiently enable more than 255 vCPUs.
:since:`Since 10.7.0` (QEMU/KVM only)
+ ``xtsup``
+ The ``xtsup`` attribute with possible values ``on`` and ``off`` can be used to
+ enable XTsup mode. A q35 domain with x2apic cpu feature ( as the ``feature`` paragraph
+ in `CPU model and topology`_), and both x2apic feature and XTsup turned on for IOMMU,
+ will be able to use more than 255 vCPUs. :since:`Since 10.9.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``).
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 6d7dee7956..6e7d92b264 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1335,6 +1335,7 @@ VIR_ENUM_IMPL(virDomainIOMMUModel,
"intel",
"smmuv3",
"virtio",
+ "amd",
);
VIR_ENUM_IMPL(virDomainVsockModel,
@@ -13933,6 +13934,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt,
if (virXMLPropTristateSwitch(driver, "dma_translation", VIR_XML_PROP_NONE,
&iommu->dma_translation) < 0)
return NULL;
+
+ if (virXMLPropTristateSwitch(driver, "xtsup", VIR_XML_PROP_NONE,
+ &iommu->xtsup) < 0)
+ return NULL;
}
if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt,
@@ -21492,6 +21497,13 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src,
virTristateSwitchTypeToString(src->dma_translation));
return false;
}
+ if (src->xtsup != dst->xtsup) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target domain IOMMU device xtsup value '%1$s' does not match source '%2$s'"),
+ virTristateSwitchTypeToString(dst->xtsup),
+ virTristateSwitchTypeToString(src->xtsup));
+ return false;
+ }
return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
}
@@ -27480,6 +27492,10 @@ virDomainIOMMUDefFormat(virBuffer *buf,
virBufferAsprintf(&driverAttrBuf, " dma_translation='%s'",
virTristateSwitchTypeToString(iommu->dma_translation));
}
+ if (iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&driverAttrBuf, " xtsup='%s'",
+ virTristateSwitchTypeToString(iommu->xtsup));
+ }
virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a15af4fae3..d527975eb3 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2919,6 +2919,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;
@@ -2932,6 +2933,7 @@ struct _virDomainIOMMUDef {
unsigned int aw_bits;
virDomainDeviceInfo info;
virTristateSwitch dma_translation;
+ virTristateSwitch xtsup;
};
typedef enum {
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index eddb4a5e74..344df0c559 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2980,7 +2980,8 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->eim != VIR_TRISTATE_SWITCH_ABSENT ||
iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT ||
- iommu->aw_bits != 0) {
+ iommu->aw_bits != 0 ||
+ iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' doesn't support additional attributes"),
virDomainIOMMUModelTypeToString(iommu->model));
@@ -2989,6 +2990,41 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
break;
case VIR_DOMAIN_IOMMU_MODEL_INTEL:
+ if (iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("iommu model '%1$s' doesn't support the xtsup attribute"),
+ virDomainIOMMUModelTypeToString(iommu->model));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_IOMMU_MODEL_AMD:
+ if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("iommu model '%1$s' doesn't support the caching_mode attribute"),
+ virDomainIOMMUModelTypeToString(iommu->model));
+ return -1;
+ }
+ if (iommu->eim != VIR_TRISTATE_SWITCH_ABSENT) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("iommu model '%1$s' doesn't support the eim attribute"),
+ virDomainIOMMUModelTypeToString(iommu->model));
+ return -1;
+ }
+ if (iommu->aw_bits != 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("iommu model '%1$s' doesn't support the aw_bits attribute"),
+ virDomainIOMMUModelTypeToString(iommu->model));
+ return -1;
+ }
+ if (iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("iommu model '%1$s' doesn't support the dma_translation attribute"),
+ virDomainIOMMUModelTypeToString(iommu->model));
+ return -1;
+ }
+ break;
+
case VIR_DOMAIN_IOMMU_MODEL_LAST:
break;
}
@@ -2996,6 +3032,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu)
switch (iommu->model) {
case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
case VIR_DOMAIN_IOMMU_MODEL_INTEL:
+ case VIR_DOMAIN_IOMMU_MODEL_AMD:
if (iommu->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
virReportError(VIR_ERR_XML_ERROR,
_("iommu model '%1$s' can't have address"),
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index efb5f00d77..d4336c5996 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6070,6 +6070,7 @@
<value>intel</value>
<value>smmuv3</value>
<value>virtio</value>
+ <value>amd</value>
</choice>
</attribute>
<interleave>
@@ -6105,6 +6106,11 @@
<ref name="virOnOff"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="xtsup">
+ <ref name="virOnOff"/>
+ </attribute>
+ </optional>
</element>
</optional>
<optional>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a0c9e5f8b3..c3d74544db 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6040,6 +6040,20 @@ 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(&props,
+ "s:driver", "amd-iommu",
+ "s:id", iommu->info.alias,
+ "S:intremap", qemuOnOffAuto(iommu->intremap),
+ "T:device-iotlb", iommu->iotlb,
+ "T:xtsup", iommu->xtsup,
+ 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);
@@ -6853,6 +6867,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 970ae3949d..37c7a59aec 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -943,6 +943,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev,
case VIR_DOMAIN_IOMMU_MODEL_INTEL:
case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
+ case VIR_DOMAIN_IOMMU_MODEL_AMD:
case VIR_DOMAIN_IOMMU_MODEL_LAST:
/* These are not PCI devices */
return 0;
@@ -2367,6 +2368,7 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def,
case VIR_DOMAIN_IOMMU_MODEL_INTEL:
case VIR_DOMAIN_IOMMU_MODEL_SMMUV3:
+ case VIR_DOMAIN_IOMMU_MODEL_AMD:
case VIR_DOMAIN_IOMMU_MODEL_LAST:
/* These are not PCI devices */
break;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index fa23c5f973..326b0a9460 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -5046,6 +5046,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu,
{
switch (iommu->model) {
case VIR_DOMAIN_IOMMU_MODEL_INTEL:
+ case VIR_DOMAIN_IOMMU_MODEL_AMD:
if (!qemuDomainIsQ35(def)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("IOMMU device: '%1$s' is only supported with Q35 machines"),
diff --git a/tests/qemuxmlconfdata/amd-iommu-aw-bits.err b/tests/qemuxmlconfdata/amd-iommu-aw-bits.err
new file mode 100644
index 0000000000..3958049227
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-aw-bits.err
@@ -0,0 +1 @@
+XML error: iommu model 'amd' doesn't support the aw_bits attribute
diff --git a/tests/qemuxmlconfdata/amd-iommu-aw-bits.xml b/tests/qemuxmlconfdata/amd-iommu-aw-bits.xml
new file mode 100644
index 0000000000..9433890f77
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-aw-bits.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <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>
+ <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' aw_bits='16'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/amd-iommu-caching-mode.err b/tests/qemuxmlconfdata/amd-iommu-caching-mode.err
new file mode 100644
index 0000000000..38f97a8e48
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-caching-mode.err
@@ -0,0 +1 @@
+XML error: iommu model 'amd' doesn't support the caching_mode attribute
diff --git a/tests/qemuxmlconfdata/amd-iommu-caching-mode.xml b/tests/qemuxmlconfdata/amd-iommu-caching-mode.xml
new file mode 100644
index 0000000000..7dcf3797c4
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-caching-mode.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <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>
+ <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' caching_mode='on'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/amd-iommu-device-iotlb.x86_64-latest.args b/tests/qemuxmlconfdata/amd-iommu-device-iotlb.x86_64-latest.args
new file mode 100644
index 0000000000..496b1378c6
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-device-iotlb.x86_64-latest.args
@@ -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":"amd-iommu","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-device-iotlb.xml b/tests/qemuxmlconfdata/amd-iommu-device-iotlb.xml
new file mode 100644
index 0000000000..a27daeba1c
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-device-iotlb.xml
@@ -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='amd'>
+ <driver intremap='on' iotlb='on'/>
+ </iommu>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/amd-iommu-dma-translation.err b/tests/qemuxmlconfdata/amd-iommu-dma-translation.err
new file mode 100644
index 0000000000..cdaa892a02
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-dma-translation.err
@@ -0,0 +1 @@
+XML error: iommu model 'amd' doesn't support the dma_translation attribute
diff --git a/tests/qemuxmlconfdata/amd-iommu-dma-translation.xml b/tests/qemuxmlconfdata/amd-iommu-dma-translation.xml
new file mode 100644
index 0000000000..8c960009c0
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-dma-translation.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <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>
+ <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' dma_translation='on'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/amd-iommu-eim.err b/tests/qemuxmlconfdata/amd-iommu-eim.err
new file mode 100644
index 0000000000..c7e7a402e9
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-eim.err
@@ -0,0 +1 @@
+XML error: iommu model 'amd' doesn't support the eim attribute
diff --git a/tests/qemuxmlconfdata/amd-iommu-eim.xml b/tests/qemuxmlconfdata/amd-iommu-eim.xml
new file mode 100644
index 0000000000..02a0926742
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-eim.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <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>
+ <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' eim='on'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/amd-iommu-xtsup.x86_64-latest.args b/tests/qemuxmlconfdata/amd-iommu-xtsup.x86_64-latest.args
new file mode 100644
index 0000000000..54eb43a998
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-xtsup.x86_64-latest.args
@@ -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,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-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":"amd-iommu","id":"iommu0", "xtsup": 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-xtsup.xml b/tests/qemuxmlconfdata/amd-iommu-xtsup.xml
new file mode 100644
index 0000000000..5c5fcfe35b
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu-xtsup.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <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>
+ <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' xtsup='on'/>
+ </devices>
+</domain>
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..e06c320dc5
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args
@@ -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,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-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":"amd-iommu","id":"iommu0"}' \
+-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.xml b/tests/qemuxmlconfdata/amd-iommu.xml
new file mode 100644
index 0000000000..acfdc96050
--- /dev/null
+++ b/tests/qemuxmlconfdata/amd-iommu.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <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>
+ <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'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/intel-iommu-xtsup.err b/tests/qemuxmlconfdata/intel-iommu-xtsup.err
new file mode 100644
index 0000000000..5598a0bf5b
--- /dev/null
+++ b/tests/qemuxmlconfdata/intel-iommu-xtsup.err
@@ -0,0 +1 @@
+XML error: iommu model 'intel' doesn't support the xtsup attribute
diff --git a/tests/qemuxmlconfdata/intel-iommu-xtsup.xml b/tests/qemuxmlconfdata/intel-iommu-xtsup.xml
new file mode 100644
index 0000000000..a8442457e2
--- /dev/null
+++ b/tests/qemuxmlconfdata/intel-iommu-xtsup.xml
@@ -0,0 +1,38 @@
+<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'>288</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>
+ <feature policy='require' name='x2apic'/>
+ </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 xtsup='on'/>
+ </iommu>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 61eb4cda75..93752f5ab1 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2758,6 +2758,7 @@ mymain(void)
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_LATEST_PARSE_ERROR("intel-iommu-xtsup");
DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64");
DO_TEST_CAPS_LATEST("virtio-iommu-x86_64");
DO_TEST_CAPS_VER_PARSE_ERROR("virtio-iommu-x86_64", "6.1.0");
@@ -2766,6 +2767,13 @@ mymain(void)
DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-no-acpi");
DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-invalid-address-type");
DO_TEST_CAPS_LATEST_PARSE_ERROR("virtio-iommu-invalid-address");
+ DO_TEST_CAPS_LATEST("amd-iommu");
+ DO_TEST_CAPS_LATEST("amd-iommu-device-iotlb");
+ DO_TEST_CAPS_LATEST("amd-iommu-xtsup");
+ DO_TEST_CAPS_LATEST_PARSE_ERROR("amd-iommu-caching-mode");
+ DO_TEST_CAPS_LATEST_PARSE_ERROR("amd-iommu-eim");
+ DO_TEST_CAPS_LATEST_PARSE_ERROR("amd-iommu-aw-bits");
+ DO_TEST_CAPS_LATEST_PARSE_ERROR("amd-iommu-dma-translation");
DO_TEST_CAPS_LATEST("cpu-hotplug-startup");
DO_TEST_CAPS_ARCH_LATEST_PARSE_ERROR("cpu-hotplug-granularity", "ppc64");
--
2.46.2
Note that this is not a full review as I don't know how the iommu is behaving/used so I can't comment on that. On Fri, Sep 27, 2024 at 15:45:46 +0800, Han Han wrote: > Fixes: https://issues.redhat.com/browse/RHEL-50560 Please describe in the commit message what/why you are doing. e.g. at the very least when the new device is useful. E.g. the docs state that with certain config it allows > 255 cpus which would be great to mention in the commit message. I'd also prefer if the implementation of the new 'xtsup' attribute is separated. The docs also don't mention when to use the 'amd' model or which options don't actually work with it. (eim,caching-mode, etc) And lastly none of the new capability flags QEMU_CAPS_AMD_IOMMU* are used by this series, which they should be, as otherwise it makes no sense to add them.
© 2016 - 2026 Red Hat, Inc.