[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240125062739.1339782-22-debug@rivosinc.com>
Date: Wed, 24 Jan 2024 22:21:46 -0800
From: debug@...osinc.com
To: rick.p.edgecombe@...el.com,
broonie@...nel.org,
Szabolcs.Nagy@....com,
kito.cheng@...ive.com,
keescook@...omium.org,
ajones@...tanamicro.com,
paul.walmsley@...ive.com,
palmer@...belt.com,
conor.dooley@...rochip.com,
cleger@...osinc.com,
atishp@...shpatra.org,
alex@...ti.fr,
bjorn@...osinc.com,
alexghiti@...osinc.com
Cc: corbet@....net,
aou@...s.berkeley.edu,
oleg@...hat.com,
akpm@...ux-foundation.org,
arnd@...db.de,
ebiederm@...ssion.com,
shuah@...nel.org,
brauner@...nel.org,
debug@...osinc.com,
guoren@...nel.org,
samitolvanen@...gle.com,
evan@...osinc.com,
xiao.w.wang@...el.com,
apatel@...tanamicro.com,
mchitale@...tanamicro.com,
waylingii@...il.com,
greentime.hu@...ive.com,
heiko@...ech.de,
jszhang@...nel.org,
shikemeng@...weicloud.com,
david@...hat.com,
charlie@...osinc.com,
panqinglin2020@...as.ac.cn,
willy@...radead.org,
vincent.chen@...ive.com,
andy.chiu@...ive.com,
gerg@...nel.org,
jeeheng.sia@...rfivetech.com,
mason.huo@...rfivetech.com,
ancientmodern4@...il.com,
mathis.salmen@...sal.de,
cuiyunhui@...edance.com,
bhe@...hat.com,
chenjiahao16@...wei.com,
ruscur@...sell.cc,
bgray@...ux.ibm.com,
alx@...nel.org,
baruch@...s.co.il,
zhangqing@...ngson.cn,
catalin.marinas@....com,
revest@...omium.org,
josh@...htriplett.org,
joey.gouly@....com,
shr@...kernel.io,
omosnace@...hat.com,
ojeda@...nel.org,
jhubbard@...dia.com,
linux-doc@...r.kernel.org,
linux-riscv@...ts.infradead.org,
linux-kernel@...r.kernel.org,
linux-mm@...ck.org,
linux-arch@...r.kernel.org,
linux-kselftest@...r.kernel.org
Subject: [RFC PATCH v1 21/28] riscv/traps: Introduce software check exception
From: Deepak Gupta <debug@...osinc.com>
zicfiss / zicfilp introduces a new exception to priv isa `software check
exception` with cause code = 18. This patch implements software check exception.
Additionally it implements a cfi violation handler which checks for code in xtval
If xtval=2, it means that sw check exception happened because of an indirect
branch not landing on 4 byte aligned PC or not landing on `lpad` instruction or
label value embedded in `lpad` not matching label value setup in `x7`.
If xtval=3, it means that sw check exception happened because of mismatch between
link register (x1 or x5) and top of shadow stack (on execution of `sspopchk`)
In case of cfi violation, SIGSEGV is raised with code=SEGV_CPERR. SEGV_CPERR was
introduced by x86 shadow stack patches.
Signed-off-by: Deepak Gupta <debug@...osinc.com>
---
arch/riscv/include/asm/asm-prototypes.h | 1 +
arch/riscv/kernel/entry.S | 3 ++
arch/riscv/kernel/traps.c | 38 +++++++++++++++++++++++++
3 files changed, 42 insertions(+)
diff --git a/arch/riscv/include/asm/asm-prototypes.h b/arch/riscv/include/asm/asm-prototypes.h
index 36b955c762ba..4ba8aea58dd0 100644
--- a/arch/riscv/include/asm/asm-prototypes.h
+++ b/arch/riscv/include/asm/asm-prototypes.h
@@ -24,6 +24,7 @@ DECLARE_DO_ERROR_INFO(do_trap_ecall_u);
DECLARE_DO_ERROR_INFO(do_trap_ecall_s);
DECLARE_DO_ERROR_INFO(do_trap_ecall_m);
DECLARE_DO_ERROR_INFO(do_trap_break);
+DECLARE_DO_ERROR_INFO(do_trap_software_check);
asmlinkage void handle_bad_stack(struct pt_regs *regs);
asmlinkage void do_page_fault(struct pt_regs *regs);
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 410659e2eadb..56dfe04094c1 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -369,6 +369,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
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index a1b9be3c4332..9fba263428a1 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -339,6 +339,44 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs)
}
+#define CFI_TVAL_FCFI_CODE 2
+#define CFI_TVAL_BCFI_CODE 3
+/* handle cfi violations */
+bool handle_user_cfi_violation(struct pt_regs *regs)
+{
+ bool ret = false;
+ unsigned long tval = csr_read(CSR_TVAL);
+
+ if (((tval == CFI_TVAL_FCFI_CODE) && cpu_supports_indirect_br_lp_instr()) ||
+ ((tval == CFI_TVAL_BCFI_CODE) && cpu_supports_shadow_stack())) {
+ do_trap_error(regs, SIGSEGV, SEGV_CPERR, regs->epc,
+ "Oops - control flow violation");
+ ret = true;
+ }
+
+ return ret;
+}
+/*
+ * software check exception is defined with risc-v cfi spec. Software check
+ * exception is raised when:-
+ * a) An indirect branch doesn't land on 4 byte aligned PC or `lpad`
+ * instruction or `label` value programmed in `lpad` instr doesn't
+ * match with value setup in `x7`. reported code in `xtval` is 2.
+ * b) `sspopchk` instruction finds a mismatch between top of shadow stack (ssp)
+ * and x1/x5. reported code in `xtval` is 3.
+ */
+asmlinkage __visible __trap_section void do_trap_software_check(struct pt_regs *regs)
+{
+ if (user_mode(regs)) {
+ /* not a cfi violation, then merge into flow of unknown trap handler */
+ if (!handle_user_cfi_violation(regs))
+ do_trap_unknown(regs);
+ } else {
+ /* sw check exception coming from kernel is a bug in kernel */
+ die(regs, "Kernel BUG");
+ }
+}
+
#ifdef CONFIG_MMU
asmlinkage __visible noinstr void do_page_fault(struct pt_regs *regs)
{
--
2.43.0
Powered by blists - more mailing lists