irq: arm: perform irqentry in entry code
authorMark Rutland <mark.rutland@arm.com>
Tue, 19 Oct 2021 17:17:17 +0000 (18:17 +0100)
committerMark Rutland <mark.rutland@arm.com>
Mon, 25 Oct 2021 09:05:31 +0000 (10:05 +0100)
In preparation for removing HANDLE_DOMAIN_IRQ_IRQENTRY, have arch/arm
perform all the irqentry accounting in its entry code.

For configurations with CONFIG_GENERIC_IRQ_MULTI_HANDLER, we can use
generic_handle_arch_irq(). Other than asm_do_IRQ(), all C calls to
handle_IRQ() are from irqchip handlers which will be called from
generic_handle_arch_irq(), so to avoid double accounting IRQ entry, the
entry logic is moved from handle_IRQ() into asm_do_IRQ().

For ARMv7M the entry assembly is tightly coupled with the NVIC irqchip, and
while the entry code should logically live under arch/arm/, moving the
entry logic there makes things more convoluted. So for now, place the
entry logic in the NVIC irqchip, but separated into a separate
function to make the split of responsibility clear.

For all other configurations without CONFIG_GENERIC_IRQ_MULTI_HANDLER,
IRQ entry is already handled in arch code, and requires no changes.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com> # ARMv7M
Cc: Russell King <linux@armlinux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
arch/arm/Kconfig
arch/arm/kernel/entry-armv.S
arch/arm/kernel/irq.c
drivers/irqchip/irq-nvic.c

index f18aff8..fc19642 100644 (file)
@@ -65,7 +65,6 @@ config ARM
        select GENERIC_SCHED_CLOCK
        select GENERIC_SMP_IDLE_THREAD
        select HANDLE_DOMAIN_IRQ
-       select HANDLE_DOMAIN_IRQ_IRQENTRY
        select HARDIRQS_SW_RESEND
        select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
        select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
index 241b73d..3d0b616 100644 (file)
  */
        .macro  irq_handler
 #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
-       ldr     r1, =handle_arch_irq
        mov     r0, sp
-       badr    lr, 9997f
-       ldr     pc, [r1]
+       bl      generic_handle_arch_irq
 #else
        arch_irq_handler_default
 #endif
-9997:
        .endm
 
        .macro  pabt_helper
index 20ab1e6..b79975b 100644 (file)
@@ -63,11 +63,8 @@ int arch_show_interrupts(struct seq_file *p, int prec)
  */
 void handle_IRQ(unsigned int irq, struct pt_regs *regs)
 {
-       struct pt_regs *old_regs = set_irq_regs(regs);
        struct irq_desc *desc;
 
-       irq_enter();
-
        /*
         * Some hardware gives randomly wrong interrupts.  Rather
         * than crashing, do something sensible.
@@ -81,9 +78,6 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs)
                handle_irq_desc(desc);
        else
                ack_bad_irq(irq);
-
-       irq_exit();
-       set_irq_regs(old_regs);
 }
 
 /*
@@ -92,7 +86,15 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs)
 asmlinkage void __exception_irq_entry
 asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
+
+       irq_enter();
+       old_regs = set_irq_regs(regs);
+
        handle_IRQ(irq, regs);
+
+       set_irq_regs(old_regs);
+       irq_exit();
 }
 
 void __init init_IRQ(void)
index b31c4cf..b2bd962 100644 (file)
 
 static struct irq_domain *nvic_irq_domain;
 
+static void __nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
+{
+       handle_domain_irq(nvic_irq_domain, hwirq, regs);
+}
+
+/*
+ * TODO: restructure the ARMv7M entry logic so that this entry logic can live
+ * in arch code.
+ */
 asmlinkage void __exception_irq_entry
 nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
 {
-       handle_domain_irq(nvic_irq_domain, hwirq, regs);
+       struct pt_regs *old_regs;
+
+       irq_enter();
+       old_regs = set_irq_regs(regs);
+       __nvic_handle_irq(hwirq, regs);
+       set_irq_regs(old_regs);
+       irq_exit();
 }
 
 static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,