Skip to content

Commit 5d5fc33

Browse files
antonblanchardpalmer-dabbelt
authored andcommitted
riscv: Improve exception and system call latency
Many CPUs implement return address branch prediction as a stack. The RISCV architecture refers to this as a return address stack (RAS). If this gets corrupted then the CPU will mispredict at least one but potentally many function returns. There are two issues with the current RISCV exception code: - We are using the alternate link stack (x5/t0) for the indirect branch which makes the hardware think this is a function return. This will corrupt the RAS. - We modify the return address of handle_exception to point to ret_from_exception. This will also corrupt the RAS. Testing the null system call latency before and after the patch: Visionfive2 (StarFive JH7110 / U74) baseline: 189.87 ns patched: 176.76 ns Lichee pi 4a (T-Head TH1520 / C910) baseline: 666.58 ns patched: 636.90 ns Just over 7% on the U74 and just over 4% on the C910. Signed-off-by: Anton Blanchard <[email protected]> Signed-off-by: Cyril Bur <[email protected]> Tested-by: Jisheng Zhang <[email protected]> Reviewed-by: Jisheng Zhang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 8d22d0d commit 5d5fc33

File tree

2 files changed

+12
-9
lines changed

2 files changed

+12
-9
lines changed

arch/riscv/kernel/entry.S

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ SYM_CODE_START(handle_exception)
8888
call riscv_v_context_nesting_start
8989
#endif
9090
move a0, sp /* pt_regs */
91-
la ra, ret_from_exception
9291

9392
/*
9493
* MSB of cause differentiates between
@@ -97,19 +96,23 @@ SYM_CODE_START(handle_exception)
9796
bge s4, zero, 1f
9897

9998
/* Handle interrupts */
100-
tail do_irq
99+
call do_irq
100+
j ret_from_exception
101101
1:
102102
/* Handle other exceptions */
103103
slli t0, s4, RISCV_LGPTR
104104
la t1, excp_vect_table
105105
la t2, excp_vect_table_end
106106
add t0, t1, t0
107107
/* Check if exception code lies within bounds */
108-
bgeu t0, t2, 1f
109-
REG_L t0, 0(t0)
110-
jr t0
111-
1:
112-
tail do_trap_unknown
108+
bgeu t0, t2, 3f
109+
REG_L t1, 0(t0)
110+
2: jalr t1
111+
j ret_from_exception
112+
3:
113+
114+
la t1, do_trap_unknown
115+
j 2b
113116
SYM_CODE_END(handle_exception)
114117
ASM_NOKPROBE(handle_exception)
115118

arch/riscv/kernel/stacktrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#ifdef CONFIG_FRAME_POINTER
1818

19-
extern asmlinkage void ret_from_exception(void);
19+
extern asmlinkage void handle_exception(void);
2020

2121
static inline int fp_is_valid(unsigned long fp, unsigned long sp)
2222
{
@@ -71,7 +71,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
7171
fp = frame->fp;
7272
pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
7373
&frame->ra);
74-
if (pc == (unsigned long)ret_from_exception) {
74+
if (pc == (unsigned long)handle_exception) {
7575
if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
7676
break;
7777

0 commit comments

Comments
 (0)