62547e
From c731ffdf9faee74e9522dff06e61cda817902088 Mon Sep 17 00:00:00 2001
62547e
From: Halil Pasic <pasic@linux.ibm.com>
62547e
Date: Mon, 7 Feb 2022 12:28:57 +0100
62547e
Subject: [PATCH 1/2] virtio: fix the condition for iommu_platform not
62547e
 supported
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: [1/2] d7edc7e3905a04644c9ff44b0d36122c72068e08
62547e
62547e
The commit 04ceb61a40 ("virtio: Fail if iommu_platform is requested, but
62547e
unsupported") claims to fail the device hotplug when iommu_platform
62547e
is requested, but not supported by the (vhost) device. On the first
62547e
glance the condition for detecting that situation looks perfect, but
62547e
because a certain peculiarity of virtio_platform it ain't.
62547e
62547e
In fact the aforementioned commit introduces a regression. It breaks
62547e
virtio-fs support for Secure Execution, and most likely also for AMD SEV
62547e
or any other confidential guest scenario that relies encrypted guest
62547e
memory.  The same also applies to any other vhost device that does not
62547e
support _F_ACCESS_PLATFORM.
62547e
62547e
The peculiarity is that iommu_platform and _F_ACCESS_PLATFORM collates
62547e
"device can not access all of the guest RAM" and "iova != gpa, thus
62547e
device needs to translate iova".
62547e
62547e
Confidential guest technologies currently rely on the device/hypervisor
62547e
offering _F_ACCESS_PLATFORM, so that, after the feature has been
62547e
negotiated, the guest  grants access to the portions of memory the
62547e
device needs to see. So in for confidential guests, generally,
62547e
_F_ACCESS_PLATFORM is about the restricted access to memory, but not
62547e
about the addresses used being something else than guest physical
62547e
addresses.
62547e
62547e
This is the very reason for which commit f7ef7e6e3b ("vhost: correctly
62547e
turn on VIRTIO_F_IOMMU_PLATFORM") fences _F_ACCESS_PLATFORM from the
62547e
vhost device that does not need it, because on the vhost interface it
62547e
only means "I/O address translation is needed".
62547e
62547e
This patch takes inspiration from f7ef7e6e3b ("vhost: correctly turn on
62547e
VIRTIO_F_IOMMU_PLATFORM"), and uses the same condition for detecting the
62547e
situation when _F_ACCESS_PLATFORM is requested, but no I/O translation
62547e
by the device, and thus no device capability is needed. In this
62547e
situation claiming that the device does not support iommu_plattform=on
62547e
is counter-productive. So let us stop doing that!
62547e
62547e
Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
62547e
Reported-by: Jakob Naucke <Jakob.Naucke@ibm.com>
62547e
Fixes: 04ceb61a40 ("virtio: Fail if iommu_platform is requested, but
62547e
unsupported")
62547e
Acked-by: Cornelia Huck <cohuck@redhat.com>
62547e
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
62547e
Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com>
62547e
Cc: Kevin Wolf <kwolf@redhat.com>
62547e
Cc: qemu-stable@nongnu.org
62547e
62547e
Message-Id: <20220207112857.607829-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
Acked-by: Jason Wang <jasowang@redhat.com>
62547e
(cherry picked from commit e65902a913bf31ba79a83a3bd3621108b85cf645)
62547e
---
62547e
 hw/virtio/virtio-bus.c | 12 +++++++-----
62547e
 1 file changed, 7 insertions(+), 5 deletions(-)
62547e
62547e
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
62547e
index d23db98c56..0f69d1c742 100644
62547e
--- a/hw/virtio/virtio-bus.c
62547e
+++ b/hw/virtio/virtio-bus.c
62547e
@@ -48,6 +48,7 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp)
62547e
     VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
62547e
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
62547e
     bool has_iommu = virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
62547e
+    bool vdev_has_iommu;
62547e
     Error *local_err = NULL;
62547e
 
62547e
     DPRINTF("%s: plug device.\n", qbus->name);
62547e
@@ -69,11 +70,6 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp)
62547e
         return;
62547e
     }
62547e
 
62547e
-    if (has_iommu && !virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
62547e
-        error_setg(errp, "iommu_platform=true is not supported by the device");
62547e
-        return;
62547e
-    }
62547e
-
62547e
     if (klass->device_plugged != NULL) {
62547e
         klass->device_plugged(qbus->parent, &local_err);
62547e
     }
62547e
@@ -82,9 +78,15 @@ 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
         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
+                       "iommu_platform=true is not supported by the device");
62547e
+            return;
62547e
+        }
62547e
     } else {
62547e
         vdev->dma_as = &address_space_memory;
62547e
     }
62547e
-- 
62547e
2.37.3
62547e