[PATCH v3 00/10] conf, qemu: Add scalable_mode, fsts, pasid_bits, and svm support for intel-iommu
Hi, This series adds support for configuring Intel vIOMMU (VT-d) in domain XML and formatting them onto the QEMU command line: * scalable_mode: Configures scalable mode support ('on'/'off'). * fsts: Enables First-Stage Translation support ('on'/'off'). * pasid_bits: Sets the number of supported PASID bits. * svm: Enables Shared Virtual Memory (SVM) / PRQ support ('on'/'off'). With these attributes, users can configure advanced vIOMMU features for both emulated devices and assigned host devices (e.g., vSVA / nested translation via iommufd and first-stage translation). Example domain XML configuration: <iommu model='intel'> <driver caching_mode='on' iotlb='on' scalable_mode='on' fsts='on' pasid_bits='6' svm='on'/> </iommu> Which formats the following QEMU command line options: -device {"driver":"intel-iommu","id":"iommu0","caching-mode":true,"device-iotlb":true,"scalable-mode":true,"fsts":true,"pasid-bits":6,"svm":true} Testing: - Validated with libvirt test suite (ninja test). - Tested DSA card passthrough and SVM/vSVA with iommufd backend. Changelog: v3: - merge qemu patch into conf patch (Peter Krempa) - fix pasid_bits type definition (Peter Krempa) - fix doc to use 'pasid_bits' rather than 'pasid-bits' (Peter Krempa) - add patch10 to print attribute name in error message (Peter Krempa) - add patch5 for missing validations v2: - Added support for 'pasid_bits' and 'svm' attributes. - rebased to master branch newest Thanks, Zhenzhong Zhenzhong Duan (10): qemu_capabilities: Introduce QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE qemu: Add scalable_mode attribute to iommu qemu_capabilities: Introduce QEMU_CAPS_INTEL_IOMMU_FSTS qemu: Add fsts attribute to iommu qemu: Validate PCI hostdev assignment against intel-iommu 'fsts' qemu_capabilities: Introduce QEMU_CAPS_INTEL_IOMMU_PASID_BITS qemu: add pasid_bits attribute to iommu qemu_capabilities: Introduce QEMU_CAPS_INTEL_IOMMU_SVM qemu: add svm attribute to iommu conf: qemu: Standardize IOMMU error messages to use XML attribute names docs/formatdomain.rst | 19 +++ src/conf/domain_conf.c | 120 +++++++++++++++--- src/conf/domain_conf.h | 7 + src/conf/domain_validate.c | 55 +++++++- src/conf/schemas/domaincommon.rng | 20 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 10 ++ src/qemu/qemu_capabilities.h | 6 + src/qemu/qemu_command.c | 4 + src/qemu/qemu_validate.c | 59 +++++++-- .../caps_11.0.0_x86_64+sgx.xml | 1 + .../caps_11.0.0_x86_64.xml | 1 + .../caps_11.1.0_x86_64.xml | 4 + .../intel-iommu-fsts.x86_64-latest.args | 34 +++++ .../intel-iommu-fsts.x86_64-latest.xml | 37 ++++++ tests/qemuxmlconfdata/intel-iommu-fsts.xml | 37 ++++++ .../intel-iommu-pasid-bits.x86_64-latest.args | 34 +++++ .../intel-iommu-pasid-bits.x86_64-latest.xml | 37 ++++++ .../intel-iommu-pasid-bits.xml | 37 ++++++ ...tel-iommu-scalable-mode.x86_64-latest.args | 34 +++++ ...ntel-iommu-scalable-mode.x86_64-latest.xml | 37 ++++++ .../intel-iommu-scalable-mode.xml | 37 ++++++ .../intel-iommu-svm.x86_64-latest.args | 34 +++++ .../intel-iommu-svm.x86_64-latest.xml | 37 ++++++ tests/qemuxmlconfdata/intel-iommu-svm.xml | 37 ++++++ tests/qemuxmlconftest.c | 4 + 26 files changed, 712 insertions(+), 31 deletions(-) create mode 100644 tests/qemuxmlconfdata/intel-iommu-fsts.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/intel-iommu-fsts.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-fsts.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-pasid-bits.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/intel-iommu-pasid-bits.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-pasid-bits.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-scalable-mode.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/intel-iommu-scalable-mode.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-scalable-mode.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-svm.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/intel-iommu-svm.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-svm.xml -- 2.52.0
This capability tracks whether intel-iommu device has scalable-mode attribute. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml | 1 + 3 files changed, 4 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index bc2b0412dc..209356a984 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -776,6 +776,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "arm-smmuv3.cmdqv", /* QEMU_CAPS_ARM_SMMUV3_CMDQV */ "iothread.poll-weight", /* QEMU_CAPS_IOTHREAD_POLL_WEIGHT */ "win-dmp.guest-aware", /* QEMU_CAPS_WIN_DMP_GUEST_AWARE */ + "intel-iommu.scalable-mode", /* QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE */ ); @@ -1619,6 +1620,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsIntelIOMMU[] = { { "device-iotlb", QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB, NULL }, { "aw-bits", QEMU_CAPS_INTEL_IOMMU_AW_BITS, NULL }, { "dma-translation", QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION, NULL }, + { "scalable-mode", QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE, NULL }, }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsMCH[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 28303fd8f0..25695d7982 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -750,6 +750,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_ARM_SMMUV3_CMDQV, /* arm-smmuv3.cmdqv */ QEMU_CAPS_IOTHREAD_POLL_WEIGHT, /* -object iothread.poll-weight */ QEMU_CAPS_WIN_DMP_GUEST_AWARE, /* 'win-dmp' is offered only to a guest that can use it */ + QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE, /* intel-iommu.scalable-mode */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml index 05e6749a17..e228b0f3d1 100644 --- a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml @@ -224,6 +224,7 @@ <flag name='object-monitor-qmp'/> <flag name='iothread.poll-weight'/> <flag name='win-dmp.guest-aware'/> + <flag name='intel-iommu.scalable-mode'/> <version>11001000</version> <microcodeVersion>43100287</microcodeVersion> <package>v11.1.0</package> -- 2.52.0
Add scalable_mode attribute to iommu to enable/disable scalable mode for intel-iommu. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- docs/formatdomain.rst | 4 ++ src/conf/domain_conf.c | 16 ++++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 3 ++ src/conf/schemas/domaincommon.rng | 5 +++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_validate.c | 6 +++ ...tel-iommu-scalable-mode.x86_64-latest.args | 34 +++++++++++++++++ ...ntel-iommu-scalable-mode.x86_64-latest.xml | 37 +++++++++++++++++++ .../intel-iommu-scalable-mode.xml | 37 +++++++++++++++++++ tests/qemuxmlconftest.c | 1 + 11 files changed, 145 insertions(+) create mode 100644 tests/qemuxmlconfdata/intel-iommu-scalable-mode.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/intel-iommu-scalable-mode.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-scalable-mode.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 5a278f3717..761c5747ed 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9482,6 +9482,10 @@ Examples: default value is used. :since:`Since 12.7.0` (QEMU/KVM and ``smmuv3`` model only) + ``scalable_mode`` + Enable scalable mode DMA translation. + :since:`Since 12.8.0` (QEMU/KVM and ``intel`` model only) + In case of ``virtio`` IOMMU device, the ``driver`` element can optionally contain ``granule`` subelement that allows to choose which granule will be used by default. It is useful when running guests with different page size diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 34d3b00079..c055395120 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14778,6 +14778,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, &iommu->oas, -1) < 0) return NULL; + if (virXMLPropTristateSwitch(driver, "scalable_mode", VIR_XML_PROP_NONE, + &iommu->scalable_mode) < 0) + return NULL; + if ((granule = virXPathNode("./driver/granule", ctxt))) { g_autofree char *mode = virXMLPropString(granule, "mode"); unsigned long long size; @@ -16888,6 +16892,7 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, a->ril != b->ril || a->ssid_size != b->ssid_size || a->oas != b->oas || + a->scalable_mode != b->scalable_mode || a->xtsup != b->xtsup || a->pt != b->pt || a->granule != b->granule) @@ -22823,6 +22828,13 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, virTristateSwitchTypeToString(src->dma_translation)); return false; } + if (src->scalable_mode != dst->scalable_mode) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device 'scalable_mode' '%1$s' does not match source '%2$s'"), + virTristateSwitchTypeToString(dst->scalable_mode), + virTristateSwitchTypeToString(src->scalable_mode)); + return false; + } if (src->pt != dst->pt) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain IOMMU device passthrough '%1$s' does not match source '%2$s'"), @@ -29278,6 +29290,10 @@ virDomainIOMMUDefFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " dma_translation='%s'", virTristateSwitchTypeToString(iommu->dma_translation)); } + if (iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&driverAttrBuf, " scalable_mode='%s'", + virTristateSwitchTypeToString(iommu->scalable_mode)); + } if (iommu->pt != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&driverAttrBuf, " passthrough='%s'", virTristateSwitchTypeToString(iommu->pt)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3732525af4..2c23a3f65a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3104,6 +3104,7 @@ struct _virDomainIOMMUDef { int pci_bus; virDomainDeviceInfo info; virTristateSwitch dma_translation; + virTristateSwitch scalable_mode; virTristateSwitch xtsup; virTristateSwitch pt; int granule; /* -1 means 'host', 0 unset, page size in KiB otherwise */ diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 15e3bb29e6..10318d89ee 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3202,6 +3202,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || + iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || iommu->pt != VIR_TRISTATE_SWITCH_ABSENT || iommu->granule != 0) { @@ -3228,6 +3229,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || + iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0 || iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || @@ -3256,6 +3258,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || + iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0 || iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 887fb8f808..01b1766150 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6424,6 +6424,11 @@ <ref name="virOnOff"/> </attribute> </optional> + <optional> + <attribute name="scalable_mode"> + <ref name="virOnOff"/> + </attribute> + </optional> <optional> <attribute name="xtsup"> <ref name="virOnOff"/> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index bcddb9c922..d7afdb4ee4 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6343,6 +6343,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, "T:device-iotlb", iommu->iotlb, "p:aw-bits", iommu->aw_bits, "T:dma-translation", iommu->dma_translation, + "T:scalable-mode", iommu->scalable_mode, NULL) < 0) return -1; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index e946f55351..efe55f16fd 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5843,6 +5843,12 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, _("iommu: updating dma translation is not supported with this QEMU binary")); return -1; } + if (iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: 'scalable_mode' is not supported with this QEMU binary")); + return -1; + } /* While QEMU_CAPS_ARM_SMMUV3_ACCEL tracks the .accel attribute of * arm-smmuv3 it is also a good indicator of .ats, .ril, .ssidsize, and diff --git a/tests/qemuxmlconfdata/intel-iommu-scalable-mode.x86_64-latest.args b/tests/qemuxmlconfdata/intel-iommu-scalable-mode.x86_64-latest.args new file mode 100644 index 0000000000..bda776f46a --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-scalable-mode.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=@mon-fd@,server=on,wait=off \ +-object '{"qom-type":"monitor-qmp","id":"monitor","chardev":"charmonitor"}' \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"intel-iommu","id":"iommu0","scalable-mode":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/intel-iommu-scalable-mode.x86_64-latest.xml b/tests/qemuxmlconfdata/intel-iommu-scalable-mode.x86_64-latest.xml new file mode 100644 index 0000000000..a8f044ee12 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-scalable-mode.x86_64-latest.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='intel'> + <driver scalable_mode='on'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/intel-iommu-scalable-mode.xml b/tests/qemuxmlconfdata/intel-iommu-scalable-mode.xml new file mode 100644 index 0000000000..a8f044ee12 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-scalable-mode.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='intel'> + <driver scalable_mode='on'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 555c029f58..e77702427f 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2989,6 +2989,7 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-device-iotlb"); DO_TEST_CAPS_LATEST("intel-iommu-aw-bits"); DO_TEST_CAPS_LATEST("intel-iommu-dma-translation"); + DO_TEST_CAPS_LATEST("intel-iommu-scalable-mode"); DO_TEST_CAPS_LATEST_PARSE_ERROR("intel-iommu-wrong-machine"); DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd"); DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd-v2"); -- 2.52.0
This capability tracks whether intel-iommu device has fsts attribute. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml | 1 + 3 files changed, 4 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 209356a984..5a4e74180a 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -777,6 +777,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "iothread.poll-weight", /* QEMU_CAPS_IOTHREAD_POLL_WEIGHT */ "win-dmp.guest-aware", /* QEMU_CAPS_WIN_DMP_GUEST_AWARE */ "intel-iommu.scalable-mode", /* QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE */ + "intel-iommu.fsts", /* QEMU_CAPS_INTEL_IOMMU_FSTS */ ); @@ -1621,6 +1622,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsIntelIOMMU[] = { { "aw-bits", QEMU_CAPS_INTEL_IOMMU_AW_BITS, NULL }, { "dma-translation", QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION, NULL }, { "scalable-mode", QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE, NULL }, + { "fsts", QEMU_CAPS_INTEL_IOMMU_FSTS, NULL }, }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsMCH[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 25695d7982..38d60b9448 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -751,6 +751,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_IOTHREAD_POLL_WEIGHT, /* -object iothread.poll-weight */ QEMU_CAPS_WIN_DMP_GUEST_AWARE, /* 'win-dmp' is offered only to a guest that can use it */ QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE, /* intel-iommu.scalable-mode */ + QEMU_CAPS_INTEL_IOMMU_FSTS, /* intel-iommu.fsts */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml index e228b0f3d1..e2ad004035 100644 --- a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml @@ -225,6 +225,7 @@ <flag name='iothread.poll-weight'/> <flag name='win-dmp.guest-aware'/> <flag name='intel-iommu.scalable-mode'/> + <flag name='intel-iommu.fsts'/> <version>11001000</version> <microcodeVersion>43100287</microcodeVersion> <package>v11.1.0</package> -- 2.52.0
Add fsts attribute to iommu to enable/disable first stage translation support for intel-iommu. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- docs/formatdomain.rst | 4 ++ src/conf/domain_conf.c | 16 ++++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 11 ++++++ src/conf/schemas/domaincommon.rng | 5 +++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_validate.c | 6 +++ .../intel-iommu-fsts.x86_64-latest.args | 34 +++++++++++++++++ .../intel-iommu-fsts.x86_64-latest.xml | 37 +++++++++++++++++++ tests/qemuxmlconfdata/intel-iommu-fsts.xml | 37 +++++++++++++++++++ tests/qemuxmlconftest.c | 1 + 11 files changed, 153 insertions(+) create mode 100644 tests/qemuxmlconfdata/intel-iommu-fsts.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/intel-iommu-fsts.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-fsts.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 761c5747ed..f376cefc16 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9486,6 +9486,10 @@ Examples: Enable scalable mode DMA translation. :since:`Since 12.8.0` (QEMU/KVM and ``intel`` model only) + ``fsts`` + Enable first stage translation. + :since:`Since 12.8.0` (QEMU/KVM and ``intel`` model only) + In case of ``virtio`` IOMMU device, the ``driver`` element can optionally contain ``granule`` subelement that allows to choose which granule will be used by default. It is useful when running guests with different page size diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c055395120..920bd0b840 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14782,6 +14782,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, &iommu->scalable_mode) < 0) return NULL; + if (virXMLPropTristateSwitch(driver, "fsts", VIR_XML_PROP_NONE, + &iommu->fsts) < 0) + return NULL; + if ((granule = virXPathNode("./driver/granule", ctxt))) { g_autofree char *mode = virXMLPropString(granule, "mode"); unsigned long long size; @@ -16893,6 +16897,7 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, a->ssid_size != b->ssid_size || a->oas != b->oas || a->scalable_mode != b->scalable_mode || + a->fsts != b->fsts || a->xtsup != b->xtsup || a->pt != b->pt || a->granule != b->granule) @@ -22835,6 +22840,13 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, virTristateSwitchTypeToString(src->scalable_mode)); return false; } + if (src->fsts != dst->fsts) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device 'fsts' '%1$s' does not match source '%2$s'"), + virTristateSwitchTypeToString(dst->fsts), + virTristateSwitchTypeToString(src->fsts)); + return false; + } if (src->pt != dst->pt) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain IOMMU device passthrough '%1$s' does not match source '%2$s'"), @@ -29294,6 +29306,10 @@ virDomainIOMMUDefFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " scalable_mode='%s'", virTristateSwitchTypeToString(iommu->scalable_mode)); } + if (iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&driverAttrBuf, " fsts='%s'", + virTristateSwitchTypeToString(iommu->fsts)); + } if (iommu->pt != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&driverAttrBuf, " passthrough='%s'", virTristateSwitchTypeToString(iommu->pt)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2c23a3f65a..e2076e7c36 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3105,6 +3105,7 @@ struct _virDomainIOMMUDef { virDomainDeviceInfo info; virTristateSwitch dma_translation; virTristateSwitch scalable_mode; + virTristateSwitch fsts; virTristateSwitch xtsup; virTristateSwitch pt; int granule; /* -1 means 'host', 0 unset, page size in KiB otherwise */ diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 10318d89ee..c321d7ceaf 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3203,6 +3203,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || + iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || iommu->pt != VIR_TRISTATE_SWITCH_ABSENT || iommu->granule != 0) { @@ -3230,6 +3231,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || + iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0 || iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || @@ -3259,6 +3261,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->aw_bits != 0 || iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || + iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0 || iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || @@ -3290,6 +3293,14 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) virDomainIOMMUModelTypeToString(iommu->model)); return -1; } + + if (iommu->scalable_mode != VIR_TRISTATE_SWITCH_ON && + iommu->fsts == VIR_TRISTATE_SWITCH_ON) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' 'fsts' requires 'scalable_mode' to be 'on'"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } break; case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 01b1766150..ff905c18c2 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6429,6 +6429,11 @@ <ref name="virOnOff"/> </attribute> </optional> + <optional> + <attribute name="fsts"> + <ref name="virOnOff"/> + </attribute> + </optional> <optional> <attribute name="xtsup"> <ref name="virOnOff"/> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d7afdb4ee4..8c59ca4383 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6344,6 +6344,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, "p:aw-bits", iommu->aw_bits, "T:dma-translation", iommu->dma_translation, "T:scalable-mode", iommu->scalable_mode, + "T:fsts", iommu->fsts, NULL) < 0) return -1; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index efe55f16fd..764d7c819e 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5849,6 +5849,12 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, _("iommu: 'scalable_mode' is not supported with this QEMU binary")); return -1; } + if (iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_FSTS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: 'fsts' is not supported with this QEMU binary")); + return -1; + } /* While QEMU_CAPS_ARM_SMMUV3_ACCEL tracks the .accel attribute of * arm-smmuv3 it is also a good indicator of .ats, .ril, .ssidsize, and diff --git a/tests/qemuxmlconfdata/intel-iommu-fsts.x86_64-latest.args b/tests/qemuxmlconfdata/intel-iommu-fsts.x86_64-latest.args new file mode 100644 index 0000000000..5db49142e5 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-fsts.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=@mon-fd@,server=on,wait=off \ +-object '{"qom-type":"monitor-qmp","id":"monitor","chardev":"charmonitor"}' \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"intel-iommu","id":"iommu0","scalable-mode":true,"fsts":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/intel-iommu-fsts.x86_64-latest.xml b/tests/qemuxmlconfdata/intel-iommu-fsts.x86_64-latest.xml new file mode 100644 index 0000000000..e188008b31 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-fsts.x86_64-latest.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='intel'> + <driver scalable_mode='on' fsts='on'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/intel-iommu-fsts.xml b/tests/qemuxmlconfdata/intel-iommu-fsts.xml new file mode 100644 index 0000000000..e188008b31 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-fsts.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='intel'> + <driver scalable_mode='on' fsts='on'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index e77702427f..837bea7b63 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2990,6 +2990,7 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-aw-bits"); DO_TEST_CAPS_LATEST("intel-iommu-dma-translation"); DO_TEST_CAPS_LATEST("intel-iommu-scalable-mode"); + DO_TEST_CAPS_LATEST("intel-iommu-fsts"); DO_TEST_CAPS_LATEST_PARSE_ERROR("intel-iommu-wrong-machine"); DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd"); DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd-v2"); -- 2.52.0
When intel-iommu device is configured with First-Stage Translation Support ('fsts'), physical PCI device assignment requires the modern iommufd backend in QEMU, because the legacy container-based VFIO backend cannot support first-stage translation. Introduce virDomainDefHasIntelIOMMUWithFSTS() in the domain configuration layer and export it to query whether a domain definition contains an intel-iommu with 'fsts' enabled. In the QEMU driver validator, reject PCI hostdev assignments that do not use the 'iommufd' backend when 'fsts' is active on an intel-iommu device. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/conf/domain_conf.c | 25 +++++++++++++++++++++++++ src/conf/domain_conf.h | 3 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_validate.c | 4 ++++ 4 files changed, 33 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 920bd0b840..9b8048f895 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -33585,3 +33585,28 @@ virDomainDefHasTimer(const virDomainDef *def, return false; } + + +static bool +virIOMMUIsIntelWithFSTS(const virDomainIOMMUDef *iommu) +{ + if (iommu && iommu->model == VIR_DOMAIN_IOMMU_MODEL_INTEL && + iommu->fsts == VIR_TRISTATE_SWITCH_ON) + return true; + + return false; +} + + +bool +virDomainDefHasIntelIOMMUWithFSTS(const virDomainDef *def) +{ + size_t i; + + for (i = 0; i < def->niommus; i++) { + if (virIOMMUIsIntelWithFSTS(def->iommus[i])) + return true; + } + + return false; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e2076e7c36..d9ec2dc786 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -4841,3 +4841,6 @@ virDomainThrottleFilterFind(const virDomainDiskDef *def, bool virDomainDefHasTimer(const virDomainDef *def, virDomainTimerNameType name); + +bool +virDomainDefHasIntelIOMMUWithFSTS(const virDomainDef *def); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 798d2d28c8..db8bbfbe1b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -341,6 +341,7 @@ virDomainDefGetVcpusMax; virDomainDefGetVcpusTopology; virDomainDefHasDeviceAddress; virDomainDefHasGraphics; +virDomainDefHasIntelIOMMUWithFSTS; virDomainDefHasManagedPR; virDomainDefHasMdevHostdev; virDomainDefHasMemballoon; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 764d7c819e..fb4d100be3 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -2833,6 +2833,10 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, _("IOMMUFD is not supported by host kernel")); return -1; } + } else if (virDomainDefHasIntelIOMMUWithFSTS(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VFIO PCI device assignment without 'iommufd' is not compatible with 'intel' IOMMU with 'fsts'")); + return -1; } } -- 2.52.0
This capability tracks whether intel-iommu device has pasid-bits attribute. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml | 1 + 3 files changed, 8 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 5a4e74180a..606c5385e9 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -778,6 +778,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "win-dmp.guest-aware", /* QEMU_CAPS_WIN_DMP_GUEST_AWARE */ "intel-iommu.scalable-mode", /* QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE */ "intel-iommu.fsts", /* QEMU_CAPS_INTEL_IOMMU_FSTS */ + + /* 505 */ + "intel-iommu.pasid-bits", /* QEMU_CAPS_INTEL_IOMMU_PASID_BITS */ ); @@ -1623,6 +1626,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsIntelIOMMU[] = { { "dma-translation", QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION, NULL }, { "scalable-mode", QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE, NULL }, { "fsts", QEMU_CAPS_INTEL_IOMMU_FSTS, NULL }, + { "pasid-bits", QEMU_CAPS_INTEL_IOMMU_PASID_BITS, NULL }, }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsMCH[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 38d60b9448..30af10da79 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -753,6 +753,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE, /* intel-iommu.scalable-mode */ QEMU_CAPS_INTEL_IOMMU_FSTS, /* intel-iommu.fsts */ + /* 505 */ + QEMU_CAPS_INTEL_IOMMU_PASID_BITS, /* intel-iommu.pasid-bits */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml index e2ad004035..38a782b2e3 100644 --- a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml @@ -226,6 +226,7 @@ <flag name='win-dmp.guest-aware'/> <flag name='intel-iommu.scalable-mode'/> <flag name='intel-iommu.fsts'/> + <flag name='intel-iommu.pasid-bits'/> <version>11001000</version> <microcodeVersion>43100287</microcodeVersion> <package>v11.1.0</package> -- 2.52.0
Add pasid_bits attribute to iommu to set pasid bit width or disable pasid capability if 0 for intel-iommu. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- docs/formatdomain.rst | 5 +++ src/conf/domain_conf.c | 15 ++++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 23 +++++++++--- src/conf/schemas/domaincommon.rng | 5 +++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_validate.c | 11 ++++++ .../intel-iommu-pasid-bits.x86_64-latest.args | 34 +++++++++++++++++ .../intel-iommu-pasid-bits.x86_64-latest.xml | 37 +++++++++++++++++++ .../intel-iommu-pasid-bits.xml | 37 +++++++++++++++++++ tests/qemuxmlconftest.c | 1 + 11 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxmlconfdata/intel-iommu-pasid-bits.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/intel-iommu-pasid-bits.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-pasid-bits.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index f376cefc16..76ce8f88c3 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9490,6 +9490,11 @@ Examples: Enable first stage translation. :since:`Since 12.8.0` (QEMU/KVM and ``intel`` model only) + ``pasid_bits`` + The ``pasid_bits`` attribute can be used to set the pasid bit width. + Max supported value is 20 according to PCI spec, pasid is disabled if 0. + :since:`Since 12.8.0` (QEMU/KVM and ``intel`` model only) + In case of ``virtio`` IOMMU device, the ``driver`` element can optionally contain ``granule`` subelement that allows to choose which granule will be used by default. It is useful when running guests with different page size diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9b8048f895..f442aed5a3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14786,6 +14786,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, &iommu->fsts) < 0) return NULL; + if (virXMLPropUInt(driver, "pasid_bits", 10, VIR_XML_PROP_NONE, + &iommu->pasid_bits) < 0) + return NULL; + if ((granule = virXPathNode("./driver/granule", ctxt))) { g_autofree char *mode = virXMLPropString(granule, "mode"); unsigned long long size; @@ -16898,6 +16902,7 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, a->oas != b->oas || a->scalable_mode != b->scalable_mode || a->fsts != b->fsts || + a->pasid_bits != b->pasid_bits || a->xtsup != b->xtsup || a->pt != b->pt || a->granule != b->granule) @@ -22847,6 +22852,12 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, virTristateSwitchTypeToString(src->fsts)); return false; } + if (src->pasid_bits != dst->pasid_bits) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device 'pasid_bits' '%1$u' does not match source '%2$u'"), + dst->pasid_bits, src->pasid_bits); + return false; + } if (src->pt != dst->pt) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain IOMMU device passthrough '%1$s' does not match source '%2$s'"), @@ -29310,6 +29321,10 @@ virDomainIOMMUDefFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " fsts='%s'", virTristateSwitchTypeToString(iommu->fsts)); } + if (iommu->pasid_bits > 0) { + virBufferAsprintf(&driverAttrBuf, " pasid_bits='%u'", + iommu->pasid_bits); + } if (iommu->pt != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&driverAttrBuf, " passthrough='%s'", virTristateSwitchTypeToString(iommu->pt)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d9ec2dc786..243254dedc 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3106,6 +3106,7 @@ struct _virDomainIOMMUDef { virTristateSwitch dma_translation; virTristateSwitch scalable_mode; virTristateSwitch fsts; + unsigned int pasid_bits; virTristateSwitch xtsup; virTristateSwitch pt; int granule; /* -1 means 'host', 0 unset, page size in KiB otherwise */ diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index c321d7ceaf..f44bc867f8 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3204,6 +3204,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || + iommu->pasid_bits != 0 || iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || iommu->pt != VIR_TRISTATE_SWITCH_ABSENT || iommu->granule != 0) { @@ -3232,6 +3233,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || + iommu->pasid_bits != 0 || iommu->pci_bus >= 0 || iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || @@ -3262,6 +3264,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || + iommu->pasid_bits != 0 || iommu->pci_bus >= 0 || iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || @@ -3294,12 +3297,20 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) return -1; } - if (iommu->scalable_mode != VIR_TRISTATE_SWITCH_ON && - iommu->fsts == VIR_TRISTATE_SWITCH_ON) { - virReportError(VIR_ERR_XML_ERROR, - _("iommu model '%1$s' 'fsts' requires 'scalable_mode' to be 'on'"), - virDomainIOMMUModelTypeToString(iommu->model)); - return -1; + if (iommu->scalable_mode != VIR_TRISTATE_SWITCH_ON) { + if (iommu->fsts == VIR_TRISTATE_SWITCH_ON) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' 'fsts' requires 'scalable_mode' to be 'on'"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + + if (iommu->pasid_bits > 0) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' 'pasid_bits' requires 'scalable_mode' to be 'on'"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } } break; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index ff905c18c2..888d0db214 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6434,6 +6434,11 @@ <ref name="virOnOff"/> </attribute> </optional> + <optional> + <attribute name="pasid_bits"> + <ref name="uint8"/> + </attribute> + </optional> <optional> <attribute name="xtsup"> <ref name="virOnOff"/> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8c59ca4383..5ea8337602 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6345,6 +6345,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, "T:dma-translation", iommu->dma_translation, "T:scalable-mode", iommu->scalable_mode, "T:fsts", iommu->fsts, + "p:pasid-bits", iommu->pasid_bits, NULL) < 0) return -1; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index fb4d100be3..2225f1a76b 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5859,6 +5859,17 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, _("iommu: 'fsts' is not supported with this QEMU binary")); return -1; } + if (iommu->pasid_bits > 0 && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_PASID_BITS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: 'pasid_bits' is not supported with this QEMU binary")); + return -1; + } + if (iommu->pasid_bits > 20) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: 'pasid_bits' exceeds maximum allowed value 20 in QEMU binary")); + return -1; + } /* While QEMU_CAPS_ARM_SMMUV3_ACCEL tracks the .accel attribute of * arm-smmuv3 it is also a good indicator of .ats, .ril, .ssidsize, and diff --git a/tests/qemuxmlconfdata/intel-iommu-pasid-bits.x86_64-latest.args b/tests/qemuxmlconfdata/intel-iommu-pasid-bits.x86_64-latest.args new file mode 100644 index 0000000000..e2f5adfc93 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-pasid-bits.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=@mon-fd@,server=on,wait=off \ +-object '{"qom-type":"monitor-qmp","id":"monitor","chardev":"charmonitor"}' \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"intel-iommu","id":"iommu0","scalable-mode":true,"fsts":true,"pasid-bits":6}' \ +-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-pasid-bits.x86_64-latest.xml b/tests/qemuxmlconfdata/intel-iommu-pasid-bits.x86_64-latest.xml new file mode 100644 index 0000000000..cbf5cce48a --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-pasid-bits.x86_64-latest.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='intel'> + <driver scalable_mode='on' fsts='on' pasid_bits='6'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/intel-iommu-pasid-bits.xml b/tests/qemuxmlconfdata/intel-iommu-pasid-bits.xml new file mode 100644 index 0000000000..cbf5cce48a --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-pasid-bits.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='intel'> + <driver scalable_mode='on' fsts='on' pasid_bits='6'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 837bea7b63..bc83367cd8 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2991,6 +2991,7 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-dma-translation"); DO_TEST_CAPS_LATEST("intel-iommu-scalable-mode"); DO_TEST_CAPS_LATEST("intel-iommu-fsts"); + DO_TEST_CAPS_LATEST("intel-iommu-pasid-bits"); DO_TEST_CAPS_LATEST_PARSE_ERROR("intel-iommu-wrong-machine"); DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd"); DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd-v2"); -- 2.52.0
This capability tracks whether intel-iommu device has svm attribute. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_11.0.0_x86_64+sgx.xml | 1 + tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml | 1 + 5 files changed, 6 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 606c5385e9..3c3a196b23 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -781,6 +781,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 505 */ "intel-iommu.pasid-bits", /* QEMU_CAPS_INTEL_IOMMU_PASID_BITS */ + "intel-iommu.svm", /* QEMU_CAPS_INTEL_IOMMU_SVM */ ); @@ -1627,6 +1628,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsIntelIOMMU[] = { { "scalable-mode", QEMU_CAPS_INTEL_IOMMU_SCALABLE_MODE, NULL }, { "fsts", QEMU_CAPS_INTEL_IOMMU_FSTS, NULL }, { "pasid-bits", QEMU_CAPS_INTEL_IOMMU_PASID_BITS, NULL }, + { "svm", QEMU_CAPS_INTEL_IOMMU_SVM, NULL }, }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsMCH[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 30af10da79..02ea9403a2 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -755,6 +755,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ /* 505 */ QEMU_CAPS_INTEL_IOMMU_PASID_BITS, /* intel-iommu.pasid-bits */ + QEMU_CAPS_INTEL_IOMMU_SVM, /* intel-iommu.svm */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64+sgx.xml b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64+sgx.xml index 108f4b0b86..74628b3c0c 100644 --- a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64+sgx.xml +++ b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64+sgx.xml @@ -222,6 +222,7 @@ <flag name='query-block-flat'/> <flag name='amd-iommu.xtsup'/> <flag name='blockdev-mirror.target-is-zero'/> + <flag name='intel-iommu.svm'/> <version>11000000</version> <microcodeVersion>43100286</microcodeVersion> <package>v11.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml index 29fdaf20d8..fb01666a16 100644 --- a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml @@ -221,6 +221,7 @@ <flag name='query-block-flat'/> <flag name='amd-iommu.xtsup'/> <flag name='blockdev-mirror.target-is-zero'/> + <flag name='intel-iommu.svm'/> <version>11000000</version> <microcodeVersion>43100286</microcodeVersion> <package>v11.0.0</package> diff --git a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml index 38a782b2e3..aa66d10a6b 100644 --- a/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_11.1.0_x86_64.xml @@ -227,6 +227,7 @@ <flag name='intel-iommu.scalable-mode'/> <flag name='intel-iommu.fsts'/> <flag name='intel-iommu.pasid-bits'/> + <flag name='intel-iommu.svm'/> <version>11001000</version> <microcodeVersion>43100287</microcodeVersion> <package>v11.1.0</package> -- 2.52.0
Add svm attribute to iommu to enable/disable shared virtual memory capability for intel-iommu. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- docs/formatdomain.rst | 6 +++ src/conf/domain_conf.c | 16 ++++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 26 +++++++++++++ src/conf/schemas/domaincommon.rng | 5 +++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_validate.c | 6 +++ .../intel-iommu-svm.x86_64-latest.args | 34 +++++++++++++++++ .../intel-iommu-svm.x86_64-latest.xml | 37 +++++++++++++++++++ tests/qemuxmlconfdata/intel-iommu-svm.xml | 37 +++++++++++++++++++ tests/qemuxmlconftest.c | 1 + 11 files changed, 170 insertions(+) create mode 100644 tests/qemuxmlconfdata/intel-iommu-svm.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/intel-iommu-svm.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/intel-iommu-svm.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 76ce8f88c3..69efa2e23b 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -9495,6 +9495,12 @@ Examples: Max supported value is 20 according to PCI spec, pasid is disabled if 0. :since:`Since 12.8.0` (QEMU/KVM and ``intel`` model only) + ``svm`` + Enable shared virtual memory. It exposes the necessary hardware + capabilities to the guest operating system so that devices can share + the exact same virtual address space as user-space applications. + :since:`Since 12.8.0` (QEMU/KVM and ``intel`` model only) + In case of ``virtio`` IOMMU device, the ``driver`` element can optionally contain ``granule`` subelement that allows to choose which granule will be used by default. It is useful when running guests with different page size diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f442aed5a3..61f3b47773 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14790,6 +14790,10 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, &iommu->pasid_bits) < 0) return NULL; + if (virXMLPropTristateSwitch(driver, "svm", VIR_XML_PROP_NONE, + &iommu->svm) < 0) + return NULL; + if ((granule = virXPathNode("./driver/granule", ctxt))) { g_autofree char *mode = virXMLPropString(granule, "mode"); unsigned long long size; @@ -16903,6 +16907,7 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, a->scalable_mode != b->scalable_mode || a->fsts != b->fsts || a->pasid_bits != b->pasid_bits || + a->svm != b->svm || a->xtsup != b->xtsup || a->pt != b->pt || a->granule != b->granule) @@ -22858,6 +22863,13 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, dst->pasid_bits, src->pasid_bits); return false; } + if (src->svm != dst->svm) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device 'svm' '%1$s' does not match source '%2$s'"), + virTristateSwitchTypeToString(dst->svm), + virTristateSwitchTypeToString(src->svm)); + return false; + } if (src->pt != dst->pt) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain IOMMU device passthrough '%1$s' does not match source '%2$s'"), @@ -29325,6 +29337,10 @@ virDomainIOMMUDefFormat(virBuffer *buf, virBufferAsprintf(&driverAttrBuf, " pasid_bits='%u'", iommu->pasid_bits); } + if (iommu->svm != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&driverAttrBuf, " svm='%s'", + virTristateSwitchTypeToString(iommu->svm)); + } if (iommu->pt != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&driverAttrBuf, " passthrough='%s'", virTristateSwitchTypeToString(iommu->pt)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 243254dedc..c9bbfd21d2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3107,6 +3107,7 @@ struct _virDomainIOMMUDef { virTristateSwitch scalable_mode; virTristateSwitch fsts; unsigned int pasid_bits; + virTristateSwitch svm; virTristateSwitch xtsup; virTristateSwitch pt; int granule; /* -1 means 'host', 0 unset, page size in KiB otherwise */ diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index f44bc867f8..0d52f4ca35 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3205,6 +3205,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || iommu->pasid_bits != 0 || + iommu->svm != VIR_TRISTATE_SWITCH_ABSENT || iommu->xtsup != VIR_TRISTATE_SWITCH_ABSENT || iommu->pt != VIR_TRISTATE_SWITCH_ABSENT || iommu->granule != 0) { @@ -3234,6 +3235,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || iommu->pasid_bits != 0 || + iommu->svm != VIR_TRISTATE_SWITCH_ABSENT || iommu->pci_bus >= 0 || iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT || @@ -3264,6 +3266,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT || iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT || iommu->fsts != VIR_TRISTATE_SWITCH_ABSENT || + iommu->svm != VIR_TRISTATE_SWITCH_ABSENT || iommu->pasid_bits != 0 || iommu->pci_bus >= 0 || iommu->accel != VIR_TRISTATE_SWITCH_ABSENT || @@ -3312,6 +3315,29 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) return -1; } } + + if (iommu->svm == VIR_TRISTATE_SWITCH_ON) { + if (iommu->iotlb != VIR_TRISTATE_SWITCH_ON) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' 'svm' requires 'iotlb' to be 'on'"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + + if (iommu->fsts != VIR_TRISTATE_SWITCH_ON) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' 'svm' requires 'fsts' to be 'on'"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + + if (iommu->pasid_bits == 0) { + virReportError(VIR_ERR_XML_ERROR, + _("iommu model '%1$s' 'svm' requires 'pasid_bits' to be configured (> 0)"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + } break; case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 888d0db214..afd506af60 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6439,6 +6439,11 @@ <ref name="uint8"/> </attribute> </optional> + <optional> + <attribute name="svm"> + <ref name="virOnOff"/> + </attribute> + </optional> <optional> <attribute name="xtsup"> <ref name="virOnOff"/> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5ea8337602..f1a1bde3aa 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6346,6 +6346,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, "T:scalable-mode", iommu->scalable_mode, "T:fsts", iommu->fsts, "p:pasid-bits", iommu->pasid_bits, + "T:svm", iommu->svm, NULL) < 0) return -1; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 2225f1a76b..bbd59a314a 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5870,6 +5870,12 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, _("iommu: 'pasid_bits' exceeds maximum allowed value 20 in QEMU binary")); return -1; } + if (iommu->svm != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_SVM)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: 'svm' is not supported with this QEMU binary")); + return -1; + } /* While QEMU_CAPS_ARM_SMMUV3_ACCEL tracks the .accel attribute of * arm-smmuv3 it is also a good indicator of .ats, .ril, .ssidsize, and diff --git a/tests/qemuxmlconfdata/intel-iommu-svm.x86_64-latest.args b/tests/qemuxmlconfdata/intel-iommu-svm.x86_64-latest.args new file mode 100644 index 0000000000..36c2b371b1 --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-svm.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=@mon-fd@,server=on,wait=off \ +-object '{"qom-type":"monitor-qmp","id":"monitor","chardev":"charmonitor"}' \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"intel-iommu","id":"iommu0","device-iotlb":true,"scalable-mode":true,"fsts":true,"pasid-bits":6,"svm":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/intel-iommu-svm.x86_64-latest.xml b/tests/qemuxmlconfdata/intel-iommu-svm.x86_64-latest.xml new file mode 100644 index 0000000000..39b2e0f27a --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-svm.x86_64-latest.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='intel'> + <driver iotlb='on' scalable_mode='on' fsts='on' pasid_bits='6' svm='on'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/intel-iommu-svm.xml b/tests/qemuxmlconfdata/intel-iommu-svm.xml new file mode 100644 index 0000000000..528b380ade --- /dev/null +++ b/tests/qemuxmlconfdata/intel-iommu-svm.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='intel'> + <driver scalable_mode='on' iotlb='on' fsts='on' pasid_bits='6' svm='on'/> + </iommu> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index bc83367cd8..39b6749a18 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2992,6 +2992,7 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-scalable-mode"); DO_TEST_CAPS_LATEST("intel-iommu-fsts"); DO_TEST_CAPS_LATEST("intel-iommu-pasid-bits"); + DO_TEST_CAPS_LATEST("intel-iommu-svm"); DO_TEST_CAPS_LATEST_PARSE_ERROR("intel-iommu-wrong-machine"); DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd"); DO_TEST_CAPS_LATEST_ABI_UPDATE("intel-iommu-eim-autoadd-v2"); -- 2.52.0
Standardize error messages to use the exact XML attribute and element names (enclosed in single quotes) as defined in the domain XML schema. Suggested-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> --- src/conf/domain_conf.c | 32 ++++++++++++++++---------------- src/conf/domain_validate.c | 4 ++-- src/qemu/qemu_validate.c | 26 +++++++++++++------------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 61f3b47773..cde8c71474 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -22762,83 +22762,83 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, } if (src->intremap != dst->intremap) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device intremap value '%1$s' does not match source '%2$s'"), + _("Target domain IOMMU device 'intremap' value '%1$s' does not match source '%2$s'"), virTristateSwitchTypeToString(dst->intremap), virTristateSwitchTypeToString(src->intremap)); return false; } if (src->caching_mode != dst->caching_mode) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device caching mode '%1$s' does not match source '%2$s'"), + _("Target domain IOMMU device 'caching_mode' '%1$s' does not match source '%2$s'"), virTristateSwitchTypeToString(dst->caching_mode), virTristateSwitchTypeToString(src->caching_mode)); return false; } if (src->eim != dst->eim) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device eim value '%1$s' does not match source '%2$s'"), + _("Target domain IOMMU device 'eim' value '%1$s' does not match source '%2$s'"), virTristateSwitchTypeToString(dst->eim), virTristateSwitchTypeToString(src->eim)); return false; } if (src->iotlb != dst->iotlb) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device iotlb value '%1$s' does not match source '%2$s'"), + _("Target domain IOMMU device 'iotlb' value '%1$s' does not match source '%2$s'"), virTristateSwitchTypeToString(dst->iotlb), virTristateSwitchTypeToString(src->iotlb)); return false; } if (src->aw_bits != dst->aw_bits) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device aw_bits value '%1$u' does not match source '%2$u'"), + _("Target domain IOMMU device 'aw_bits' value '%1$u' does not match source '%2$u'"), dst->aw_bits, src->aw_bits); return false; } if (src->pci_bus != dst->pci_bus) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device pci_bus value '%1$d' does not match source '%2$d'"), + _("Target domain IOMMU device 'pciBus' value '%1$d' does not match source '%2$d'"), dst->pci_bus, src->pci_bus); return false; } if (src->accel != dst->accel) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device accel value '%1$d' does not match source '%2$d'"), + _("Target domain IOMMU device 'accel' value '%1$d' does not match source '%2$d'"), dst->accel, src->accel); return false; } if (src->cmdqv != dst->cmdqv) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device cmdqv value '%1$d' does not match source '%2$d'"), + _("Target domain IOMMU device 'cmdqv' value '%1$d' does not match source '%2$d'"), dst->cmdqv, src->cmdqv); return false; } if (src->ats != dst->ats) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device ATS value '%1$d' does not match source '%2$d'"), + _("Target domain IOMMU device 'ats' value '%1$d' does not match source '%2$d'"), dst->ats, src->ats); return false; } if (src->ril != dst->ril) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device ril value '%1$d' does not match source '%2$d'"), + _("Target domain IOMMU device 'ril' value '%1$d' does not match source '%2$d'"), dst->ril, src->ril); return false; } if (src->ssid_size != dst->ssid_size) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device ssid_size value '%1$d' does not match source '%2$d'"), + _("Target domain IOMMU device 'ssidsize' value '%1$d' does not match source '%2$d'"), dst->ssid_size, src->ssid_size); return false; } if (src->oas != dst->oas) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device oas value '%1$d' does not match source '%2$d'"), + _("Target domain IOMMU device 'oas' value '%1$d' does not match source '%2$d'"), dst->oas, src->oas); return false; } if (src->dma_translation != dst->dma_translation) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device dma translation '%1$s' does not match source '%2$s'"), + _("Target domain IOMMU device 'dma_translation' '%1$s' does not match source '%2$s'"), virTristateSwitchTypeToString(dst->dma_translation), virTristateSwitchTypeToString(src->dma_translation)); return false; @@ -22872,14 +22872,14 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, } if (src->pt != dst->pt) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device passthrough '%1$s' does not match source '%2$s'"), + _("Target domain IOMMU device 'passthrough' '%1$s' does not match source '%2$s'"), virTristateSwitchTypeToString(dst->pt), virTristateSwitchTypeToString(src->pt)); return false; } if (src->xtsup != dst->xtsup) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device xtsup '%1$s' does not match source '%2$s'"), + _("Target domain IOMMU device 'xtsup' '%1$s' does not match source '%2$s'"), virTristateSwitchTypeToString(dst->xtsup), virTristateSwitchTypeToString(src->xtsup)); return false; @@ -22889,7 +22889,7 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUDef *src, g_autofree char *dst_granule = virDomainIOMMUGranuleModeTypeToString(dst->granule); virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target domain IOMMU device granule '%1$s' does not match source '%2$s'"), + _("Target domain IOMMU device 'granule' '%1$s' does not match source '%2$s'"), dst_granule, src_granule); return false; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 0d52f4ca35..cef844aead 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -3221,7 +3221,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) iommu->ssid_size >= 0 || iommu->oas >= 0)) { virReportError(VIR_ERR_XML_ERROR, - _("accel must be enabled for iommu model '%1$s' when setting ats, ril, ssidsize, oas, or cmdqv"), + _("'accel' must be enabled for iommu model '%1$s' when setting ats, ril, ssidsize, oas, or cmdqv"), virDomainIOMMUModelTypeToString(iommu->model)); return -1; } @@ -3254,7 +3254,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) * be assumed to be hypervisor agnostic and thus can live here. */ if (iommu->aw_bits != 0 && (iommu->aw_bits < 32 || iommu->aw_bits > 64)) { virReportError(VIR_ERR_XML_ERROR, "%s", - _("aw-bits must be within [32,64]")); + _("'aw_bits' must be within [32,64]")); return -1; } break; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index bbd59a314a..24f01c36e1 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -2824,13 +2824,13 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOMMUFD)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("IOMMUFD is not supported by this version of qemu")); + _("'iommufd' is not supported by this version of qemu")); return -1; } if (!virIOMMUFDSupported()) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("IOMMUFD is not supported by host kernel")); + _("'iommufd' is not supported by host kernel")); return -1; } } else if (virDomainDefHasIntelIOMMUWithFSTS(def)) { @@ -5735,7 +5735,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, if (iommu->pci_bus >= 0) { if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_ARM_SMMUV3_SMMU_PER_BUS)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("IOMMU device: Setting pciBus for '%1$s' is not supported with this QEMU binary"), + _("IOMMU device: Setting 'pciBus' for '%1$s' is not supported with this QEMU binary"), virDomainIOMMUModelTypeToString(iommu->model)); return -1; } @@ -5815,36 +5815,36 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: interrupt remapping is not supported with this QEMU binary")); + _("iommu: 'intremap' is not supported with this QEMU binary")); return -1; } if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_CACHING_MODE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: caching mode is not supported with this QEMU binary")); + _("iommu: 'caching_mode' is not supported with this QEMU binary")); return -1; } if (iommu->eim != VIR_TRISTATE_SWITCH_ABSENT && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: eim is not supported with this QEMU binary")); + _("iommu: 'eim' is not supported with this QEMU binary")); return -1; } if (iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: device IOTLB is not supported with this QEMU binary")); + _("iommu: 'iotlb' is not supported with this QEMU binary")); return -1; } if (iommu->aw_bits > 0 && !aw_bits_supported) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: aw_bits is not supported with this QEMU binary")); + _("iommu: 'aw_bits' is not supported with this QEMU binary")); return -1; } if (iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_DMA_TRANSLATION)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: updating dma translation is not supported with this QEMU binary")); + _("iommu: updating 'dma_translation' is not supported with this QEMU binary")); return -1; } if (iommu->scalable_mode != VIR_TRISTATE_SWITCH_ABSENT && @@ -5885,7 +5885,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, iommu->accel != VIR_TRISTATE_SWITCH_ABSENT && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_ARM_SMMUV3_ACCEL)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: accel is not supported with this QEMU binary")); + _("iommu: 'accel' is not supported with this QEMU binary")); return -1; } @@ -5893,7 +5893,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, iommu->cmdqv != VIR_TRISTATE_SWITCH_ABSENT && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_ARM_SMMUV3_CMDQV)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: cmdqv is not supported with this QEMU binary")); + _("iommu: 'cmdqv' is not supported with this QEMU binary")); return -1; } @@ -5904,7 +5904,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, iommu->granule == 16 || iommu->granule == 64)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: unsupported granule size. Supported values are 4, 8, 16 and 64 KiB")); + _("iommu: unsupported 'granule' size. Supported values are 4, 8, 16 and 64 KiB")); return -1; } @@ -5915,7 +5915,7 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, * other makes no sense. */ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOMMU_AW_BITS)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: page granule is not supported with this QEMU binary")); + _("iommu: page 'granule' is not supported with this QEMU binary")); return -1; } } -- 2.52.0
participants (1)
-
Zhenzhong Duan