Blame SOURCES/kvm-s390x-pci-let-intercept-devices-have-separate-PCI-gr.patch

62547e
From b98a5bc4c21284dd0a8a1c86b91af81fcb75f060 Mon Sep 17 00:00:00 2001
62547e
From: Matthew Rosato <mjrosato@linux.ibm.com>
62547e
Date: Fri, 2 Sep 2022 13:27:35 -0400
62547e
Subject: [PATCH 10/42] s390x/pci: let intercept devices have separate PCI
62547e
 groups
62547e
MIME-Version: 1.0
62547e
Content-Type: text/plain; charset=UTF-8
62547e
Content-Transfer-Encoding: 8bit
62547e
62547e
RH-Author: Cédric Le Goater <clg@redhat.com>
62547e
RH-MergeRequest: 226: s390: Enhanced Interpretation for PCI Functions and Secure Execution guest dump
62547e
RH-Bugzilla: 1664378 2043909
62547e
RH-Acked-by: Thomas Huth <thuth@redhat.com>
62547e
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
62547e
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
62547e
RH-Commit: [10/41] 1545bdcd2e21386afa9869f0414e96eecb62647d
62547e
62547e
Let's use the reserved pool of simulated PCI groups to allow intercept
62547e
devices to have separate groups from interpreted devices as some group
62547e
values may be different. If we run out of simulated PCI groups, subsequent
62547e
intercept devices just get the default group.
62547e
Furthermore, if we encounter any PCI groups from hostdevs that are marked
62547e
as simulated, let's just assign them to the default group to avoid
62547e
conflicts between host simulated groups and our own simulated groups.
62547e
62547e
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
62547e
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
62547e
Message-Id: <20220902172737.170349-7-mjrosato@linux.ibm.com>
62547e
Signed-off-by: Thomas Huth <thuth@redhat.com>
62547e
(cherry picked from commit 30dcf4f7fd23bef7d72a2454c60881710fd4c785)
62547e
Signed-off-by: Cédric Le Goater <clg@redhat.com>
62547e
---
62547e
 hw/s390x/s390-pci-bus.c         | 19 ++++++++++++++--
62547e
 hw/s390x/s390-pci-vfio.c        | 40 ++++++++++++++++++++++++++++++---
62547e
 include/hw/s390x/s390-pci-bus.h |  6 ++++-
62547e
 3 files changed, 59 insertions(+), 6 deletions(-)
62547e
62547e
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
62547e
index cd152ce711..d8b1e44a02 100644
62547e
--- a/hw/s390x/s390-pci-bus.c
62547e
+++ b/hw/s390x/s390-pci-bus.c
62547e
@@ -748,13 +748,14 @@ static void s390_pci_iommu_free(S390pciState *s, PCIBus *bus, int32_t devfn)
62547e
     object_unref(OBJECT(iommu));
62547e
 }
62547e
 
62547e
-S390PCIGroup *s390_group_create(int id)
62547e
+S390PCIGroup *s390_group_create(int id, int host_id)
62547e
 {
62547e
     S390PCIGroup *group;
62547e
     S390pciState *s = s390_get_phb();
62547e
 
62547e
     group = g_new0(S390PCIGroup, 1);
62547e
     group->id = id;
62547e
+    group->host_id = host_id;
62547e
     QTAILQ_INSERT_TAIL(&s->zpci_groups, group, link);
62547e
     return group;
62547e
 }
62547e
@@ -772,12 +773,25 @@ S390PCIGroup *s390_group_find(int id)
62547e
     return NULL;
62547e
 }
62547e
 
62547e
+S390PCIGroup *s390_group_find_host_sim(int host_id)
62547e
+{
62547e
+    S390PCIGroup *group;
62547e
+    S390pciState *s = s390_get_phb();
62547e
+
62547e
+    QTAILQ_FOREACH(group, &s->zpci_groups, link) {
62547e
+        if (group->id >= ZPCI_SIM_GRP_START && group->host_id == host_id) {
62547e
+            return group;
62547e
+        }
62547e
+    }
62547e
+    return NULL;
62547e
+}
62547e
+
62547e
 static void s390_pci_init_default_group(void)
62547e
 {
62547e
     S390PCIGroup *group;
62547e
     ClpRspQueryPciGrp *resgrp;
62547e
 
62547e
-    group = s390_group_create(ZPCI_DEFAULT_FN_GRP);
62547e
+    group = s390_group_create(ZPCI_DEFAULT_FN_GRP, ZPCI_DEFAULT_FN_GRP);
62547e
     resgrp = &group->zpci_group;
62547e
     resgrp->fr = 1;
62547e
     resgrp->dasm = 0;
62547e
@@ -825,6 +839,7 @@ static void s390_pcihost_realize(DeviceState *dev, Error **errp)
62547e
                                            NULL, g_free);
62547e
     s->zpci_table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
62547e
     s->bus_no = 0;
62547e
+    s->next_sim_grp = ZPCI_SIM_GRP_START;
62547e
     QTAILQ_INIT(&s->pending_sei);
62547e
     QTAILQ_INIT(&s->zpci_devs);
62547e
     QTAILQ_INIT(&s->zpci_dma_limit);
