From 93d256cd3c1e93c4093e8015b371e832de4c4146 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 3 Mar 2022 18:04:43 -0600 Subject: x86/PCI: Eliminate remove_e820_regions() common subexpressions Add local variables to reduce repetition later. No functional change intended. Link: https://lore.kernel.org/r/20220304035110.988712-2-helgaas@kernel.org Signed-off-by: Bjorn Helgaas Reviewed-by: Hans de Goede Reviewed-by: Mika Westerberg Acked-by: Rafael J. Wysocki --- arch/x86/kernel/resource.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/x86/kernel') diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c index 9b9fb7882c20..8ffe68437744 100644 --- a/arch/x86/kernel/resource.c +++ b/arch/x86/kernel/resource.c @@ -27,12 +27,14 @@ static void remove_e820_regions(struct resource *avail) { int i; struct e820_entry *entry; + u64 e820_start, e820_end; for (i = 0; i < e820_table->nr_entries; i++) { entry = &e820_table->entries[i]; + e820_start = entry->addr; + e820_end = entry->addr + entry->size - 1; - resource_clip(avail, entry->addr, - entry->addr + entry->size - 1); + resource_clip(avail, e820_start, e820_end); } } -- cgit From 31bf0f4333254469ebf34d7f17d64a57bce516d4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 7 Apr 2022 17:42:02 -0500 Subject: x86: Log resource clipping for E820 regions When remove_e820_regions() clips a resource because an E820 region overlaps it, log a note in dmesg to add in debugging. Signed-off-by: Bjorn Helgaas --- arch/x86/kernel/resource.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/x86/kernel') diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c index 8ffe68437744..30d524adb012 100644 --- a/arch/x86/kernel/resource.c +++ b/arch/x86/kernel/resource.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include static void resource_clip(struct resource *res, resource_size_t start, @@ -28,6 +29,7 @@ static void remove_e820_regions(struct resource *avail) int i; struct e820_entry *entry; u64 e820_start, e820_end; + struct resource orig = *avail; for (i = 0; i < e820_table->nr_entries; i++) { entry = &e820_table->entries[i]; @@ -35,6 +37,11 @@ static void remove_e820_regions(struct resource *avail) e820_end = entry->addr + entry->size - 1; resource_clip(avail, e820_start, e820_end); + if (orig.start != avail->start || orig.end != avail->end) { + pr_info("clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", + &orig, avail, e820_start, e820_end); + orig = *avail; + } } } -- cgit From 4c5e242d3e937bb9f9c226d06888d9189826879d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 3 Mar 2022 16:00:39 -0600 Subject: x86/PCI: Clip only host bridge windows for E820 regions ACPI firmware advertises PCI host bridge resources via PNP0A03 _CRS methods. Some BIOSes include non-window address space in _CRS, and if we allocate that non-window space for PCI devices, they don't work. 4dc2287c1805 ("x86: avoid E820 regions when allocating address space") works around this issue by clipping out any regions mentioned in the E820 table in the allocate_resource() path, but the implementation has a couple issues: - The clipping is done for *all* allocations, not just those for PCI address space, and - The clipping is done at each allocation instead of being done once when setting up the host bridge windows. Rework the implementation so we only clip PCI host bridge windows, and we do it once when setting them up. Example output changes: BIOS-e820: [mem 0x00000000b0000000-0x00000000c00fffff] reserved + acpi PNP0A08:00: clipped [mem 0xc0000000-0xfebfffff window] to [mem 0xc0100000-0xfebfffff window] for e820 entry [mem 0xb0000000-0xc00fffff] - pci_bus 0000:00: root bus resource [mem 0xc0000000-0xfebfffff window] + pci_bus 0000:00: root bus resource [mem 0xc0100000-0xfebfffff window] Link: https://lore.kernel.org/r/20220304035110.988712-3-helgaas@kernel.org Signed-off-by: Bjorn Helgaas Reviewed-by: Hans de Goede Reviewed-by: Mika Westerberg Acked-by: Rafael J. Wysocki --- arch/x86/kernel/resource.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch/x86/kernel') diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c index 30d524adb012..db2b350a37b7 100644 --- a/arch/x86/kernel/resource.c +++ b/arch/x86/kernel/resource.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include -#include #include static void resource_clip(struct resource *res, resource_size_t start, @@ -24,13 +24,16 @@ static void resource_clip(struct resource *res, resource_size_t start, res->start = end + 1; } -static void remove_e820_regions(struct resource *avail) +void remove_e820_regions(struct device *dev, struct resource *avail) { int i; struct e820_entry *entry; u64 e820_start, e820_end; struct resource orig = *avail; + if (!(avail->flags & IORESOURCE_MEM)) + return; + for (i = 0; i < e820_table->nr_entries; i++) { entry = &e820_table->entries[i]; e820_start = entry->addr; @@ -38,7 +41,7 @@ static void remove_e820_regions(struct resource *avail) resource_clip(avail, e820_start, e820_end); if (orig.start != avail->start || orig.end != avail->end) { - pr_info("clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", + dev_info(dev, "clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", &orig, avail, e820_start, e820_end); orig = *avail; } @@ -52,9 +55,6 @@ void arch_remove_reservations(struct resource *avail) * the low 1MB unconditionally, as this area is needed for some ISA * cards requiring a memory range, e.g. the i82365 PCMCIA controller. */ - if (avail->flags & IORESOURCE_MEM) { + if (avail->flags & IORESOURCE_MEM) resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); - - remove_e820_regions(avail); - } } -- cgit