aboutsummaryrefslogtreecommitdiffstats
path: root/arch/riscv/kernel/entry.S
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer@rivosinc.com>2022-12-01 11:38:39 -0800
committerPalmer Dabbelt <palmer@rivosinc.com>2022-12-01 11:38:39 -0800
commit39cefc5f6cd25d555e0455b24810e9aff365b8d6 (patch)
tree3f5ae903747a2bec6fab24ea9de151ddbdf766cf /arch/riscv/kernel/entry.S
parentd556a9aeb62a6cd44aa05aeadcc48245da0a1939 (diff)
parent7e1864332fbc1b993659eab7974da9fe8bf8c128 (diff)
downloadlinux-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/entry.S')
-rw-r--r--arch/riscv/kernel/entry.S13
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index b9eda3fcbd6d..186abd146eaf 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -404,6 +404,19 @@ handle_syscall_trace_exit:
#ifdef CONFIG_VMAP_STACK
handle_kernel_stack_overflow:
+ /*
+ * Takes the psuedo-spinlock for the shadow stack, in case multiple
+ * harts are concurrently overflowing their kernel stacks. We could
+ * store any value here, but since we're overflowing the kernel stack
+ * already we only have SP to use as a scratch register. So we just
+ * swap in the address of the spinlock, as that's definately non-zero.
+ *
+ * Pairs with a store_release in handle_bad_stack().
+ */
+1: la sp, spin_shadow_stack
+ REG_AMOSWAP_AQ sp, sp, (sp)
+ bnez sp, 1b
+
la sp, shadow_stack
addi sp, sp, SHADOW_OVERFLOW_STACK_SIZE