• Michael Ellerman's avatar
    powerpc/64: Fix HMI exception on LE with CONFIG_RELOCATABLE=y · be5c5e84
    Michael Ellerman authored
    Prior to commit 2337d207 ("powerpc/64: CONFIG_RELOCATABLE support for hmi
    interrupts"), the branch from hmi_exception_early() to hmi_exception_realmode()
    was just a bl hmi_exception_realmode, which the linker would turn into a bl to
    the local entry point of hmi_exception_realmode. This was broken when
    CONFIG_RELOCATABLE=y because hmi_exception_realmode() is not in the low part of
    the kernel text that is copied down to 0x0.
    
    But in fixing that, we added a new bug on little endian kernels. Because the
    branch is now a bctrl when CONFIG_RELOCATABLE=y, we branch to the global entry
    point of hmi_exception_realmode(). The global entry point must be called with
    r12 containing the address of hmi_exception_realmode(), because it uses that
    value to calculate the TOC value (r2).
    
    This may manifest as a checkstop, because we take a junk value from r12 which
    came from HSRR1, add a small constant to it and then use that as the TOC
    pointer. The HSRR1 value will have 0x9 as the top nibble, which puts it above
    RAM and somewhere in MMIO space.
    
    Fix it by changing the BRANCH_LINK_TO_FAR() macro to always use r12 to load the
    label we're branching to. This means r12 will be setup correctly on LE, fixing
    this bug, and r12 is also volatile across function calls on BE so it's a good
    choice anyway.
    
    Fixes: 2337d207 ("powerpc/64: CONFIG_RELOCATABLE support for hmi interrupts")
    Reported-by: default avatarMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
    Acked-by: default avatarNicholas Piggin <npiggin@gmail.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    be5c5e84
exception-64s.h 18.9 KB