Skip to content
  • Steve Wahl's avatar
    x86/purgatory: Change compiler flags from -mcmodel=kernel to -mcmodel=large to... · e16c2983
    Steve Wahl authored
    
    x86/purgatory: Change compiler flags from -mcmodel=kernel to -mcmodel=large to fix kexec relocation errors
    
    The last change to this Makefile caused relocation errors when loading
    a kdump kernel.  Restore -mcmodel=large (not -mcmodel=kernel),
    -ffreestanding, and -fno-zero-initialized-bsss, without reverting to
    the former practice of resetting KBUILD_CFLAGS.
    
    Purgatory.ro is a standalone binary that is not linked against the
    rest of the kernel.  Its image is copied into an array that is linked
    to the kernel, and from there kexec relocates it wherever it desires.
    
    With the previous change to compiler flags, the error "kexec: Overflow
    in relocation type 11 value 0x11fffd000" was encountered when trying
    to load the crash kernel.  This is from kexec code trying to relocate
    the purgatory.ro object.
    
    From the error message, relocation type 11 is R_X86_64_32S.  The
    x86_64 ABI says:
    
      "The R_X86_64_32 and R_X86_64_32S relocations truncate the
       computed value to 32-bits.  The linker must verify that the
       generated value for the R_X86_64_32 (R_X86_64_32S) relocation
       zero-extends (sign-extends) to the original 64-bit value."
    
    This type of relocation doesn't work when kexec chooses to place the
    purgatory binary in memory that is not reachable with 32 bit
    addresses.
    
    The compiler flag -mcmodel=kernel allows those type of relocations to
    be emitted, so revert to using -mcmodel=large as was done before.
    
    Also restore the -ffreestanding and -fno-zero-initialized-bss flags
    because they are appropriate for a stand alone piece of object code
    which doesn't explicitly zero the bss, and one other report has said
    undefined symbols are encountered without -ffreestanding.
    
    These identical compiler flag changes need to happen for every object
    that becomes part of the purgatory.ro object, so gather them together
    first into PURGATORY_CFLAGS_REMOVE and PURGATORY_CFLAGS, and then
    apply them to each of the objects that have C source.  Do not apply
    any of these flags to kexec-purgatory.o, which is not part of the
    standalone object but part of the kernel proper.
    
    Tested-by: default avatarVaibhav Rustagi <vaibhavrustagi@google.com>
    Tested-by: default avatarAndreas Smas <andreas@lonelycoder.com>
    Signed-off-by: default avatarSteve Wahl <steve.wahl@hpe.com>
    Reviewed-by: default avatarNick Desaulniers <ndesaulniers@google.com>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: None
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: clang-built-linux@googlegroups.com
    Cc: dimitri.sivanich@hpe.com
    Cc: mike.travis@hpe.com
    Cc: russ.anderson@hpe.com
    Fixes: b059f801 ("x86/purgatory: Use CFLAGS_REMOVE rather than reset KBUILD_CFLAGS")
    Link: https://lkml.kernel.org/r/20190905202346.GA26595@swahl-linux
    
    
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    e16c2983