Commit b1ee8a3d authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman

powerpc/64s: Dedicated system reset interrupt stack

The system reset interrupt is used for crash/debug situations, so it is
desirable to have as little impact on the normal state of the system as
possible.

Currently it uses the current kernel stack to process the exception.
This stores into the stack which may be involved with the crash. The
stack pointer may be corrupted, or it may have overflowed.

Avoid or minimise these problems by creating a dedicated NMI stack for
the system reset interrupt to use.
Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent c4f3b52c
...@@ -563,6 +563,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_CTRL) ...@@ -563,6 +563,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
bl hdlr; \ bl hdlr; \
b ret b ret
/*
* Exception where stack is already set in r1, r1 is saved in r10, and it
* continues rather than returns.
*/
#define EXCEPTION_COMMON_NORET_STACK(area, trap, label, hdlr, additions) \
EXCEPTION_PROLOG_COMMON_1(); \
EXCEPTION_PROLOG_COMMON_2(area); \
EXCEPTION_PROLOG_COMMON_3(trap); \
/* Volatile regs are potentially clobbered here */ \
additions; \
addi r3,r1,STACK_FRAME_OVERHEAD; \
bl hdlr
#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ #define STD_EXCEPTION_COMMON(trap, label, hdlr) \
EXCEPTION_COMMON(PACA_EXGEN, trap, label, hdlr, \ EXCEPTION_COMMON(PACA_EXGEN, trap, label, hdlr, \
ret_from_except, ADD_NVGPRS;ADD_RECONCILE) ret_from_except, ADD_NVGPRS;ADD_RECONCILE)
......
...@@ -185,7 +185,8 @@ struct paca_struct { ...@@ -185,7 +185,8 @@ struct paca_struct {
u64 exmc[13]; /* used for machine checks */ u64 exmc[13]; /* used for machine checks */
#endif #endif
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
/* Exclusive emergency stack pointer for machine check exception. */ /* Exclusive stacks for system reset and machine check exception. */
void *nmi_emergency_sp;
void *mc_emergency_sp; void *mc_emergency_sp;
u16 in_nmi; /* In nmi handler */ u16 in_nmi; /* In nmi handler */
......
...@@ -234,6 +234,7 @@ int main(void) ...@@ -234,6 +234,7 @@ int main(void)
OFFSET(PACAEMERGSP, paca_struct, emergency_sp); OFFSET(PACAEMERGSP, paca_struct, emergency_sp);
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
OFFSET(PACAMCEMERGSP, paca_struct, mc_emergency_sp); OFFSET(PACAMCEMERGSP, paca_struct, mc_emergency_sp);
OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp);
OFFSET(PACA_IN_MCE, paca_struct, in_mce); OFFSET(PACA_IN_MCE, paca_struct, in_mce);
OFFSET(PACA_IN_NMI, paca_struct, in_nmi); OFFSET(PACA_IN_NMI, paca_struct, in_nmi);
#endif #endif
......
...@@ -144,10 +144,12 @@ EXC_COMMON_BEGIN(system_reset_common) ...@@ -144,10 +144,12 @@ EXC_COMMON_BEGIN(system_reset_common)
li r10,MSR_RI li r10,MSR_RI
mtmsrd r10,1 mtmsrd r10,1
EXCEPTION_COMMON(PACA_EXNMI, 0x100, mr r10,r1
system_reset, system_reset_exception, 1f, ld r1,PACA_NMI_EMERG_SP(r13)
subi r1,r1,INT_FRAME_SIZE
EXCEPTION_COMMON_NORET_STACK(PACA_EXNMI, 0x100,
system_reset, system_reset_exception,
ADD_NVGPRS;ADD_RECONCILE) ADD_NVGPRS;ADD_RECONCILE)
1: /* EXCEPTION_COMMON continues here */
/* /*
* The stack is no longer in use, decrement in_nmi. * The stack is no longer in use, decrement in_nmi.
......
...@@ -628,6 +628,11 @@ void __init emergency_stack_init(void) ...@@ -628,6 +628,11 @@ void __init emergency_stack_init(void)
paca[i].emergency_sp = (void *)ti + THREAD_SIZE; paca[i].emergency_sp = (void *)ti + THREAD_SIZE;
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
/* emergency stack for NMI exception handling. */
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
klp_init_thread_info(ti);
paca[i].nmi_emergency_sp = (void *)ti + THREAD_SIZE;
/* emergency stack for machine check exception handling. */ /* emergency stack for machine check exception handling. */
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
klp_init_thread_info(ti); klp_init_thread_info(ti);
......
...@@ -2235,6 +2235,7 @@ static void dump_one_paca(int cpu) ...@@ -2235,6 +2235,7 @@ static void dump_one_paca(int cpu)
DUMP(p, kernel_msr, "lx"); DUMP(p, kernel_msr, "lx");
DUMP(p, emergency_sp, "p"); DUMP(p, emergency_sp, "p");
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
DUMP(p, nmi_emergency_sp, "p");
DUMP(p, mc_emergency_sp, "p"); DUMP(p, mc_emergency_sp, "p");
DUMP(p, in_nmi, "x"); DUMP(p, in_nmi, "x");
DUMP(p, in_mce, "x"); DUMP(p, in_mce, "x");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment