A device with an attribude 'model'. intel-iommu is accepted so far: <devices> ... <iommu model='intel-iommu'/> </devices> https://bugzilla.redhat.com/show_bug.cgi?id=1235580 --- docs/schemas/domaincommon.rng | 11 +++++++ src/conf/domain_conf.c | 37 ++++++++++++++++++++++ src/conf/domain_conf.h | 14 ++++++++ src/libvirt_private.syms | 2 ++ .../qemuxml2argvdata/qemuxml2argv-intel-iommu.xml | 37 ++++++++++++++++++++++ .../qemuxml2xmlout-intel-iommu.xml | 37 ++++++++++++++++++++++ tests/qemuxml2xmltest.c | 4 +++ 7 files changed, 142 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-intel-iommu.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-intel-iommu.xml diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 162c2e0..c8a8ecb 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3709,6 +3709,14 @@ </optional> </define> + <define name="iommu"> + <element name="iommu"> + <attribute name="model"> + <value>intel-iommu</value> + </attribute> + </element> + </define> + <define name="input"> <element name="input"> <choice> @@ -4198,6 +4206,9 @@ <zeroOrMore> <ref name="panic"/> </zeroOrMore> + <optional> + <ref name="iommu"/> + </optional> </interleave> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9443281..07889ff 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -802,6 +802,9 @@ VIR_ENUM_IMPL(virDomainTPMModel, VIR_DOMAIN_TPM_MODEL_LAST, VIR_ENUM_IMPL(virDomainTPMBackend, VIR_DOMAIN_TPM_TYPE_LAST, "passthrough") +VIR_ENUM_IMPL(virDomainIOMMUModel, VIR_DOMAIN_IOMMU_MODEL_LAST, + "intel-iommu") + VIR_ENUM_IMPL(virDomainDiskDiscard, VIR_DOMAIN_DISK_DISCARD_LAST, "default", "unmap", @@ -2615,6 +2618,8 @@ void virDomainDefFree(virDomainDefPtr def) virDomainPanicDefFree(def->panics[i]); VIR_FREE(def->panics); + VIR_FREE(def->iommu); + VIR_FREE(def->idmap.uidmap); VIR_FREE(def->idmap.gidmap); @@ -17239,6 +17244,33 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(nodes); + if ((n = virXPathNodeSet("./devices/iommu", ctxt, &nodes)) < 0) + goto error; + + if (n > 1) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single IOMMU device is supported")); + goto error; + } + + if (n > 0) { + int val; + if (VIR_ALLOC(def->iommu) < 0) + goto error; + + if (!(tmp = virXMLPropString(nodes[0], "model"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing model for IOMMU device")); + goto error; + } + if ((val = virDomainIOMMUModelTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_XML_ERROR, _("unknown IOMMU model: %s"), tmp); + goto error; + } + def->iommu->model = val; + } + VIR_FREE(nodes); + /* analysis of the user namespace mapping */ if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0) goto error; @@ -23561,6 +23593,11 @@ virDomainDefFormatInternal(virDomainDefPtr def, goto error; } + if (def->iommu) { + virBufferAsprintf(buf, "<iommu model='%s'/>\n", + virDomainIOMMUModelTypeToString(def->iommu->model)); + } + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</devices>\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6e81e52..918c185 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -150,6 +150,9 @@ typedef virDomainShmemDef *virDomainShmemDefPtr; typedef struct _virDomainTPMDef virDomainTPMDef; typedef virDomainTPMDef *virDomainTPMDefPtr; +typedef struct _virDomainIOMMUDef virDomainIOMMUDef; +typedef virDomainIOMMUDef *virDomainIOMMUDefPtr; + /* Flags for the 'type' field in virDomainDeviceDef */ typedef enum { VIR_DOMAIN_DEVICE_NONE = 0, @@ -2112,6 +2115,15 @@ struct _virDomainKeyWrapDef { int dea; /* enum virTristateSwitch */ }; +typedef enum { + VIR_DOMAIN_IOMMU_MODEL_INTEL, + + VIR_DOMAIN_IOMMU_MODEL_LAST +} virDomainIOMMUModel; + +struct _virDomainIOMMUDef { + virDomainIOMMUModel model; +}; /* * Guest VM main configuration * @@ -2249,6 +2261,7 @@ struct _virDomainDef { virCPUDefPtr cpu; virSysinfoDefPtr sysinfo; virDomainRedirFilterDefPtr redirfilter; + virDomainIOMMUDefPtr iommu; void *namespaceData; virDomainXMLNamespace ns; @@ -3006,6 +3019,7 @@ VIR_ENUM_DECL(virDomainTPMModel) VIR_ENUM_DECL(virDomainTPMBackend) VIR_ENUM_DECL(virDomainMemoryModel) VIR_ENUM_DECL(virDomainMemoryBackingModel) +VIR_ENUM_DECL(virDomainIOMMUModel) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainNostateReason) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 501c23e..73cecfd 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -343,6 +343,8 @@ virDomainHubTypeToString; virDomainHypervTypeFromString; virDomainHypervTypeToString; virDomainInputDefFree; +virDomainIOMMUModelTypeFromString; +virDomainIOMMUModelTypeToString; virDomainIOThreadIDAdd; virDomainIOThreadIDDefFree; virDomainIOThreadIDDel; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-intel-iommu.xml b/tests/qemuxml2argvdata/qemuxml2argv-intel-iommu.xml new file mode 100644 index 0000000..8d95383 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-intel-iommu.xml @@ -0,0 +1,37 @@ +<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> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <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'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> + </memballoon> + <iommu model='intel-iommu'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-intel-iommu.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-intel-iommu.xml new file mode 100644 index 0000000..8d95383 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-intel-iommu.xml @@ -0,0 +1,37 @@ +<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> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <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'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> + </memballoon> + <iommu model='intel-iommu'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 7db9cb7..855eb40 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -829,6 +829,10 @@ mymain(void) DO_TEST("video-qxl-heads"); DO_TEST("video-qxl-noheads"); + DO_TEST_FULL("intel-iommu", WHEN_ACTIVE, GIC_NONE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE); + qemuTestDriverFree(&driver); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; -- 2.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list