Blame SOURCES/kvm-virtio-fix-feature-negotiation-for-ACCESS_PLATFORM.patch

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