Skip to content

Commit

Permalink
x86/pci: Skip early E820 check for ECAM region
Browse files Browse the repository at this point in the history
Arul, Mateusz, Imcarneiro91, and Aman reported a regression caused by
07eab09 ("efi/x86: Remove EfiMemoryMappedIO from E820 map").  On the
Lenovo Legion 9i laptop, that commit removes the ECAM area from E820, which
means the early E820 validation fails, which means we don't enable ECAM in
the "early MCFG" path.

The static MCFG table describes ECAM without depending on the ACPI
interpreter.  Many Legion 9i ACPI methods rely on that, so they fail when
PCI config access isn't available, resulting in the embedded controller,
PS/2, audio, trackpad, and battery devices not being detected.  The _OSC
method also fails, so Linux can't take control of the PCIe hotplug, PME,
and AER features:

  # pci_mmcfg_early_init()

  PCI: ECAM [mem 0xc0000000-0xce0fffff] (base 0xc0000000) for domain 0000 [bus 00-e0]
  PCI: not using ECAM ([mem 0xc0000000-0xce0fffff] not reserved)

  ACPI Error: AE_ERROR, Returned by Handler for [PCI_Config] (20230628/evregion-300)
  ACPI: Interpreter enabled
  ACPI: Ignoring error and continuing table load
  ACPI BIOS Error (bug): Could not resolve symbol [\_SB.PC00.RP01._SB.PC00], AE_NOT_FOUND (20230628/dswload2-162)
  ACPI Error: AE_NOT_FOUND, During name lookup/catalog (20230628/psobject-220)
  ACPI: Skipping parse of AML opcode: OpcodeName unavailable (0x0010)
  ACPI BIOS Error (bug): Could not resolve symbol [\_SB.PC00.RP01._SB.PC00], AE_NOT_FOUND (20230628/dswload2-162)
  ACPI Error: AE_NOT_FOUND, During name lookup/catalog (20230628/psobject-220)
  ...
  ACPI Error: Aborting method \_SB.PC00._OSC due to previous error (AE_NOT_FOUND) (20230628/psparse-529)
  acpi PNP0A08:00: _OSC: platform retains control of PCIe features (AE_NOT_FOUND)

  # pci_mmcfg_late_init()

  PCI: ECAM [mem 0xc0000000-0xce0fffff] (base 0xc0000000) for domain 0000 [bus 00-e0]
  PCI: [Firmware Info]: ECAM [mem 0xc0000000-0xce0fffff] not reserved in ACPI motherboard resources
  PCI: ECAM [mem 0xc0000000-0xce0fffff] is EfiMemoryMappedIO; assuming valid
  PCI: ECAM [mem 0xc0000000-0xce0fffff] reserved to work around lack of ACPI motherboard _CRS

Per PCI Firmware r3.3, sec 4.1.2, ECAM space must be reserved by a PNP0C02
resource, but there's no requirement to mention it in E820, so we shouldn't
look at E820 to validate the ECAM space described by MCFG.

In 2006, 946f2ee ("[PATCH] i386/x86-64: Check that MCFG points to an
e820 reserved area") added a sanity check of E820 to work around buggy MCFG
tables, but that over-aggressive validation causes failures like this one.

Keep the E820 validation check for machines older than 2016, an arbitrary
ten years after 946f2ee, so machines that depend on it don't break.

Skip the early E820 check for 2016 and newer BIOSes since there's no
requirement to describe ECAM in E820.

Link: https://lore.kernel.org/r/[email protected]
Fixes: 07eab09 ("efi/x86: Remove EfiMemoryMappedIO from E820 map")
Reported-by: Mateusz Kaduk <[email protected]>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218444
Signed-off-by: Bjorn Helgaas <[email protected]>
Tested-by: Mateusz Kaduk <[email protected]>
Reviewed-by: Andy Shevchenko <[email protected]>
Reviewed-by: Hans de Goede <[email protected]>
Reviewed-by: Kuppuswamy Sathyanarayanan <[email protected]>
Cc: [email protected]
  • Loading branch information
bjorn-helgaas committed May 16, 2024
1 parent 844177a commit 199f968
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions arch/x86/pci/mmconfig-shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,34 @@ static bool __ref pci_mmcfg_reserved(struct device *dev,
{
struct resource *conflict;

if (!early && !acpi_disabled) {
if (early) {

/*
* Don't try to do this check unless configuration type 1
* is available. How about type 2?
*/

/*
* 946f2ee5c731 ("Check that MCFG points to an e820
* reserved area") added this E820 check in 2006 to work
* around BIOS defects.
*
* Per PCI Firmware r3.3, sec 4.1.2, ECAM space must be
* reserved by a PNP0C02 resource, but it need not be
* mentioned in E820. Before the ACPI interpreter is
* available, we can't check for PNP0C02 resources, so
* there's no reliable way to verify the region in this
* early check. Keep it only for the old machines that
* motivated 946f2ee5c731.
*/
if (dmi_get_bios_year() < 2016 && raw_pci_ops)
return is_mmconf_reserved(e820__mapped_all, cfg, dev,
"E820 entry");

return true;
}

if (!acpi_disabled) {
if (is_mmconf_reserved(is_acpi_reserved, cfg, dev,
"ACPI motherboard resource"))
return true;
Expand Down Expand Up @@ -551,16 +578,7 @@ static bool __ref pci_mmcfg_reserved(struct device *dev,
* For MCFG information constructed from hotpluggable host bridge's
* _CBA method, just assume it's reserved.
*/
if (pci_mmcfg_running_state)
return true;

/* Don't try to do this check unless configuration
type 1 is available. how about type 2 ?*/
if (raw_pci_ops)
return is_mmconf_reserved(e820__mapped_all, cfg, dev,
"E820 entry");

return false;
return pci_mmcfg_running_state;
}

static void __init pci_mmcfg_reject_broken(int early)
Expand Down

0 comments on commit 199f968

Please sign in to comment.