Skip to content

Commit c6ac667

Browse files
npigginmpe
authored andcommitted
powerpc/64e/interrupt: Fix nvgprs being clobbered
Some interrupt handlers have an "extra" that saves 1 or 2 registers (r14, r15) in the paca save area and makes them available to use by the handler. The change to always save nvgprs in exception handlers lead to some interrupt handlers saving those scratch r14 / r15 registers into the interrupt frame's GPR saves, which get restored on interrupt exit. Fix this by always reloading those scratch registers from paca before the EXCEPTION_COMMON that saves nvgprs. Fixes: 4228b2c ("powerpc/64e/interrupt: always save nvgprs on interrupt") Reported-by: Christian Zigotzky <[email protected]> Signed-off-by: Nicholas Piggin <[email protected]> Tested-by: Christian Zigotzky <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 4ec5fee commit c6ac667

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

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

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,12 @@ ret_from_mc_except:
340340
andi. r10,r10,IRQS_DISABLED; /* yes -> go out of line */ \
341341
bne masked_interrupt_book3e_##n
342342

343+
/*
344+
* Additional regs must be re-loaded from paca before EXCEPTION_COMMON* is
345+
* called, because that does SAVE_NVGPRS which must see the original register
346+
* values, otherwise the scratch values might be restored when exiting the
347+
* interrupt.
348+
*/
343349
#define PROLOG_ADDITION_2REGS_GEN(n) \
344350
std r14,PACA_EXGEN+EX_R14(r13); \
345351
std r15,PACA_EXGEN+EX_R15(r13)
@@ -535,6 +541,10 @@ __end_interrupts:
535541
PROLOG_ADDITION_2REGS)
536542
mfspr r14,SPRN_DEAR
537543
mfspr r15,SPRN_ESR
544+
std r14,_DAR(r1)
545+
std r15,_DSISR(r1)
546+
ld r14,PACA_EXGEN+EX_R14(r13)
547+
ld r15,PACA_EXGEN+EX_R15(r13)
538548
EXCEPTION_COMMON(0x300)
539549
b storage_fault_common
540550

@@ -544,6 +554,10 @@ __end_interrupts:
544554
PROLOG_ADDITION_2REGS)
545555
li r15,0
546556
mr r14,r10
557+
std r14,_DAR(r1)
558+
std r15,_DSISR(r1)
559+
ld r14,PACA_EXGEN+EX_R14(r13)
560+
ld r15,PACA_EXGEN+EX_R15(r13)
547561
EXCEPTION_COMMON(0x400)
548562
b storage_fault_common
549563

@@ -557,6 +571,10 @@ __end_interrupts:
557571
PROLOG_ADDITION_2REGS)
558572
mfspr r14,SPRN_DEAR
559573
mfspr r15,SPRN_ESR
574+
std r14,_DAR(r1)
575+
std r15,_DSISR(r1)
576+
ld r14,PACA_EXGEN+EX_R14(r13)
577+
ld r15,PACA_EXGEN+EX_R15(r13)
560578
EXCEPTION_COMMON(0x600)
561579
b alignment_more /* no room, go out of line */
562580

@@ -565,10 +583,10 @@ __end_interrupts:
565583
NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM,
566584
PROLOG_ADDITION_1REG)
567585
mfspr r14,SPRN_ESR
568-
EXCEPTION_COMMON(0x700)
569586
std r14,_DSISR(r1)
570-
addi r3,r1,STACK_FRAME_OVERHEAD
571587
ld r14,PACA_EXGEN+EX_R14(r13)
588+
EXCEPTION_COMMON(0x700)
589+
addi r3,r1,STACK_FRAME_OVERHEAD
572590
bl program_check_exception
573591
REST_NVGPRS(r1)
574592
b interrupt_return
@@ -725,11 +743,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
725743
* normal exception
726744
*/
727745
mfspr r14,SPRN_DBSR
728-
EXCEPTION_COMMON_CRIT(0xd00)
729746
std r14,_DSISR(r1)
730-
addi r3,r1,STACK_FRAME_OVERHEAD
731747
ld r14,PACA_EXCRIT+EX_R14(r13)
732748
ld r15,PACA_EXCRIT+EX_R15(r13)
749+
EXCEPTION_COMMON_CRIT(0xd00)
750+
addi r3,r1,STACK_FRAME_OVERHEAD
733751
bl DebugException
734752
REST_NVGPRS(r1)
735753
b interrupt_return
@@ -796,11 +814,11 @@ kernel_dbg_exc:
796814
* normal exception
797815
*/
798816
mfspr r14,SPRN_DBSR
799-
EXCEPTION_COMMON_DBG(0xd08)
800817
std r14,_DSISR(r1)
801-
addi r3,r1,STACK_FRAME_OVERHEAD
802818
ld r14,PACA_EXDBG+EX_R14(r13)
803819
ld r15,PACA_EXDBG+EX_R15(r13)
820+
EXCEPTION_COMMON_DBG(0xd08)
821+
addi r3,r1,STACK_FRAME_OVERHEAD
804822
bl DebugException
805823
REST_NVGPRS(r1)
806824
b interrupt_return
@@ -931,11 +949,7 @@ masked_interrupt_book3e_0x2c0:
931949
* original values stashed away in the PACA
932950
*/
933951
storage_fault_common:
934-
std r14,_DAR(r1)
935-
std r15,_DSISR(r1)
936952
addi r3,r1,STACK_FRAME_OVERHEAD
937-
ld r14,PACA_EXGEN+EX_R14(r13)
938-
ld r15,PACA_EXGEN+EX_R15(r13)
939953
bl do_page_fault
940954
b interrupt_return
941955

@@ -944,11 +958,7 @@ storage_fault_common:
944958
* continues here.
945959
*/
946960
alignment_more:
947-
std r14,_DAR(r1)
948-
std r15,_DSISR(r1)
949961
addi r3,r1,STACK_FRAME_OVERHEAD
950-
ld r14,PACA_EXGEN+EX_R14(r13)
951-
ld r15,PACA_EXGEN+EX_R15(r13)
952962
bl alignment_exception
953963
REST_NVGPRS(r1)
954964
b interrupt_return

0 commit comments

Comments
 (0)