Skip to content

Commit

Permalink
irq: remove handle_domain_{irq,nmi}()
Browse files Browse the repository at this point in the history
Now that entry code handles IRQ entry (including setting the IRQ regs)
before calling irqchip code, irqchip code can safely call
generic_handle_domain_irq(), and there's no functional reason for it to
call handle_domain_irq().

Let's cement this split of responsibility and remove handle_domain_irq()
entirely, updating irqchip drivers to call generic_handle_domain_irq().

For consistency, handle_domain_nmi() is similarly removed and replaced
with a generic_handle_domain_nmi() function which also does not perform
any entry logic.

Previously handle_domain_{irq,nmi}() had a WARN_ON() which would fire
when they were called in an inappropriate context. So that we can
identify similar issues going forward, similar WARN_ON_ONCE() logic is
added to the generic_handle_*() functions, and comments are updated for
clarity and consistency.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Mark Rutland committed Oct 26, 2021
1 parent 5aecc24 commit 0953fb2
Show file tree
Hide file tree
Showing 48 changed files with 80 additions and 141 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/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
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
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
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
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
20 changes: 10 additions & 10 deletions drivers/irqchip/irq-apple-aic.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs)
irq = FIELD_GET(AIC_EVENT_NUM, event);

if (type == AIC_EVENT_TYPE_HW)
handle_domain_irq(aic_irqc->hw_domain, irq, regs);
generic_handle_domain_irq(aic_irqc->hw_domain, irq);
else if (type == AIC_EVENT_TYPE_IPI && irq == 1)
aic_handle_ipi(regs);
else if (event != 0)
Expand Down Expand Up @@ -392,25 +392,25 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
}

if (TIMER_FIRING(read_sysreg(cntp_ctl_el0)))
handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + AIC_TMR_EL0_PHYS, regs);
generic_handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + AIC_TMR_EL0_PHYS);

if (TIMER_FIRING(read_sysreg(cntv_ctl_el0)))
handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + AIC_TMR_EL0_VIRT, regs);
generic_handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + AIC_TMR_EL0_VIRT);

if (is_kernel_in_hyp_mode()) {
uint64_t enabled = read_sysreg_s(SYS_IMP_APL_VM_TMR_FIQ_ENA_EL2);

if ((enabled & VM_TMR_FIQ_ENABLE_P) &&
TIMER_FIRING(read_sysreg_s(SYS_CNTP_CTL_EL02)))
handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + AIC_TMR_EL02_PHYS, regs);
generic_handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + AIC_TMR_EL02_PHYS);

if ((enabled & VM_TMR_FIQ_ENABLE_V) &&
TIMER_FIRING(read_sysreg_s(SYS_CNTV_CTL_EL02)))
handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + AIC_TMR_EL02_VIRT, regs);
generic_handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + AIC_TMR_EL02_VIRT);
}

if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) ==
Expand Down Expand Up @@ -674,7 +674,7 @@ static void aic_handle_ipi(struct pt_regs *regs)
firing = atomic_fetch_andnot(enabled, this_cpu_ptr(&aic_vipi_flag)) & enabled;

for_each_set_bit(i, &firing, AIC_NR_SWIPI)
handle_domain_irq(aic_irqc->ipi_domain, i, regs);
generic_handle_domain_irq(aic_irqc->ipi_domain, i);

