Skip to content

Commit

Permalink
Merge branch irq/remove-handle-domain-irq-20211026 into irq/irqchip-next
Browse files Browse the repository at this point in the history
* irq/remove-handle-domain-irq-20211026:
  : Large rework of the architecture entry code from Mark Rutland.
  : From the cover letter:
  :
  : <quote>
  : The handle_domain_{irq,nmi}() functions were oringally intended as a
  : convenience, but recent rework to entry code across the kernel tree has
  : demonstrated that they cause more pain than they're worth and prevent
  : architectures from being able to write robust entry code.
  :
  : This series reworks the irq code to remove them, handling the necessary
  : entry work consistently in entry code (be it architectural or generic).
  : </quote>
  MIPS: irq: Avoid an unused-variable error
  irq: remove handle_domain_{irq,nmi}()
  irq: remove CONFIG_HANDLE_DOMAIN_IRQ_IRQENTRY
  irq: riscv: perform irqentry in entry code
  irq: openrisc: perform irqentry in entry code
  irq: csky: perform irqentry in entry code
  irq: arm64: perform irqentry in entry code
  irq: arm: perform irqentry in entry code
  irq: add a (temporary) CONFIG_HANDLE_DOMAIN_IRQ_IRQENTRY
  irq: nds32: avoid CONFIG_HANDLE_DOMAIN_IRQ
  irq: arc: avoid CONFIG_HANDLE_DOMAIN_IRQ
  irq: add generic_handle_arch_irq()
  irq: unexport handle_irq_desc()
  irq: simplify handle_domain_{irq,nmi}()
  irq: mips: simplify do_domain_IRQ()
  irq: mips: stop (ab)using handle_domain_irq()
  irq: mips: simplify bcm6345_l1_irq_handle()
  irq: mips: avoid nested irq_enter()

Signed-off-by: Marc Zyngier <[email protected]>
  • Loading branch information
Marc Zyngier committed Oct 28, 2021
2 parents e6a767a + 34fca89 commit c6dca71
Show file tree
Hide file tree
Showing 67 changed files with 192 additions and 221 deletions.
3 changes: 0 additions & 3 deletions Documentation/core-api/irq/irq-domain.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ variety of methods:
deprecated
- generic_handle_domain_irq() handles an interrupt described by a
domain and a hwirq number
- handle_domain_irq() does the same thing for root interrupt
controllers and deals with the set_irq_reg()/irq_enter() sequences
that most architecture requires

Note that irq domain lookups must happen in contexts that are
compatible with a RCU read-side critical section.
Expand Down
1 change: 0 additions & 1 deletion arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ config ARC
select HAVE_KRETPROBES
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_PERF_EVENTS
select HANDLE_DOMAIN_IRQ
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select OF
Expand Down
10 changes: 9 additions & 1 deletion arch/arc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <linux/interrupt.h>
#include <linux/irqchip.h>
#include <asm/mach_desc.h>

#include <asm/irq_regs.h>
#include <asm/smp.h>

/*
Expand Down Expand Up @@ -39,5 +41,11 @@ void __init init_IRQ(void)
*/
void arch_do_IRQ(unsigned int hwirq, struct pt_regs *regs)
{
handle_domain_irq(NULL, hwirq, regs);
struct pt_regs *old_regs;

irq_enter();
old_regs = set_irq_regs(regs);
generic_handle_domain_irq(NULL, hwirq);
set_irq_regs(old_regs);
irq_exit();
}
1 change: 0 additions & 1 deletion arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ config ARM
select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
Expand Down
5 changes: 1 addition & 4 deletions arch/arm/kernel/entry-armv.S
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,11 @@
*/
.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
Expand Down
14 changes: 8 additions & 6 deletions arch/arm/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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);
}

