From 774a16b16328310c2be41794fa462a0f6691c121 Mon Sep 17 00:00:00 2001 From: Hongyan Xia Date: Tue, 6 Apr 2021 15:11:52 +0100 Subject: Fix where the real mode interrupt vector ends The real mode ends at 0x400, not 0x100. The code intentionally excludes the IVT as RAM, so use the correct address. Also, 0x100 is not 1K aligned and will be rejected by add_memmap(). We have observed problems that after a multiboot2 kexec, the next kexec will throw away such unaligned chunks, losing memory for the next next kernel. In some corner cases, such loss of memory can actually cause OOM during boot. Signed-off-by: Hongyan Xia Signed-off-by: Simon Horman --- kexec/arch/i386/kexec-x86-common.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c index 9303704a..ffc95a9e 100644 --- a/kexec/arch/i386/kexec-x86-common.c +++ b/kexec/arch/i386/kexec-x86-common.c @@ -48,6 +48,12 @@ #define E820_PRAM 12 #endif +/* + * The real mode IVT ends at 0x400. + * See https://wiki.osdev.org/Interrupt_Vector_Table. + */ +#define REALMODE_IVT_END 0x400 + static struct memory_range memory_range[MAX_MEMORY_RANGES]; /** @@ -360,8 +366,8 @@ int get_memory_ranges(struct memory_range **range, int *ranges, /* Don't report the interrupt table as ram */ for (i = 0; i < *ranges; i++) { if ((*range)[i].type == RANGE_RAM && - ((*range)[i].start < 0x100)) { - (*range)[i].start = 0x100; + ((*range)[i].start < REALMODE_IVT_END)) { + (*range)[i].start = REALMODE_IVT_END; break; } } -- cgit 1.2.3-korg