summaryrefslogtreecommitdiff
path: root/arch/riscv/kernel
diff options
context:
space:
mode:
authorDeepak Gupta <debug@rivosinc.com>2026-01-25 21:09:55 -0700
committerPaul Walmsley <pjw@kernel.org>2026-01-29 02:38:40 -0700
commit41213bf2ae6c936f51a79986b37f95da9ecbb970 (patch)
treec0a3e34c70940969493e139928372ed9ed704802 /arch/riscv/kernel
parentc9b859c4d8f56c014b3d5fbd1bcfb916c34955a1 (diff)
riscv: enable kernel access to shadow stack memory via the FWFT SBI call
The kernel has to perform shadow stack operations on the user shadow stack. During signal delivery and sigreturn, the shadow stack token must be created and validated respectively. Thus shadow stack access for the kernel must be enabled. In the future, when kernel shadow stacks are enabled, they must be enabled as early as possible for better coverage and to prevent any imbalance between the regular stack and the shadow stack. After 'relocate_enable_mmu' has completed, this is the earliest that it can be enabled. Reviewed-by: Zong Li <zong.li@sifive.com> Signed-off-by: Deepak Gupta <debug@rivosinc.com> Tested-by: Andreas Korb <andreas.korb@aisec.fraunhofer.de> # QEMU, custom CVA6 Tested-by: Valentin Haudiquet <valentin.haudiquet@canonical.com> Link: https://patch.msgid.link/20251112-v5_user_cfi_series-v23-22-b55691eacf4f@rivosinc.com [pjw@kernel.org: updated to apply; cleaned up commit message] Signed-off-by: Paul Walmsley <pjw@kernel.org>
Diffstat (limited to 'arch/riscv/kernel')
-rw-r--r--arch/riscv/kernel/asm-offsets.c6
-rw-r--r--arch/riscv/kernel/head.S27
2 files changed, 33 insertions, 0 deletions
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index 8a2b2656cb2f..af827448a609 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -533,4 +533,10 @@ void asm_offsets(void)
DEFINE(FREGS_A6, offsetof(struct __arch_ftrace_regs, a6));
DEFINE(FREGS_A7, offsetof(struct __arch_ftrace_regs, a7));
#endif
+#ifdef CONFIG_RISCV_SBI
+ DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
+ DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
+ DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
+ DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
+#endif
}
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index bdf3352acf4c..9c99c5ad6fe8 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -15,6 +15,7 @@
#include <asm/image.h>
#include <asm/scs.h>
#include <asm/xip_fixup.h>
+#include <asm/usercfi.h>
#include "efi-header.S"
__HEAD
@@ -170,6 +171,19 @@ secondary_start_sbi:
call relocate_enable_mmu
#endif
call .Lsetup_trap_vector
+#if defined(CONFIG_RISCV_SBI) && defined(CONFIG_RISCV_USER_CFI)
+ li a7, SBI_EXT_FWFT
+ li a6, SBI_EXT_FWFT_SET
+ li a0, SBI_FWFT_SHADOW_STACK
+ li a1, 1 /* enable supervisor to access shadow stack access */
+ li a2, SBI_FWFT_SET_FLAG_LOCK
+ ecall
+ beqz a0, 1f
+ la a1, riscv_nousercfi
+ li a0, CMDLINE_DISABLE_RISCV_USERCFI_BCFI
+ REG_S a0, (a1)
+1:
+#endif
scs_load_current
call smp_callin
#endif /* CONFIG_SMP */
@@ -330,6 +344,19 @@ SYM_CODE_START(_start_kernel)
la tp, init_task
la sp, init_thread_union + THREAD_SIZE
addi sp, sp, -PT_SIZE_ON_STACK
+#if defined(CONFIG_RISCV_SBI) && defined(CONFIG_RISCV_USER_CFI)
+ li a7, SBI_EXT_FWFT
+ li a6, SBI_EXT_FWFT_SET
+ li a0, SBI_FWFT_SHADOW_STACK
+ li a1, 1 /* enable supervisor to access shadow stack access */
+ li a2, SBI_FWFT_SET_FLAG_LOCK
+ ecall
+ beqz a0, 1f
+ la a1, riscv_nousercfi
+ li a0, CMDLINE_DISABLE_RISCV_USERCFI_BCFI
+ REG_S a0, (a1)
+1:
+#endif
scs_load_current
#ifdef CONFIG_KASAN