]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/boot/e820: Change e820_search_gap() to search for the highest-address PCI gap
authorIngo Molnar <mingo@kernel.org>
Thu, 15 May 2025 12:05:37 +0000 (14:05 +0200)
committerIngo Molnar <mingo@kernel.org>
Sun, 14 Dec 2025 08:19:40 +0000 (09:19 +0100)
Right now the main x86 function that determines the position and size
of the 'PCI gap', e820_search_gap(), has this curious property:

        while (--idx >= 0) {
...
if (gap >= *gap_size) {

I.e. it will iterate the E820 table backwards, from its end to the beginning,
and will search for larger and larger gaps in the memory map below 4GB,
until it finishes with the table.

This logic will, should there be two gaps with the same size, pick the
one with the lower physical address - which is contrary to usual
practice that the PCI gap is just below 4GB.

Furthermore, the commit that introduced this weird logic 16 years ago:

  3381959da5a0 ("x86: cleanup e820_setup_gap(), add e820_search_gap(), v2")

  -                       if (gap > gapsize) {
  +                       if (gap >= *gapsize) {

didn't even declare this change, the title says it's a cleanup,
and the changelog declares it as a preparatory refactoring
for a later bugfix:

  809d9a8f93bd ("x86/PCI: ACPI based PCI gap calculation")

which bugfix was reverted only 1 day later without much of an
explanation, and was never reintroduced:

  58b6e5538460 ("Revert "x86/PCI: ACPI based PCI gap calculation"")

So based on the Git archeology and by the plain reading of the
code I declare this '>=' change an unintended bug and side effect.

Change it to '>' again.

It should not make much of a difference in practice, as the
likelihood of having *two* largest gaps with exactly the same
size are very low outside of weird user-provided memory maps.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: H . Peter Anvin <hpa@zytor.com>
Cc: Andy Shevchenko <andy@kernel.org>
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: David Woodhouse <dwmw@amazon.co.uk>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Paul Menzel <pmenzel@molgen.mpg.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://patch.msgid.link/20250515120549.2820541-22-mingo@kernel.org
arch/x86/kernel/e820.c

index b8edc5e32d8705a7130a8e2f147a61b1e9dc5923..3fba5406502a1b7f61d71a2007d803bb39e4b10c 100644 (file)
@@ -655,7 +655,7 @@ static int __init e820_search_gap(unsigned long *gap_start, unsigned long *gap_s
                if (last > end) {
                        unsigned long gap = last - end;
 
-                       if (gap >= *gap_size) {
+                       if (gap > *gap_size) {
                                *gap_size = gap;
                                *gap_start = end;
                                found = 1;