summaryrefslogtreecommitdiff
path: root/arch/riscv/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv/kernel/entry.S')
-rw-r--r--arch/riscv/kernel/entry.S38
1 files changed, 38 insertions, 0 deletions
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 9b9dec6893b8..60eb221296a6 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -92,6 +92,35 @@
REG_L a0, TASK_TI_A0(tp)
.endm
+/*
+ * If previous mode was U, capture shadow stack pointer and save it away
+ * Zero CSR_SSP at the same time for sanitization.
+ */
+.macro save_userssp tmp, status
+ ALTERNATIVE("nops(4)",
+ __stringify( \
+ andi \tmp, \status, SR_SPP; \
+ bnez \tmp, skip_ssp_save; \
+ csrrw \tmp, CSR_SSP, x0; \
+ REG_S \tmp, TASK_TI_USER_SSP(tp); \
+ skip_ssp_save:),
+ 0,
+ RISCV_ISA_EXT_ZICFISS,
+ CONFIG_RISCV_USER_CFI)
+.endm
+
+.macro restore_userssp tmp, status
+ ALTERNATIVE("nops(4)",
+ __stringify( \
+ andi \tmp, \status, SR_SPP; \
+ bnez \tmp, skip_ssp_restore; \
+ REG_L \tmp, TASK_TI_USER_SSP(tp); \
+ csrw CSR_SSP, \tmp; \
+ skip_ssp_restore:),
+ 0,
+ RISCV_ISA_EXT_ZICFISS,
+ CONFIG_RISCV_USER_CFI)
+.endm
SYM_CODE_START(handle_exception)
/*
@@ -145,9 +174,14 @@ SYM_CODE_START(handle_exception)
* or vector in kernel space.
*/
li t0, SR_SUM | SR_FS_VS
+#ifdef CONFIG_64BIT
+ li t1, SR_ELP
+ or t0, t0, t1
+#endif
REG_L s0, TASK_TI_USER_SP(tp)
csrrc s1, CSR_STATUS, t0
+ save_userssp s2, s1
csrr s2, CSR_EPC
csrr s3, CSR_TVAL
csrr s4, CSR_CAUSE
@@ -243,6 +277,7 @@ SYM_CODE_START_NOALIGN(ret_from_exception)
call riscv_v_context_nesting_end
#endif
REG_L a0, PT_STATUS(sp)
+ restore_userssp s3, a0
/*
* The current load reservation is effectively part of the processor's
* state, in the sense that load reservations cannot be shared between
@@ -460,6 +495,9 @@ SYM_DATA_START_LOCAL(excp_vect_table)
RISCV_PTR do_page_fault /* load page fault */
RISCV_PTR do_trap_unknown
RISCV_PTR do_page_fault /* store page fault */
+ RISCV_PTR do_trap_unknown /* cause=16 */
+ RISCV_PTR do_trap_unknown /* cause=17 */
+ RISCV_PTR do_trap_software_check /* cause=18 is sw check exception */
SYM_DATA_END_LABEL(excp_vect_table, SYM_L_LOCAL, excp_vect_table_end)
#ifndef CONFIG_MMU