/*
* No ordering needed here; at worst this just changes the timing of
Expand Down
13 changes: 4 additions & 9 deletions drivers/irqchip/irq-armada-370-xp.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,12 +589,7 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained)

irq = msinr - PCI_MSI_DOORBELL_START;

if (is_chained)
generic_handle_domain_irq(armada_370_xp_msi_inner_domain,
irq);
else
handle_domain_irq(armada_370_xp_msi_inner_domain,
irq, regs);
generic_handle_domain_irq(armada_370_xp_msi_inner_domain, irq);
}
}
#else
Expand Down Expand Up @@ -646,8 +641,8 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
break;

if (irqnr > 1) {
handle_domain_irq(armada_370_xp_mpic_domain,
irqnr, regs);
generic_handle_domain_irq(armada_370_xp_mpic_domain,
irqnr);
continue;
}

Expand All @@ -666,7 +661,7 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
& IPI_DOORBELL_MASK;

for_each_set_bit(ipi, &ipimask, IPI_DOORBELL_END)
handle_domain_irq(ipi_domain, ipi, regs);
generic_handle_domain_irq(ipi_domain, ipi);
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-aspeed-vic.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
if (stat == 0)
break;
irq += ffs(stat) - 1;
handle_domain_irq(vic->dom, irq, regs);
generic_handle_domain_irq(vic->dom, irq);
}
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-atmel-aic.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ aic_handle(struct pt_regs *regs)
if (!irqstat)
irq_reg_writel(gc, 0, AT91_AIC_EOICR);
else
handle_domain_irq(aic_domain, irqnr, regs);
generic_handle_domain_irq(aic_domain, irqnr);
}

static int aic_retrigger(struct irq_data *d)
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-atmel-aic5.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ aic5_handle(struct pt_regs *regs)
if (!irqstat)
irq_reg_writel(bgc, 0, AT91_AIC5_EOICR);
else
handle_domain_irq(aic5_domain, irqnr, regs);
generic_handle_domain_irq(aic5_domain, irqnr);
}

static void aic5_mask(struct irq_data *d)
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-bcm2835.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ static void __exception_irq_entry bcm2835_handle_irq(
u32 hwirq;

while ((hwirq = get_next_armctrl_hwirq()) != ~0)
handle_domain_irq(intc.domain, hwirq, regs);
generic_handle_domain_irq(intc.domain, hwirq);
}

static void bcm2836_chained_handle_irq(struct irq_desc *desc)
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-bcm2836.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
if (stat) {
u32 hwirq = ffs(stat) - 1;

handle_domain_irq(intc.domain, hwirq, regs);
generic_handle_domain_irq(intc.domain, hwirq);
}
}

Expand Down
8 changes: 4 additions & 4 deletions drivers/irqchip/irq-clps711x.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ static asmlinkage void __exception_irq_entry clps711x_irqh(struct pt_regs *regs)
irqstat = readw_relaxed(clps711x_intc->intmr[0]) &
readw_relaxed(clps711x_intc->intsr[0]);
if (irqstat)
handle_domain_irq(clps711x_intc->domain,
fls(irqstat) - 1, regs);
generic_handle_domain_irq(clps711x_intc->domain,
fls(irqstat) - 1);

irqstat = readw_relaxed(clps711x_intc->intmr[1]) &
readw_relaxed(clps711x_intc->intsr[1]);
if (irqstat)
handle_domain_irq(clps711x_intc->domain,
fls(irqstat) - 1 + 16, regs);
generic_handle_domain_irq(clps711x_intc->domain,
fls(irqstat) - 1 + 16);
} while (irqstat);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-csky-apb-intc.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ static inline bool handle_irq_perbit(struct pt_regs *regs, u32 hwirq,
if (hwirq == 0)
return 0;

handle_domain_irq(root_domain, irq_base + __fls(hwirq), regs);
generic_handle_domain_irq(root_domain, irq_base + __fls(hwirq));

return 1;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/irqchip/irq-csky-mpintc.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ static void csky_mpintc_handler(struct pt_regs *regs)
{
void __iomem *reg_base = this_cpu_read(intcl_reg);

handle_domain_irq(root_domain,
readl_relaxed(reg_base + INTCL_RDYIR), regs);
generic_handle_domain_irq(root_domain,
readl_relaxed(reg_base + INTCL_RDYIR));
}

static void csky_mpintc_enable(struct irq_data *d)
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-davinci-aintc.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ davinci_aintc_handle_irq(struct pt_regs *regs)
irqnr >>= 2;
irqnr -= 1;

handle_domain_irq(davinci_aintc_irq_domain, irqnr, regs);
generic_handle_domain_irq(davinci_aintc_irq_domain, irqnr);
}

/* ARM Interrupt Controller Initialization */
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-davinci-cp-intc.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ davinci_cp_intc_handle_irq(struct pt_regs *regs)
return;
}

handle_domain_irq(davinci_cp_intc_irq_domain, irqnr, regs);
generic_handle_domain_irq(davinci_cp_intc_irq_domain, irqnr);
}

static int davinci_cp_intc_host_map(struct irq_domain *h, unsigned int virq,
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-digicolor.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static void __exception_irq_entry digicolor_handle_irq(struct pt_regs *regs)
return;
}

