1
0
mirror of https://github.com/torvalds/linux.git synced 2024-12-24 11:51:27 +00:00
linux/arch/x86/boot
Kairui Song 220dd7699c x86, efi: Never relocate kernel below lowest acceptable address
Currently, kernel fails to boot on some HyperV VMs when using EFI.
And it's a potential issue on all x86 platforms.

It's caused by broken kernel relocation on EFI systems, when below three
conditions are met:

1. Kernel image is not loaded to the default address (LOAD_PHYSICAL_ADDR)
   by the loader.
2. There isn't enough room to contain the kernel, starting from the
   default load address (eg. something else occupied part the region).
3. In the memmap provided by EFI firmware, there is a memory region
   starts below LOAD_PHYSICAL_ADDR, and suitable for containing the
   kernel.

EFI stub will perform a kernel relocation when condition 1 is met. But
due to condition 2, EFI stub can't relocate kernel to the preferred
address, so it fallback to ask EFI firmware to alloc lowest usable memory
region, got the low region mentioned in condition 3, and relocated
kernel there.

It's incorrect to relocate the kernel below LOAD_PHYSICAL_ADDR. This
is the lowest acceptable kernel relocation address.

The first thing goes wrong is in arch/x86/boot/compressed/head_64.S.
Kernel decompression will force use LOAD_PHYSICAL_ADDR as the output
address if kernel is located below it. Then the relocation before
decompression, which move kernel to the end of the decompression buffer,
will overwrite other memory region, as there is no enough memory there.

To fix it, just don't let EFI stub relocate the kernel to any address
lower than lowest acceptable address.

[ ardb: introduce efi_low_alloc_above() to reduce the scope of the change ]

Signed-off-by: Kairui Song <kasong@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20191029173755.27149-6-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2019-10-31 09:40:19 +01:00
..
compressed x86, efi: Never relocate kernel below lowest acceptable address 2019-10-31 09:40:19 +01:00
tools x86/boot: Add missing va_end() to die() 2018-11-28 20:06:07 +01:00
.gitignore x86/build: Add more generated files to the .gitignore file 2017-11-07 11:22:21 +01:00
a20.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
apm.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
bioscall.S treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 83 2019-05-24 17:37:52 +02:00
bitops.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
boot.h x86/boot: Use common BUILD_BUG_ON 2019-08-16 14:15:50 +02:00
cmdline.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
code16gcc.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
copy.S treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
cpu.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
cpucheck.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
cpuflags.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cpuflags.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ctype.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
early_serial_console.c x86: Clean up 'sizeof x' => 'sizeof(x)' 2018-10-29 07:13:28 +01:00
edd.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
genimage.sh x86/build: Make isoimage work on Debian 2017-12-16 16:23:31 +01:00
header.S It's been a relatively busy cycle for docs: 2019-07-09 12:34:26 -07:00
install.sh kbuild: use INSTALLKERNEL to select customized installkernel script 2009-09-20 12:18:14 +02:00
main.c x86/boot: Use common BUILD_BUG_ON 2019-08-16 14:15:50 +02:00
Makefile x86/build: Specify elf_i386 linker emulation explicitly for i386 objects 2019-01-12 00:11:39 +01:00
memory.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
mkcpustr.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 83 2019-05-24 17:37:52 +02:00
mtools.conf.in
pm.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
pmjump.S treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
printf.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
regs.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 83 2019-05-24 17:37:52 +02:00
setup.ld x86/build: Use the single-argument OUTPUT_FORMAT() linker script command 2019-01-16 12:21:53 +01:00
string.c x86/purgatory: Do not use __builtin_memcpy and __builtin_memset 2019-08-08 08:25:52 +02:00
string.h x86/boot: Copy kstrtoull() to boot/string.c 2019-02-01 11:52:54 +01:00
tty.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
version.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
vesa.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 48 2019-05-24 17:27:13 +02:00
video-bios.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
video-mode.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
video-vesa.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
video-vga.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
video.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00
video.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 497 2019-06-19 17:09:53 +02:00