From 9d15647dcb96831c93ac8c1d67c47265b5ed9072 Mon Sep 17 00:00:00 2001 From: Jim Fehlig Date: Fri, 14 Aug 2020 10:28:38 -0600 Subject: [PATCH] Xen: Add writeFiltering option for PCI devices MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit By default Xen only allows guests to write "known safe" values into PCI configuration space, yet many devices require writes to other areas of the configuration space in order to operate properly. To allow writing any values Xen supports the 'permissive' setting, see xl.cfg(5) man page. This change models Xen's permissive setting by adding a writeFiltering attribute on the element of a PCI hostdev. When writeFiltering is set to 'no', the Xen permissive setting will be enabled and guests will be able to write any values into the device's configuration space. The permissive setting remains disabled in the absense of the writeFiltering attribute, of if it is explicitly set to 'yes'. Signed-off-by: Jim Fehlig Signed-off-by: Simon Gaiser Signed-off-by: Marek Marczykowski-Górecki Reviewed-by: Daniel P. Berrangé --- docs/formatdomain.rst | 7 ++++++- docs/schemas/domaincommon.rng | 5 +++++ src/conf/domain_conf.c | 14 ++++++++++++++ src/conf/domain_conf.h | 1 + src/libxl/libxl_conf.c | 1 + src/qemu/qemu_validate.c | 7 +++++++ tests/libxlxml2domconfigdata/moredevs-hvm.json | 6 ++++++ tests/libxlxml2domconfigdata/moredevs-hvm.xml | 5 +++++ 8 files changed, 45 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 250beb4b76..1979dfb8d3 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -3733,7 +3733,7 @@ or: ... - +
@@ -3899,6 +3899,11 @@ or: ``pci`` PCI devices can only be described by their ``address``. + :since:`Since 6.8.0 (Xen only)` , the ``source`` element of a PCI device + may contain the ``writeFiltering`` attribute to control write access to + the PCI configuration space. By default Xen only allows writes of known + safe values to the configuration space. Setting ``writeFiltering='no'`` + will allow all writes to the device's PCI configuration space. ``scsi`` SCSI devices are described by both the ``adapter`` and ``address`` elements. The ``address`` element includes a ``bus`` attribute (a 2-digit diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 0d8a0caaf6..a1d6d19e2f 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5021,6 +5021,11 @@ + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5d3ae8bb28..7d177a5562 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8137,8 +8137,18 @@ virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node, virDomainHostdevDefPtr def, unsigned int flags) { + g_autofree char *filtering = NULL; xmlNodePtr cur; + if ((filtering = virXMLPropString(node, "writeFiltering"))) { + if ((def->writeFiltering = virTristateBoolTypeFromString(filtering)) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown pci writeFiltering setting '%s'"), + filtering); + return -1; + } + } + cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { @@ -26247,6 +26257,10 @@ virDomainHostdevDefFormatSubsysPCI(virBufferPtr buf, g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf); virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci; + if (def->writeFiltering != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(&sourceAttrBuf, " writeFiltering='%s'", + virTristateBoolTypeToString(def->writeFiltering)); + if (pcisrc->backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) { const char *backend = virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8a0f26f5c0..14a376350c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -347,6 +347,7 @@ struct _virDomainHostdevDef { bool missing; bool readonly; bool shareable; + virTristateBool writeFiltering; union { virDomainHostdevSubsys subsys; virDomainHostdevCaps caps; diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 9ae8ad1860..ff0ddda62d 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -2286,6 +2286,7 @@ libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev) pcidev->bus = pcisrc->addr.bus; pcidev->dev = pcisrc->addr.slot; pcidev->func = pcisrc->addr.function; + pcidev->permissive = hostdev->writeFiltering == VIR_TRISTATE_BOOL_NO; return 0; } diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 6f3fee5427..4052f9807b 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1836,6 +1836,13 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev, return -1; } } + + if (hostdev->writeFiltering != VIR_TRISTATE_BOOL_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Write filtering of PCI device configuration " + "space is not supported by qemu")); + return -1; + } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: diff --git a/tests/libxlxml2domconfigdata/moredevs-hvm.json b/tests/libxlxml2domconfigdata/moredevs-hvm.json index 7bfd68bd67..474aa2cef6 100644 --- a/tests/libxlxml2domconfigdata/moredevs-hvm.json +++ b/tests/libxlxml2domconfigdata/moredevs-hvm.json @@ -88,6 +88,12 @@ "dev": 16, "bus": 10, "rdm_policy": "invalid" + }, + { + "dev": 8, + "bus": 10, + "permissive": true, + "rdm_policy": "invalid" } ], "vfbs": [ diff --git a/tests/libxlxml2domconfigdata/moredevs-hvm.xml b/tests/libxlxml2domconfigdata/moredevs-hvm.xml index f7eb09fa3b..89ad80631d 100644 --- a/tests/libxlxml2domconfigdata/moredevs-hvm.xml +++ b/tests/libxlxml2domconfigdata/moredevs-hvm.xml @@ -48,6 +48,11 @@
+ + +
+ +