handle_domain_irq(digicolor_irq_domain, hwirq, regs);
generic_handle_domain_irq(digicolor_irq_domain, hwirq);
} while (1);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-dw-apb-ictl.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static void __irq_entry dw_apb_ictl_handle_irq(struct pt_regs *regs)
while (stat) {
u32 hwirq = ffs(stat) - 1;

handle_domain_irq(d, hwirq, regs);
generic_handle_domain_irq(d, hwirq);
stat &= ~BIT(hwirq);
}
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-ftintc010.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ asmlinkage void __exception_irq_entry ft010_irqchip_handle_irq(struct pt_regs *r

while ((status = readl(FT010_IRQ_STATUS(f->base)))) {
irq = ffs(status) - 1;
handle_domain_irq(f->domain, irq, regs);
generic_handle_domain_irq(f->domain, irq);
}
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/irqchip/irq-gic-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
* PSR.I will be restored when we ERET to the
* interrupted context.
*/
err = handle_domain_nmi(gic_data.domain, irqnr, regs);
err = generic_handle_domain_nmi(gic_data.domain, irqnr);
if (err)
gic_deactivate_unhandled(irqnr);

Expand Down Expand Up @@ -728,7 +728,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
else
isb();

if (handle_domain_irq(gic_data.domain, irqnr, regs)) {
if (generic_handle_domain_irq(gic_data.domain, irqnr)) {
WARN_ONCE(true, "Unexpected interrupt received!\n");
gic_deactivate_unhandled(irqnr);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
this_cpu_write(sgi_intid, irqstat);
}

handle_domain_irq(gic->domain, irqnr, regs);
generic_handle_domain_irq(gic->domain, irqnr);
} while (1);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-hip04.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ static void __exception_irq_entry hip04_handle_irq(struct pt_regs *regs)
irqnr = irqstat & GICC_IAR_INT_ID_MASK;

if (irqnr <= HIP04_MAX_IRQS)
handle_domain_irq(hip04_data.domain, irqnr, regs);
generic_handle_domain_irq(hip04_data.domain, irqnr);
} while (irqnr > HIP04_MAX_IRQS);
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/irqchip/irq-ixp4xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs)

status = __raw_readl(ixi->irqbase + IXP4XX_ICIP);
for_each_set_bit(i, &status, 32)
handle_domain_irq(ixi->domain, i, regs);
generic_handle_domain_irq(ixi->domain, i);

/*
* IXP465/IXP435 has an upper IRQ status register
*/
if (ixi->is_356) {
status = __raw_readl(ixi->irqbase + IXP4XX_ICIP2);
for_each_set_bit(i, &status, 32)
handle_domain_irq(ixi->domain, i + 32, regs);
generic_handle_domain_irq(ixi->domain, i + 32);
}
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-lpc32xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ static void __exception_irq_entry lpc32xx_handle_irq(struct pt_regs *regs)
while (hwirq) {
irq = __ffs(hwirq);
hwirq &= ~BIT(irq);
handle_domain_irq(lpc32xx_mic_irqc->domain, irq, regs);
generic_handle_domain_irq(lpc32xx_mic_irqc->domain, irq);
}
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/irqchip/irq-mmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs)
if (!(hwirq & SEL_INT_PENDING))
return;
hwirq &= SEL_INT_NUM_MASK;
handle_domain_irq(icu_data[0].domain, hwirq, regs);
generic_handle_domain_irq(icu_data[0].domain, hwirq);
}

static void __exception_irq_entry mmp2_handle_irq(struct pt_regs *regs)
Expand All @@ -241,7 +241,7 @@ static void __exception_irq_entry mmp2_handle_irq(struct pt_regs *regs)
if (!(hwirq & SEL_INT_PENDING))
return;
hwirq &= SEL_INT_NUM_MASK;
handle_domain_irq(icu_data[0].domain, hwirq, regs);
generic_handle_domain_irq(icu_data[0].domain, hwirq);
}

/* MMP (ARMv5) */
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-mxs.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)

irqnr = __raw_readl(icoll_priv.stat);
__raw_writel(irqnr, icoll_priv.vector);
handle_domain_irq(icoll_domain, irqnr, regs);
generic_handle_domain_irq(icoll_domain, irqnr);
}

static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
Expand Down
Loading

0 comments on commit 0953fb2

Please sign in to comment.