62547e
diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c
62547e
index 08bcc55e85..338f436e87 100644
62547e
--- a/hw/s390x/s390-pci-vfio.c
62547e
+++ b/hw/s390x/s390-pci-vfio.c
62547e
@@ -150,13 +150,18 @@ static void s390_pci_read_group(S390PCIBusDevice *pbdev,
62547e
 {
62547e
     struct vfio_info_cap_header *hdr;
62547e
     struct vfio_device_info_cap_zpci_group *cap;
62547e
+    S390pciState *s = s390_get_phb();
62547e
     ClpRspQueryPciGrp *resgrp;
62547e
     VFIOPCIDevice *vpci =  container_of(pbdev->pdev, VFIOPCIDevice, pdev);
62547e
+    uint8_t start_gid = pbdev->zpci_fn.pfgid;
62547e
 
62547e
     hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_ZPCI_GROUP);
62547e
 
62547e
-    /* If capability not provided, just use the default group */
62547e
-    if (hdr == NULL) {
62547e
+    /*
62547e
+     * If capability not provided or the underlying hostdev is simulated, just
62547e
+     * use the default group.
62547e
+     */
62547e
+    if (hdr == NULL || pbdev->zpci_fn.pfgid >= ZPCI_SIM_GRP_START) {
62547e
         trace_s390_pci_clp_cap(vpci->vbasedev.name,
62547e
                                VFIO_DEVICE_INFO_CAP_ZPCI_GROUP);
62547e
         pbdev->zpci_fn.pfgid = ZPCI_DEFAULT_FN_GRP;
62547e
@@ -165,11 +170,40 @@ static void s390_pci_read_group(S390PCIBusDevice *pbdev,
62547e
     }
62547e
     cap = (void *) hdr;
62547e
 
62547e
+    /*
62547e
+     * For an intercept device, let's use an existing simulated group if one
62547e
+     * one was already created for other intercept devices in this group.
62547e
+     * If not, create a new simulated group if any are still available.
62547e
+     * If all else fails, just fall back on the default group.
62547e
+     */
62547e
+    if (!pbdev->interp) {
62547e
+        pbdev->pci_group = s390_group_find_host_sim(pbdev->zpci_fn.pfgid);
62547e
+        if (pbdev->pci_group) {
62547e
+            /* Use existing simulated group */
62547e
+            pbdev->zpci_fn.pfgid = pbdev->pci_group->id;
62547e
+            return;
62547e
+        } else {
62547e
+            if (s->next_sim_grp == ZPCI_DEFAULT_FN_GRP) {
62547e
+                /* All out of simulated groups, use default */
62547e
+                trace_s390_pci_clp_cap(vpci->vbasedev.name,
62547e
+                                       VFIO_DEVICE_INFO_CAP_ZPCI_GROUP);
62547e
+                pbdev->zpci_fn.pfgid = ZPCI_DEFAULT_FN_GRP;
62547e
+                pbdev->pci_group = s390_group_find(ZPCI_DEFAULT_FN_GRP);
62547e
+                return;
62547e
+            } else {
62547e
+                /* We can assign a new simulated group */
62547e
+                pbdev->zpci_fn.pfgid = s->next_sim_grp;
62547e
+                s->next_sim_grp++;
62547e
+                /* Fall through to create the new sim group using CLP info */
62547e
+            }
62547e
+        }
62547e
+    }
62547e
+
62547e
     /* See if the PCI group is already defined, create if not */
62547e
     pbdev->pci_group = s390_group_find(pbdev->zpci_fn.pfgid);
62547e
 
62547e
     if (!pbdev->pci_group) {
62547e
-        pbdev->pci_group = s390_group_create(pbdev->zpci_fn.pfgid);
62547e
+        pbdev->pci_group = s390_group_create(pbdev->zpci_fn.pfgid, start_gid);
62547e
 
62547e
         resgrp = &pbdev->pci_group->zpci_group;
62547e
         if (cap->flags & VFIO_DEVICE_INFO_ZPCI_FLAG_REFRESH) {
62547e
diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h
62547e
index 5b09f0cf2f..0605fcea24 100644
62547e
--- a/include/hw/s390x/s390-pci-bus.h
62547e
+++ b/include/hw/s390x/s390-pci-bus.h
62547e
@@ -315,13 +315,16 @@ typedef struct ZpciFmb {
62547e
 QEMU_BUILD_BUG_MSG(offsetof(ZpciFmb, fmt0) != 48, "padding in ZpciFmb");
62547e
 
62547e
 #define ZPCI_DEFAULT_FN_GRP 0xFF
62547e
+#define ZPCI_SIM_GRP_START 0xF0
62547e
 typedef struct S390PCIGroup {
62547e
     ClpRspQueryPciGrp zpci_group;
62547e
     int id;
62547e
+    int host_id;
62547e
     QTAILQ_ENTRY(S390PCIGroup) link;
62547e
 } S390PCIGroup;
62547e
-S390PCIGroup *s390_group_create(int id);
62547e
+S390PCIGroup *s390_group_create(int id, int host_id);
62547e
 S390PCIGroup *s390_group_find(int id);
62547e
+S390PCIGroup *s390_group_find_host_sim(int host_id);
62547e
 
62547e
 struct S390PCIBusDevice {
62547e
     DeviceState qdev;
62547e
@@ -370,6 +373,7 @@ struct S390pciState {
62547e
     QTAILQ_HEAD(, S390PCIBusDevice) zpci_devs;
62547e
     QTAILQ_HEAD(, S390PCIDMACount) zpci_dma_limit;
62547e
     QTAILQ_HEAD(, S390PCIGroup) zpci_groups;
62547e
+    uint8_t next_sim_grp;
62547e
 };
62547e
 
62547e
 S390pciState *s390_get_phb(void);
62547e
-- 
62547e
2.37.3
62547e