1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/cpumask.h>
3 #include <linux/kernel.h>
4 #include <linux/string.h>
5 #include <linux/errno.h>
9 #include <linux/irqdomain.h>
11 #include <asm/hw_irq.h>
12 #include <asm/irq_remapping.h>
13 #include <asm/processor.h>
14 #include <asm/x86_init.h>
18 #include "irq_remapping.h"
20 int irq_remapping_enabled
;
22 int disable_sourceid_checking
;
25 int disable_irq_post
= 0;
27 static int disable_irq_remap
;
28 static struct irq_remap_ops
*remap_ops
;
30 static void irq_remapping_restore_boot_irq_mode(void)
33 * With interrupt-remapping, for now we will use virtual wire A
34 * mode, as virtual wire B is little complex (need to configure
35 * both IOAPIC RTE as well as interrupt-remapping table entry).
36 * As this gets called during crash dump, keep this simple for
39 if (boot_cpu_has(X86_FEATURE_APIC
) || apic_from_smp_config())
40 disconnect_bsp_APIC(0);
43 static void __init
irq_remapping_modify_x86_ops(void)
45 x86_apic_ops
.restore
= irq_remapping_restore_boot_irq_mode
;
48 static __init
int setup_nointremap(char *str
)
50 disable_irq_remap
= 1;
53 early_param("nointremap", setup_nointremap
);
55 static __init
int setup_irqremap(char *str
)
61 if (!strncmp(str
, "on", 2)) {
62 disable_irq_remap
= 0;
64 } else if (!strncmp(str
, "off", 3)) {
65 disable_irq_remap
= 1;
67 } else if (!strncmp(str
, "nosid", 5))
68 disable_sourceid_checking
= 1;
69 else if (!strncmp(str
, "no_x2apic_optout", 16))
71 else if (!strncmp(str
, "nopost", 6))
74 str
+= strcspn(str
, ",");
81 early_param("intremap", setup_irqremap
);
83 void set_irq_remapping_broken(void)
88 bool irq_remapping_cap(enum irq_remap_cap cap
)
90 if (!remap_ops
|| disable_irq_post
)
93 return (remap_ops
->capability
& (1 << cap
));
95 EXPORT_SYMBOL_GPL(irq_remapping_cap
);
97 int __init
irq_remapping_prepare(void)
99 if (disable_irq_remap
)
102 if (intel_irq_remap_ops
.prepare() == 0)
103 remap_ops
= &intel_irq_remap_ops
;
104 else if (IS_ENABLED(CONFIG_AMD_IOMMU
) &&
105 amd_iommu_irq_ops
.prepare() == 0)
106 remap_ops
= &amd_iommu_irq_ops
;
107 else if (IS_ENABLED(CONFIG_HYPERV_IOMMU
) &&
108 hyperv_irq_remap_ops
.prepare() == 0)
109 remap_ops
= &hyperv_irq_remap_ops
;
116 int __init
irq_remapping_enable(void)
120 if (!remap_ops
->enable
)
123 ret
= remap_ops
->enable();
125 if (irq_remapping_enabled
)
126 irq_remapping_modify_x86_ops();
131 void irq_remapping_disable(void)
133 if (irq_remapping_enabled
&& remap_ops
->disable
)
134 remap_ops
->disable();
137 int irq_remapping_reenable(int mode
)
139 if (irq_remapping_enabled
&& remap_ops
->reenable
)
140 return remap_ops
->reenable(mode
);
145 int __init
irq_remap_enable_fault_handling(void)
147 if (!irq_remapping_enabled
)
150 if (!remap_ops
->enable_faulting
)
153 return remap_ops
->enable_faulting();
156 void panic_if_irq_remap(const char *msg
)
158 if (irq_remapping_enabled
)