diff mbox series

[1/5] virtio-iommu: Default to bypass during boot

Message ID 20200821162839.3182051-2-jean-philippe@linaro.org
State Superseded
Headers show
Series virtio-iommu: Built-in topology and x86 support | expand

Commit Message

Jean-Philippe Brucker Aug. 21, 2020, 4:28 p.m. UTC
When a virtio-iommu is present, we currently require the guest to
configure it before it can use DMA in any other PCI device. This
prevents, for example, a bootloader that doesn't know how to drive
virtio-iommu from loading an OS from storage.

Add the "boot-bypass" option, defaulting to true, to let DMA bypass the
virtio-iommu during boot similarly to the other vIOMMUs. It makes the
system vulnerable to malicious endpoints during boot, but that isn't
much of a concern in virtual systems.

Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>

---
 include/hw/virtio/virtio-iommu.h |  1 +
 hw/virtio/virtio-iommu.c         | 22 ++++++++++++++++++++--
 2 files changed, 21 insertions(+), 2 deletions(-)

-- 
2.28.0
diff mbox series

Patch

diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
index 49eb105cd84..ae57efab1f3 100644
--- a/include/hw/virtio/virtio-iommu.h
+++ b/include/hw/virtio/virtio-iommu.h
@@ -58,6 +58,7 @@  typedef struct VirtIOIOMMU {
     GTree *domains;
     QemuMutex mutex;
     GTree *endpoints;
+    bool boot_bypass;
 } VirtIOIOMMU;
 
 #endif
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 5d56865e569..3b821fc005d 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -595,6 +595,24 @@  static void virtio_iommu_report_fault(VirtIOIOMMU *viommu, uint8_t reason,
 
 }
 
+static bool virtio_iommu_bypass_is_allowed(VirtIOIOMMU *s)
+{
+    VirtIODevice *vdev = &s->parent_obj;
+    /*
+     * Allow bypass if:
+     * - boot_bypass is enabled and the BYPASS feature hasn't yet been
+     *   acknowledged.
+     * - the BYPASS feature has been negotiated.
+     */
+    if (s->boot_bypass && !(vdev->status & VIRTIO_CONFIG_S_FEATURES_OK)) {
+        return true;
+    }
+    if (virtio_vdev_has_feature(vdev, VIRTIO_IOMMU_F_BYPASS)) {
+        return true;
+    }
+    return false;
+}
+
 static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
                                             IOMMUAccessFlags flag,
                                             int iommu_idx)
@@ -621,8 +639,7 @@  static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
         .perm = IOMMU_NONE,
     };
 
-    bypass_allowed = virtio_vdev_has_feature(&s->parent_obj,
-                                             VIRTIO_IOMMU_F_BYPASS);
+    bypass_allowed = virtio_iommu_bypass_is_allowed(s);
 
     sid = virtio_iommu_get_bdf(sdev);
 
@@ -947,6 +964,7 @@  static const VMStateDescription vmstate_virtio_iommu = {
 
 static Property virtio_iommu_properties[] = {
     DEFINE_PROP_LINK("primary-bus", VirtIOIOMMU, primary_bus, "PCI", PCIBus *),
+    DEFINE_PROP_BOOL("boot-bypass", VirtIOIOMMU, boot_bypass, true),
     DEFINE_PROP_END_OF_LIST(),
 };