thebeanogamer / rpms / qemu-kvm

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