Skip to content

Commit

Permalink
x86: handle BIOSes which terminate e820 with CF=1 and no SMAP
Browse files Browse the repository at this point in the history
The proper way to terminate the e820 chain is with %ebx == 0 on the
last legitimate memory block.  However, several BIOSes don't do that
and instead return error (CF = 1) when trying to read off the end of
the list.  For this error return, %eax doesn't necessarily return the
SMAP signature -- correctly so, since %ah should contain an error code
in this case.

To deal with some particularly broken BIOSes, we clear the entire e820
chain if the SMAP signature is missing in the middle, indicating a
plain insane e820 implementation.  However, we need to make the test
for CF = 1 before the SMAP check.

This fixes at least one HP laptop (nc6400) for which none of the
memory-probing methods (e820, e801, 88) functioned fully according to
spec.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
H. Peter Anvin authored and Ingo Molnar committed Feb 26, 2008
1 parent 4cd2095 commit 829157b
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions arch/x86/boot/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ static int detect_memory_e820(void)
"=m" (*desc)
: "D" (desc), "d" (SMAP), "a" (0xe820));

/* BIOSes which terminate the chain with CF = 1 as opposed
to %ebx = 0 don't always report the SMAP signature on
the final, failing, probe. */
if (err)
break;

/* Some BIOSes stop returning SMAP in the middle of
the search loop. We don't know exactly how the BIOS
screwed up the map at that point, we might have a
Expand All @@ -47,9 +53,6 @@ static int detect_memory_e820(void)
break;
}

if (err)
break;

count++;
desc++;
} while (next && count < E820MAX);
Expand Down

0 comments on commit 829157b

Please sign in to comment.