<interface type='user'>
<mac address='52:54:56:5a:5c:5e'/>
<model type='virtio'/>
<driver iommu_platform='on' ats='on'/>
</interface>
https://bugzilla.redhat.com/show_bug.cgi?id=1283251
---
docs/formatdomain.html.in | 19 +++++++
docs/schemas/domaincommon.rng | 12 +++++
src/conf/domain_conf.c | 63 ++++++++++++++++++++++
src/conf/domain_conf.h | 19 +++++++
.../qemuxml2argv-virtio-options.xml | 2 +
.../qemuxml2xmlout-virtio-options.xml | 2 +
6 files changed, 117 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 2f1e030..dcc2e5e 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3451,6 +3451,19 @@
</dd>
</dl>
+ <h4><a name="elementsVirtio">Virtio-related
options</a></h4>
+
+ <p>
+ QEMU's virtio devices have some attributes related to the virtio transport
under
+ the <code>driver</code> element:
+ The <code>iommu_platform</code> attribute enables the use of emulated
IOMMU
+ by the device. The attribute <code>ats</code> controls the Address
+ Translation Service support for PCIe devices. This is needed to make use
+ of IOTLB support (see <a href="#elementsIommu">IOMMU
device</a>).
+ Possible values are <code>on</code> or <code>off</code>.
+ <span class="since">Since 3.5.0</span>
+ </p>
+
<h4><a
name="elementsControllers">Controllers</a></h4>
<p>
@@ -5142,6 +5155,12 @@ qemu-kvm -net nic,model=? /dev/null
<b>In general you should leave this option alone, unless you
are very certain you know what you are doing.</b>
</dd>
+ <dt>virtio options</dt>
+ <dd>
+ For virtio interfaces,
+ <a href="#elementsVirtio">Virtio-specific options</a> can
also be
+ set. (<span class="since">Since 3.5.0</span>)
+ </dd>
</dl>
<p>
Offloading options for the host and guest can be configured using
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 6c3e885..d7f3b02 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2686,6 +2686,7 @@
</optional>
</group>
</choice>
+ <ref name="virtioOptions"/>
<interleave>
<optional>
<element name='host'>
@@ -5006,6 +5007,17 @@
</element>
</define>
+ <define name="virtioOptions">
+ <optional>
+ <attribute name="iommu_platform">
+ <ref name="virOnOff"/>
+ </attribute>
+ <attribute name="ats">
+ <ref name="virOnOff"/>
+ </attribute>
+ </optional>
+ </define>
+
<define name="usbmaster">
<element name="master">
<attribute name="startport">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c83af5d..a83f7dc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1098,6 +1098,46 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt)
return &xmlopt->ns;
}
+static int
+virDomainVirtioOptionsParseXML(xmlXPathContextPtr ctxt,
+ virDomainVirtioOptionsPtr *virtio)
+{
+ char *str = NULL;
+ int ret = -1;
+ int val;
+ virDomainVirtioOptionsPtr res;
+
+ if (VIR_ALLOC(*virtio) < 0)
+ return -1;
+
+ res = *virtio;
+
+ if ((str = virXPathString("string(./driver/@iommu_platform)", ctxt))) {
+ if ((val = virTristateSwitchTypeFromString(str)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("invalid iommu_platform value"));
+ goto cleanup;
+ }
+ res->iommu_platform = val;
+ }
+ VIR_FREE(str);
+
+ if ((str = virXPathString("string(./driver/@ats)", ctxt))) {
+ if ((val = virTristateSwitchTypeFromString(str)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("invalid ats value"));
+ goto cleanup;
+ }
+ res->ats = val;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(str);
+ return ret;
+}
+
void
virBlkioDeviceArrayClear(virBlkioDevicePtr devices,
@@ -1945,6 +1985,7 @@ virDomainNetDefClear(virDomainNetDefPtr def)
VIR_FREE(def->ifname);
VIR_FREE(def->ifname_guest);
VIR_FREE(def->ifname_guest_actual);
+ VIR_FREE(def->virtio);
virNetDevIPInfoClear(&def->guestIP);
virNetDevIPInfoClear(&def->hostIP);
@@ -5214,6 +5255,24 @@ virDomainDefValidate(virDomainDefPtr def,
}
+static void
+virDomainVirtioOptionsFormat(virBufferPtr buf,
+ virDomainVirtioOptionsPtr virtio)
+{
+ if (!virtio)
+ return;
+
+ if (virtio->iommu_platform != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(buf, "iommu_platform='%s' ",
+ virTristateSwitchTypeToString(virtio->iommu_platform));
+ }
+ if (virtio->ats != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(buf, "ats='%s' ",
+ virTristateSwitchTypeToString(virtio->ats));
+ }
+}
+
+
/* Generate a string representation of a device address
* @info address Device address to stringify
*/
@@ -10360,6 +10419,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
goto error;
}
+ if (virDomainVirtioOptionsParseXML(ctxt, &def->virtio) < 0)
+ goto error;
+
cleanup:
ctxt->node = oldnode;
VIR_FREE(macaddr);
@@ -22092,6 +22154,7 @@ virDomainVirtioNetDriverFormat(char **outstr,
virBufferAsprintf(&buf, "rx_queue_size='%u' ",
def->driver.virtio.rx_queue_size);
+ virDomainVirtioOptionsFormat(&buf, def->virtio);
virBufferTrim(&buf, " ", -1);
if (virBufferCheckError(&buf) < 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cb570ef..68f8d0c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -155,6 +155,17 @@ typedef virDomainTPMDef *virDomainTPMDefPtr;
typedef struct _virDomainIOMMUDef virDomainIOMMUDef;
typedef virDomainIOMMUDef *virDomainIOMMUDefPtr;
+typedef struct _virDomainVirtioOptions virDomainVirtioOptions;
+typedef virDomainVirtioOptions *virDomainVirtioOptionsPtr;
+
+typedef enum {
+ VIR_DOMAIN_DRIVER_COMPATIBILITY_DEFAULT,
+ VIR_DOMAIN_DRIVER_COMPATIBILITY_LEGACY,
+ VIR_DOMAIN_DRIVER_COMPATIBILITY_TRANSITIONAL,
+ VIR_DOMAIN_DRIVER_COMPATIBILITY_MODERN,
+ VIR_DOMAIN_DRIVER_COMPATIBILITY_LAST,
+} virDomainDriverCompatibility;
+
/* Flags for the 'type' field in virDomainDeviceDef */
typedef enum {
VIR_DOMAIN_DEVICE_NONE = 0,
@@ -1039,6 +1050,7 @@ struct _virDomainNetDef {
int linkstate;
unsigned int mtu;
virNetDevCoalescePtr coalesce;
+ virDomainVirtioOptionsPtr virtio;
};
typedef enum {
@@ -2214,6 +2226,12 @@ struct _virDomainIOMMUDef {
virTristateSwitch eim;
virTristateSwitch device_iotlb;
};
+
+struct _virDomainVirtioOptions {
+ virTristateSwitch iommu_platform;
+ virTristateSwitch ats;
+};
+
/*
* Guest VM main configuration
*
@@ -3174,6 +3192,7 @@ VIR_ENUM_DECL(virDomainMemorySource)
VIR_ENUM_DECL(virDomainMemoryAllocation)
VIR_ENUM_DECL(virDomainIOMMUModel)
VIR_ENUM_DECL(virDomainShmemModel)
+VIR_ENUM_DECL(virDomainDriverCompatibility)
/* from libvirt.h */
VIR_ENUM_DECL(virDomainState)
VIR_ENUM_DECL(virDomainNostateReason)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.xml
b/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.xml
index 9ead938..a2bbbee 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.xml
@@ -53,11 +53,13 @@
<interface type='user'>
<mac address='52:54:56:58:5a:5c'/>
<model type='virtio'/>
+ <driver iommu_platform='on' ats='on'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x06' function='0x0'/>
</interface>
<interface type='user'>
<mac address='52:54:56:5a:5c:5e'/>
<model type='virtio'/>
+ <driver iommu_platform='off' ats='off'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x07' function='0x0'/>
</interface>
<input type='mouse' bus='virtio'>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-virtio-options.xml
b/tests/qemuxml2xmloutdata/qemuxml2xmlout-virtio-options.xml
index 9ead938..a2bbbee 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-virtio-options.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-virtio-options.xml
@@ -53,11 +53,13 @@
<interface type='user'>
<mac address='52:54:56:58:5a:5c'/>
<model type='virtio'/>
+ <driver iommu_platform='on' ats='on'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x06' function='0x0'/>
</interface>
<interface type='user'>
<mac address='52:54:56:5a:5c:5e'/>
<model type='virtio'/>
+ <driver iommu_platform='off' ats='off'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x07' function='0x0'/>
</interface>
<input type='mouse' bus='virtio'>
--
2.10.2