diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2016-12-20 04:30:06 +1000 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-04-28 21:02:25 +1000 |
commit | b1ee8a3de5790777f325416ad97340428d8ae25f (patch) | |
tree | 7fb570821268ff0eab738759eb345b85bc7df179 /arch/powerpc/kernel | |
parent | c4f3b52ce7b16824befb16ab3d045c891b08b7db (diff) | |
download | op-kernel-dev-b1ee8a3de5790777f325416ad97340428d8ae25f.zip op-kernel-dev-b1ee8a3de5790777f325416ad97340428d8ae25f.tar.gz |
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: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 5 |
3 files changed, 11 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 1466e96..439c257 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -234,6 +234,7 @@ int main(void) OFFSET(PACAEMERGSP, paca_struct, emergency_sp); #ifdef CONFIG_PPC_BOOK3S_64 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_NMI, paca_struct, in_nmi); #endif diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 4be6256..3840a77 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -144,10 +144,12 @@ EXC_COMMON_BEGIN(system_reset_common) li r10,MSR_RI mtmsrd r10,1 - EXCEPTION_COMMON(PACA_EXNMI, 0x100, - system_reset, system_reset_exception, 1f, + mr r10,r1 + 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) -1: /* EXCEPTION_COMMON continues here */ /* * The stack is no longer in use, decrement in_nmi. diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 729e990..0f7b158 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -628,6 +628,11 @@ void __init emergency_stack_init(void) paca[i].emergency_sp = (void *)ti + THREAD_SIZE; #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. */ ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit)); klp_init_thread_info(ti); |