thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone

Blame SOURCES/kvm-s390x-pci-enable-adapter-event-notification-for-inte.patch

bf143f
From 362fae654bbae03741003e565fb95d73d8c0025f Mon Sep 17 00:00:00 2001
bf143f
From: Matthew Rosato <mjrosato@linux.ibm.com>
bf143f
Date: Fri, 2 Sep 2022 13:27:34 -0400
bf143f
Subject: [PATCH 09/42] s390x/pci: enable adapter event notification for
bf143f
 interpreted devices
bf143f
MIME-Version: 1.0
bf143f
Content-Type: text/plain; charset=UTF-8
bf143f
Content-Transfer-Encoding: 8bit
bf143f
bf143f
RH-Author: Cédric Le Goater <clg@redhat.com>
bf143f
RH-MergeRequest: 226: s390: Enhanced Interpretation for PCI Functions and Secure Execution guest dump
bf143f
RH-Bugzilla: 1664378 2043909
bf143f
RH-Acked-by: Thomas Huth <thuth@redhat.com>
bf143f
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
bf143f
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
bf143f
RH-Commit: [9/41] 771975c436c7cb608e0e9e40edd732ac310beb69
bf143f
bf143f
Use the associated kvm ioctl operation to enable adapter event notification
bf143f
and forwarding for devices when requested.  This feature will be set up
bf143f
with or without firmware assist based upon the 'forwarding_assist' setting.
bf143f
bf143f
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
bf143f
Message-Id: <20220902172737.170349-6-mjrosato@linux.ibm.com>
bf143f
[thuth: Rename "forwarding_assist" property to "forwarding-assist"]
bf143f
Signed-off-by: Thomas Huth <thuth@redhat.com>
bf143f
(cherry picked from commit d0bc7091c2013ad2fa164100cf7b17962370e8ab)
bf143f
Signed-off-by: Cédric Le Goater <clg@redhat.com>
bf143f
---
bf143f
 hw/s390x/s390-pci-bus.c         | 20 ++++++++++++++---
bf143f
 hw/s390x/s390-pci-inst.c        | 40 +++++++++++++++++++++++++++++++--
bf143f
 hw/s390x/s390-pci-kvm.c         | 30 +++++++++++++++++++++++++
bf143f
 include/hw/s390x/s390-pci-bus.h |  1 +
bf143f
 include/hw/s390x/s390-pci-kvm.h | 14 ++++++++++++
bf143f
 5 files changed, 100 insertions(+), 5 deletions(-)
bf143f
bf143f
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
bf143f
index 07c7c155e3..cd152ce711 100644
bf143f
--- a/hw/s390x/s390-pci-bus.c
bf143f
+++ b/hw/s390x/s390-pci-bus.c
bf143f
@@ -190,7 +190,10 @@ void s390_pci_sclp_deconfigure(SCCB *sccb)
bf143f
         rc = SCLP_RC_NO_ACTION_REQUIRED;
bf143f
         break;
bf143f
     default:
bf143f
-        if (pbdev->summary_ind) {
bf143f
+        if (pbdev->interp && (pbdev->fh & FH_MASK_ENABLE)) {
bf143f
+            /* Interpreted devices were using interrupt forwarding */
bf143f
+            s390_pci_kvm_aif_disable(pbdev);
bf143f
+        } else if (pbdev->summary_ind) {
bf143f
             pci_dereg_irqs(pbdev);
bf143f
         }
bf143f
         if (pbdev->iommu->enabled) {
bf143f
@@ -1082,6 +1085,7 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
bf143f
                 } else {
bf143f
                     DPRINTF("zPCI interpretation facilities missing.\n");
bf143f
                     pbdev->interp = false;
bf143f
+                    pbdev->forwarding_assist = false;
bf143f
                 }
bf143f
             }
bf143f
             pbdev->iommu->dma_limit = s390_pci_start_dma_count(s, pbdev);
bf143f
@@ -1090,11 +1094,13 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
bf143f
             if (!pbdev->interp) {
bf143f
                 /* Do vfio passthrough but intercept for I/O */
bf143f
                 pbdev->fh |= FH_SHM_VFIO;
bf143f
+                pbdev->forwarding_assist = false;
bf143f
             }
bf143f
         } else {
bf143f
             pbdev->fh |= FH_SHM_EMUL;
bf143f
             /* Always intercept emulated devices */
bf143f
             pbdev->interp = false;
bf143f
+            pbdev->forwarding_assist = false;
bf143f
         }
bf143f
 
