[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20221202211838.1061278-2-helgaas@kernel.org>
Date: Fri, 2 Dec 2022 15:18:35 -0600
From: Bjorn Helgaas <helgaas@...nel.org>
To: linux-pci@...r.kernel.org
Cc: Hans de Goede <hdegoede@...hat.com>,
Florent DELAHAYE <kernelorg@...ead.fr>,
Konrad J Hambrick <kjhambrick@...il.com>,
Matt Hansen <2lprbe78@...k.com>,
Benoit Grégoire <benoitg@...us.ca>,
Nicholas Johnson <nicholas.johnson-opensource@...look.com.au>,
Mika Westerberg <mika.westerberg@...ux.intel.com>,
Werner Sembach <wse@...edocomputers.com>,
mumblingdrunkard@...tonmail.com, linux-kernel@...r.kernel.org,
Bjorn Helgaas <bhelgaas@...gle.com>
Subject: [PATCH 1/4] efi/x86: Remove EfiMemoryMappedIO from E820 map
From: Bjorn Helgaas <bhelgaas@...gle.com>
Firmware can use EfiMemoryMappedIO to request that MMIO regions be mapped
by the OS so they can be accessed by EFI runtime services, but should have
no other significance to the OS (UEFI r2.10, sec 7.2). However, most
bootloaders and EFI stubs convert EfiMemoryMappedIO regions to
E820_TYPE_RESERVED entries, which prevent Linux from allocating space from
them (see remove_e820_regions()).
Some platforms use EfiMemoryMappedIO entries for PCI MMCONFIG space and PCI
host bridge windows, which means Linux can't allocate BAR space for
hot-added devices.
Remove any EfiMemoryMappedIO regions from the E820 map to avoid this
problem.
The previous solution to the problem of allocating BARs in these regions
was to add pci_crs_quirks[] entries to disable E820 checking for these
machines (see d341838d776a ("x86/PCI: Disable E820 reserved region clipping
via quirks")):
Acer DMI_PRODUCT_NAME Spin SP513-54N
Clevo DMI_BOARD_NAME X170KM-G
Lenovo DMI_PRODUCT_VERSION *IIL*
Florent reported the BAR allocation issue on the Clevo NL4XLU. We could
add another quirk for the NL4XLU, but I hope this generic change can solve
it for many machines without having to add quirks.
This change has been tested on Clevo X170KM-G (Konrad) and Lenovo Ideapad
Slim 3 (Matt) and solves the problem even when overriding the existing
quirks by booting with "pci=use_e820".
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216565 Clevo NL4XLU
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206459#c78 Clevo X170KM-G
Link: https://bugzilla.redhat.com/show_bug.cgi?id=1868899 Ideapad Slim 3
Reported-by: Florent DELAHAYE <kernelorg@...ead.fr>
Signed-off-by: Bjorn Helgaas <bhelgaas@...gle.com>
Tested-by: Konrad J Hambrick <kjhambrick@...il.com>
Tested-by: Matt Hansen <2lprbe78@...k.com>
Cc: Hans de Goede <hdegoede@...hat.com>
---
arch/x86/platform/efi/efi.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ebc98a68c400..4728f60119da 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -303,6 +303,40 @@ static void __init efi_clean_memmap(void)
}
}
+/*
+ * Firmware can use EfiMemoryMappedIO to request that MMIO regions be
+ * mapped by the OS so they can be accessed by EFI runtime services, but
+ * should have no other significance to the OS (UEFI r2.10, sec 7.2).
+ * However, most bootloaders and EFI stubs convert EfiMemoryMappedIO
+ * regions to E820_TYPE_RESERVED entries, which prevent Linux from
+ * allocating space from them (see remove_e820_regions()).
+ *
+ * Some platforms use EfiMemoryMappedIO entries for PCI MMCONFIG space and
+ * PCI host bridge windows, which means Linux can't allocate BAR space for
+ * hot-added devices.
+ *
+ * Remove any EfiMemoryMappedIO regions from the E820 map to avoid this
+ * problem.
+ */
+static void __init efi_remove_e820_mmio(void)
+{
+ efi_memory_desc_t *md;
+ u64 size, start, end;
+ int i = 0;
+
+ for_each_efi_memory_desc(md) {
+ if (md->type == EFI_MEMORY_MAPPED_IO) {
+ size = md->num_pages << EFI_PAGE_SHIFT;
+ start = md->phys_addr;
+ end = start + size - 1;
+ pr_info("Remove mem%02u: MMIO range=[0x%08llx-0x%08llx] (%lluMB) from e820 map\n",
+ i, start, end, size >> 20);
+ e820__range_remove(start, size, E820_TYPE_RESERVED, 1);
+ }
+ i++;
+ }
+}
+
void __init efi_print_memmap(void)
{
efi_memory_desc_t *md;
@@ -474,6 +508,8 @@ void __init efi_init(void)
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
efi_clean_memmap();
+ efi_remove_e820_mmio();
+
if (efi_enabled(EFI_DBG))
efi_print_memmap();
}
--
2.25.1
Powered by blists - more mailing lists