diff options
author | Palmer Dabbelt <palmer@rivosinc.com> | 2022-12-01 11:38:39 -0800 |
---|---|---|
committer | Palmer Dabbelt <palmer@rivosinc.com> | 2022-12-01 11:38:39 -0800 |
commit | 39cefc5f6cd25d555e0455b24810e9aff365b8d6 (patch) | |
tree | 3f5ae903747a2bec6fab24ea9de151ddbdf766cf /arch/riscv/kernel/traps.c | |
parent | d556a9aeb62a6cd44aa05aeadcc48245da0a1939 (diff) | |
parent | 7e1864332fbc1b993659eab7974da9fe8bf8c128 (diff) | |
download | linux-39cefc5f6cd25d555e0455b24810e9aff365b8d6.tar.gz |
RISC-V: Fix a race condition during kernel stack overflow
This fixes a concrete bug but is also the basis for some cleanup work,
so I'm merging it based on the offending commit in order to minimize
future conflicts.
* commit '7e1864332fbc1b993659eab7974da9fe8bf8c128':
riscv: fix race when vmap stack overflow
Diffstat (limited to 'arch/riscv/kernel/traps.c')
-rw-r--r-- | arch/riscv/kernel/traps.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index f3e96d60a2ff..7abd8e4c4df6 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -221,11 +221,29 @@ asmlinkage unsigned long get_overflow_stack(void) OVERFLOW_STACK_SIZE; } +/* + * A pseudo spinlock to protect the shadow stack from being used by multiple + * harts concurrently. This isn't a real spinlock because the lock side must + * be taken without a valid stack and only a single register, it's only taken + * while in the process of panicing anyway so the performance and error + * checking a proper spinlock gives us doesn't matter. + */ +unsigned long spin_shadow_stack; + asmlinkage void handle_bad_stack(struct pt_regs *regs) { unsigned long tsk_stk = (unsigned long)current->stack; unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack); + /* + * We're done with the shadow stack by this point, as we're on the + * overflow stack. Tell any other concurrent overflowing harts that + * they can proceed with panicing by releasing the pseudo-spinlock. + * + * This pairs with an amoswap.aq in handle_kernel_stack_overflow. + */ + smp_store_release(&spin_shadow_stack, 0); + console_verbose(); pr_emerg("Insufficient stack space to handle exception!\n"); |