bf143f
         if (s390_pci_msix_init(pbdev) && !pbdev->interp) {
bf143f
@@ -1244,7 +1250,10 @@ static void s390_pcihost_reset(DeviceState *dev)
bf143f
     /* Process all pending unplug requests */
bf143f
     QTAILQ_FOREACH_SAFE(pbdev, &s->zpci_devs, link, next) {
bf143f
         if (pbdev->unplug_requested) {
bf143f
-            if (pbdev->summary_ind) {
bf143f
+            if (pbdev->interp && (pbdev->fh & FH_MASK_ENABLE)) {
bf143f
+                /* Interpreted devices were using interrupt forwarding */
bf143f
+                s390_pci_kvm_aif_disable(pbdev);
bf143f
+            } else if (pbdev->summary_ind) {
bf143f
                 pci_dereg_irqs(pbdev);
bf143f
             }
bf143f
             if (pbdev->iommu->enabled) {
bf143f
@@ -1382,7 +1391,10 @@ static void s390_pci_device_reset(DeviceState *dev)
bf143f
         break;
bf143f
     }
bf143f
 
bf143f
-    if (pbdev->summary_ind) {
bf143f
+    if (pbdev->interp && (pbdev->fh & FH_MASK_ENABLE)) {
bf143f
+        /* Interpreted devices were using interrupt forwarding */
bf143f
+        s390_pci_kvm_aif_disable(pbdev);
bf143f
+    } else if (pbdev->summary_ind) {
bf143f
         pci_dereg_irqs(pbdev);
bf143f
     }
bf143f
     if (pbdev->iommu->enabled) {
bf143f
@@ -1428,6 +1440,8 @@ static Property s390_pci_device_properties[] = {
bf143f
     DEFINE_PROP_S390_PCI_FID("fid", S390PCIBusDevice, fid),
bf143f
     DEFINE_PROP_STRING("target", S390PCIBusDevice, target),
bf143f
     DEFINE_PROP_BOOL("interpret", S390PCIBusDevice, interp, true),
bf143f
+    DEFINE_PROP_BOOL("forwarding-assist", S390PCIBusDevice, forwarding_assist,
bf143f
+                     true),
bf143f
     DEFINE_PROP_END_OF_LIST(),
bf143f
 };
bf143f
 
bf143f
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
bf143f
index 651ec38635..20a9bcc7af 100644
bf143f
--- a/hw/s390x/s390-pci-inst.c
bf143f
+++ b/hw/s390x/s390-pci-inst.c
bf143f
@@ -1066,6 +1066,32 @@ static void fmb_update(void *opaque)
bf143f
     timer_mod(pbdev->fmb_timer, t + pbdev->pci_group->zpci_group.mui);
bf143f
 }
bf143f
 
bf143f
+static int mpcifc_reg_int_interp(S390PCIBusDevice *pbdev, ZpciFib *fib)
bf143f
+{
bf143f
+    int rc;
bf143f
+
bf143f
+    rc = s390_pci_kvm_aif_enable(pbdev, fib, pbdev->forwarding_assist);
bf143f
+    if (rc) {
bf143f
+        DPRINTF("Failed to enable interrupt forwarding\n");
bf143f
+        return rc;
bf143f
+    }
bf143f
+
bf143f
+    return 0;
bf143f
+}
bf143f
+
bf143f
+static int mpcifc_dereg_int_interp(S390PCIBusDevice *pbdev, ZpciFib *fib)
bf143f
+{
bf143f
+    int rc;
bf143f
+
bf143f
+    rc = s390_pci_kvm_aif_disable(pbdev);
bf143f
+    if (rc) {
bf143f
+        DPRINTF("Failed to disable interrupt forwarding\n");
bf143f
+        return rc;
bf143f
+    }
bf143f
+
bf143f
+    return 0;
bf143f
+}
bf143f
+
bf143f
 int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
bf143f
                         uintptr_t ra)
bf143f
 {
bf143f
@@ -1120,7 +1146,12 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
bf143f
 
bf143f
     switch (oc) {
bf143f
     case ZPCI_MOD_FC_REG_INT:
bf143f
-        if (pbdev->summary_ind) {
bf143f
+        if (pbdev->interp) {
bf143f
+            if (mpcifc_reg_int_interp(pbdev, &fib)) {
bf143f
+                cc = ZPCI_PCI_LS_ERR;
bf143f
+                s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
bf143f
+            }
bf143f
+        } else if (pbdev->summary_ind) {
bf143f
             cc = ZPCI_PCI_LS_ERR;
bf143f
             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
bf143f
         } else if (reg_irqs(env, pbdev, fib)) {
bf143f
@@ -1129,7 +1160,12 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
bf143f
         }
bf143f
         break;
bf143f
     case ZPCI_MOD_FC_DEREG_INT:
bf143f
-        if (!pbdev->summary_ind) {
bf143f
+        if (pbdev->interp) {
bf143f
+            if (mpcifc_dereg_int_interp(pbdev, &fib)) {
bf143f
+                cc = ZPCI_PCI_LS_ERR;
bf143f
+                s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
bf143f
+            }
bf143f
+        } else if (!pbdev->summary_ind) {
bf143f
             cc = ZPCI_PCI_LS_ERR;
bf143f
             s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
bf143f
         } else {
bf143f
diff --git a/hw/s390x/s390-pci-kvm.c b/hw/s390x/s390-pci-kvm.c
bf143f
index 0f16104a74..9134fe185f 100644
bf143f
--- a/hw/s390x/s390-pci-kvm.c
bf143f
+++ b/hw/s390x/s390-pci-kvm.c
bf143f
@@ -11,12 +11,42 @@
bf143f
 
bf143f
 #include "qemu/osdep.h"
bf143f
 
bf143f
+#include <linux/kvm.h>
bf143f
+
bf143f
 #include "kvm/kvm_s390x.h"
bf143f
 #include "hw/s390x/pv.h"
bf143f
+#include "hw/s390x/s390-pci-bus.h"
bf143f
 #include "hw/s390x/s390-pci-kvm.h"
bf143f
+#include "hw/s390x/s390-pci-inst.h"
bf143f
 #include "cpu_models.h"
bf143f
 
bf143f
 bool s390_pci_kvm_interp_allowed(void)
bf143f
 {
bf143f
     return kvm_s390_get_zpci_op() && !s390_is_pv();
bf143f
 }
bf143f
+
bf143f
+int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib, bool assist)
bf143f
+{
bf143f
+    struct kvm_s390_zpci_op args = {
bf143f
+        .fh = pbdev->fh,
bf143f
+        .op = KVM_S390_ZPCIOP_REG_AEN,
bf143f
+        .u.reg_aen.ibv = fib->aibv,
bf143f
+        .u.reg_aen.sb = fib->aisb,
bf143f
+        .u.reg_aen.noi = FIB_DATA_NOI(fib->data),
bf143f
+        .u.reg_aen.isc = FIB_DATA_ISC(fib->data),
bf143f
+        .u.reg_aen.sbo = FIB_DATA_AISBO(fib->data),
bf143f
+        .u.reg_aen.flags = (assist) ? 0 : KVM_S390_ZPCIOP_REGAEN_HOST
bf143f
+    };
bf143f
+
bf143f
+    return kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args);
bf143f
+}
bf143f
+
bf143f
+int s390_pci_kvm_aif_disable(S390PCIBusDevice *pbdev)
bf143f
+{
bf143f
+    struct kvm_s390_zpci_op args = {
bf143f
+        .fh = pbdev->fh,
bf143f
+        .op = KVM_S390_ZPCIOP_DEREG_AEN
bf143f
+    };
bf143f
+
bf143f
+    return kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args);
bf143f
+}
bf143f
diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h
bf143f
index a9843dfe97..5b09f0cf2f 100644
bf143f
--- a/include/hw/s390x/s390-pci-bus.h
bf143f
+++ b/include/hw/s390x/s390-pci-bus.h
bf143f
@@ -351,6 +351,7 @@ struct S390PCIBusDevice {
bf143f
     bool pci_unplug_request_processed;
bf143f
     bool unplug_requested;
bf143f
     bool interp;
bf143f
+    bool forwarding_assist;
bf143f
     QTAILQ_ENTRY(S390PCIBusDevice) link;
bf143f
 };
bf143f
 
bf143f
diff --git a/include/hw/s390x/s390-pci-kvm.h b/include/hw/s390x/s390-pci-kvm.h
bf143f
index 80a2e7d0ca..933814a402 100644
bf143f
--- a/include/hw/s390x/s390-pci-kvm.h
bf143f
+++ b/include/hw/s390x/s390-pci-kvm.h
bf143f
@@ -12,13 +12,27 @@
bf143f
 #ifndef HW_S390_PCI_KVM_H
bf143f
 #define HW_S390_PCI_KVM_H
bf143f
 
bf143f
+#include "hw/s390x/s390-pci-bus.h"
bf143f
+#include "hw/s390x/s390-pci-inst.h"
bf143f
+
bf143f
 #ifdef CONFIG_KVM
bf143f
 bool s390_pci_kvm_interp_allowed(void);
bf143f
+int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib, bool assist);
bf143f
+int s390_pci_kvm_aif_disable(S390PCIBusDevice *pbdev);
bf143f
 #else
bf143f
 static inline bool s390_pci_kvm_interp_allowed(void)
bf143f
 {
bf143f
     return false;
bf143f
 }
bf143f
+static inline int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib,
bf143f
+                                          bool assist)
bf143f
+{
bf143f
+    return -EINVAL;
bf143f
+}
bf143f
+static inline int s390_pci_kvm_aif_disable(S390PCIBusDevice *pbdev)
bf143f
+{
bf143f
+    return -EINVAL;
bf143f
+}
bf143f
 #endif
bf143f
 
bf143f
 #endif
bf143f
-- 
bf143f
2.37.3
bf143f