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

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