From 441e90369344d229c0f04024ea5d4d51f06b137d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 24 Sep 2021 18:12:45 +0200 Subject: x86/softirq: Disable softirq stacks on PREEMPT_RT PREEMPT_RT preempts softirqs and the current implementation avoids do_softirq_own_stack() and only uses __do_softirq(). Disable the unused softirqs stacks on PREEMPT_RT to safe some memory and ensure that do_softirq_own_stack() is not used which is not expected. [ bigeasy: commit description. ] Signed-off-by: Thomas Gleixner Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/20210924161245.2357247-1-bigeasy@linutronix.de --- arch/x86/include/asm/irq_stack.h | 3 +++ arch/x86/kernel/irq_32.c | 2 ++ 2 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h index 562854c60808..ea0c5ab31da4 100644 --- a/arch/x86/include/asm/irq_stack.h +++ b/arch/x86/include/asm/irq_stack.h @@ -185,6 +185,7 @@ IRQ_CONSTRAINTS, regs, vector); \ } +#ifndef CONFIG_PREEMPT_RT #define ASM_CALL_SOFTIRQ \ "call %P[__func] \n" @@ -201,6 +202,8 @@ __this_cpu_write(hardirq_stack_inuse, false); \ } +#endif + #else /* CONFIG_X86_64 */ /* System vector handlers always run on the stack they interrupted. */ #define run_sysvec_on_irqstack_cond(func, regs) \ diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 044902d5a3c4..e5dd6da78713 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -132,6 +132,7 @@ int irq_init_percpu_irqstack(unsigned int cpu) return 0; } +#ifndef CONFIG_PREEMPT_RT void do_softirq_own_stack(void) { struct irq_stack *irqstk; @@ -148,6 +149,7 @@ void do_softirq_own_stack(void) call_on_stack(__do_softirq, isp); } +#endif void __handle_irq(struct irq_desc *desc, struct pt_regs *regs) { -- cgit v1.2.3 From dfd8c90eb28b8f7c77ce7173c4bae591b26ea51a Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 2 Sep 2021 15:49:14 +0200 Subject: arm64: meson: remove MESON_IRQ_GPIO selection Selecting MESON_IRQ_GPIO forces it as built-in, but we may need to build it as a module, thus remove it here and let the "default ARCH_MESON" build as built-in by default with the option to switch it to module. Signed-off-by: Neil Armstrong Reviewed-by: Kevin Hilman Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210902134914.176986-3-narmstrong@baylibre.com --- arch/arm64/Kconfig.platforms | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index b0ce18d4cc98..ff2d83fbbde1 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -167,7 +167,6 @@ config ARCH_MEDIATEK config ARCH_MESON bool "Amlogic Platforms" select COMMON_CLK - select MESON_IRQ_GPIO help This enables support for the arm64 based Amlogic SoCs such as the s905, S905X/D, S912, A113X/D or S905X/D2 -- cgit v1.2.3 From bf8bde41d296849fd5f9db8becd71ad4e84bc521 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 20 Oct 2021 11:48:47 -0700 Subject: MIPS: BMIPS: Remove use of irq_cpu_offline irq_cpu_offline() is only used by MIPS and we should instead use irq_migrate_all_off_this_cpu(). This will be helpful in order to remove drivers/irqchip/irq-bcm7038-l1.c irq_cpu_offline callback which would have got in the way of making this driver modular. Suggested-by: Thomas Gleixner Acked-by: Thomas Bogendoerfer Signed-off-by: Florian Fainelli Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20211020184859.2705451-2-f.fainelli@gmail.com --- arch/mips/Kconfig | 1 + arch/mips/kernel/smp-bmips.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 771ca53af06d..2c03b27cec02 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1782,6 +1782,7 @@ config CPU_BMIPS select CPU_HAS_PREFETCH select CPU_SUPPORTS_CPUFREQ select MIPS_EXTERNAL_TIMER + select GENERIC_IRQ_MIGRATION if HOTPLUG_CPU help Support for BMIPS32/3300/4350/4380 and BMIPS5000 processors. diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index b6ef5f7312cf..f5d7bfa3472a 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -373,7 +374,7 @@ static int bmips_cpu_disable(void) set_cpu_online(cpu, false); calculate_cpu_foreign_map(); - irq_cpu_offline(); + irq_migrate_all_off_this_cpu(); clear_c0_status(IE_IRQ5); local_flush_tlb_all(); -- cgit v1.2.3 From 9db71e8966bf7c80ab89d8d5b113d8daa3b237ea Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 20 Oct 2021 11:48:57 -0700 Subject: arm64: broadcom: Removed forced select of interrupt controllers Now that the various second level interrupt controllers have been moved to IRQCHIP_PLATFORM_DRIVER and they do default to ARCH_BRCMSTB and ARCH_BCM2835 where relevant, remove their forced selection from the machine entry to allow an user to build them as modules. Signed-off-by: Florian Fainelli Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20211020184859.2705451-12-f.fainelli@gmail.com --- arch/arm64/Kconfig.platforms | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index ff2d83fbbde1..96a81967c3bf 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -44,7 +44,6 @@ config ARCH_BCM2835 select ARM_AMBA select ARM_GIC select ARM_TIMER_SP804 - select BRCMSTB_L2_IRQ help This enables support for the Broadcom BCM2837 and BCM2711 SoC. These SoCs are used in the Raspberry Pi 3 and 4 devices. @@ -82,8 +81,6 @@ config ARCH_BITMAIN config ARCH_BRCMSTB bool "Broadcom Set-Top-Box SoCs" select ARCH_HAS_RESET_CONTROLLER - select BCM7038_L1_IRQ - select BRCMSTB_L2_IRQ select GENERIC_IRQ_CHIP select PINCTRL help -- cgit v1.2.3 From c40ef4c57599c30efc0c1e8ad6bec4f842295521 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 20 Oct 2021 11:48:58 -0700 Subject: ARM: bcm: Removed forced select of interrupt controllers Now that the various second level interrupt controllers have been moved to IRQCHIP_PLATFORM_DRIVER and they do default to ARCH_BRCMSTB and ARCH_BCM2835 where relevant, remove their forced selection from the machine entry to allow an user to build them as modules. Signed-off-by: Florian Fainelli Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20211020184859.2705451-13-f.fainelli@gmail.com --- arch/arm/mach-bcm/Kconfig | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 2890e61b2b46..bd3f82788ebc 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -161,7 +161,6 @@ config ARCH_BCM2835 select ARM_TIMER_SP804 select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 select BCM2835_TIMER - select BRCMSTB_L2_IRQ select PINCTRL select PINCTRL_BCM2835 select MFD_CORE @@ -209,9 +208,6 @@ config ARCH_BRCMSTB select ARM_GIC select ARM_ERRATA_798181 if SMP select HAVE_ARM_ARCH_TIMER - select BCM7038_L1_IRQ - select BRCMSTB_L2_IRQ - select BCM7120_L2_IRQ select ZONE_DMA if ARM_LPAE select SOC_BRCMSTB select SOC_BUS -- cgit v1.2.3 From bab4ff1edccd5853c956ac72e5152b073a237b50 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 20 Oct 2021 15:24:40 +0100 Subject: irq: mips: stop (ab)using handle_domain_irq() On MIPS, the only user of handle_domain_irq() is octeon_irq_ciu3_ip2(), which is called from the platform-specific plat_irq_dispatch() function invoked from the early assembly code. No other irqchip relevant to arch/mips uses handle_domain_irq(): * No other plat_irq_dispatch() function transitively calls handle_domain_irq(). * No other vectored IRQ dispatch function registered with set_vi_handler() calls handle_domain_irq(). * No chained irqchip handlers call handle_domain_irq(), which makes sense as this is meant to only be used by root irqchip handlers. Currently octeon_irq_ciu3_ip2() passes NULL as the `regs` argument to handle_domain_irq(), and as handle_domain_irq() will pass this to set_irq_regs(), any invoked IRQ handlers will erroneously see a NULL pt_regs if they call get_pt_regs(). Fix this by calling generic_handle_domain_irq() directly, and performing the necessary irq_{enter,exit}() logic directly in octeon_irq_ciu3_ip2(). At the same time, deselect HANDLE_DOMAIN_IRQ, which subsequent patches will remove. Other than the corrected behaviour of get_pt_regs(), there should be no functional change as a result of this patch. Fixes: ce210d35bb93c2c5 ("MIPS: OCTEON: Add support for OCTEON III interrupt controller.") Signed-off-by: Mark Rutland Reviewed-by: Marc Zyngier Acked-by: Thomas Bogendoerfer Cc: Thomas Gleixner --- arch/mips/Kconfig | 1 - arch/mips/cavium-octeon/octeon-irq.c | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 771ca53af06d..7b004c5bd796 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -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 diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index be5d4afcd30f..844f882096e6 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -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); -- cgit v1.2.3 From 4cb6f4df976b288aa02bbb658d38e73d34d8231f Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 20 Oct 2021 18:20:32 +0100 Subject: irq: mips: simplify do_domain_IRQ() There's no need fpr arch/mips's do_domain_IRQ() to open-code the NULL check performed by handle_irq_desc(), nor the resolution of the desc performed by generic_handle_domain_irq(). Use generic_handle_domain_irq() directly, as this is functioanlly equivalent and clearer. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Reviewed-by: Marc Zyngier Acked-by: Thomas Bogendoerfer Cc: Thomas Gleixner --- arch/mips/kernel/irq.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index d20e002b3246..1fee96ef8059 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -115,11 +115,7 @@ void __irq_entry do_domain_IRQ(struct irq_domain *domain, unsigned int hwirq) 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 -- cgit v1.2.3 From e54957fa3b3b374c63c66f60a8236dd95cf5e2be Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 19 Oct 2021 12:26:41 +0100 Subject: irq: arc: avoid CONFIG_HANDLE_DOMAIN_IRQ In preparation for removing HANDLE_DOMAIN_IRQ, have arch/arc perform all the necessary IRQ entry accounting in its entry code. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Reviewed-by: Marc Zyngier Cc: Thomas Gleixner Cc: Vineet Gupta --- arch/arc/Kconfig | 1 - arch/arc/kernel/irq.c | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 3a5a80f302e1..b4ae6058902a 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -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 diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index ef909dd4b40c..dd09b58ff82d 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c @@ -6,6 +6,8 @@ #include #include #include + +#include #include /* @@ -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(); } -- cgit v1.2.3 From 6f877e13c24d8b7b96a2f4e78f13a2bdfd401c8b Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 20 Oct 2021 11:36:08 +0100 Subject: irq: nds32: avoid CONFIG_HANDLE_DOMAIN_IRQ In preparation for removing HANDLE_DOMAIN_IRQ, have arch/nds32 perform all the necessary IRQ entry accounting in its entry code. Currently arch/nds32 is tightly coupled with the ativic32 irqchip, and while the entry code should logically live under arch/nds32/, moving the entry logic there makes things more convoluted. So for now, place the entry logic in the ativic32 irqchip, but separated into a separate function to make the split of responsibility clear. In future this should probably use GENERIC_IRQ_MULTI_HANDLER to cleanly decouple this. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Reviewed-by: Marc Zyngier Cc: Greentime Hu Cc: Nick Hu Cc: Thomas Gleixner Cc: Vincent Chen --- arch/nds32/Kconfig | 1 - drivers/irqchip/irq-ativic32.c | 22 ++++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig index aea26e739543..4d1421b18734 100644 --- a/arch/nds32/Kconfig +++ b/arch/nds32/Kconfig @@ -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 diff --git a/drivers/irqchip/irq-ativic32.c b/drivers/irqchip/irq-ativic32.c index 476d6024aaf2..223dd2f97d28 100644 --- a/drivers/irqchip/irq-ativic32.c +++ b/drivers/irqchip/irq-ativic32.c @@ -5,11 +5,14 @@ #include #include #include +#include #include #include #include #include +#include + unsigned long wake_mask; static void ativic32_ack_irq(struct irq_data *data) @@ -103,10 +106,25 @@ static irq_hw_number_t get_intr_src(void) - NDS32_VECTOR_offINTERRUPT; } -asmlinkage void asm_do_IRQ(struct pt_regs *regs) +static void ativic32_handle_irq(struct pt_regs *regs) { irq_hw_number_t hwirq = get_intr_src(); - handle_domain_irq(root_domain, hwirq, regs); + generic_handle_domain_irq(root_domain, hwirq); +} + +/* + * TODO: convert nds32 to GENERIC_IRQ_MULTI_HANDLER so that this entry logic + * can live in arch code. + */ +asmlinkage void asm_do_IRQ(struct pt_regs *regs) +{ + struct pt_regs *old_regs; + + irq_enter(); + old_regs = set_irq_regs(regs); + ativic32_handle_irq(regs); + set_irq_regs(old_regs); + irq_exit(); } int __init ativic32_init_irq(struct device_node *node, struct device_node *parent) -- cgit v1.2.3 From 2fe35f8ee726466f0898ba60c5868c6f9a1ac566 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 19 Oct 2021 11:12:31 +0100 Subject: irq: add a (temporary) CONFIG_HANDLE_DOMAIN_IRQ_IRQENTRY Going forward we want architecture/entry code to perform all the necessary work to enter/exit IRQ context, with irqchip code merely handling the mapping of the interrupt to any handler(s). Among other reasons, this is necessary to consistently fix some longstanding issues with the ordering of lockdep/RCU/tracing instrumentation which many architectures get wrong today in their entry code. Importantly, rcu_irq_{enter,exit}() must be called precisely once per IRQ exception, so that rcu_is_cpu_rrupt_from_idle() can correctly identify when an interrupt was taken from an idle context which must be explicitly preempted. Currently handle_domain_irq() calls rcu_irq_{enter,exit}() via irq_{enter,exit}(), but entry code needs to be able to call rcu_irq_{enter,exit}() earlier for correct ordering across lockdep/RCU/tracing updates for sequences such as: lockdep_hardirqs_off(CALLER_ADDR0); rcu_irq_enter(); trace_hardirqs_off_finish(); To permit each architecture to be converted to the new style in turn, this patch adds a new CONFIG_HANDLE_DOMAIN_IRQ_IRQENTRY selected by all current users of HANDLE_DOMAIN_IRQ, which gates the existing behaviour. When CONFIG_HANDLE_DOMAIN_IRQ_IRQENTRY is not selected, handle_domain_irq() requires entry code to perform the irq_{enter,exit}() work, with an explicit check for this matching the style of handle_domain_nmi(). Subsequent patches will: 1) Add the necessary IRQ entry accounting to each architecture in turn, dropping CONFIG_HANDLE_DOMAIN_IRQ_IRQENTRY from that architecture's Kconfig. 2) Remove CONFIG_HANDLE_DOMAIN_IRQ_IRQENTRY once it is no longer selected. 3) Convert irqchip drivers to consistently use generic_handle_domain_irq() rather than handle_domain_irq(). 4) Remove handle_domain_irq() and CONFIG_HANDLE_DOMAIN_IRQ. ... which should leave us with a clear split of responsiblity across the entry and irqchip code, making it possible to perform additional cleanups and fixes for the aforementioned longstanding issues with entry code. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Reviewed-by: Marc Zyngier Cc: Thomas Gleixner --- arch/arm/Kconfig | 1 + arch/arm64/Kconfig | 1 + arch/csky/Kconfig | 1 + arch/openrisc/Kconfig | 1 + arch/riscv/Kconfig | 1 + kernel/irq/Kconfig | 4 ++++ kernel/irq/irqdesc.c | 30 ++++++++++++++++++++++++++++++ 7 files changed, 39 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc196421b2ce..f18aff82c27b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -65,6 +65,7 @@ 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 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 5c7ae4c3954b..553239a5a5f7 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -134,6 +134,7 @@ config ARM64 select GENERIC_GETTIMEOFDAY select GENERIC_VDSO_TIME_NS select HANDLE_DOMAIN_IRQ + select HANDLE_DOMAIN_IRQ_IRQENTRY select HARDIRQS_SW_RESEND select HAVE_MOVE_PMD select HAVE_MOVE_PUD diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 9d4d898df76b..45f03f674a61 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -18,6 +18,7 @@ config CSKY select DMA_DIRECT_REMAP select IRQ_DOMAIN select HANDLE_DOMAIN_IRQ + select HANDLE_DOMAIN_IRQ_IRQENTRY select DW_APB_TIMER_OF select GENERIC_IOREMAP select GENERIC_LIB_ASHLDI3 diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index e804026b4797..ed783a67065e 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -14,6 +14,7 @@ config OPENRISC select OF_EARLY_FLATTREE select IRQ_DOMAIN select HANDLE_DOMAIN_IRQ + select HANDLE_DOMAIN_IRQ_IRQENTRY select GPIOLIB select HAVE_ARCH_TRACEHOOK select SPARSE_IRQ diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 301a54233c7e..740653063a56 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -63,6 +63,7 @@ config RISCV select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL if MMU && 64BIT select HANDLE_DOMAIN_IRQ + select HANDLE_DOMAIN_IRQ_IRQENTRY select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index fbc54c2a7f23..897dfc552bb0 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -100,6 +100,10 @@ config IRQ_MSI_IOMMU config HANDLE_DOMAIN_IRQ bool +# Legacy behaviour; architectures should call irq_{enter,exit}() themselves +config HANDLE_DOMAIN_IRQ_IRQENTRY + bool + config IRQ_TIMINGS bool diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index e25d4bddf3d8..5677a849cf1f 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -676,6 +676,7 @@ int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq) EXPORT_SYMBOL_GPL(generic_handle_domain_irq); #ifdef CONFIG_HANDLE_DOMAIN_IRQ +#ifdef CONFIG_HANDLE_DOMAIN_IRQ_IRQENTRY /** * handle_domain_irq - Invoke the handler for a HW irq belonging to a domain, * usually for a root interrupt controller @@ -699,6 +700,35 @@ int handle_domain_irq(struct irq_domain *domain, set_irq_regs(old_regs); return ret; } +#else +/** + * handle_domain_irq - Invoke the handler for a HW irq belonging to a domain, + * usually for a root interrupt controller + * @domain: The domain where to perform the lookup + * @hwirq: The HW irq number to convert to a logical one + * @regs: Register file coming from the low-level handling code + * + * This function must be called from an IRQ context. + * + * Returns: 0 on success, or -EINVAL if conversion has failed + */ +int handle_domain_irq(struct irq_domain *domain, + unsigned int hwirq, struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + int ret; + + /* + * IRQ context needs to be setup earlier. + */ + WARN_ON(!in_irq()); + + ret = generic_handle_domain_irq(domain, hwirq); + + set_irq_regs(old_regs); + return ret; +} +#endif /** * handle_domain_nmi - Invoke the handler for a HW irq belonging to a domain -- cgit v1.2.3 From a7b0872e964cf306fe26d9d49585a90486e32fdf Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 19 Oct 2021 18:17:17 +0100 Subject: irq: arm: perform irqentry in entry code 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 Reviewed-by: Marc Zyngier Tested-by: Vladimir Murzin # ARMv7M Cc: Russell King Cc: Thomas Gleixner --- arch/arm/Kconfig | 1 - arch/arm/kernel/entry-armv.S | 5 +---- arch/arm/kernel/irq.c | 14 ++++++++------ drivers/irqchip/irq-nvic.c | 17 ++++++++++++++++- 4 files changed, 25 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f18aff82c27b..fc196421b2ce 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -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 diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 241b73d64df7..3d0b6169ab86 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -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 diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 20ab1e607522..b79975bd988c 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -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) diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c index b31c4cff4d3a..b2bd96253d40 100644 --- a/drivers/irqchip/irq-nvic.c +++ b/drivers/irqchip/irq-nvic.c @@ -37,10 +37,25 @@ 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, -- cgit v1.2.3 From 26dc129342cfc1e09dcf8473331efcf419a471af Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 19 Oct 2021 18:28:39 +0100 Subject: irq: arm64: perform irqentry in entry code In preparation for removing HANDLE_DOMAIN_IRQ_IRQENTRY, have arch/arm64 perform all the irqentry accounting in its entry code. As arch/arm64 already performs portions of the irqentry logic in enter_from_kernel_mode() and exit_to_kernel_mode(), including rcu_irq_{enter,exit}(), the only additional calls that need to be made are to irq_{enter,exit}_rcu(). Removing the calls to rcu_irq_{enter,exit}() from handle_domain_irq() ensures that we inform RCU once per IRQ entry and will correctly identify quiescent periods. Since we should not call irq_{enter,exit}_rcu() when entering a pseudo-NMI, el1_interrupt() is reworked to have separate __el1_irq() and __el1_pnmi() paths for regular IRQ and psuedo-NMI entry, with irq_{enter,exit}_irq() only called for the former. In preparation for removing HANDLE_DOMAIN_IRQ, the irq regs are managed in do_interrupt_handler() for both regular IRQ and pseudo-NMI. This is currently redundant, but not harmful. For clarity the preemption logic is moved into __el1_irq(). We should never preempt within a pseudo-NMI, and arm64_enter_nmi() already enforces this by incrementing the preempt_count, but it's clearer if we never invoke the preemption logic when entering a pseudo-NMI. Signed-off-by: Mark Rutland Reviewed-by: Pingfan Liu Reviewed-by: Marc Zyngier Acked-by: Catalin Marinas Cc: Catalin Marinas Cc: Thomas Gleixner Cc: Will Deacon --- arch/arm64/Kconfig | 1 - arch/arm64/kernel/entry-common.c | 52 ++++++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 553239a5a5f7..5c7ae4c3954b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -134,7 +134,6 @@ config ARM64 select GENERIC_GETTIMEOFDAY select GENERIC_VDSO_TIME_NS select HANDLE_DOMAIN_IRQ - select HANDLE_DOMAIN_IRQ_IRQENTRY select HARDIRQS_SW_RESEND select HAVE_MOVE_PMD select HAVE_MOVE_PUD diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index 32f9796c4ffe..f7408edf8571 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -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(); @@ -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 *); @@ -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 @@ -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) @@ -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); } -- cgit v1.2.3 From 287232987f0ebb29f68cfab13625017bbfb38adc Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 20 Oct 2021 11:00:46 +0100 Subject: irq: csky: perform irqentry in entry code In preparation for removing HANDLE_DOMAIN_IRQ_IRQENTRY, have arch/csky perform all the irqentry accounting in its entry code. As arch/csky uses GENERIC_IRQ_MULTI_HANDLER, we can use generic_handle_arch_irq() to do so. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Reviewed-by: Guo Ren Reviewed-by: Marc Zyngier Cc: Thomas Gleixner --- arch/csky/Kconfig | 1 - arch/csky/kernel/entry.S | 2 +- arch/csky/kernel/irq.c | 5 ----- 3 files changed, 1 insertion(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 45f03f674a61..9d4d898df76b 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -18,7 +18,6 @@ config CSKY select DMA_DIRECT_REMAP select IRQ_DOMAIN select HANDLE_DOMAIN_IRQ - select HANDLE_DOMAIN_IRQ_IRQENTRY select DW_APB_TIMER_OF select GENERIC_IOREMAP select GENERIC_LIB_ASHLDI3 diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index 00e3c8ebf9b8..a4ababf25e24 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -249,7 +249,7 @@ ENTRY(csky_irq) mov a0, sp - jbsr csky_do_IRQ + jbsr generic_handle_arch_irq jmpi ret_from_exception diff --git a/arch/csky/kernel/irq.c b/arch/csky/kernel/irq.c index 03a1930f1cbb..fcdaf3156286 100644 --- a/arch/csky/kernel/irq.c +++ b/arch/csky/kernel/irq.c @@ -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); -} -- cgit v1.2.3 From 418360b23113d62aa99586ada37806b4a7a53afa Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 20 Oct 2021 11:31:56 +0100 Subject: irq: openrisc: perform irqentry in entry code In preparation for removing HANDLE_DOMAIN_IRQ_IRQENTRY, have arch/openrisc perform all the irqentry accounting in its entry code. As arch/openrisc uses GENERIC_IRQ_MULTI_HANDLER, we can use generic_handle_arch_irq() to do so. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Reviewed-by: Marc Zyngier Reviewed-by: Stafford Horne Cc: Jonas Bonn Cc: Stefan Kristiansson Cc: Thomas Gleixner --- arch/openrisc/Kconfig | 1 - arch/openrisc/kernel/entry.S | 4 ++-- arch/openrisc/kernel/irq.c | 5 ----- 3 files changed, 2 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index ed783a67065e..e804026b4797 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -14,7 +14,6 @@ config OPENRISC select OF_EARLY_FLATTREE select IRQ_DOMAIN select HANDLE_DOMAIN_IRQ - select HANDLE_DOMAIN_IRQ_IRQENTRY select GPIOLIB select HAVE_ARCH_TRACEHOOK select SPARSE_IRQ diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index edaa775a648e..59c6d3aa7081 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -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 diff --git a/arch/openrisc/kernel/irq.c b/arch/openrisc/kernel/irq.c index c38fa863afa8..f38e10962a84 100644 --- a/arch/openrisc/kernel/irq.c +++ b/arch/openrisc/kernel/irq.c @@ -36,8 +36,3 @@ void __init init_IRQ(void) { irqchip_init(); } - -void __irq_entry do_IRQ(struct pt_regs *regs) -{ - handle_arch_irq(regs); -} -- cgit v1.2.3 From 7ecbc648102f2fa80d2aefb75b7f8b482f1a4483 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 20 Oct 2021 11:33:49 +0100 Subject: irq: riscv: perform irqentry in entry code In preparation for removing HANDLE_DOMAIN_IRQ_IRQENTRY, have arch/riscv perform all the irqentry accounting in its entry code. As arch/riscv uses GENERIC_IRQ_MULTI_HANDLER, we can use generic_handle_arch_irq() to do so. Since generic_handle_arch_irq() handles the irq entry and setting the irq regs, and happens before the irqchip code calls handle_IPI(), we can remove the redundant irq entry and irq regs manipulation from handle_IPI(). There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Reviewed-by: Guo Ren Reviewed-by: Marc Zyngier Cc: Albert Ou Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Thomas Gleixner --- arch/riscv/Kconfig | 1 - arch/riscv/kernel/entry.S | 3 +-- arch/riscv/kernel/smp.c | 9 +-------- 3 files changed, 2 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 740653063a56..301a54233c7e 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -63,7 +63,6 @@ config RISCV select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL if MMU && 64BIT select HANDLE_DOMAIN_IRQ - select HANDLE_DOMAIN_IRQ_IRQENTRY select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 98f502654edd..64236f7efde5 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -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: /* diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index 921d9d7df400..2f6da845c9ae 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -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) { @@ -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]++; @@ -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[] = { -- cgit v1.2.3 From 0953fb263714e1c8c1c3d395036d9a14310081dd Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 20 Oct 2021 20:23:09 +0100 Subject: irq: remove handle_domain_{irq,nmi}() 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 Reviewed-by: Marc Zyngier Cc: Thomas Gleixner --- Documentation/core-api/irq/irq-domain.rst | 3 -- arch/arm/Kconfig | 1 - arch/arm/mach-imx/avic.c | 2 +- arch/arm/mach-imx/tzic.c | 2 +- arch/arm/mach-omap1/irq.c | 2 +- arch/arm/mach-s3c/irq-s3c24xx.c | 2 +- arch/arm64/Kconfig | 1 - arch/csky/Kconfig | 1 - arch/openrisc/Kconfig | 1 - arch/riscv/Kconfig | 1 - drivers/irqchip/irq-apple-aic.c | 20 ++++----- drivers/irqchip/irq-armada-370-xp.c | 13 ++---- drivers/irqchip/irq-aspeed-vic.c | 2 +- drivers/irqchip/irq-atmel-aic.c | 2 +- drivers/irqchip/irq-atmel-aic5.c | 2 +- drivers/irqchip/irq-bcm2835.c | 2 +- drivers/irqchip/irq-bcm2836.c | 2 +- drivers/irqchip/irq-clps711x.c | 8 ++-- drivers/irqchip/irq-csky-apb-intc.c | 2 +- drivers/irqchip/irq-csky-mpintc.c | 4 +- drivers/irqchip/irq-davinci-aintc.c | 2 +- drivers/irqchip/irq-davinci-cp-intc.c | 2 +- drivers/irqchip/irq-digicolor.c | 2 +- drivers/irqchip/irq-dw-apb-ictl.c | 2 +- drivers/irqchip/irq-ftintc010.c | 2 +- drivers/irqchip/irq-gic-v3.c | 4 +- drivers/irqchip/irq-gic.c | 2 +- drivers/irqchip/irq-hip04.c | 2 +- drivers/irqchip/irq-ixp4xx.c | 4 +- drivers/irqchip/irq-lpc32xx.c | 2 +- drivers/irqchip/irq-mmp.c | 4 +- drivers/irqchip/irq-mxs.c | 2 +- drivers/irqchip/irq-nvic.c | 6 +-- drivers/irqchip/irq-omap-intc.c | 2 +- drivers/irqchip/irq-or1k-pic.c | 2 +- drivers/irqchip/irq-orion.c | 4 +- drivers/irqchip/irq-rda-intc.c | 2 +- drivers/irqchip/irq-riscv-intc.c | 2 +- drivers/irqchip/irq-sa11x0.c | 4 +- drivers/irqchip/irq-sun4i.c | 2 +- drivers/irqchip/irq-versatile-fpga.c | 2 +- drivers/irqchip/irq-vic.c | 2 +- drivers/irqchip/irq-vt8500.c | 2 +- drivers/irqchip/irq-wpcm450-aic.c | 2 +- drivers/irqchip/irq-zevio.c | 2 +- include/linux/irqdesc.h | 9 +--- kernel/irq/Kconfig | 7 ---- kernel/irq/irqdesc.c | 68 ++++++++----------------------- 48 files changed, 80 insertions(+), 141 deletions(-) (limited to 'arch') diff --git a/Documentation/core-api/irq/irq-domain.rst b/Documentation/core-api/irq/irq-domain.rst index 9c0e8758037a..d30b4d0a9769 100644 --- a/Documentation/core-api/irq/irq-domain.rst +++ b/Documentation/core-api/irq/irq-domain.rst @@ -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. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc196421b2ce..3361a6c29ee9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -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 diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 21bce4049cec..cf6546ddc7a3 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -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); } diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c index 479a01bdac56..8b3d98d288d9 100644 --- a/arch/arm/mach-imx/tzic.c +++ b/arch/arm/mach-imx/tzic.c @@ -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); } } diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index b11edc8a46f0..ee6a93083154 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -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); diff --git a/arch/arm/mach-s3c/irq-s3c24xx.c b/arch/arm/mach-s3c/irq-s3c24xx.c index 3edc5f614eef..45dfd546e6fa 100644 --- a/arch/arm/mach-s3c/irq-s3c24xx.c +++ b/arch/arm/mach-s3c/irq-s3c24xx.c @@ -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; } diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 5c7ae4c3954b..e6593a03ea27 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -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 diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 9d4d898df76b..e0bd71b9e23f 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -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 diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index e804026b4797..c2491b295d60 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -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 diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 301a54233c7e..353e28f5f849 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -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 diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c index 6fc145aacaf0..3759dc36cc8f 100644 --- a/drivers/irqchip/irq-apple-aic.c +++ b/drivers/irqchip/irq-apple-aic.c @@ -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) @@ -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)) == @@ -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 diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 53e0fb0562c1..80906bfec845 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -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 @@ -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; } @@ -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 diff --git a/drivers/irqchip/irq-aspeed-vic.c b/drivers/irqchip/irq-aspeed-vic.c index 58717cd44f99..62ccf2c0c414 100644 --- a/drivers/irqchip/irq-aspeed-vic.c +++ b/drivers/irqchip/irq-aspeed-vic.c @@ -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); } } diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index 2c999dc310c1..4631f6847953 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c @@ -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) diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index fb4ad2aaa727..145535bd7560 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -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) diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c index adc1556ed332..e94e2882286c 100644 --- a/drivers/irqchip/irq-bcm2835.c +++ b/drivers/irqchip/irq-bcm2835.c @@ -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) diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c index 501facdb4570..51491c3c6fdd 100644 --- a/drivers/irqchip/irq-bcm2836.c +++ b/drivers/irqchip/irq-bcm2836.c @@ -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); } } diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c index d0da29aeedc8..77ebe7e47e0e 100644 --- a/drivers/irqchip/irq-clps711x.c +++ b/drivers/irqchip/irq-clps711x.c @@ -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); } diff --git a/drivers/irqchip/irq-csky-apb-intc.c b/drivers/irqchip/irq-csky-apb-intc.c index ab91afa86755..d36f536506ba 100644 --- a/drivers/irqchip/irq-csky-apb-intc.c +++ b/drivers/irqchip/irq-csky-apb-intc.c @@ -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; } diff --git a/drivers/irqchip/irq-csky-mpintc.c b/drivers/irqchip/irq-csky-mpintc.c index a1534edef7fa..cb403c960ac0 100644 --- a/drivers/irqchip/irq-csky-mpintc.c +++ b/drivers/irqchip/irq-csky-mpintc.c @@ -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) diff --git a/drivers/irqchip/irq-davinci-aintc.c b/drivers/irqchip/irq-davinci-aintc.c index 810ccc4fe476..123eb7bfc117 100644 --- a/drivers/irqchip/irq-davinci-aintc.c +++ b/drivers/irqchip/irq-davinci-aintc.c @@ -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 */ diff --git a/drivers/irqchip/irq-davinci-cp-intc.c b/drivers/irqchip/irq-davinci-cp-intc.c index 276da2772e7f..7482c8ed34b2 100644 --- a/drivers/irqchip/irq-davinci-cp-intc.c +++ b/drivers/irqchip/irq-davinci-cp-intc.c @@ -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, diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c index fc38d2da11b9..3b0d78aac13b 100644 --- a/drivers/irqchip/irq-digicolor.c +++ b/drivers/irqchip/irq-digicolor.c @@ -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); } diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c index a67266e44491..d5c1c750c8d2 100644 --- a/drivers/irqchip/irq-dw-apb-ictl.c +++ b/drivers/irqchip/irq-dw-apb-ictl.c @@ -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); } } diff --git a/drivers/irqchip/irq-ftintc010.c b/drivers/irqchip/irq-ftintc010.c index 0bf98425dca5..5cc268880f8e 100644 --- a/drivers/irqchip/irq-ftintc010.c +++ b/drivers/irqchip/irq-ftintc010.c @@ -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); } } diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index fd4e9a37fea6..daec3309b014 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -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); @@ -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); } diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 5f22c9d65e57..b8bb46c65a97 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -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); } diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 058ebaebe2c4..46161f6ff289 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c @@ -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); } diff --git a/drivers/irqchip/irq-ixp4xx.c b/drivers/irqchip/irq-ixp4xx.c index 37e0749215c7..fb68f8c59fbb 100644 --- a/drivers/irqchip/irq-ixp4xx.c +++ b/drivers/irqchip/irq-ixp4xx.c @@ -114,7 +114,7 @@ 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 @@ -122,7 +122,7 @@ asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs) 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); } } diff --git a/drivers/irqchip/irq-lpc32xx.c b/drivers/irqchip/irq-lpc32xx.c index 5e6f6e25f2ae..a29357f39450 100644 --- a/drivers/irqchip/irq-lpc32xx.c +++ b/drivers/irqchip/irq-lpc32xx.c @@ -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); } } diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c index 4a74ac7b7c42..83455ca72439 100644 --- a/drivers/irqchip/irq-mmp.c +++ b/drivers/irqchip/irq-mmp.c @@ -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) @@ -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) */ diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index d1f5740cd575..55cb6b5a686e 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -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, diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c index b2bd96253d40..63bac3f78863 100644 --- a/drivers/irqchip/irq-nvic.c +++ b/drivers/irqchip/irq-nvic.c @@ -37,9 +37,9 @@ static struct irq_domain *nvic_irq_domain; -static void __nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs) +static void __nvic_handle_irq(irq_hw_number_t hwirq) { - handle_domain_irq(nvic_irq_domain, hwirq, regs); + generic_handle_domain_irq(nvic_irq_domain, hwirq); } /* @@ -53,7 +53,7 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs) irq_enter(); old_regs = set_irq_regs(regs); - __nvic_handle_irq(hwirq, regs); + __nvic_handle_irq(hwirq); set_irq_regs(old_regs); irq_exit(); } diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index d360a6eddd6d..dc82162ba763 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c @@ -357,7 +357,7 @@ omap_intc_handle_irq(struct pt_regs *regs) } irqnr &= ACTIVEIRQ_MASK; - handle_domain_irq(domain, irqnr, regs); + generic_handle_domain_irq(domain, irqnr); } static int __init intc_of_init(struct device_node *node, diff --git a/drivers/irqchip/irq-or1k-pic.c b/drivers/irqchip/irq-or1k-pic.c index 03d2366118dd..49b47e787644 100644 --- a/drivers/irqchip/irq-or1k-pic.c +++ b/drivers/irqchip/irq-or1k-pic.c @@ -116,7 +116,7 @@ static void or1k_pic_handle_irq(struct pt_regs *regs) int irq = -1; while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) - handle_domain_irq(root_domain, irq, regs); + generic_handle_domain_irq(root_domain, irq); } static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index b6868f7b805a..17c2c7a07f10 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c @@ -42,8 +42,8 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs) gc->mask_cache; while (stat) { u32 hwirq = __fls(stat); - handle_domain_irq(orion_irq_domain, - gc->irq_base + hwirq, regs); + generic_handle_domain_irq(orion_irq_domain, + gc->irq_base + hwirq); stat &= ~(1 << hwirq); } } diff --git a/drivers/irqchip/irq-rda-intc.c b/drivers/irqchip/irq-rda-intc.c index 960168303b73..9f0144a73777 100644 --- a/drivers/irqchip/irq-rda-intc.c +++ b/drivers/irqchip/irq-rda-intc.c @@ -53,7 +53,7 @@ static void __exception_irq_entry rda_handle_irq(struct pt_regs *regs) while (stat) { hwirq = __fls(stat); - handle_domain_irq(rda_irq_domain, hwirq, regs); + generic_handle_domain_irq(rda_irq_domain, hwirq); stat &= ~BIT(hwirq); } } diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c index 8017f6d32d52..b65bd8878d4f 100644 --- a/drivers/irqchip/irq-riscv-intc.c +++ b/drivers/irqchip/irq-riscv-intc.c @@ -37,7 +37,7 @@ static asmlinkage void riscv_intc_irq(struct pt_regs *regs) break; #endif default: - handle_domain_irq(intc_domain, cause, regs); + generic_handle_domain_irq(intc_domain, cause); break; } } diff --git a/drivers/irqchip/irq-sa11x0.c b/drivers/irqchip/irq-sa11x0.c index dbccc7dafbf8..31c202a1ae62 100644 --- a/drivers/irqchip/irq-sa11x0.c +++ b/drivers/irqchip/irq-sa11x0.c @@ -140,8 +140,8 @@ sa1100_handle_irq(struct pt_regs *regs) if (mask == 0) break; - handle_domain_irq(sa1100_normal_irqdomain, - ffs(mask) - 1, regs); + generic_handle_domain_irq(sa1100_normal_irqdomain, + ffs(mask) - 1); } while (1); } diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c index 8a315d6a3399..dd506ebfdacb 100644 --- a/drivers/irqchip/irq-sun4i.c +++ b/drivers/irqchip/irq-sun4i.c @@ -195,7 +195,7 @@ static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) return; do { - handle_domain_irq(irq_ic_data->irq_domain, hwirq, regs); + generic_handle_domain_irq(irq_ic_data->irq_domain, hwirq); hwirq = readl(irq_ic_data->irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; } while (hwirq != 0); diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index 75be350cf82f..f2757b6aecc8 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c @@ -105,7 +105,7 @@ static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs) while ((status = readl(f->base + IRQ_STATUS))) { irq = ffs(status) - 1; - handle_domain_irq(f->domain, irq, regs); + generic_handle_domain_irq(f->domain, irq); handled = 1; } diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 1e1f2d115257..9e3d5561e04e 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -208,7 +208,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { irq = ffs(stat) - 1; - handle_domain_irq(vic->domain, irq, regs); + generic_handle_domain_irq(vic->domain, irq); handled = 1; } diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c index 5bce936af5d9..e17dd3a8c2d5 100644 --- a/drivers/irqchip/irq-vt8500.c +++ b/drivers/irqchip/irq-vt8500.c @@ -183,7 +183,7 @@ static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs) continue; } - handle_domain_irq(intc[i].domain, irqnr, regs); + generic_handle_domain_irq(intc[i].domain, irqnr); } } diff --git a/drivers/irqchip/irq-wpcm450-aic.c b/drivers/irqchip/irq-wpcm450-aic.c index f3ac392d5bc8..0dcbeb1a05a1 100644 --- a/drivers/irqchip/irq-wpcm450-aic.c +++ b/drivers/irqchip/irq-wpcm450-aic.c @@ -69,7 +69,7 @@ static void __exception_irq_entry wpcm450_aic_handle_irq(struct pt_regs *regs) /* Read IPER to signal that nIRQ can be de-asserted */ hwirq = readl(aic->regs + AIC_IPER) / 4; - handle_domain_irq(aic->domain, hwirq, regs); + generic_handle_domain_irq(aic->domain, hwirq); } static void wpcm450_aic_eoi(struct irq_data *d) diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c index 84163f1ebfcf..7a72620fc478 100644 --- a/drivers/irqchip/irq-zevio.c +++ b/drivers/irqchip/irq-zevio.c @@ -50,7 +50,7 @@ static void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs) while (readl(zevio_irq_io + IO_STATUS)) { irqnr = readl(zevio_irq_io + IO_CURRENT); - handle_domain_irq(zevio_irq_domain, irqnr, regs); + generic_handle_domain_irq(zevio_irq_domain, irqnr); } } diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 59aea39785bf..93d270ca0c56 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -168,14 +168,7 @@ int generic_handle_irq(unsigned int irq); * conversion failed. */ int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq); - -#ifdef CONFIG_HANDLE_DOMAIN_IRQ -int handle_domain_irq(struct irq_domain *domain, - unsigned int hwirq, struct pt_regs *regs); - -int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, - struct pt_regs *regs); -#endif +int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq); #endif /* Test to see if a driver has successfully requested an irq */ diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 897dfc552bb0..1b41078222f3 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -97,13 +97,6 @@ config GENERIC_MSI_IRQ_DOMAIN config IRQ_MSI_IOMMU bool -config HANDLE_DOMAIN_IRQ - bool - -# Legacy behaviour; architectures should call irq_{enter,exit}() themselves -config HANDLE_DOMAIN_IRQ_IRQENTRY - bool - config IRQ_TIMINGS bool diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 7041698a7bff..2267e6527db3 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -651,7 +651,11 @@ int handle_irq_desc(struct irq_desc *desc) * generic_handle_irq - Invoke the handler for a particular irq * @irq: The irq number to handle * - */ + * Returns: 0 on success, or -EINVAL if conversion has failed + * + * This function must be called from an IRQ context with irq regs + * initialized. + */ int generic_handle_irq(unsigned int irq) { return handle_irq_desc(irq_to_desc(irq)); @@ -661,77 +665,39 @@ EXPORT_SYMBOL_GPL(generic_handle_irq); #ifdef CONFIG_IRQ_DOMAIN /** * generic_handle_domain_irq - Invoke the handler for a HW irq belonging - * to a domain, usually for a non-root interrupt - * controller + * to a domain. * @domain: The domain where to perform the lookup * @hwirq: The HW irq number to convert to a logical one * * Returns: 0 on success, or -EINVAL if conversion has failed * + * This function must be called from an IRQ context with irq regs + * initialized. */ int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq) { + WARN_ON_ONCE(!in_irq()); return handle_irq_desc(irq_resolve_mapping(domain, hwirq)); } EXPORT_SYMBOL_GPL(generic_handle_domain_irq); -#ifdef CONFIG_HANDLE_DOMAIN_IRQ /** - * handle_domain_irq - Invoke the handler for a HW irq belonging to a domain, - * usually for a root interrupt controller + * generic_handle_domain_nmi - Invoke the handler for a HW nmi belonging + * to a domain. * @domain: The domain where to perform the lookup * @hwirq: The HW irq number to convert to a logical one - * @regs: Register file coming from the low-level handling code - * - * This function must be called from an IRQ context. * * Returns: 0 on success, or -EINVAL if conversion has failed - */ -int handle_domain_irq(struct irq_domain *domain, - unsigned int hwirq, struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - int ret; - - /* - * IRQ context needs to be setup earlier. - */ - WARN_ON(!in_irq()); - - ret = generic_handle_domain_irq(domain, hwirq); - - set_irq_regs(old_regs); - return ret; -} - -/** - * handle_domain_nmi - Invoke the handler for a HW irq belonging to a domain - * @domain: The domain where to perform the lookup - * @hwirq: The HW irq number to convert to a logical one - * @regs: Register file coming from the low-level handling code - * - * This function must be called from an NMI context. * - * Returns: 0 on success, or -EINVAL if conversion has failed - */ -int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, - struct pt_regs *regs) + * This function must be called from an NMI context with irq regs + * initialized. + **/ +int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq) { - struct pt_regs *old_regs = set_irq_regs(regs); - int ret; - - /* - * NMI context needs to be setup earlier in order to deal with tracing. - */ - WARN_ON(!in_nmi()); - - ret = generic_handle_domain_irq(domain, hwirq); - - set_irq_regs(old_regs); - return ret; + WARN_ON_ONCE(!in_nmi()); + return handle_irq_desc(irq_resolve_mapping(domain, hwirq)); } #endif -#endif /* Dynamic interrupt handling */ -- cgit v1.2.3 From eb5411334c289c473bc11d5cef8b0bea8d7ce324 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 21 Oct 2021 18:04:12 +0100 Subject: MIPS: loongson64: Drop call to irq_cpu_offline() Also loongson64 calls irq_cpu_offline(), none of its interrupt controllers implement the .irq_cpu_offline callback. It is thus obvious that this call only serves the dubious purpose of wasting precious CPU cycles by iterating over all interrupts. Get rid of the call altogether. Signed-off-by: Marc Zyngier Acked-by: Thomas Bogendoerfer Reviewed-by: Florian Fainelli Tested-by: Serge Semin Link: https://lore.kernel.org/r/20211021170414.3341522-2-maz@kernel.org --- arch/mips/loongson64/smp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/loongson64/smp.c b/arch/mips/loongson64/smp.c index 09ebe84a17fe..660e1de4412a 100644 --- a/arch/mips/loongson64/smp.c +++ b/arch/mips/loongson64/smp.c @@ -550,7 +550,6 @@ static int loongson3_cpu_disable(void) set_cpu_online(cpu, false); calculate_cpu_foreign_map(); local_irq_save(flags); - irq_cpu_offline(); clear_c0_status(ST0_IM); local_irq_restore(flags); local_flush_tlb_all(); -- cgit v1.2.3 From 34fca8947b2743e6a3a9a8a3a44962e625993533 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Thu, 28 Oct 2021 17:56:52 +0800 Subject: MIPS: irq: Avoid an unused-variable error When CONFIG_IRQ_DOMAIN is set, there is a warning: arch/mips/kernel/irq.c:114:19: error: unused variable 'desc' [-Werror=unused-variable] 114 | struct irq_desc *desc; | ^~~~ This variable is unused, let's remove it. Signed-off-by: Yanteng Si Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20211028095652.3503790-1-siyanteng@loongson.cn --- arch/mips/kernel/irq.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 1fee96ef8059..5e11582fe308 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -111,8 +111,6 @@ 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(); generic_handle_domain_irq(domain, hwirq); -- cgit v1.2.3 From 837d7a8fe852cf93fff1cd3b73d707b3a6ae340f Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 28 Oct 2021 19:24:25 +0100 Subject: h8300: Fix linux/irqchip.h include mess h8300 drags linux/irqchip.h from asm/irq.h, which is in general a bad idea (asm/*.h should avoid dragging linux/*.h, as it is usually supposed to work the other way around). Move the inclusion of linux/irqchip.h to the single location where it actually matters in the arch code. Reported-by: Guenter Roeck Tested-by: Guenter Roeck Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20211028172849.GA701812@roeck-us.net --- arch/h8300/include/asm/irq.h | 2 -- arch/h8300/kernel/irq.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/h8300/include/asm/irq.h b/arch/h8300/include/asm/irq.h index 5fc5b436dde9..776cf06d7a59 100644 --- a/arch/h8300/include/asm/irq.h +++ b/arch/h8300/include/asm/irq.h @@ -2,8 +2,6 @@ #ifndef _H8300_IRQ_H_ #define _H8300_IRQ_H_ -#include - #if defined(CONFIG_CPU_H8300H) #define NR_IRQS 64 #define IRQ_CHIP h8300h_irq_chip diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c index 834e4d7b1bcf..8ad6d702cd0b 100644 --- a/arch/h8300/kernel/irq.c +++ b/arch/h8300/kernel/irq.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3