62547e
From 56e2aef97e750ffdc572dcecbfc31314728d37a9 Mon Sep 17 00:00:00 2001
62547e
From: Halil Pasic <pasic@linux.ibm.com>
62547e
Date: Mon, 7 Mar 2022 12:29:39 +0100
62547e
Subject: [PATCH 2/2] virtio: fix feature negotiation for ACCESS_PLATFORM
62547e
MIME-Version: 1.0
62547e
Content-Type: text/plain; charset=UTF-8
62547e
Content-Transfer-Encoding: 8bit
62547e
62547e
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
62547e
RH-MergeRequest: 224: virtiofs on s390 secure execution
62547e
RH-Bugzilla: 2116302
62547e
RH-Acked-by: Thomas Huth <thuth@redhat.com>
62547e
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
62547e
RH-Acked-by: Cédric Le Goater <None>
62547e
RH-Commit: [2/2] 264d3bdbbde985f16ed6f5a1786547c25fb8cc04
62547e
62547e
Unlike most virtio features ACCESS_PLATFORM is considered mandatory by
62547e
QEMU, i.e. the driver must accept it if offered by the device. The
62547e
virtio specification says that the driver SHOULD accept the
62547e
ACCESS_PLATFORM feature if offered, and that the device MAY fail to
62547e
operate if ACCESS_PLATFORM was offered but not negotiated.
62547e
62547e
While a SHOULD ain't exactly a MUST, we are certainly allowed to fail
62547e
the device when the driver fences ACCESS_PLATFORM. With commit
62547e
2943b53f68 ("virtio: force VIRTIO_F_IOMMU_PLATFORM") we already made the
62547e
decision to do so whenever the get_dma_as() callback is implemented (by
62547e
the bus), which in practice means for the entirety of virtio-pci.
62547e
62547e
That means, if the device needs to translate I/O addresses, then
62547e
ACCESS_PLATFORM is mandatory. The aforementioned commit tells us in the
62547e
commit message that this is for security reasons. More precisely if we
62547e
were to allow a less then trusted driver (e.g. an user-space driver, or
62547e
a nested guest) to make the device bypass the IOMMU by not negotiating
62547e
ACCESS_PLATFORM, then the guest kernel would have no ability to
62547e
control/police (by programming the IOMMU) what pieces of guest memory
62547e
the driver may manipulate using the device. Which would break security
62547e
assumptions within the guest.
62547e
62547e
If ACCESS_PLATFORM is offered not because we want the device to utilize
62547e
an IOMMU and do address translation, but because the device does not
62547e
have access to the entire guest RAM, and needs the driver to grant
62547e
access to the bits it needs access to (e.g. confidential guest support),
62547e
we still require the guest to have the corresponding logic and to accept
62547e
ACCESS_PLATFORM. If the driver does not accept ACCESS_PLATFORM, then
62547e
things are bound to go wrong, and we may see failures much less graceful
62547e
than failing the device because the driver didn't negotiate
62547e
ACCESS_PLATFORM.
62547e
62547e
So let us make ACCESS_PLATFORM mandatory for the driver regardless
62547e
of whether the get_dma_as() callback is implemented or not.
62547e
62547e
Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
62547e
Fixes: 2943b53f68 ("virtio: force VIRTIO_F_IOMMU_PLATFORM")
62547e
62547e
Message-Id: <20220307112939.2780117-1-pasic@linux.ibm.com>
62547e
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
62547e
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
62547e
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
62547e
(cherry picked from commit 06134e2bc35dc21543d4cbcf31f858c03d383442)
62547e
---
62547e
 hw/virtio/virtio-bus.c | 22 ++++++++++++++--------
62547e
 1 file changed, 14 insertions(+), 8 deletions(-)
62547e
62547e
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
62547e
index 0f69d1c742..d7ec023adf 100644
62547e
--- a/hw/virtio/virtio-bus.c
62547e
+++ b/hw/virtio/virtio-bus.c
62547e
@@ -78,17 +78,23 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp)
62547e
         return;
62547e
     }
62547e
 
62547e
-    vdev_has_iommu = virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
62547e
-    if (klass->get_dma_as != NULL && has_iommu) {
62547e
+    vdev->dma_as = &address_space_memory;
62547e
+    if (has_iommu) {
62547e
+        vdev_has_iommu = virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
62547e
+        /*
62547e
+         * Present IOMMU_PLATFORM to the driver iff iommu_plattform=on and
62547e
+         * device operational. If the driver does not accept IOMMU_PLATFORM
62547e
+         * we fail the device.
62547e
+         */
62547e
         virtio_add_feature(&vdev->host_features, VIRTIO_F_IOMMU_PLATFORM);
62547e
-        vdev->dma_as = klass->get_dma_as(qbus->parent);
62547e
-        if (!vdev_has_iommu && vdev->dma_as != &address_space_memory) {
62547e
-            error_setg(errp,
62547e
+        if (klass->get_dma_as) {
62547e
+            vdev->dma_as = klass->get_dma_as(qbus->parent);
62547e
+            if (!vdev_has_iommu && vdev->dma_as != &address_space_memory) {
62547e
+                error_setg(errp,
62547e
                        "iommu_platform=true is not supported by the device");
62547e
-            return;
62547e
+                return;
62547e
+            }
62547e
         }
62547e
-    } else {
62547e
-        vdev->dma_as = &address_space_memory;
62547e
     }
62547e
 }
62547e
 
62547e
-- 
62547e
2.37.3
62547e