diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 7b702cfc6b..39f3e38351 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6453,6 +6453,37 @@ qemuDomainPstoreDefPostParse(virDomainPstoreDef *pstore, } +static int +qemuDomainIOMMUDefPostParse(virDomainIOMMUDef *iommu, + const virDomainDef *def, + virQEMUCaps *qemuCaps, + unsigned int parseFlags) +{ + /* In case domain has huge number of vCPUS and Extended Interrupt Mode + * (EIM) is not explicitly turned off, let's enable it. If we didn't then + * guest will have troubles with interrupts. */ + if (parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE && + ARCH_IS_X86(def->os.arch) && + virDomainDefGetVcpusMax(def) > QEMU_MAX_VCPUS_WITHOUT_EIM && + qemuDomainIsQ35(def) && + iommu && iommu->model == VIR_DOMAIN_IOMMU_MODEL_INTEL) { + + /* eim requires intremap. */ + if (iommu->intremap == VIR_TRISTATE_SWITCH_ABSENT && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { + iommu->intremap = VIR_TRISTATE_SWITCH_ON; + } + + if (iommu->eim == VIR_TRISTATE_SWITCH_ABSENT && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) { + iommu->eim = VIR_TRISTATE_SWITCH_ON; + } + } + + return 0; +} + + static int qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev, const virDomainDef *def, @@ -6518,6 +6549,11 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev, ret = qemuDomainPstoreDefPostParse(dev->data.pstore, def, driver); break; + case VIR_DOMAIN_DEVICE_IOMMU: + ret = qemuDomainIOMMUDefPostParse(dev->data.iommu, def, + qemuCaps, parseFlags); + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: @@ -6530,7 +6566,6 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: case VIR_DOMAIN_DEVICE_RNG: - case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: case VIR_DOMAIN_DEVICE_CRYPTO: ret = 0; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index fa23c5f973..aaa056379e 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -31,7 +31,6 @@ #include "virutil.h" #define VIR_FROM_THIS VIR_FROM_QEMU -#define QEMU_MAX_VCPUS_WITHOUT_EIM 255 VIR_LOG_INIT("qemu.qemu_validate"); diff --git a/src/qemu/qemu_validate.h b/src/qemu/qemu_validate.h index e06a43b8e3..9315be73f5 100644 --- a/src/qemu/qemu_validate.h +++ b/src/qemu/qemu_validate.h @@ -22,6 +22,8 @@ #include "qemu_capabilities.h" +#define QEMU_MAX_VCPUS_WITHOUT_EIM 255 + int qemuValidateDomainDef(const virDomainDef *def, void *opaque, diff --git a/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.x86_64-latest.abi-update.args b/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.x86_64-latest.abi-update.args new file mode 100644 index 0000000000..07fa1191b7 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.x86_64-latest.abi-update.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 288,sockets=288,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","eim":"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-eim-autoadd.x86_64-latest.abi-update.xml b/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.x86_64-latest.abi-update.xml new file mode 100644 index 0000000000..1caa0ceb60 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-eim-autoadd.x86_64-latest.abi-update.xml @@ -0,0 +1,37 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 288 + + hvm + + + + + + + qemu64 + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + +
+ + + +