[PATCH RFC v3 27/30] ARM: irq: Add irqstack helpers
From: Linus Walleij <hidden>
Date: 2025-01-07 09:42:03
Also in:
lkml
Subsystem:
arm port, the rest · Maintainers:
Russell King, Linus Torvalds
Add two helpers that essentially re-implement some IRQ dispatch code in C: on_irq_stack() that checks if a regs context is on the IRQ stack, and call_on_irq_stack() so we can explicitly issue handle_irq() on the IRQ stack from a C program. Cc: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Linus Walleij <redacted> --- arch/arm/kernel/irq.c | 31 +++++++++++++++++++++++++++++++ arch/arm/kernel/irq.h | 3 +++ 2 files changed, 34 insertions(+)
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index e1993e28a9ecfd80b55b2677253ac582467e6c14..4c1a678b72b326e42c871b994c09d1fa4b0863f6 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c@@ -43,6 +43,7 @@ #include <asm/mach/irq.h> #include <asm/mach/time.h> +#include "irq.h" #include "reboot.h" unsigned long irq_err_count;
@@ -71,6 +72,36 @@ static void __init init_irq_stacks(void) } } +/* + * on_irq_stack() - check if a regs context is using the IRQ stack + * @regs: the context to check + * Returns true if regs is using the IRQ stack + */ +bool on_irq_stack(struct pt_regs *regs) +{ + u8 *high = __this_cpu_read(irq_stack_ptr); + u8 *low = high - THREAD_SIZE; + u8 *sp = (u8 *)regs->ARM_sp; + bool on_stack; + + on_stack = (low <= sp && sp <= high); + + if (on_stack && IS_ENABLED(CONFIG_VMAP_STACK)) + /* + * Also check that SP is inside the linear kernel memory + * if using VMAP:ed stacks. + * TODO: Ask Ard to explain why we need to do this + */ + on_stack = (sp > (u8 *)high_memory); + + return on_stack; +} + +void call_on_irq_stack(void (*fn)(void *), void *arg) +{ + call_with_stack(fn, arg, __this_cpu_read(irq_stack_ptr)); +} + #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK static void ____do_softirq(void *arg) {
diff --git a/arch/arm/kernel/irq.h b/arch/arm/kernel/irq.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5186b67242a2976fe702154ed4f2a22eca51add
--- /dev/null
+++ b/arch/arm/kernel/irq.h@@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +bool on_irq_stack(struct pt_regs *regs); +void call_on_irq_stack(void (*fn)(void *), void *arg);
--
2.47.1