|
@@ -589,6 +589,7 @@ static int __init intel_prepare_irq_remapping(void)
|
|
|
{
|
|
|
struct dmar_drhd_unit *drhd;
|
|
|
struct intel_iommu *iommu;
|
|
|
+ int eim = 0;
|
|
|
|
|
|
if (irq_remap_broken) {
|
|
|
pr_warn("This system BIOS has enabled interrupt remapping\n"
|
|
@@ -616,6 +617,26 @@ static int __init intel_prepare_irq_remapping(void)
|
|
|
if (!ecap_ir_support(iommu->ecap))
|
|
|
goto error;
|
|
|
|
|
|
+ /* Detect remapping mode: lapic or x2apic */
|
|
|
+ if (x2apic_supported()) {
|
|
|
+ eim = !dmar_x2apic_optout();
|
|
|
+ if (!eim) {
|
|
|
+ pr_info("x2apic is disabled because BIOS sets x2apic opt out bit.");
|
|
|
+ pr_info("Use 'intremap=no_x2apic_optout' to override the BIOS setting.\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for_each_iommu(iommu, drhd) {
|
|
|
+ if (eim && !ecap_eim_support(iommu->ecap)) {
|
|
|
+ pr_info("%s does not support EIM\n", iommu->name);
|
|
|
+ eim = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ eim_mode = eim;
|
|
|
+ if (eim)
|
|
|
+ pr_info("Queued invalidation will be enabled to support x2apic and Intr-remapping.\n");
|
|
|
+
|
|
|
/* Do the allocations early */
|
|
|
for_each_iommu(iommu, drhd)
|
|
|
if (intel_setup_irq_remapping(iommu))
|
|
@@ -633,13 +654,6 @@ static int __init intel_enable_irq_remapping(void)
|
|
|
struct dmar_drhd_unit *drhd;
|
|
|
struct intel_iommu *iommu;
|
|
|
bool setup = false;
|
|
|
- int eim = 0;
|
|
|
-
|
|
|
- if (x2apic_supported()) {
|
|
|
- eim = !dmar_x2apic_optout();
|
|
|
- if (!eim)
|
|
|
- pr_info("x2apic is disabled because BIOS sets x2apic opt out bit. You can use 'intremap=no_x2apic_optout' to override the BIOS setting.\n");
|
|
|
- }
|
|
|
|
|
|
for_each_iommu(iommu, drhd) {
|
|
|
/*
|
|
@@ -663,19 +677,6 @@ static int __init intel_enable_irq_remapping(void)
|
|
|
dmar_disable_qi(iommu);
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * check for the Interrupt-remapping support
|
|
|
- */
|
|
|
- for_each_iommu(iommu, drhd)
|
|
|
- if (eim && !ecap_eim_support(iommu->ecap)) {
|
|
|
- pr_info("DRHD %Lx: EIM not supported by DRHD, "
|
|
|
- " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap);
|
|
|
- eim = 0;
|
|
|
- }
|
|
|
- eim_mode = eim;
|
|
|
- if (eim)
|
|
|
- pr_info("Queued invalidation will be enabled to support x2apic and Intr-remapping.\n");
|
|
|
-
|
|
|
/*
|
|
|
* Enable queued invalidation for all the DRHD's.
|
|
|
*/
|
|
@@ -694,7 +695,7 @@ static int __init intel_enable_irq_remapping(void)
|
|
|
* Setup Interrupt-remapping for all the DRHD's now.
|
|
|
*/
|
|
|
for_each_iommu(iommu, drhd) {
|
|
|
- iommu_set_irq_remapping(iommu, eim);
|
|
|
+ iommu_set_irq_remapping(iommu, eim_mode);
|
|
|
setup = true;
|
|
|
}
|
|
|
|
|
@@ -710,9 +711,9 @@ static int __init intel_enable_irq_remapping(void)
|
|
|
*/
|
|
|
x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries;
|
|
|
|
|
|
- pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic");
|
|
|
+ pr_info("Enabled IRQ remapping in %s mode\n", eim_mode ? "x2apic" : "xapic");
|
|
|
|
|
|
- return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
|
|
|
+ return eim_mode ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
|
|
|
|
|
|
error:
|
|
|
intel_cleanup_irq_remapping();
|