/*
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-imx/avic.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
if (nivector == 0xffff)
break;

handle_domain_irq(domain, nivector, regs);
generic_handle_domain_irq(domain, nivector);
} while (1);
}

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-imx/tzic.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
while (stat) {
handled = 1;
irqofs = fls(stat) - 1;
handle_domain_irq(domain, irqofs + i * 32, regs);
generic_handle_domain_irq(domain, irqofs + i * 32);
stat &= ~(1 << irqofs);
}
}
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-omap1/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs)
}
irq:
if (irqnr)
handle_domain_irq(domain, irqnr, regs);
generic_handle_domain_irq(domain, irqnr);
else
break;
} while (irqnr);
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-s3c/irq-s3c24xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
if (!(pnd & (1 << offset)))
offset = __ffs(pnd);

handle_domain_irq(intc->domain, intc_offset + offset, regs);
generic_handle_domain_irq(intc->domain, intc_offset + offset);
return true;
}

Expand Down
1 change: 0 additions & 1 deletion arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ config ARM64
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_TIME_NS
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_MOVE_PMD
select HAVE_MOVE_PUD
Expand Down
52 changes: 31 additions & 21 deletions arch/arm64/kernel/entry-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <asm/daifflags.h>
#include <asm/esr.h>
#include <asm/exception.h>
#include <asm/irq_regs.h>
#include <asm/kprobes.h>
#include <asm/mmu.h>
#include <asm/processor.h>
Expand Down Expand Up @@ -219,22 +220,6 @@ static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)
lockdep_hardirqs_on(CALLER_ADDR0);
}

static void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs)
{
if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
arm64_enter_nmi(regs);
else
enter_from_kernel_mode(regs);
}

static void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs)
{
if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
arm64_exit_nmi(regs);
else
exit_to_kernel_mode(regs);
}

static void __sched arm64_preempt_schedule_irq(void)
{
lockdep_assert_irqs_disabled();
Expand Down Expand Up @@ -263,10 +248,14 @@ static void __sched arm64_preempt_schedule_irq(void)
static void do_interrupt_handler(struct pt_regs *regs,
void (*handler)(struct pt_regs *))
{
struct pt_regs *old_regs = set_irq_regs(regs);

if (on_thread_stack())
call_on_irq_stack(regs, handler);
else
handler(regs);

set_irq_regs(old_regs);
}

extern void (*handle_arch_irq)(struct pt_regs *);
Expand Down Expand Up @@ -432,13 +421,22 @@ asmlinkage void noinstr el1h_64_sync_handler(struct pt_regs *regs)
}
}

static void noinstr el1_interrupt(struct pt_regs *regs,
void (*handler)(struct pt_regs *))
static __always_inline void __el1_pnmi(struct pt_regs *regs,
void (*handler)(struct pt_regs *))
{
write_sysreg(DAIF_PROCCTX_NOIRQ, daif);
arm64_enter_nmi(regs);
do_interrupt_handler(regs, handler);
arm64_exit_nmi(regs);
}

static __always_inline void __el1_irq(struct pt_regs *regs,
void (*handler)(struct pt_regs *))
{
enter_from_kernel_mode(regs);

enter_el1_irq_or_nmi(regs);
irq_enter_rcu();
do_interrupt_handler(regs, handler);
irq_exit_rcu();

/*
* Note: thread_info::preempt_count includes both thread_info::count
Expand All @@ -449,7 +447,17 @@ static void noinstr el1_interrupt(struct pt_regs *regs,
READ_ONCE(current_thread_info()->preempt_count) == 0)
arm64_preempt_schedule_irq();

exit_el1_irq_or_nmi(regs);
exit_to_kernel_mode(regs);
}
static void noinstr el1_interrupt(struct pt_regs *regs,
void (*handler)(struct pt_regs *))
{
write_sysreg(DAIF_PROCCTX_NOIRQ, daif);

if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
__el1_pnmi(regs, handler);
else
__el1_irq(regs, handler);
}

asmlinkage void noinstr el1h_64_irq_handler(struct pt_regs *regs)
Expand Down Expand Up @@ -667,7 +675,9 @@ static void noinstr el0_interrupt(struct pt_regs *regs,
if (regs->pc & BIT(55))
arm64_apply_bp_hardening();

irq_enter_rcu();
do_interrupt_handler(regs, handler);
irq_exit_rcu();

exit_to_user_mode(regs);
}
Expand Down
1 change: 0 additions & 1 deletion arch/csky/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ config CSKY
select CSKY_APB_INTC
select DMA_DIRECT_REMAP
select IRQ_DOMAIN
select HANDLE_DOMAIN_IRQ
select DW_APB_TIMER_OF
select GENERIC_IOREMAP
select GENERIC_LIB_ASHLDI3
Expand Down
2 changes: 1 addition & 1 deletion arch/csky/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ ENTRY(csky_irq)


mov a0, sp
jbsr csky_do_IRQ
jbsr generic_handle_arch_irq

jmpi ret_from_exception

Expand Down
5 changes: 0 additions & 5 deletions arch/csky/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,3 @@ void __init init_IRQ(void)
setup_smp_ipi();
#endif
}

asmlinkage void __irq_entry csky_do_IRQ(struct pt_regs *regs)
{
handle_arch_irq(regs);
}
1 change: 0 additions & 1 deletion arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ config MIPS
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GUP_GET_PTE_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_COMPILER_H
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_KGDB if MIPS_FP_SUPPORT
Expand Down
5 changes: 4 additions & 1 deletion arch/mips/cavium-octeon/octeon-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -2609,7 +2609,10 @@ static void octeon_irq_ciu3_ip2(void)
else
hw = intsn;

ret = handle_domain_irq(domain, hw, NULL);
irq_enter();
ret = generic_handle_domain_irq(domain, hw);
irq_exit();

if (ret < 0) {
union cvmx_ciu3_iscx_w1c isc_w1c;
u64 isc_w1c_addr = ciu3_addr + CIU3_ISC_W1C(intsn);
Expand Down
8 changes: 1 addition & 7 deletions arch/mips/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,9 @@ void __irq_entry do_IRQ(unsigned int irq)
#ifdef CONFIG_IRQ_DOMAIN
void __irq_entry do_domain_IRQ(struct irq_domain *domain, unsigned int hwirq)
{
struct irq_desc *desc;

irq_enter();
check_stack_overflow();

desc = irq_resolve_mapping(domain, hwirq);
if (likely(desc))
handle_irq_desc(desc);

generic_handle_domain_irq(domain, hwirq);
irq_exit();
}
#endif
1 change: 0 additions & 1 deletion arch/nds32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ config NDS32
select GENERIC_LIB_MULDI3
select GENERIC_LIB_UCMPDI2
select GENERIC_TIME_VSYSCALL
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_TRACEHOOK
select HAVE_DEBUG_KMEMLEAK
select HAVE_EXIT_THREAD
Expand Down
1 change: 0 additions & 1 deletion arch/openrisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ config OPENRISC
select OF
select OF_EARLY_FLATTREE
select IRQ_DOMAIN
select HANDLE_DOMAIN_IRQ
select GPIOLIB
select HAVE_ARCH_TRACEHOOK
select SPARSE_IRQ
Expand Down
4 changes: 2 additions & 2 deletions arch/openrisc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,8 @@ EXCEPTION_ENTRY(_external_irq_handler)
#endif
CLEAR_LWA_FLAG(r3)
l.addi r3,r1,0
l.movhi r8,hi(do_IRQ)
l.ori r8,r8,lo(do_IRQ)
l.movhi r8,hi(generic_handle_arch_irq)
l.ori r8,r8,lo(generic_handle_arch_irq)
l.jalr r8
l.nop
l.j _ret_from_intr
Expand Down
5 changes: 0 additions & 5 deletions arch/openrisc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,3 @@ void __init init_IRQ(void)
{
irqchip_init();
}

void __irq_entry do_IRQ(struct pt_regs *regs)
{
handle_arch_irq(regs);
}
1 change: 0 additions & 1 deletion arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ config RISCV
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL if MMU && 64BIT
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL
Expand Down
3 changes: 1 addition & 2 deletions arch/riscv/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ skip_context_tracking:

/* Handle interrupts */
move a0, sp /* pt_regs */
la a1, handle_arch_irq
REG_L a1, (a1)
la a1, generic_handle_arch_irq
jr a1
1:
/*
Expand Down
9 changes: 1 addition & 8 deletions arch/riscv/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,9 @@ void arch_irq_work_raise(void)

void handle_IPI(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits;
unsigned long *stats = ipi_data[smp_processor_id()].stats;

irq_enter();

riscv_clear_ipi();

while (true) {
Expand All @@ -156,7 +153,7 @@ void handle_IPI(struct pt_regs *regs)

ops = xchg(pending_ipis, 0);
if (ops == 0)
goto done;
return;

if (ops & (1 << IPI_RESCHEDULE)) {
stats[IPI_RESCHEDULE]++;
Expand Down Expand Up @@ -189,10 +186,6 @@ void handle_IPI(struct pt_regs *regs)
/* Order data access and bit testing. */
mb();
}

done:
irq_exit();
set_irq_regs(old_regs);
}

static const char * const ipi_names[] = {
Expand Down
Loading

0 comments on commit c6dca71

Please sign in to comment.