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

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