Skip to content

Commit 9f47ed3

Browse files
author
Fox Snowpatch
committed
1 parent a85c72f commit 9f47ed3

File tree

11 files changed

+51
-101
lines changed

11 files changed

+51
-101
lines changed

arch/arm/kernel/machine_kexec.c

-23
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

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ config ARM64
150150
select GENERIC_IDLE_POLL_SETUP
151151
select GENERIC_IOREMAP
152152
select GENERIC_IRQ_IPI
153+
select GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
153154
select GENERIC_IRQ_PROBE
154155
select GENERIC_IRQ_SHOW
155156
select GENERIC_IRQ_SHOW_LEVEL

arch/arm64/kernel/machine_kexec.c

-31
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

-1
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

-22
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

+1
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

-23
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

+3
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

+9
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,12 @@ config DEPRECATED_IRQ_CPU_ONOFFLINE
154154
bool
155155
depends on CAVIUM_OCTEON_SOC
156156
default CAVIUM_OCTEON_SOC
157+
158+
config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
159+
bool "Clear forwarded VM interrupts during kexec"
160+
default n
161+
help
162+
When enabled, this option allows the kernel to clear the active state
163+
of interrupts that are forwarded to virtual machines (VMs) during a
164+
machine kexec. For interrupts that are not forwarded, if supported,
165+
the kernel will attempt to trigger an End of Interrupt (EOI).

kernel/irq/Makefile

+1-1
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

kernel/irq/kexec.c

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/interrupt.h>
4+
#include <linux/irq.h>
5+
#include <linux/irqdesc.h>
6+
#include <linux/irqnr.h>
7+
8+
#include "internals.h"
9+
10+
void machine_kexec_mask_interrupts(void)
11+
{
12+
struct irq_desc *desc;
13+
unsigned int i;
14+
15+
for_each_irq_desc(i, desc) {
16+
struct irq_chip *chip;
17+
int check_eoi = 1;
18+
19+
chip = irq_desc_get_chip(desc);
20+
if (!chip || !irqd_is_started(&desc->irq_data))
21+
continue;
22+
23+
if (IS_ENABLED(CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD)) {
24+
/*
25+
* First try to remove the active state from an interrupt which is forwarded
26+
* to a VM. If the interrupt is not forwarded, try to EOI the interrupt.
27+
*/
28+
check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
29+
}
30+
31+
if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
32+
chip->irq_eoi(&desc->irq_data);
33+
34+
irq_shutdown(desc);
35+
}
36+
}

0 commit comments

Comments
 (0)