Skip to content

Commit be5c5e8

Browse files
committed
powerpc/64: Fix HMI exception on LE with CONFIG_RELOCATABLE=y
Prior to commit 2337d20 ("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: 2337d20 ("powerpc/64: CONFIG_RELOCATABLE support for hmi interrupts") Reported-by: Mahesh Salgaonkar <[email protected]> Acked-by: Nicholas Piggin <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent 9e1ba4f commit be5c5e8

File tree

2 files changed

+5
-5
lines changed

2 files changed

+5
-5
lines changed

arch/powerpc/include/asm/exception-64s.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,9 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
236236
mtctr reg; \
237237
bctr
238238

239-
#define BRANCH_LINK_TO_FAR(reg, label) \
240-
__LOAD_FAR_HANDLER(reg, label); \
241-
mtctr reg; \
239+
#define BRANCH_LINK_TO_FAR(label) \
240+
__LOAD_FAR_HANDLER(r12, label); \
241+
mtctr r12; \
242242
bctrl
243243

244244
/*
@@ -265,7 +265,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
265265
#define BRANCH_TO_COMMON(reg, label) \
266266
b label
267267

268-
#define BRANCH_LINK_TO_FAR(reg, label) \
268+
#define BRANCH_LINK_TO_FAR(label) \
269269
bl label
270270

271271
#define BRANCH_TO_KVM(reg, label) \

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early)
982982
EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN)
983983
EXCEPTION_PROLOG_COMMON_3(0xe60)
984984
addi r3,r1,STACK_FRAME_OVERHEAD
985-
BRANCH_LINK_TO_FAR(r4, hmi_exception_realmode)
985+
BRANCH_LINK_TO_FAR(hmi_exception_realmode) /* Function call ABI */
986986
/* Windup the stack. */
987987
/* Move original HSRR0 and HSRR1 into the respective regs */
988988
ld r9,_MSR(r1)

0 commit comments

Comments
 (0)