hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/s390/kernel/irq.c
....@@ -26,6 +26,7 @@
2626 #include <asm/lowcore.h>
2727 #include <asm/irq.h>
2828 #include <asm/hw_irq.h>
29
+#include <asm/stacktrace.h>
2930 #include "entry.h"
3031
3132 DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat);
....@@ -73,7 +74,6 @@
7374 {.irq = IRQEXT_CMC, .name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"},
7475 {.irq = IRQEXT_FTP, .name = "FTP", .desc = "[EXT] HMC FTP Service"},
7576 {.irq = IRQIO_CIO, .name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"},
76
- {.irq = IRQIO_QAI, .name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"},
7777 {.irq = IRQIO_DAS, .name = "DAS", .desc = "[I/O] DASD"},
7878 {.irq = IRQIO_C15, .name = "C15", .desc = "[I/O] 3215"},
7979 {.irq = IRQIO_C70, .name = "C70", .desc = "[I/O] 3270"},
....@@ -81,24 +81,19 @@
8181 {.irq = IRQIO_VMR, .name = "VMR", .desc = "[I/O] Unit Record Devices"},
8282 {.irq = IRQIO_LCS, .name = "LCS", .desc = "[I/O] LCS"},
8383 {.irq = IRQIO_CTC, .name = "CTC", .desc = "[I/O] CTC"},
84
- {.irq = IRQIO_APB, .name = "APB", .desc = "[I/O] AP Bus"},
8584 {.irq = IRQIO_ADM, .name = "ADM", .desc = "[I/O] EADM Subchannel"},
8685 {.irq = IRQIO_CSC, .name = "CSC", .desc = "[I/O] CHSC Subchannel"},
87
- {.irq = IRQIO_PCI, .name = "PCI", .desc = "[I/O] PCI Interrupt" },
88
- {.irq = IRQIO_MSI, .name = "MSI", .desc = "[I/O] MSI Interrupt" },
8986 {.irq = IRQIO_VIR, .name = "VIR", .desc = "[I/O] Virtual I/O Devices"},
90
- {.irq = IRQIO_VAI, .name = "VAI", .desc = "[I/O] Virtual I/O Devices AI"},
87
+ {.irq = IRQIO_QAI, .name = "QAI", .desc = "[AIO] QDIO Adapter Interrupt"},
88
+ {.irq = IRQIO_APB, .name = "APB", .desc = "[AIO] AP Bus"},
89
+ {.irq = IRQIO_PCF, .name = "PCF", .desc = "[AIO] PCI Floating Interrupt"},
90
+ {.irq = IRQIO_PCD, .name = "PCD", .desc = "[AIO] PCI Directed Interrupt"},
91
+ {.irq = IRQIO_MSI, .name = "MSI", .desc = "[AIO] MSI Interrupt"},
92
+ {.irq = IRQIO_VAI, .name = "VAI", .desc = "[AIO] Virtual I/O Devices AI"},
93
+ {.irq = IRQIO_GAL, .name = "GAL", .desc = "[AIO] GIB Alert"},
9194 {.irq = NMI_NMI, .name = "NMI", .desc = "[NMI] Machine Check"},
9295 {.irq = CPU_RST, .name = "RST", .desc = "[CPU] CPU Restart"},
9396 };
94
-
95
-void __init init_IRQ(void)
96
-{
97
- BUILD_BUG_ON(ARRAY_SIZE(irqclass_sub_desc) != NR_ARCH_IRQS);
98
- init_cio_interrupts();
99
- init_airq_interrupts();
100
- init_ext_interrupts();
101
-}
10297
10398 void do_IRQ(struct pt_regs *regs, int irq)
10499 {
....@@ -115,6 +110,34 @@
115110 set_irq_regs(old_regs);
116111 }
117112
113
+static void show_msi_interrupt(struct seq_file *p, int irq)
114
+{
115
+ struct irq_desc *desc;
116
+ unsigned long flags;
117
+ int cpu;
118
+
119
+ irq_lock_sparse();
120
+ desc = irq_to_desc(irq);
121
+ if (!desc)
122
+ goto out;
123
+
124
+ raw_spin_lock_irqsave(&desc->lock, flags);
125
+ seq_printf(p, "%3d: ", irq);
126
+ for_each_online_cpu(cpu)
127
+ seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu));
128
+
129
+ if (desc->irq_data.chip)
130
+ seq_printf(p, " %8s", desc->irq_data.chip->name);
131
+
132
+ if (desc->action)
133
+ seq_printf(p, " %s", desc->action->name);
134
+
135
+ seq_putc(p, '\n');
136
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
137
+out:
138
+ irq_unlock_sparse();
139
+}
140
+
118141 /*
119142 * show_interrupts is needed by /proc/interrupts.
120143 */
....@@ -127,7 +150,7 @@
127150 if (index == 0) {
128151 seq_puts(p, " ");
129152 for_each_online_cpu(cpu)
130
- seq_printf(p, "CPU%d ", cpu);
153
+ seq_printf(p, "CPU%-8d", cpu);
131154 seq_putc(p, '\n');
132155 }
133156 if (index < NR_IRQS_BASE) {
....@@ -138,9 +161,10 @@
138161 seq_putc(p, '\n');
139162 goto out;
140163 }
141
- if (index > NR_IRQS_BASE)
164
+ if (index < nr_irqs) {
165
+ show_msi_interrupt(p, index);
142166 goto out;
143
-
167
+ }
144168 for (index = 0; index < NR_ARCH_IRQS; index++) {
145169 seq_printf(p, "%s: ", irqclass_sub_desc[index].name);
146170 irq = irqclass_sub_desc[index].irq;
....@@ -172,15 +196,7 @@
172196 /* Check against async. stack address range. */
173197 new = S390_lowcore.async_stack;
174198 if (((new - old) >> (PAGE_SHIFT + THREAD_SIZE_ORDER)) != 0) {
175
- /* Need to switch to the async. stack. */
176
- new -= STACK_FRAME_OVERHEAD;
177
- ((struct stack_frame *) new)->back_chain = old;
178
- asm volatile(" la 15,0(%0)\n"
179
- " brasl 14,__do_softirq\n"
180
- " la 15,0(%1)\n"
181
- : : "a" (new), "a" (old)
182
- : "0", "1", "2", "3", "4", "5", "14",
183
- "cc", "memory" );
199
+ CALL_ON_STACK(__do_softirq, new, 0);
184200 } else {
185201 /* We are already on the async stack. */
186202 __do_softirq();
....@@ -270,12 +286,7 @@
270286 return IRQ_HANDLED;
271287 }
272288
273
-static struct irqaction external_interrupt = {
274
- .name = "EXT",
275
- .handler = do_ext_interrupt,
276
-};
277
-
278
-void __init init_ext_interrupts(void)
289
+static void __init init_ext_interrupts(void)
279290 {
280291 int idx;
281292
....@@ -284,7 +295,16 @@
284295
285296 irq_set_chip_and_handler(EXT_INTERRUPT,
286297 &dummy_irq_chip, handle_percpu_irq);
287
- setup_irq(EXT_INTERRUPT, &external_interrupt);
298
+ if (request_irq(EXT_INTERRUPT, do_ext_interrupt, 0, "EXT", NULL))
299
+ panic("Failed to register EXT interrupt\n");
300
+}
301
+
302
+void __init init_IRQ(void)
303
+{
304
+ BUILD_BUG_ON(ARRAY_SIZE(irqclass_sub_desc) != NR_ARCH_IRQS);
305
+ init_cio_interrupts();
306
+ init_airq_interrupts();
307
+ init_ext_interrupts();
288308 }
289309
290310 static DEFINE_SPINLOCK(irq_subclass_lock);