Blame SOURCES/kvm-s390x-pci-Fix-primary-bus-number-for-PCI-bridges.patch

ae23c9
From 160715e23b00c660f0dfee3f1bdc021f9693d222 Mon Sep 17 00:00:00 2001
ae23c9
From: Cornelia Huck <cohuck@redhat.com>
ae23c9
Date: Wed, 17 Apr 2019 13:57:36 +0100
ae23c9
Subject: [PATCH 19/24] s390x/pci: Fix primary bus number for PCI bridges
ae23c9
ae23c9
RH-Author: Cornelia Huck <cohuck@redhat.com>
ae23c9
Message-id: <20190417135741.25297-20-cohuck@redhat.com>
ae23c9
Patchwork-id: 85800
ae23c9
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH v2 19/24] s390x/pci: Fix primary bus number for PCI bridges
ae23c9
Bugzilla: 1699070
ae23c9
RH-Acked-by: David Hildenbrand <david@redhat.com>
ae23c9
RH-Acked-by: Thomas Huth <thuth@redhat.com>
ae23c9
RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
ae23c9
ae23c9
From: David Hildenbrand <david@redhat.com>
ae23c9
ae23c9
The primary bus number corresponds always to the bus number of the
ae23c9
bus the bridge is attached to.
ae23c9
ae23c9
Right now, if we have two bridges attached to the same bus (e.g. root
ae23c9
bus) this is however not the case. The first bridge will have primary
ae23c9
bus 0, the second bridge primary bus 1, which is wrong. Fix the assignment.
ae23c9
ae23c9
While at it, drop setting the PCI_SUBORDINATE_BUS temporarily to 0xff.
ae23c9
Setting it temporarily to that value (as discussed e.g. in [1]), is
ae23c9
only relevant for a running system that probes the buses. The value is
ae23c9
effectively unused for us just doing a DFS.
ae23c9
ae23c9
Also add a comment why we have to reassign during every reset (which I
ae23c9
found to be surprising.
ae23c9
ae23c9
Please note that hotplugging of bridges is in general still broken, will
ae23c9
be fixed next.
ae23c9
ae23c9
[1] http://www.science.unitn.it/~fiorella/guidelinux/tlk/node76.html
ae23c9
ae23c9
Reviewed-by: Thomas Huth <thuth@redhat.com>
ae23c9
Signed-off-by: David Hildenbrand <david@redhat.com>
ae23c9
Message-Id: <20190130155733.32742-2-david@redhat.com>
ae23c9
Reviewed-by: Collin Walling <walling@linux.ibm.com>
ae23c9
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
ae23c9
(cherry picked from commit d30a7507edf1ca23d33dbf00b25f5e49a7808492)
ae23c9
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
ae23c9
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ae23c9
---
ae23c9
 hw/s390x/s390-pci-bus.c | 13 ++++++++-----
ae23c9
 1 file changed, 8 insertions(+), 5 deletions(-)
ae23c9
ae23c9
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
ae23c9
index 07a286a..309ad79 100644
ae23c9
--- a/hw/s390x/s390-pci-bus.c
ae23c9
+++ b/hw/s390x/s390-pci-bus.c
ae23c9
@@ -900,7 +900,8 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
ae23c9
         qbus_set_hotplug_handler(bus, DEVICE(s), errp);
ae23c9
 
ae23c9
         if (dev->hotplugged) {
ae23c9
-            pci_default_write_config(pdev, PCI_PRIMARY_BUS, s->bus_no, 1);
ae23c9
+            pci_default_write_config(pdev, PCI_PRIMARY_BUS,
ae23c9
+                                     pci_dev_bus_num(pdev), 1);
ae23c9
             s->bus_no += 1;
ae23c9
             pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1);
ae23c9
             do {
ae23c9
@@ -1053,8 +1054,6 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
ae23c9
                                       void *opaque)
ae23c9
 {
ae23c9
     S390pciState *s = opaque;
ae23c9
-    unsigned int primary = s->bus_no;
ae23c9
-    unsigned int subordinate = 0xff;
ae23c9
     PCIBus *sec_bus = NULL;
ae23c9
 
ae23c9
     if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) !=
ae23c9
@@ -1063,7 +1062,7 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
ae23c9
     }
ae23c9
 
ae23c9
     (s->bus_no)++;
ae23c9
-    pci_default_write_config(pdev, PCI_PRIMARY_BUS, primary, 1);
ae23c9
+    pci_default_write_config(pdev, PCI_PRIMARY_BUS, pci_dev_bus_num(pdev), 1);
ae23c9
     pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1);
ae23c9
     pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, s->bus_no, 1);
ae23c9
 
ae23c9
@@ -1072,7 +1071,7 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
ae23c9
         return;
ae23c9
     }
ae23c9
 
ae23c9
-    pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, subordinate, 1);
ae23c9
+    /* Assign numbers to all child bridges. The last is the highest number. */
ae23c9
     pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
ae23c9
                         s390_pci_enumerate_bridge, s);
ae23c9
     pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, s->bus_no, 1);
ae23c9
@@ -1083,6 +1082,10 @@ static void s390_pcihost_reset(DeviceState *dev)
ae23c9
     S390pciState *s = S390_PCI_HOST_BRIDGE(dev);
ae23c9
     PCIBus *bus = s->parent_obj.bus;
ae23c9
 
ae23c9
+    /*
ae23c9
+     * When resetting a PCI bridge, the assigned numbers are set to 0. So
ae23c9
+     * on every system reset, we also have to reassign numbers.
ae23c9
+     */
ae23c9
     s->bus_no = 0;
ae23c9
     pci_for_each_device(bus, pci_bus_num(bus), s390_pci_enumerate_bridge, s);
ae23c9
 }
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9