• K
    x86, efi: Never relocate kernel below lowest acceptable address · 220dd769
    Kairui Song 提交于
    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: NKairui Song <kasong@redhat.com>
    Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
    Acked-by: NJarkko 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.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
    220dd769
eboot.c 22.9 KB