]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Xen: Add writeFiltering option for PCI devices
authorJim Fehlig <jfehlig@suse.com>
Fri, 14 Aug 2020 16:28:38 +0000 (10:28 -0600)
committerJim Fehlig <jfehlig@suse.com>
Tue, 1 Sep 2020 20:29:17 +0000 (14:29 -0600)
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 <source> 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 <jfehlig@suse.com>
Signed-off-by: Simon Gaiser <simon@invisiblethingslab.com>
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
docs/formatdomain.rst
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libxl/libxl_conf.c
src/qemu/qemu_validate.c
tests/libxlxml2domconfigdata/moredevs-hvm.json
tests/libxlxml2domconfigdata/moredevs-hvm.xml

index 250beb4b7606dab97de30b0c021214ce54b85ca5..1979dfb8d334f05b51d221088220b776cbf59d04 100644 (file)
@@ -3733,7 +3733,7 @@ or:
    ...
    <devices>
      <hostdev mode='subsystem' type='pci' managed='yes'>
-       <source>
+       <source writeFiltering='no'>
          <address domain='0x0000' bus='0x06' slot='0x02' function='0x0'/>
        </source>
        <boot order='1'/>
@@ -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
index 0d8a0caaf62118f658f3fce606278180224d899b..a1d6d19e2f71868eeee9bb29a14fe1c43a3cd803 100644 (file)
         <optional>
           <ref name="startupPolicy"/>
         </optional>
+        <optional>
+          <attribute name="writeFiltering">
+            <ref name="virYesNo"/>
+          </attribute>
+        </optional>
         <element name="address">
           <ref name="pciaddress"/>
         </element>
index 5d3ae8bb281c9789f4e4787413890a1ff8b49102..7d177a55626437fffacf2754fbb859368858f3ef 100644 (file)
@@ -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);
 
index 8a0f26f5c0cf3ecad08fa2381665214ae79a9839..14a376350cb1bdde59de66ddf650c99080a1b152 100644 (file)
@@ -347,6 +347,7 @@ struct _virDomainHostdevDef {
     bool missing;
     bool readonly;
     bool shareable;
+    virTristateBool writeFiltering;
     union {
         virDomainHostdevSubsys subsys;
         virDomainHostdevCaps caps;
index 9ae8ad1860e41f6c16f741f59836952682a6b1dd..ff0ddda62d37ed45f42db9a85205e44bd2b7e8ba 100644 (file)
@@ -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;
 }
index 6f3fee542791e54e676544c96b59cb48f758a97b..4052f9807bcfe0246637c79822b7b07a316c5a9d 100644 (file)
@@ -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:
index 7bfd68bd672c0680095fa05b959ff9e6245da298..474aa2cef644d0f7f4e1302cc5a778df5b9cb35d 100644 (file)
             "dev": 16,
             "bus": 10,
            "rdm_policy": "invalid"
+        },
+        {
+            "dev": 8,
+            "bus": 10,
+            "permissive": true,
+           "rdm_policy": "invalid"
         }
     ],
     "vfbs": [
index f7eb09fa3b5c7ffa9fb9d5c10f383ee5e9ada978..89ad80631d9fb4572f527d028156375150da72bb 100644 (file)
         <address type='pci' domain='0x0000' bus='0x0a' slot='0x10' function='0x0'/>
       </source>
     </interface>
+    <hostdev mode='subsystem' type='pci' managed='yes'>
+      <source writeFiltering='no'>
+        <address domain='0x0000' bus='0x0a' slot='0x08' function='0x0'/>
+      </source>
+    </hostdev>
     <graphics type='vnc'/>
     <video>
       <model type='cirrus' vram='8192' heads='1' primary='yes'/>