|
|
aa0606 |
From ded76fad62293d5dbe4eebf30d3b19c9eb8330de Mon Sep 17 00:00:00 2001
|
|
|
aa0606 |
From: Igor Mammedov <imammedo@redhat.com>
|
|
|
aa0606 |
Date: Mon, 29 Nov 2021 06:48:11 -0500
|
|
|
aa0606 |
Subject: pci: reserve resources for pcie-pci-bridge to fix regressed hotplug
|
|
|
aa0606 |
on q35
|
|
|
aa0606 |
|
|
|
aa0606 |
RH-Bugzilla: 2001732
|
|
|
aa0606 |
|
|
|
aa0606 |
If QEMU is started with unpopulated pcie-pci-bridge with ACPI PCI
|
|
|
aa0606 |
hotplug enabled (default since QEMU-6.1), hotplugging a PCI device
|
|
|
aa0606 |
into one of the bridge slots fails due to lack of resources.
|
|
|
aa0606 |
|
|
|
aa0606 |
once linux guest is booted (test used Fedora 34), hotplug NIC from
|
|
|
aa0606 |
QEMU monitor:
|
|
|
aa0606 |
(qemu) device_add rtl8139,bus=pcie-pci-bridge-0,addr=0x2
|
|
|
aa0606 |
|
|
|
aa0606 |
guest fails hotplug with:
|
|
|
aa0606 |
pci 0000:01:02.0: [10ec:8139] type 00 class 0x020000
|
|
|
aa0606 |
pci 0000:01:02.0: reg 0x10: [io 0x0000-0x00ff]
|
|
|
aa0606 |
pci 0000:01:02.0: reg 0x14: [mem 0x00000000-0x000000ff]
|
|
|
aa0606 |
pci 0000:01:02.0: reg 0x30: [mem 0x00000000-0x0003ffff pref]
|
|
|
aa0606 |
pci 0000:01:02.0: BAR 6: no space for [mem size 0x00040000 pref]
|
|
|
aa0606 |
pci 0000:01:02.0: BAR 6: failed to assign [mem size 0x00040000 pref]
|
|
|
aa0606 |
pci 0000:01:02.0: BAR 0: no space for [io size 0x0100]
|
|
|
aa0606 |
pci 0000:01:02.0: BAR 0: failed to assign [io size 0x0100]
|
|
|
aa0606 |
pci 0000:01:02.0: BAR 1: no space for [mem size 0x00000100]
|
|
|
aa0606 |
pci 0000:01:02.0: BAR 1: failed to assign [mem size 0x00000100]
|
|
|
aa0606 |
8139cp: 8139cp: 10/100 PCI Ethernet driver v1.3 (Mar 22, 2004)
|
|
|
aa0606 |
PCI Interrupt Link [GSIG] enabled at IRQ 22
|
|
|
aa0606 |
8139cp 0000:01:02.0: no MMIO resource
|
|
|
aa0606 |
8139cp: probe of 0000:01:02.0 failed with error -5
|
|
|
aa0606 |
|
|
|
aa0606 |
Reason for this is that commit [1] didn't take into account
|
|
|
aa0606 |
pcie-pci-bridge, marking bridge as non hotpluggable instead of
|
|
|
aa0606 |
handling it as possibly SHPC capable bridge.
|
|
|
aa0606 |
Fix issue by checking if pcie-pci-bridge is SHPC capable and
|
|
|
aa0606 |
if it is mark it as hotpluggable.
|
|
|
aa0606 |
|
|
|
aa0606 |
Fixes regression in QEMU-6.1 and later, since it was switched
|
|
|
aa0606 |
to ACPI based PCI hotplug on Q35 by default at that time.
|
|
|
aa0606 |
|
|
|
aa0606 |
[1]
|
|
|
aa0606 |
Fixes: 3aa31d7d637 ("hw/pci: reserve IO and mem for pci express downstream ports with no devices attached")
|
|
|
aa0606 |
Signed-off-by: Igor Mammedov imammedo@redhat.com
|
|
|
aa0606 |
CC: mapfelba@redhat.com
|
|
|
aa0606 |
CC: kraxel@redhat.com
|
|
|
aa0606 |
CC: mst@redhat.com
|
|
|
aa0606 |
CC: lvivier@redhat.com
|
|
|
aa0606 |
CC: jusual@redhat.com
|
|
|
aa0606 |
Tested-by: Laurent Vivier <lvivier@redhat.com>
|
|
|
aa0606 |
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
aa0606 |
Message-Id: <20211129114812.231849-2-imammedo@redhat.com>
|
|
|
aa0606 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
aa0606 |
---
|
|
|
aa0606 |
src/fw/pciinit.c | 5 +++++
|
|
|
aa0606 |
1 file changed, 5 insertions(+)
|
|
|
aa0606 |
|
|
|
aa0606 |
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
|
|
|
aa0606 |
index 3c99d514..badf13d3 100644
|
|
|
aa0606 |
--- a/src/fw/pciinit.c
|
|
|
aa0606 |
+++ b/src/fw/pciinit.c
|
|
|
aa0606 |
@@ -808,6 +808,10 @@ static hotplug_type_t pci_bus_hotplug_support(struct pci_bus *bus, u8 pcie_cap)
|
|
|
aa0606 |
pcie_cap + PCI_EXP_FLAGS);
|
|
|
aa0606 |
u8 port_type = ((pcie_flags & PCI_EXP_FLAGS_TYPE) >>
|
|
|
aa0606 |
(__builtin_ffs(PCI_EXP_FLAGS_TYPE) - 1));
|
|
|
aa0606 |
+
|
|
|
aa0606 |
+ if (port_type == PCI_EXP_TYPE_PCI_BRIDGE)
|
|
|
aa0606 |
+ goto check_shpc;
|
|
|
aa0606 |
+
|
|
|
aa0606 |
u8 downstream_port = (port_type == PCI_EXP_TYPE_DOWNSTREAM) ||
|
|
|
aa0606 |
(port_type == PCI_EXP_TYPE_ROOT_PORT);
|
|
|
aa0606 |
/*
|
|
|
aa0606 |
@@ -825,6 +829,7 @@ static hotplug_type_t pci_bus_hotplug_support(struct pci_bus *bus, u8 pcie_cap)
|
|
|
aa0606 |
HOTPLUG_PCIE : HOTPLUG_NO_SUPPORTED;
|
|
|
aa0606 |
}
|
|
|
aa0606 |
|
|
|
aa0606 |
+check_shpc:
|
|
|
aa0606 |
shpc_cap = pci_find_capability(bus->bus_dev->bdf, PCI_CAP_ID_SHPC, 0);
|
|
|
aa0606 |
return !!shpc_cap ? HOTPLUG_SHPC : HOTPLUG_NO_SUPPORTED;
|
|
|
aa0606 |
}
|
|
|
aa0606 |
--
|
|
|
aa0606 |
2.27.0
|
|
|
aa0606 |
|