]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - arch/riscv/kernel/irq.c
Merge tag 'riscv-for-linus-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[thirdparty/linux.git] / arch / riscv / kernel / irq.c
index 9cc0a76692715ea6ff2ec56630f7b60ed0a37f92..9ceda02507cae9c73efac8c0589695b38d03e499 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/irqchip.h>
 #include <linux/irqdomain.h>
 #include <linux/module.h>
+#include <linux/scs.h>
 #include <linux/seq_file.h>
 #include <asm/sbi.h>
 #include <asm/smp.h>
@@ -34,6 +35,24 @@ EXPORT_SYMBOL_GPL(riscv_get_intc_hwnode);
 #ifdef CONFIG_IRQ_STACKS
 #include <asm/irq_stack.h>
 
+DECLARE_PER_CPU(ulong *, irq_shadow_call_stack_ptr);
+
+#ifdef CONFIG_SHADOW_CALL_STACK
+DEFINE_PER_CPU(ulong *, irq_shadow_call_stack_ptr);
+#endif
+
+static void init_irq_scs(void)
+{
+       int cpu;
+
+       if (!scs_is_enabled())
+               return;
+
+       for_each_possible_cpu(cpu)
+               per_cpu(irq_shadow_call_stack_ptr, cpu) =
+                       scs_alloc(cpu_to_node(cpu));
+}
+
 DEFINE_PER_CPU(ulong *, irq_stack_ptr);
 
 #ifdef CONFIG_VMAP_STACK
@@ -61,40 +80,22 @@ static void init_irq_stacks(void)
 #endif /* CONFIG_VMAP_STACK */
 
 #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK
+static void ___do_softirq(struct pt_regs *regs)
+{
+       __do_softirq();
+}
+
 void do_softirq_own_stack(void)
 {
-#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"
-               "call   __do_softirq            \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)
-               : "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
-                 "t0", "t1", "t2", "t3", "t4", "t5", "t6",
-#ifndef CONFIG_FRAME_POINTER
-                 "s0",
-#endif
-                 "memory");
-       } else
-#endif
+       if (on_thread_stack())
+               call_on_irq_stack(NULL, ___do_softirq);
+       else
                __do_softirq();
 }
 #endif /* CONFIG_SOFTIRQ_ON_OWN_STACK */
 
 #else
+static void init_irq_scs(void) {}
 static void init_irq_stacks(void) {}
 #endif /* CONFIG_IRQ_STACKS */
 
@@ -106,6 +107,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 
 void __init init_IRQ(void)
 {
+       init_irq_scs();
        init_irq_stacks();
        irqchip_init();
        if (!handle_arch_irq)