In preparation to support VIRTIO_F_DMB, read the platform DMA bypass
quirk from either feature. The data DMA of a device that negotiates DMB
is routed through the IOMMU in front of the region it owns, so the
driver has to map every address it publishes through virtio_map_ops.
VIRTIO_F_ACCESS_PLATFORM asks a driver for the same thing, and
virtio_has_dma_quirk() looks only at it.

virtio_features_ok() demands VIRTIO_F_ACCESS_PLATFORM of a device under
restricted memory access, so accept VIRTIO_F_DMB there too.

Assisted-by: Kiro:claude-opus-5 checkpatch sparse
Signed-off-by: Alexander Graf <[email protected]>
---
 drivers/virtio/virtio.c       | 10 ++++++++--
 include/linux/virtio_config.h | 13 ++++++++++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 6f112593566c..3f9d4a3b5930 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -216,9 +216,15 @@ static int virtio_features_ok(struct virtio_device *dev)
                        return -ENODEV;
                }
 
-               if (!virtio_has_feature(dev, VIRTIO_F_ACCESS_PLATFORM)) {
+               /*
+                * VIRTIO_F_ACCESS_PLATFORM and VIRTIO_F_DMB both ensure that
+                * the device does not access guest memory directly, bypassing
+                * the platform DMA topology.
+                */
+               if (!virtio_has_feature(dev, VIRTIO_F_ACCESS_PLATFORM) &&
+                   !virtio_has_feature(dev, VIRTIO_F_DMB)) {
                        dev_warn(&dev->dev,
-                                "device must provide 
VIRTIO_F_ACCESS_PLATFORM\n");
+                                "device must provide VIRTIO_F_ACCESS_PLATFORM 
or VIRTIO_F_DMB\n");
                        return -ENODEV;
                }
        }
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index a10d7c27a2aa..a30eb708046a 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -273,8 +273,19 @@ static inline bool virtio_has_dma_quirk(const struct 
virtio_device *vdev)
        /*
         * Note the reverse polarity of the quirk feature (compared to most
         * other features), this is for compatibility with legacy systems.
+        *
+        * VIRTIO_F_ACCESS_PLATFORM says that the device is subject to the
+        * platform DMA topology and the driver maps every address it
+        * publishes through that topology.  The device performs no direct
+        * guest memory access, so the quirk does not apply.
+        *
+        * VIRTIO_F_DMB says that the device holds the virtqueues and the
+        * buffers they reference in a region it owns, and routes its data
+        * DMA through the IOMMU in front of that region.  The driver maps
+        * through that IOMMU, so the quirk does not apply either.
         */
-       return !virtio_has_feature(vdev, VIRTIO_F_ACCESS_PLATFORM);
+       return !(virtio_has_feature(vdev, VIRTIO_F_ACCESS_PLATFORM) ||
+                virtio_has_feature(vdev, VIRTIO_F_DMB));
 }
 
 static inline

Reply via email to