summaryrefslogtreecommitdiff
path: root/arch/riscv/kernel/traps.c
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer@rivosinc.com>2023-06-22 10:38:39 -0700
committerPalmer Dabbelt <palmer@rivosinc.com>2023-06-23 10:06:21 -0700
commitb5e13f3ace78a8159dbad92bb005090a431e36d7 (patch)
treeecf5360b87b4aef89194904804670c12b5e5f56b /arch/riscv/kernel/traps.c
parent42b89447b65863904eaf802ee05b55a238eac538 (diff)
parenta7555f6b62e7f5b3a3b783cc6d4c4dafcb8527c8 (diff)
downloadlinux-b5e13f3ace78a8159dbad92bb005090a431e36d7.tar.gz
linux-b5e13f3ace78a8159dbad92bb005090a431e36d7.tar.bz2
linux-b5e13f3ace78a8159dbad92bb005090a431e36d7.zip
Merge patch series "riscv: Add independent irq/softirq stacks support"
guoren@kernel.org <guoren@kernel.org> says: From: Guo Ren <guoren@linux.alibaba.com> This patch series adds independent irq/softirq stacks to decrease the press of the thread stack. Also, add a thread STACK_SIZE config for users to adjust the proper size during compile time. * b4-shazam-merge: riscv: stack: Add config of thread stack size riscv: stack: Support HAVE_SOFTIRQ_ON_OWN_STACK riscv: stack: Support HAVE_IRQ_EXIT_ON_IRQ_STACK Link: https://lore.kernel.org/r/20230614013018.2168426-1-guoren@kernel.org Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Diffstat (limited to 'arch/riscv/kernel/traps.c')
-rw-r--r--arch/riscv/kernel/traps.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 05ffdcd1424e..5158961ea977 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -27,6 +27,7 @@
#include <asm/syscall.h>
#include <asm/thread_info.h>
#include <asm/vector.h>
+#include <asm/irq_stack.h>
int show_unhandled_signals = 1;
@@ -327,16 +328,46 @@ asmlinkage __visible noinstr void do_page_fault(struct pt_regs *regs)
}
#endif
-asmlinkage __visible noinstr void do_irq(struct pt_regs *regs)
+static void noinstr handle_riscv_irq(struct pt_regs *regs)
{
struct pt_regs *old_regs;
- irqentry_state_t state = irqentry_enter(regs);
irq_enter_rcu();
old_regs = set_irq_regs(regs);
handle_arch_irq(regs);
set_irq_regs(old_regs);
irq_exit_rcu();
+}
+
+asmlinkage void noinstr do_irq(struct pt_regs *regs)
+{
+ irqentry_state_t state = irqentry_enter(regs);
+#ifdef CONFIG_IRQ_STACKS
+ if (on_thread_stack()) {
+ ulong *sp = per_cpu(irq_stack_ptr, smp_processor_id())
+ + IRQ_STACK_SIZE/sizeof(ulong);
+ __asm__ __volatile(
+ "addi sp, sp, -"RISCV_SZPTR "\n"
+ REG_S" ra, (sp) \n"
+ "addi sp, sp, -"RISCV_SZPTR "\n"
+ REG_S" s0, (sp) \n"
+ "addi s0, sp, 2*"RISCV_SZPTR "\n"
+ "move sp, %[sp] \n"
+ "move a0, %[regs] \n"
+ "call handle_riscv_irq \n"
+ "addi sp, s0, -2*"RISCV_SZPTR"\n"
+ REG_L" s0, (sp) \n"
+ "addi sp, sp, "RISCV_SZPTR "\n"
+ REG_L" ra, (sp) \n"
+ "addi sp, sp, "RISCV_SZPTR "\n"
+ :
+ : [sp] "r" (sp), [regs] "r" (regs)
+ : "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6",
+ "memory");
+ } else
+#endif
+ handle_riscv_irq(regs);
irqentry_exit(regs, state);
}