Skip to content

Commit 6fdcfc0

Browse files
Igor Druzhiningregkh
authored andcommitted
xen/pci: reserve MCFG areas earlier
[ Upstream commit a4098bc ] If MCFG area is not reserved in E820, Xen by default will defer its usage until Dom0 registers it explicitly after ACPI parser recognizes it as a reserved resource in DSDT. Having it reserved in E820 is not mandatory according to "PCI Firmware Specification, rev 3.2" (par. 4.1.2) and firmware is free to keep a hole in E820 in that place. Xen doesn't know what exactly is inside this hole since it lacks full ACPI view of the platform therefore it's potentially harmful to access MCFG region without additional checks as some machines are known to provide inconsistent information on the size of the region. Now xen_mcfg_late() runs after acpi_init() which is too late as some basic PCI enumeration starts exactly there as well. Trying to register a device prior to MCFG reservation causes multiple problems with PCIe extended capability initializations in Xen (e.g. SR-IOV VF BAR sizing). There are no convenient hooks for us to subscribe to so register MCFG areas earlier upon the first invocation of xen_add_device(). It should be safe to do once since all the boot time buses must have their MCFG areas in MCFG table already and we don't support PCI bus hot-plug. Signed-off-by: Igor Druzhinin <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Signed-off-by: Boris Ostrovsky <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 16a56a8 commit 6fdcfc0

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

drivers/xen/pci.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "../pci/pci.h"
3030
#ifdef CONFIG_PCI_MMCONFIG
3131
#include <asm/pci_x86.h>
32+
33+
static int xen_mcfg_late(void);
3234
#endif
3335

3436
static bool __read_mostly pci_seg_supported = true;
@@ -40,7 +42,18 @@ static int xen_add_device(struct device *dev)
4042
#ifdef CONFIG_PCI_IOV
4143
struct pci_dev *physfn = pci_dev->physfn;
4244
#endif
43-
45+
#ifdef CONFIG_PCI_MMCONFIG
46+
static bool pci_mcfg_reserved = false;
47+
/*
48+
* Reserve MCFG areas in Xen on first invocation due to this being
49+
* potentially called from inside of acpi_init immediately after
50+
* MCFG table has been finally parsed.
51+
*/
52+
if (!pci_mcfg_reserved) {
53+
xen_mcfg_late();
54+
pci_mcfg_reserved = true;
55+
}
56+
#endif
4457
if (pci_seg_supported) {
4558
struct {
4659
struct physdev_pci_device_add add;
@@ -213,7 +226,7 @@ static int __init register_xen_pci_notifier(void)
213226
arch_initcall(register_xen_pci_notifier);
214227

215228
#ifdef CONFIG_PCI_MMCONFIG
216-
static int __init xen_mcfg_late(void)
229+
static int xen_mcfg_late(void)
217230
{
218231
struct pci_mmcfg_region *cfg;
219232
int rc;
@@ -252,8 +265,4 @@ static int __init xen_mcfg_late(void)
252265
}
253266
return 0;
254267
}
255-
/*
256-
* Needs to be done after acpi_init which are subsys_initcall.
257-
*/
258-
subsys_initcall_sync(xen_mcfg_late);
259268
#endif

0 commit comments

Comments
 (0)