diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 39f3e38351..562fa76a78 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4262,6 +4262,7 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
bool addDefaultUSBMouse = false;
bool addPanicDevice = false;
bool addITCOWatchdog = false;
+ bool addIOMMU = false;
/* add implicit input devices */
if (qemuDomainDefAddImplicitInputDevice(def, qemuCaps) < 0)
@@ -4284,6 +4285,10 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
addImplicitSATA = true;
addITCOWatchdog = true;
+ if (virDomainDefGetVcpusMax(def) > QEMU_MAX_VCPUS_WITHOUT_EIM) {
+ addIOMMU = true;
+ }
+
/* Prefer adding a USB3 controller if supported, fall back
* to USB2 if there is no USB3 available, and if that's
* unavailable don't add anything.
@@ -4530,6 +4535,21 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
}
}
+ if (addIOMMU && !def->iommu &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU) &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP) &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) {
+ g_autoptr(virDomainIOMMUDef) iommu = NULL;
+
+ iommu = virDomainIOMMUDefNew();
+ iommu->model = VIR_DOMAIN_IOMMU_MODEL_INTEL;
+ /* eim requires intremap. */
+ iommu->intremap = VIR_TRISTATE_SWITCH_ON;
+ iommu->eim = VIR_TRISTATE_SWITCH_ON;
+
+ def->iommu = g_steal_pointer(&iommu);
+ }
+
if (qemuDomainDefAddDefaultAudioBackend(driver, def) < 0)
return -1;
diff --git a/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.xml b/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.xml
index 7c294fe2f9..fa3aaf0d44 100644
--- a/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.xml
+++ b/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.xml
@@ -30,6 +30,5 @@
-