File tree 11 files changed +51
-101
lines changed
11 files changed +51
-101
lines changed Original file line number Diff line number Diff line change @@ -127,29 +127,6 @@ void crash_smp_send_stop(void)
127
127
cpus_stopped = 1 ;
128
128
}
129
129
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
-
153
130
void machine_crash_shutdown (struct pt_regs * regs )
154
131
{
155
132
local_irq_disable ();
Original file line number Diff line number Diff line change @@ -150,6 +150,7 @@ config ARM64
150
150
select GENERIC_IDLE_POLL_SETUP
151
151
select GENERIC_IOREMAP
152
152
select GENERIC_IRQ_IPI
153
+ select GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
153
154
select GENERIC_IRQ_PROBE
154
155
select GENERIC_IRQ_SHOW
155
156
select GENERIC_IRQ_SHOW_LEVEL
Original file line number Diff line number Diff line change @@ -207,37 +207,6 @@ void machine_kexec(struct kimage *kimage)
207
207
BUG (); /* Should never get here. */
208
208
}
209
209
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
-
241
210
/**
242
211
* machine_crash_shutdown - shutdown non-crashing cpus and save registers
243
212
*/
Original file line number Diff line number Diff line change @@ -61,7 +61,6 @@ struct pt_regs;
61
61
extern void kexec_smp_wait (void ); /* get and clear naca physid, wait for
62
62
master to copy new code to 0 */
63
63
extern void default_machine_kexec (struct kimage * image );
64
- extern void machine_kexec_mask_interrupts (void );
65
64
66
65
void relocate_new_kernel (unsigned long indirection_page , unsigned long reboot_code_buffer ,
67
66
unsigned long start_address ) __noreturn ;
Original file line number Diff line number Diff line change 22
22
#include <asm/setup.h>
23
23
#include <asm/firmware.h>
24
24
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
-
47
25
#ifdef CONFIG_CRASH_DUMP
48
26
void machine_crash_shutdown (struct pt_regs * regs )
49
27
{
Original file line number Diff line number Diff line change 7
7
* Copyright (C) 2005 IBM Corporation.
8
8
*/
9
9
10
+ #include <linux/irq.h>
10
11
#include <linux/kexec.h>
11
12
#include <linux/mm.h>
12
13
#include <linux/string.h>
Original file line number Diff line number Diff line change @@ -114,29 +114,6 @@ void machine_shutdown(void)
114
114
#endif
115
115
}
116
116
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
-
140
117
/*
141
118
* machine_crash_shutdown - Prepare to kexec after a kernel crash
142
119
*
Original file line number Diff line number Diff line change @@ -694,6 +694,9 @@ extern int irq_chip_request_resources_parent(struct irq_data *data);
694
694
extern void irq_chip_release_resources_parent (struct irq_data * data );
695
695
#endif
696
696
697
+ /* Disable or mask interrupts during a kernel kexec */
698
+ extern void machine_kexec_mask_interrupts (void );
699
+
697
700
/* Handling of unhandled and spurious interrupts: */
698
701
extern void note_interrupt (struct irq_desc * desc , irqreturn_t action_ret );
699
702
Original file line number Diff line number Diff line change @@ -154,3 +154,12 @@ config DEPRECATED_IRQ_CPU_ONOFFLINE
154
154
bool
155
155
depends on CAVIUM_OCTEON_SOC
156
156
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).
Original file line number Diff line number Diff line change 1
1
# SPDX-License-Identifier: GPL-2.0
2
2
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
4
4
obj-$(CONFIG_IRQ_TIMINGS) += timings.o
5
5
ifeq ($(CONFIG_TEST_IRQ_TIMINGS ) ,y)
6
6
CFLAGS_timings.o += -DDEBUG
Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments