hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/arch/x86/kernel/apic/msi.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Support of MSI, HPET and DMAR interrupts.
34 *
....@@ -5,10 +6,6 @@
56 * Moved from arch/x86/kernel/apic/io_apic.c.
67 * Jiang Liu <jiang.liu@linux.intel.com>
78 * Convert to hierarchical irqdomain
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License version 2 as
11
- * published by the Free Software Foundation.
129 */
1310 #include <linux/mm.h>
1411 #include <linux/interrupt.h>
....@@ -24,7 +21,7 @@
2421 #include <asm/apic.h>
2522 #include <asm/irq_remapping.h>
2623
27
-static struct irq_domain *msi_default_domain;
24
+struct irq_domain *x86_pci_msi_default_domain __ro_after_init;
2825
2926 static void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg)
3027 {
....@@ -48,7 +45,7 @@
4845 MSI_DATA_VECTOR(cfg->vector);
4946 }
5047
51
-static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
48
+void x86_vector_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
5249 {
5350 __irq_msi_compose_msg(irqd_cfg(data), msg);
5451 }
....@@ -120,7 +117,8 @@
120117 * denote it as spurious which is no harm as this is a rare event
121118 * and interrupt handlers have to cope with spurious interrupts
122119 * anyway. If the vector is unused, then it is marked so it won't
123
- * trigger the 'No irq handler for vector' warning in do_IRQ().
120
+ * trigger the 'No irq handler for vector' warning in
121
+ * common_interrupt().
124122 *
125123 * This requires to hold vector lock to prevent concurrent updates to
126124 * the affected vector.
....@@ -181,40 +179,10 @@
181179 .irq_mask = pci_msi_mask_irq,
182180 .irq_ack = irq_chip_ack_parent,
183181 .irq_retrigger = irq_chip_retrigger_hierarchy,
184
- .irq_compose_msi_msg = irq_msi_compose_msg,
185182 .irq_set_affinity = msi_set_affinity,
186183 .flags = IRQCHIP_SKIP_SET_WAKE |
187184 IRQCHIP_AFFINITY_PRE_STARTUP,
188185 };
189
-
190
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
191
-{
192
- struct irq_domain *domain;
193
- struct irq_alloc_info info;
194
-
195
- init_irq_alloc_info(&info, NULL);
196
- info.type = X86_IRQ_ALLOC_TYPE_MSI;
197
- info.msi_dev = dev;
198
-
199
- domain = irq_remapping_get_irq_domain(&info);
200
- if (domain == NULL)
201
- domain = msi_default_domain;
202
- if (domain == NULL)
203
- return -ENOSYS;
204
-
205
- return msi_domain_alloc_irqs(domain, &dev->dev, nvec);
206
-}
207
-
208
-void native_teardown_msi_irq(unsigned int irq)
209
-{
210
- irq_domain_free_irqs(irq, 1);
211
-}
212
-
213
-static irq_hw_number_t pci_msi_get_hwirq(struct msi_domain_info *info,
214
- msi_alloc_info_t *arg)
215
-{
216
- return arg->msi_hwirq;
217
-}
218186
219187 int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
220188 msi_alloc_info_t *arg)
....@@ -223,11 +191,10 @@
223191 struct msi_desc *desc = first_pci_msi_entry(pdev);
224192
225193 init_irq_alloc_info(arg, NULL);
226
- arg->msi_dev = pdev;
227194 if (desc->msi_attrib.is_msix) {
228
- arg->type = X86_IRQ_ALLOC_TYPE_MSIX;
195
+ arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
229196 } else {
230
- arg->type = X86_IRQ_ALLOC_TYPE_MSI;
197
+ arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;
231198 arg->flags |= X86_IRQ_ALLOC_CONTIGUOUS_VECTORS;
232199 }
233200
....@@ -235,16 +202,8 @@
235202 }
236203 EXPORT_SYMBOL_GPL(pci_msi_prepare);
237204
238
-void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
239
-{
240
- arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc);
241
-}
242
-EXPORT_SYMBOL_GPL(pci_msi_set_desc);
243
-
244205 static struct msi_domain_ops pci_msi_domain_ops = {
245
- .get_hwirq = pci_msi_get_hwirq,
246206 .msi_prepare = pci_msi_prepare,
247
- .set_desc = pci_msi_set_desc,
248207 };
249208
250209 static struct msi_domain_info pci_msi_domain_info = {
....@@ -256,25 +215,32 @@
256215 .handler_name = "edge",
257216 };
258217
259
-void __init arch_init_msi_domain(struct irq_domain *parent)
218
+struct irq_domain * __init native_create_pci_msi_domain(void)
260219 {
261220 struct fwnode_handle *fn;
221
+ struct irq_domain *d;
262222
263223 if (disable_apic)
264
- return;
224
+ return NULL;
265225
266226 fn = irq_domain_alloc_named_fwnode("PCI-MSI");
267
- if (fn) {
268
- msi_default_domain =
269
- pci_msi_create_irq_domain(fn, &pci_msi_domain_info,
270
- parent);
271
- }
272
- if (!msi_default_domain) {
227
+ if (!fn)
228
+ return NULL;
229
+
230
+ d = pci_msi_create_irq_domain(fn, &pci_msi_domain_info,
231
+ x86_vector_domain);
232
+ if (!d) {
273233 irq_domain_free_fwnode(fn);
274
- pr_warn("failed to initialize irqdomain for MSI/MSI-x.\n");
234
+ pr_warn("Failed to initialize PCI-MSI irqdomain.\n");
275235 } else {
276
- msi_default_domain->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK;
236
+ d->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK;
277237 }
238
+ return d;
239
+}
240
+
241
+void __init x86_create_pci_msi_domain(void)
242
+{
243
+ x86_pci_msi_default_domain = x86_init.irqs.create_pci_msi_domain();
278244 }
279245
280246 #ifdef CONFIG_IRQ_REMAP
....@@ -284,7 +250,6 @@
284250 .irq_mask = pci_msi_mask_irq,
285251 .irq_ack = irq_chip_ack_parent,
286252 .irq_retrigger = irq_chip_retrigger_hierarchy,
287
- .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent,
288253 .flags = IRQCHIP_SKIP_SET_WAKE |
289254 IRQCHIP_AFFINITY_PRE_STARTUP,
290255 };
....@@ -327,36 +292,29 @@
327292 .irq_ack = irq_chip_ack_parent,
328293 .irq_set_affinity = msi_domain_set_affinity,
329294 .irq_retrigger = irq_chip_retrigger_hierarchy,
330
- .irq_compose_msi_msg = irq_msi_compose_msg,
331295 .irq_write_msi_msg = dmar_msi_write_msg,
332296 .flags = IRQCHIP_SKIP_SET_WAKE |
333297 IRQCHIP_AFFINITY_PRE_STARTUP,
334298 };
335299
336
-static irq_hw_number_t dmar_msi_get_hwirq(struct msi_domain_info *info,
337
- msi_alloc_info_t *arg)
338
-{
339
- return arg->dmar_id;
340
-}
341
-
342300 static int dmar_msi_init(struct irq_domain *domain,
343301 struct msi_domain_info *info, unsigned int virq,
344302 irq_hw_number_t hwirq, msi_alloc_info_t *arg)
345303 {
346
- irq_domain_set_info(domain, virq, arg->dmar_id, info->chip, NULL,
347
- handle_edge_irq, arg->dmar_data, "edge");
304
+ irq_domain_set_info(domain, virq, arg->devid, info->chip, NULL,
305
+ handle_edge_irq, arg->data, "edge");
348306
349307 return 0;
350308 }
351309
352310 static struct msi_domain_ops dmar_msi_domain_ops = {
353
- .get_hwirq = dmar_msi_get_hwirq,
354311 .msi_init = dmar_msi_init,
355312 };
356313
357314 static struct msi_domain_info dmar_msi_domain_info = {
358315 .ops = &dmar_msi_domain_ops,
359316 .chip = &dmar_msi_controller,
317
+ .flags = MSI_FLAG_USE_DEF_DOM_OPS,
360318 };
361319
362320 static struct irq_domain *dmar_get_irq_domain(void)
....@@ -391,8 +349,9 @@
391349
392350 init_irq_alloc_info(&info, NULL);
393351 info.type = X86_IRQ_ALLOC_TYPE_DMAR;
394
- info.dmar_id = id;
395
- info.dmar_data = arg;
352
+ info.devid = id;
353
+ info.hwirq = id;
354
+ info.data = arg;
396355
397356 return irq_domain_alloc_irqs(domain, 1, node, &info);
398357 }
....@@ -426,24 +385,17 @@
426385 .irq_ack = irq_chip_ack_parent,
427386 .irq_set_affinity = msi_domain_set_affinity,
428387 .irq_retrigger = irq_chip_retrigger_hierarchy,
429
- .irq_compose_msi_msg = irq_msi_compose_msg,
430388 .irq_write_msi_msg = hpet_msi_write_msg,
431389 .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_AFFINITY_PRE_STARTUP,
432390 };
433
-
434
-static irq_hw_number_t hpet_msi_get_hwirq(struct msi_domain_info *info,
435
- msi_alloc_info_t *arg)
436
-{
437
- return arg->hpet_index;
438
-}
439391
440392 static int hpet_msi_init(struct irq_domain *domain,
441393 struct msi_domain_info *info, unsigned int virq,
442394 irq_hw_number_t hwirq, msi_alloc_info_t *arg)
443395 {
444396 irq_set_status_flags(virq, IRQ_MOVE_PCNTXT);
445
- irq_domain_set_info(domain, virq, arg->hpet_index, info->chip, NULL,
446
- handle_edge_irq, arg->hpet_data, "edge");
397
+ irq_domain_set_info(domain, virq, arg->hwirq, info->chip, NULL,
398
+ handle_edge_irq, arg->data, "edge");
447399
448400 return 0;
449401 }
....@@ -455,7 +407,6 @@
455407 }
456408
457409 static struct msi_domain_ops hpet_msi_domain_ops = {
458
- .get_hwirq = hpet_msi_get_hwirq,
459410 .msi_init = hpet_msi_init,
460411 .msi_free = hpet_msi_free,
461412 };
....@@ -463,6 +414,7 @@
463414 static struct msi_domain_info hpet_msi_domain_info = {
464415 .ops = &hpet_msi_domain_ops,
465416 .chip = &hpet_msi_controller,
417
+ .flags = MSI_FLAG_USE_DEF_DOM_OPS,
466418 };
467419
468420 struct irq_domain *hpet_create_irq_domain(int hpet_id)
....@@ -483,9 +435,9 @@
483435 domain_info->data = (void *)(long)hpet_id;
484436
485437 init_irq_alloc_info(&info, NULL);
486
- info.type = X86_IRQ_ALLOC_TYPE_HPET;
487
- info.hpet_id = hpet_id;
488
- parent = irq_remapping_get_ir_irq_domain(&info);
438
+ info.type = X86_IRQ_ALLOC_TYPE_HPET_GET_PARENT;
439
+ info.devid = hpet_id;
440
+ parent = irq_remapping_get_irq_domain(&info);
489441 if (parent == NULL)
490442 parent = x86_vector_domain;
491443 else
....@@ -506,16 +458,16 @@
506458 return d;
507459 }
508460
509
-int hpet_assign_irq(struct irq_domain *domain, struct hpet_dev *dev,
461
+int hpet_assign_irq(struct irq_domain *domain, struct hpet_channel *hc,
510462 int dev_num)
511463 {
512464 struct irq_alloc_info info;
513465
514466 init_irq_alloc_info(&info, NULL);
515467 info.type = X86_IRQ_ALLOC_TYPE_HPET;
516
- info.hpet_data = dev;
517
- info.hpet_id = hpet_dev_id(domain);
518
- info.hpet_index = dev_num;
468
+ info.data = hc;
469
+ info.devid = hpet_dev_id(domain);
470
+ info.hwirq = dev_num;
519471
520472 return irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, &info);
521473 }