The quilt patch titled Subject: kexec: consolidate machine_kexec_mask_interrupts() implementation has been removed from the -mm tree. Its filename was kexec-consolidate-machine_kexec_mask_interrupts-implementation.patch This patch was dropped because it is obsolete ------------------------------------------------------ From: Eliav Farber <farbere@xxxxxxxxxx> Subject: kexec: consolidate machine_kexec_mask_interrupts() implementation Date: Wed, 4 Dec 2024 14:20:02 +0000 Patch series "Improve interrupt handling during machine kexec", v6. This patch series focuses on improving the machine_kexec_mask_interrupts() function by consolidating its implementation and optimizing its behavior to avoid redundant interrupt masking. Patch Summary: [PATCH v6 1/2] Move machine_kexec_mask_interrupts() to kernel/irq/kexec.c, removing duplicate architecture-specific implementations. [PATCH v6 2/2] Refine machine_kexec_mask_interrupts() to avoid re-masking already-masked interrupts, resolving specific warnings triggered in GPIO IRQ flows. This patch (of 2): Consolidate the machine_kexec_mask_interrupts implementation into a common function located in a new file: kernel/irq/kexec.c. This removes duplicate implementations from architecture-specific files in arch/arm, arch/arm64, arch/powerpc, and arch/riscv, reducing code duplication and improving maintainability. The new implementation retains architecture-specific behavior for CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD, which was previously implemented for ARM64. When enabled (currently for ARM64), it clears the active state of interrupts forwarded to virtual machines (VMs) before handling other interrupt masking operations. Link: https://lkml.kernel.org/r/20241204142003.32859-1-farbere@xxxxxxxxxx Link: https://lkml.kernel.org/r/20241204142003.32859-2-farbere@xxxxxxxxxx Signed-off-by: Eliav Farber <farbere@xxxxxxxxxx> Cc: Aditya Gupta <adityag@xxxxxxxxxxxxx> Cc: Albert Ou <aou@xxxxxxxxxxxxxxxxx> Cc: Baoquan He <bhe@xxxxxxxxxx> Cc: Catalin Marinas <catalin.marinas@xxxxxxx> Cc: Christophe Leroy <christophe.leroy@xxxxxxxxxx> Cc: Hari Bathini <hbathini@xxxxxxxxxxxxx> Cc: Jonathan Chocron <jonnyc@xxxxxxxxxx> Cc: Madhavan Srinivasan <maddy@xxxxxxxxxxxxx> Cc: Michael Ellerman <mpe@xxxxxxxxxxxxxx> Cc: Naveen N Rao <naveen@xxxxxxxxxx> Cc: Nicholas Piggin <npiggin@xxxxxxxxx> Cc: Palmer Dabbelt <palmer@xxxxxxxxxxx> Cc: Paul Walmsley <paul.walmsley@xxxxxxxxxx> Cc: Russell King <linux@xxxxxxxxxxxxxxx> Cc: Ryo Takakura <takakura@xxxxxxxxxxxxx> Cc: Song Shuai <songshuaishuai@xxxxxxxxxxx> Cc: Sourabh Jain <sourabhjain@xxxxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Will Deacon <will@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- arch/arm/kernel/machine_kexec.c | 23 ---------------- arch/arm64/Kconfig | 1 arch/arm64/kernel/machine_kexec.c | 31 --------------------- arch/powerpc/include/asm/kexec.h | 1 arch/powerpc/kexec/core.c | 22 --------------- arch/powerpc/kexec/core_32.c | 1 arch/riscv/kernel/machine_kexec.c | 23 ---------------- include/linux/irq.h | 3 ++ kernel/irq/Kconfig | 6 ++++ kernel/irq/Makefile | 2 - kernel/irq/kexec.c | 40 ++++++++++++++++++++++++++++ 11 files changed, 52 insertions(+), 101 deletions(-) --- a/arch/arm64/Kconfig~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/arch/arm64/Kconfig @@ -149,6 +149,7 @@ config ARM64 select GENERIC_IDLE_POLL_SETUP select GENERIC_IOREMAP select GENERIC_IRQ_IPI + select GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW_LEVEL --- a/arch/arm64/kernel/machine_kexec.c~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/arch/arm64/kernel/machine_kexec.c @@ -207,37 +207,6 @@ void machine_kexec(struct kimage *kimage BUG(); /* Should never get here. */ } -static void machine_kexec_mask_interrupts(void) -{ - unsigned int i; - struct irq_desc *desc; - - for_each_irq_desc(i, desc) { - struct irq_chip *chip; - int ret; - - chip = irq_desc_get_chip(desc); - if (!chip) - continue; - - /* - * First try to remove the active state. If this - * fails, try to EOI the interrupt. - */ - ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false); - - if (ret && irqd_irq_inprogress(&desc->irq_data) && - chip->irq_eoi) - chip->irq_eoi(&desc->irq_data); - - if (chip->irq_mask) - chip->irq_mask(&desc->irq_data); - - if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) - chip->irq_disable(&desc->irq_data); - } -} - /** * machine_crash_shutdown - shutdown non-crashing cpus and save registers */ --- a/arch/arm/kernel/machine_kexec.c~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/arch/arm/kernel/machine_kexec.c @@ -127,29 +127,6 @@ void crash_smp_send_stop(void) cpus_stopped = 1; } -static void machine_kexec_mask_interrupts(void) -{ - unsigned int i; - struct irq_desc *desc; - - for_each_irq_desc(i, desc) { - struct irq_chip *chip; - - chip = irq_desc_get_chip(desc); - if (!chip) - continue; - - if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) - chip->irq_eoi(&desc->irq_data); - - if (chip->irq_mask) - chip->irq_mask(&desc->irq_data); - - if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) - chip->irq_disable(&desc->irq_data); - } -} - void machine_crash_shutdown(struct pt_regs *regs) { local_irq_disable(); --- a/arch/powerpc/include/asm/kexec.h~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/arch/powerpc/include/asm/kexec.h @@ -61,7 +61,6 @@ struct pt_regs; extern void kexec_smp_wait(void); /* get and clear naca physid, wait for master to copy new code to 0 */ extern void default_machine_kexec(struct kimage *image); -extern void machine_kexec_mask_interrupts(void); void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer, unsigned long start_address) __noreturn; --- a/arch/powerpc/kexec/core_32.c~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/arch/powerpc/kexec/core_32.c @@ -7,6 +7,7 @@ * Copyright (C) 2005 IBM Corporation. */ +#include <linux/irq.h> #include <linux/kexec.h> #include <linux/mm.h> #include <linux/string.h> --- a/arch/powerpc/kexec/core.c~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/arch/powerpc/kexec/core.c @@ -22,28 +22,6 @@ #include <asm/setup.h> #include <asm/firmware.h> -void machine_kexec_mask_interrupts(void) { - unsigned int i; - struct irq_desc *desc; - - for_each_irq_desc(i, desc) { - struct irq_chip *chip; - - chip = irq_desc_get_chip(desc); - if (!chip) - continue; - - if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) - chip->irq_eoi(&desc->irq_data); - - if (chip->irq_mask) - chip->irq_mask(&desc->irq_data); - - if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) - chip->irq_disable(&desc->irq_data); - } -} - #ifdef CONFIG_CRASH_DUMP void machine_crash_shutdown(struct pt_regs *regs) { --- a/arch/riscv/kernel/machine_kexec.c~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/arch/riscv/kernel/machine_kexec.c @@ -114,29 +114,6 @@ void machine_shutdown(void) #endif } -static void machine_kexec_mask_interrupts(void) -{ - unsigned int i; - struct irq_desc *desc; - - for_each_irq_desc(i, desc) { - struct irq_chip *chip; - - chip = irq_desc_get_chip(desc); - if (!chip) - continue; - - if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) - chip->irq_eoi(&desc->irq_data); - - if (chip->irq_mask) - chip->irq_mask(&desc->irq_data); - - if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) - chip->irq_disable(&desc->irq_data); - } -} - /* * machine_crash_shutdown - Prepare to kexec after a kernel crash * --- a/include/linux/irq.h~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/include/linux/irq.h @@ -694,6 +694,9 @@ extern int irq_chip_request_resources_pa extern void irq_chip_release_resources_parent(struct irq_data *data); #endif +/* Disable or mask interrupts during a kernel kexec */ +extern void machine_kexec_mask_interrupts(void); + /* Handling of unhandled and spurious interrupts: */ extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret); --- a/kernel/irq/Kconfig~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/kernel/irq/Kconfig @@ -141,6 +141,12 @@ config GENERIC_IRQ_DEBUGFS If you don't know what to do here, say N. +# Clear forwarded VM interrupts during kexec. +# This option ensures the kernel clears active states for interrupts +# forwarded to virtual machines (VMs) during a machine kexec. +config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD + bool + endmenu config GENERIC_IRQ_MULTI_HANDLER diff --git a/kernel/irq/kexec.c a/kernel/irq/kexec.c new file mode 100644 --- /dev/null +++ a/kernel/irq/kexec.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/irqdesc.h> +#include <linux/irqnr.h> + +#include "internals.h" + +void machine_kexec_mask_interrupts(void) +{ + struct irq_desc *desc; + unsigned int i; + + for_each_irq_desc(i, desc) { + struct irq_chip *chip; + int check_eoi = 1; + + chip = irq_desc_get_chip(desc); + if (!chip) + continue; + + if (IS_ENABLED(CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD)) { + /* + * First try to remove the active state from an interrupt which is forwarded + * to a VM. If the interrupt is not forwarded, try to EOI the interrupt. + */ + check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false); + } + + if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) + chip->irq_eoi(&desc->irq_data); + + if (chip->irq_mask) + chip->irq_mask(&desc->irq_data); + + if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) + chip->irq_disable(&desc->irq_data); + } +} --- a/kernel/irq/Makefile~kexec-consolidate-machine_kexec_mask_interrupts-implementation +++ a/kernel/irq/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o +obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o kexec.o obj-$(CONFIG_IRQ_TIMINGS) += timings.o ifeq ($(CONFIG_TEST_IRQ_TIMINGS),y) CFLAGS_timings.o += -DDEBUG _ Patches currently in -mm which might be from farbere@xxxxxxxxxx are kexec-prevent-redundant-irq-masking-by-checking-state-before-shutdown.patch