From 7667b332ec942112270da554ded58658a78860b9 Mon Sep 17 00:00:00 2001 Message-Id: <7667b332ec942112270da554ded58658a78860b9@dist-git> From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Fri, 9 Jun 2017 12:49:00 +0200 Subject: [PATCH] Add virtio-related options to interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugzilla.redhat.com/show_bug.cgi?id=1283251 Reviewed-by: Pavel Hrdina (cherry picked from commit fd518643402d8233ceffe4ef28279bcce53284f6) Signed-off-by: Ján Tomko Signed-off-by: Jiri Denemark --- docs/formatdomain.html.in | 19 ++++ docs/schemas/domaincommon.rng | 12 ++ src/conf/domain_conf.c | 121 +++++++++++++++++++++ src/conf/domain_conf.h | 10 ++ .../qemuxml2argv-virtio-options.xml | 1 + 5 files changed, 163 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e8a3367bac..23546daae9 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3448,6 +3448,19 @@ +

Virtio-related options

+ +

+ QEMU's virtio devices have some attributes related to the virtio transport under + the driver element: + The iommu attribute enables the use of emulated IOMMU + by the device. The attribute ats controls the Address + Translation Service support for PCIe devices. This is needed to make use + of IOTLB support (see IOMMU device). + Possible values are on or off. + Since 3.5.0 +

+

Controllers

@@ -5139,6 +5152,12 @@ qemu-kvm -net nic,model=? /dev/null In general you should leave this option alone, unless you are very certain you know what you are doing. +

virtio options
+
+ For virtio interfaces, + Virtio-specific options can also be + set. (Since 3.5.0) +

Offloading options for the host and guest can be configured using diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 1b66362f17..9e68bbc52d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2632,6 +2632,7 @@ + @@ -4952,6 +4953,17 @@ + + + + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 4652e1c72b..bba50cf3fd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1112,6 +1112,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)", ctxt))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("invalid iommu value")); + goto cleanup; + } + res->iommu = 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; +} + virSaveCookieCallbacksPtr virDomainXMLOptionGetSaveCookie(virDomainXMLOptionPtr xmlopt) @@ -1953,6 +1993,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); @@ -4313,6 +4354,28 @@ virDomainHostdevDefPostParse(virDomainHostdevDefPtr dev, static int +virDomainCheckVirtioOptions(virDomainVirtioOptionsPtr virtio) +{ + if (!virtio) + return 0; + + if (virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu driver option is only supported " + "for virtio devices")); + return -1; + } + if (virtio->ats != VIR_TRISTATE_SWITCH_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("ats driver option is only supported " + "for virtio devices")); + return -1; + } + return 0; +} + + +static int virDomainDeviceDefPostParseInternal(virDomainDeviceDefPtr dev, const virDomainDef *def, virCapsPtr caps ATTRIBUTE_UNUSED, @@ -4410,6 +4473,13 @@ virDomainDeviceDefPostParseInternal(virDomainDeviceDefPtr dev, } } + if (dev->type == VIR_DOMAIN_DEVICE_NET) { + virDomainNetDefPtr net = dev->data.net; + if (STRNEQ_NULLABLE(net->model, "virtio") && + virDomainCheckVirtioOptions(net->virtio) < 0) + return -1; + } + return 0; } @@ -5208,6 +5278,24 @@ virDomainDefValidate(virDomainDefPtr def, } +static void +virDomainVirtioOptionsFormat(virBufferPtr buf, + virDomainVirtioOptionsPtr virtio) +{ + if (!virtio) + return; + + if (virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(buf, " iommu='%s'", + virTristateSwitchTypeToString(virtio->iommu)); + } + 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 */ @@ -10354,6 +10442,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, goto error; } + if (virDomainVirtioOptionsParseXML(ctxt, &def->virtio) < 0) + goto error; + cleanup: ctxt->node = oldnode; VIR_FREE(macaddr); @@ -18979,6 +19070,30 @@ virDomainDeviceInfoCheckABIStability(virDomainDeviceInfoPtr src, static bool +virDomainVirtioOptionsCheckABIStability(virDomainVirtioOptionsPtr src, + virDomainVirtioOptionsPtr dst) +{ + if (src->iommu != dst->iommu) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target device iommu option '%s' does not " + "match source '%s'"), + virTristateSwitchTypeToString(dst->iommu), + virTristateSwitchTypeToString(src->iommu)); + return false; + } + if (src->ats != dst->ats) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target device ats option '%s' does not " + "match source '%s'"), + virTristateSwitchTypeToString(dst->ats), + virTristateSwitchTypeToString(src->ats)); + return false; + } + return true; +} + + +static bool virDomainDiskDefCheckABIStability(virDomainDiskDefPtr src, virDomainDiskDefPtr dst) { @@ -19137,6 +19252,10 @@ virDomainNetDefCheckABIStability(virDomainNetDefPtr src, return false; } + if (src->virtio && dst->virtio && + !virDomainVirtioOptionsCheckABIStability(src->virtio, dst->virtio)) + return false; + if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info)) return false; @@ -22074,6 +22193,8 @@ virDomainVirtioNetDriverFormat(char **outstr, virBufferAsprintf(&buf, " rx_queue_size='%u'", def->driver.virtio.rx_queue_size); + virDomainVirtioOptionsFormat(&buf, def->virtio); + if (virBufferCheckError(&buf) < 0) return -1; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e6c20a9e1e..603d35bd50 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -156,6 +156,9 @@ typedef virDomainTPMDef *virDomainTPMDefPtr; typedef struct _virDomainIOMMUDef virDomainIOMMUDef; typedef virDomainIOMMUDef *virDomainIOMMUDefPtr; +typedef struct _virDomainVirtioOptions virDomainVirtioOptions; +typedef virDomainVirtioOptions *virDomainVirtioOptionsPtr; + /* Flags for the 'type' field in virDomainDeviceDef */ typedef enum { VIR_DOMAIN_DEVICE_NONE = 0, @@ -1040,6 +1043,7 @@ struct _virDomainNetDef { int linkstate; unsigned int mtu; virNetDevCoalescePtr coalesce; + virDomainVirtioOptionsPtr virtio; }; typedef enum { @@ -2215,6 +2219,12 @@ struct _virDomainIOMMUDef { virTristateSwitch eim; virTristateSwitch iotlb; }; + +struct _virDomainVirtioOptions { + virTristateSwitch iommu; + virTristateSwitch ats; +}; + /* * Guest VM main configuration * diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.xml b/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.xml index c88cf649b1..3357bc6d1b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.xml @@ -47,6 +47,7 @@ +

-- 2.13.1