Skip to content

Commit bad6722

Browse files
Eliav FarberKAGA-KOKO
authored andcommitted
kexec: Consolidate machine_kexec_mask_interrupts() implementation
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. Signed-off-by: Eliav Farber <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent 429f49a commit bad6722

File tree

11 files changed

+52
-101
lines changed

11 files changed

+52
-101
lines changed

arch/arm/kernel/machine_kexec.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -127,29 +127,6 @@ void crash_smp_send_stop(void)
127127
cpus_stopped = 1;
128128
}
129129

130-
static void machine_kexec_mask_interrupts(void)
131-
{
132-
unsigned int i;
133-
struct irq_desc *desc;
134-
135-
for_each_irq_desc(i, desc) {
136-
struct irq_chip *chip;
137-
138-
chip = irq_desc_get_chip(desc);
139-
if (!chip)
140-
continue;
141-
142-
if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
143-
chip->irq_eoi(&desc->irq_data);
144-
145-
if (chip->irq_mask)
146-
chip->irq_mask(&desc->irq_data);
147-
148-
if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
149-
chip->irq_disable(&desc->irq_data);
150-
}
151-
}
152-
153130
void machine_crash_shutdown(struct pt_regs *regs)
154131
{
155132
local_irq_disable();

arch/arm64/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ config ARM64
149149
select GENERIC_IDLE_POLL_SETUP
150150
select GENERIC_IOREMAP
151151
select GENERIC_IRQ_IPI
152+
select GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
152153
select GENERIC_IRQ_PROBE
153154
select GENERIC_IRQ_SHOW
154155
select GENERIC_IRQ_SHOW_LEVEL

arch/arm64/kernel/machine_kexec.c

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -207,37 +207,6 @@ void machine_kexec(struct kimage *kimage)
207207
BUG(); /* Should never get here. */
208208
}
209209

210-
static void machine_kexec_mask_interrupts(void)
211-
{
212-
unsigned int i;
213-
struct irq_desc *desc;
214-
215-
for_each_irq_desc(i, desc) {
216-
struct irq_chip *chip;
217-
int ret;
218-
219-
chip = irq_desc_get_chip(desc);
220-
if (!chip)
221-
continue;
222-
223-
/*
224-
* First try to remove the active state. If this
225-
* fails, try to EOI the interrupt.
226-
*/
227-
ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
228-
229-
if (ret && irqd_irq_inprogress(&desc->irq_data) &&
230-
chip->irq_eoi)
231-
chip->irq_eoi(&desc->irq_data);
232-
233-
if (chip->irq_mask)
234-
chip->irq_mask(&desc->irq_data);
235-
236-
if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
237-
chip->irq_disable(&desc->irq_data);
238-
}
239-
}
240-
241210
/**
242211
* machine_crash_shutdown - shutdown non-crashing cpus and save registers
243212
*/

arch/powerpc/include/asm/kexec.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ struct pt_regs;
6161
extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
6262
master to copy new code to 0 */
6363
extern void default_machine_kexec(struct kimage *image);
64-
extern void machine_kexec_mask_interrupts(void);
6564

6665
void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer,
6766
unsigned long start_address) __noreturn;

arch/powerpc/kexec/core.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,6 @@
2222
#include <asm/setup.h>
2323
#include <asm/firmware.h>
2424

25-
void machine_kexec_mask_interrupts(void) {
26-
unsigned int i;
27-
struct irq_desc *desc;
28-
29-
for_each_irq_desc(i, desc) {
30-
struct irq_chip *chip;
31-
32-
chip = irq_desc_get_chip(desc);
33-
if (!chip)
34-
continue;
35-
36-
if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
37-
chip->irq_eoi(&desc->irq_data);
38-
39-
if (chip->irq_mask)
40-
chip->irq_mask(&desc->irq_data);
41-
42-
if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
43-
chip->irq_disable(&desc->irq_data);
44-
}
45-
}
46-
4725
#ifdef CONFIG_CRASH_DUMP
4826
void machine_crash_shutdown(struct pt_regs *regs)
4927
{

arch/powerpc/kexec/core_32.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Copyright (C) 2005 IBM Corporation.
88
*/
99

10+
#include <linux/irq.h>
1011
#include <linux/kexec.h>
1112
#include <linux/mm.h>
1213
#include <linux/string.h>

arch/riscv/kernel/machine_kexec.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -114,29 +114,6 @@ void machine_shutdown(void)
114114
#endif
115115
}
116116

117-
static void machine_kexec_mask_interrupts(void)
118-
{
119-
unsigned int i;
120-
struct irq_desc *desc;
121-
122-
for_each_irq_desc(i, desc) {
123-
struct irq_chip *chip;
124-
125-
chip = irq_desc_get_chip(desc);
126-
if (!chip)
127-
continue;
128-
129-
if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
130-
chip->irq_eoi(&desc->irq_data);
131-
132-
if (chip->irq_mask)
133-
chip->irq_mask(&desc->irq_data);
134-
135-
if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
136-
chip->irq_disable(&desc->irq_data);
137-
}
138-
}
139-
140117
/*
141118
* machine_crash_shutdown - Prepare to kexec after a kernel crash
142119
*

include/linux/irq.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,9 @@ extern int irq_chip_request_resources_parent(struct irq_data *data);
694694
extern void irq_chip_release_resources_parent(struct irq_data *data);
695695
#endif
696696

697+
/* Disable or mask interrupts during a kernel kexec */
698+
extern void machine_kexec_mask_interrupts(void);
699+
697700
/* Handling of unhandled and spurious interrupts: */
698701
extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
699702

kernel/irq/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ config GENERIC_IRQ_DEBUGFS
141141

142142
If you don't know what to do here, say N.
143143

144+
# Clear forwarded VM interrupts during kexec.
145+
# This option ensures the kernel clears active states for interrupts
146+
# forwarded to virtual machines (VMs) during a machine kexec.
147+
config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
148+
bool
149+
144150
endmenu
145151

146152
config GENERIC_IRQ_MULTI_HANDLER

kernel/irq/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0
22

3-
obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o
3+
obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o kexec.o
44
obj-$(CONFIG_IRQ_TIMINGS) += timings.o
55
ifeq ($(CONFIG_TEST_IRQ_TIMINGS),y)
66
CFLAGS_timings.o += -DDEBUG

0 commit comments

Comments
 (0)