]> xenbits.xensource.com Git - xen.git/commitdiff
IOMMU: default to always quarantining PCI devices
authorJan Beulich <jbeulich@suse.com>
Tue, 26 Nov 2019 13:23:08 +0000 (14:23 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 26 Nov 2019 13:23:08 +0000 (14:23 +0100)
XSA-302 relies on the use of libxl's "assignable-add" feature to prepare
devices to be assigned to untrusted guests.

Unfortunately, this is not considered a strictly required step for
device assignment. The PCI passthrough documentation on the wiki
describes alternate ways of preparing devices for assignment, and
libvirt uses its own ways as well. Hosts where these alternate methods
are used will still leave the system in a vulnerable state after the
device comes back from a guest.

Default to always quarantining PCI devices, but provide a command line
option to revert back to prior behavior (such that people who both
sufficiently trust their guests and want to be able to use devices in
Dom0 again after they had been in use by a guest wouldn't need to
"manually" move such devices back from DomIO to Dom0).

This is XSA-306.

Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Wei Liu <wl@xen.org>
master commit: ba2ab00bbb8c74e311a252d816d68dee47c779a0
master date: 2019-11-26 14:15:01 +0100

docs/misc/xen-command-line.pandoc
xen/drivers/passthrough/iommu.c
xen/drivers/passthrough/pci.c
xen/include/xen/iommu.h

index 8988c7afbcae872e66a83e68576a98f4d5b73c0d..82272d72ffaf3fca4caf9652416651078bcd3259 100644 (file)
@@ -1196,7 +1196,7 @@ detection of systems known to misbehave upon accesses to that port.
 > Default: `new` unless directed-EOI is supported
 
 ### iommu
-    = List of [ <bool>, verbose, debug, force, required,
+    = List of [ <bool>, verbose, debug, force, required, quarantine,
                 sharept, intremap, intpost, crash-disable,
                 snoop, qinval, igfx, amd-iommu-perdev-intremap,
                 dom0-{passthrough,strict} ]
@@ -1234,6 +1234,12 @@ boolean (e.g. `iommu=no`) can override this and leave the IOMMUs disabled.
     will prevent Xen from booting if IOMMUs aren't discovered and enabled
     successfully.
 
+*   The `quarantine` boolean can be used to control Xen's behavior when
+    de-assigning devices from guests.  If enabled (the default), Xen always
+    quarantines such devices; they must be explicitly assigned back to Dom0
+    before they can be used there again.  If disabled, Xen will only
+    quarantine devices the toolstack hass arranged for getting quarantined.
+
 *   The `sharept` boolean controls whether the IOMMU pagetables are shared
     with the CPU-side HAP pagetables, or allocated separately.  Sharing
     reduces the memory overhead, but doesn't work in combination with CPU-side
index 2762e1342f3f4c22d7d9fb6f5fb0d3efaaba7af8..20db08e1df6adb6a0cbbb03cfd399c9e625296c9 100644 (file)
@@ -30,6 +30,7 @@ bool_t __initdata iommu_enable = 1;
 bool_t __read_mostly iommu_enabled;
 bool_t __read_mostly force_iommu;
 bool_t __read_mostly iommu_verbose;
+bool __read_mostly iommu_quarantine = true;
 bool_t __read_mostly iommu_igfx = 1;
 bool_t __read_mostly iommu_snoop = 1;
 bool_t __read_mostly iommu_qinval = 1;
@@ -74,6 +75,8 @@ static int __init parse_iommu_param(const char *s)
         else if ( (val = parse_boolean("force", s, ss)) >= 0 ||
                   (val = parse_boolean("required", s, ss)) >= 0 )
             force_iommu = val;
+        else if ( (val = parse_boolean("quarantine", s, ss)) >= 0 )
+            iommu_quarantine = val;
         else if ( (val = parse_boolean("igfx", s, ss)) >= 0 )
             iommu_igfx = val;
         else if ( (val = parse_boolean("verbose", s, ss)) >= 0 )
index 4dfbd48b00802bb3a5ea82eb87fd7a9db9404e0f..41e5f7f63e33d61bba45807c2343249cf4e7a96c 100644 (file)
@@ -1548,7 +1548,8 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
         return -ENODEV;
 
     /* De-assignment from dom_io should de-quarantine the device */
-    target = (pdev->quarantine && pdev->domain != dom_io) ?
+    target = ((pdev->quarantine || iommu_quarantine) &&
+              pdev->domain != dom_io) ?
         dom_io : hardware_domain;
 
     while ( pdev->phantom_stride )
index 62a24d542a4b4c840c5429703622845608c52189..70ee53d083c42ed91c7713b4dd59122edf39d3ac 100644 (file)
@@ -53,7 +53,7 @@ static inline bool_t dfn_eq(dfn_t x, dfn_t y)
 }
 
 extern bool_t iommu_enable, iommu_enabled;
-extern bool_t force_iommu, iommu_verbose, iommu_igfx;
+extern bool force_iommu, iommu_quarantine, iommu_verbose, iommu_igfx;
 extern bool_t iommu_snoop, iommu_qinval, iommu_intremap, iommu_intpost;
 extern bool_t iommu_hap_pt_share;
 extern bool_t iommu_debug;