[PATCH v4 08/11] s390x/pci: use KVM-managed IOMMU for interpretation

Matthew Rosato posted 11 patches 3 years, 11 months ago
Maintainers: Halil Pasic <pasic@linux.ibm.com>, Christian Borntraeger <borntraeger@linux.ibm.com>, Eric Farman <farman@linux.ibm.com>, Cornelia Huck <cohuck@redhat.com>, Thomas Huth <thuth@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, David Hildenbrand <david@redhat.com>, Matthew Rosato <mjrosato@linux.ibm.com>, Tony Krowiak <akrowiak@linux.ibm.com>, Jason Herne <jjherne@linux.ibm.com>, Alex Williamson <alex.williamson@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
There is a newer version of this series
[PATCH v4 08/11] s390x/pci: use KVM-managed IOMMU for interpretation
Posted by Matthew Rosato 3 years, 11 months ago
When interpreting zPCI instructions, KVM will control the IOMMU mappings
in response to RPCIT instructions rather than relying on mapping ioctls
from userspace.  Mark the vfio device in pre_plug so that the appropriate
iommu domain will be allocated on the host during VFIO_SET_IOMMU.

Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
---
 hw/s390x/s390-pci-bus.c          | 11 +++++++++++
 hw/s390x/s390-pci-vfio.c         | 22 ++++++++++++++++++++++
 include/hw/s390x/s390-pci-vfio.h |  5 +++++
 3 files changed, 38 insertions(+)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 5043b8c85c..513a276711 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -950,6 +950,17 @@ static void s390_pcihost_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
             error_setg(errp, "multifunction not supported in s390");
             return;
         }
+        /*
+         * If we have a vfio-pci device that wishes to use interpretation
+         * we must update the host IOMMU domain ops.
+         */
+        if (s390_pci_kvm_zpciop_allowed() &&
+            object_dynamic_cast(OBJECT(dev), "vfio-pci")) {
+            if (s390_pci_set_kvm_iommu(s, dev)) {
+                error_setg(errp, "KVM IOMMU not available for interpretation");
+                return;
+            }
+        }
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
         S390PCIBusDevice *pbdev = S390_PCI_DEVICE(dev);
 
diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c
index 4bf0a7e22d..7808e8d939 100644
--- a/hw/s390x/s390-pci-vfio.c
+++ b/hw/s390x/s390-pci-vfio.c
@@ -324,3 +324,25 @@ void s390_pci_get_clp_info(S390PCIBusDevice *pbdev)
 
     return;
 }
+
+/*
+ * This function will determine if the specified VFIOPCIDevice is linked to a
+ * zPCI device that requests interpretation support.  In this case, we must
+ * inform vfio that the KVM-managed IOMMU should be requested when the
+ * VFIO_SET_IOMMU ioctl is issued.
+ */
+int s390_pci_set_kvm_iommu(S390pciState *s, DeviceState *dev)
+{
+    VFIOPCIDevice *vdev = VFIO_PCI(dev);
+    S390PCIBusDevice *pbdev = s390_pci_find_dev_by_target(s, dev->id);
+
+    if (!pbdev) {
+        return -ENODEV;
+    }
+
+    if (pbdev->interp) {
+        vdev->kvm_managed_iommu = true;
+    }
+
+    return 0;
+}
diff --git a/include/hw/s390x/s390-pci-vfio.h b/include/hw/s390x/s390-pci-vfio.h
index 0c2e4b5175..5026f978c2 100644
--- a/include/hw/s390x/s390-pci-vfio.h
+++ b/include/hw/s390x/s390-pci-vfio.h
@@ -22,6 +22,7 @@ S390PCIDMACount *s390_pci_start_dma_count(S390pciState *s,
 void s390_pci_end_dma_count(S390pciState *s, S390PCIDMACount *cnt);
 bool s390_pci_get_host_fh(S390PCIBusDevice *pbdev, uint32_t *fh);
 void s390_pci_get_clp_info(S390PCIBusDevice *pbdev);
+int s390_pci_set_kvm_iommu(S390pciState *s, DeviceState *dev);
 #else
 static inline bool s390_pci_update_dma_avail(int fd, unsigned int *avail)
 {
@@ -40,6 +41,10 @@ static inline bool s390_pci_get_host_fh(S390PCIBusDevice *pbdev,
     return false;
 }
 static inline void s390_pci_get_clp_info(S390PCIBusDevice *pbdev) { }
+static inline int s390_pci_set_kvm_iommu(S390pciState *s, DeviceState *dev)
+{
+    return -EINVAL;
+}
 #endif
 
 #endif
-- 
2.27.0