static int __init intel_prepare_irq_remapping(void) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu; if (irq_remap_broken) { printk(KERN_WARNING "This system BIOS has enabled interrupt remapping\n" "on a chipset that contains an erratum making that\n" "feature unstable. To maintain system stability\n" "interrupt remapping is being disabled. Please\n" "contact your BIOS vendor for an update\n"); add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); return -ENODEV; } if (dmar_table_init() < 0) return -ENODEV; if (!dmar_ir_support()) return -ENODEV; if (parse_ioapics_under_ir() != 1) { printk(KERN_INFO "Not enabling interrupt remapping\n"); goto error; } /* First make sure all IOMMUs support IRQ remapping */ for_each_iommu(iommu, drhd) if (!ecap_ir_support(iommu->ecap)) goto error; /* Do the allocations early */ for_each_iommu(iommu, drhd) if (intel_setup_irq_remapping(iommu)) goto error; return 0; error: intel_cleanup_irq_remapping(); return -ENODEV; }
int __init enable_intr_remapping(int eim) { struct dmar_drhd_unit *drhd; int setup = 0; if (parse_ioapics_under_ir() != 1) { printk(KERN_INFO "Not enable interrupt remapping\n"); return -1; } for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; /* * If the queued invalidation is already initialized, * shouldn't disable it. */ if (iommu->qi) continue; /* * Clear previous faults. */ dmar_fault(-1, iommu); /* * Disable intr remapping and queued invalidation, if already * enabled prior to OS handover. */ iommu_disable_intr_remapping(iommu); dmar_disable_qi(iommu); } /* * check for the Interrupt-remapping support */ for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (eim && !ecap_eim_support(iommu->ecap)) { printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, " " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); return -1; } } /* * Enable queued invalidation for all the DRHD's. */ for_each_drhd_unit(drhd) { int ret; struct intel_iommu *iommu = drhd->iommu; ret = dmar_enable_qi(iommu); if (ret) { printk(KERN_ERR "DRHD %Lx: failed to enable queued, " " invalidation, ecap %Lx, ret %d\n", drhd->reg_base_addr, iommu->ecap, ret); return -1; } } /* * Setup Interrupt-remapping for all the DRHD's now. */ for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (setup_intr_remapping(iommu, eim)) goto error; setup = 1; } if (!setup) goto error; intr_remapping_enabled = 1; return 0; error: /* * handle error condition gracefully here! */ return -1; }
static int __init intel_enable_irq_remapping(void) { struct dmar_drhd_unit *drhd; int setup = 0; int eim = 0; if (parse_ioapics_under_ir() != 1) { printk(KERN_INFO "Not enable interrupt remapping\n"); return -1; } if (x2apic_supported()) { eim = !dmar_x2apic_optout(); WARN(!eim, KERN_WARNING "Your BIOS is broken and requested that x2apic be disabled\n" "This will leave your machine vulnerable to irq-injection attacks\n" "Use 'intremap=no_x2apic_optout' to override BIOS request\n"); } for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; /* * If the queued invalidation is already initialized, * shouldn't disable it. */ if (iommu->qi) continue; /* * Clear previous faults. */ dmar_fault(-1, iommu); /* * Disable intr remapping and queued invalidation, if already * enabled prior to OS handover. */ iommu_disable_irq_remapping(iommu); dmar_disable_qi(iommu); } /* * check for the Interrupt-remapping support */ for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (eim && !ecap_eim_support(iommu->ecap)) { printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, " " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); return -1; } } /* * Enable queued invalidation for all the DRHD's. */ for_each_drhd_unit(drhd) { int ret; struct intel_iommu *iommu = drhd->iommu; ret = dmar_enable_qi(iommu); if (ret) { printk(KERN_ERR "DRHD %Lx: failed to enable queued, " " invalidation, ecap %Lx, ret %d\n", drhd->reg_base_addr, iommu->ecap, ret); return -1; } } /* * Setup Interrupt-remapping for all the DRHD's now. */ for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (intel_setup_irq_remapping(iommu, eim)) goto error; setup = 1; } if (!setup) goto error; irq_remapping_enabled = 1; pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; error: /* * handle error condition gracefully here! */ return -1; }
static int __init intel_enable_irq_remapping(void) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu; bool x2apic_present; int setup = 0; int eim = 0; x2apic_present = x2apic_supported(); if (parse_ioapics_under_ir() != 1) { printk(KERN_INFO "Not enable interrupt remapping\n"); goto error; } if (x2apic_present) { eim = !dmar_x2apic_optout(); if (!eim) printk(KERN_WARNING "Your BIOS is broken and requested that x2apic be disabled.\n" "This will slightly decrease performance.\n" "Use 'intremap=no_x2apic_optout' to override BIOS request.\n"); } for_each_iommu(iommu, drhd) { /* * If the queued invalidation is already initialized, * shouldn't disable it. */ if (iommu->qi) continue; /* * Clear previous faults. */ dmar_fault(-1, iommu); /* * Disable intr remapping and queued invalidation, if already * enabled prior to OS handover. */ iommu_disable_irq_remapping(iommu); dmar_disable_qi(iommu); } /* * check for the Interrupt-remapping support */ for_each_iommu(iommu, drhd) { if (!ecap_ir_support(iommu->ecap)) continue; if (eim && !ecap_eim_support(iommu->ecap)) { printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, " " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); goto error; } } /* * Enable queued invalidation for all the DRHD's. */ for_each_iommu(iommu, drhd) { int ret = dmar_enable_qi(iommu); if (ret) { printk(KERN_ERR "DRHD %Lx: failed to enable queued, " " invalidation, ecap %Lx, ret %d\n", drhd->reg_base_addr, iommu->ecap, ret); goto error; } }
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" "on a chipset that contains an erratum making that\n" "feature unstable. To maintain system stability\n" "interrupt remapping is being disabled. Please\n" "contact your BIOS vendor for an update\n"); add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); return -ENODEV; } if (dmar_table_init() < 0) return -ENODEV; if (!dmar_ir_support()) return -ENODEV; if (parse_ioapics_under_ir()) { pr_info("Not enabling interrupt remapping\n"); goto error; } /* First make sure all IOMMUs support IRQ remapping */ for_each_iommu(iommu, drhd) 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 initializations early */ for_each_iommu(iommu, drhd) { if (intel_setup_irq_remapping(iommu)) { pr_err("Failed to setup irq remapping for %s\n", iommu->name); goto error; } } return 0; error: intel_cleanup_irq_remapping(); return -ENODEV; }
static int __init intel_enable_irq_remapping(void) { struct dmar_drhd_unit *drhd; bool x2apic_present; int setup = 0; int eim = 0; x2apic_present = x2apic_supported(); if (parse_ioapics_under_ir() != 1) { printk(KERN_INFO "Not enable interrupt remapping\n"); goto error; } if (x2apic_present) { eim = !dmar_x2apic_optout(); if (!eim) printk(KERN_WARNING "Your BIOS is broken and requested that x2apic be disabled.\n" "This will slightly decrease performance.\n" "Use 'intremap=no_x2apic_optout' to override BIOS request.\n"); } for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; /* * If the queued invalidation is already initialized, * shouldn't disable it. */ if (iommu->qi) continue; /* * Clear previous faults. */ dmar_fault(-1, iommu); /* * Disable intr remapping and queued invalidation, if already * enabled prior to OS handover. */ iommu_disable_irq_remapping(iommu); dmar_disable_qi(iommu); } /* * check for the Interrupt-remapping support */ for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (eim && !ecap_eim_support(iommu->ecap)) { printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, " " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); goto error; } } /* * Enable queued invalidation for all the DRHD's. */ for_each_drhd_unit(drhd) { int ret; struct intel_iommu *iommu = drhd->iommu; ret = dmar_enable_qi(iommu); if (ret) { printk(KERN_ERR "DRHD %Lx: failed to enable queued, " " invalidation, ecap %Lx, ret %d\n", drhd->reg_base_addr, iommu->ecap, ret); goto error; } } /* * Setup Interrupt-remapping for all the DRHD's now. */ for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (intel_setup_irq_remapping(iommu, eim)) goto error; setup = 1; } if (!setup) goto error; irq_remapping_enabled = 1; /* * VT-d has a different layout for IO-APIC entries when * interrupt remapping is enabled. So it needs a special routine * to print IO-APIC entries for debugging purposes too. */ x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries; pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; error: /* * handle error condition gracefully here! */ if (x2apic_present) pr_warn("Failed to enable irq remapping. You are vulnerable to irq-injection attacks.\n"); return -1; }
int __init enable_intr_remapping(void) { struct dmar_drhd_unit *drhd; int setup = 0; int eim = 0; if (parse_ioapics_under_ir() != 1) { printk(KERN_INFO "Not enable interrupt remapping\n"); return -1; } if (x2apic_supported()) { eim = !dmar_x2apic_optout(); WARN(!eim, KERN_WARNING "Your BIOS is broken and requested that x2apic be disabled\n" "This will leave your machine vulnerable to irq-injection attacks\n" "Use 'intremap=no_x2apic_optout' to override BIOS request\n"); } for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (iommu->qi) continue; dmar_fault(-1, iommu); iommu_disable_intr_remapping(iommu); dmar_disable_qi(iommu); } for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (eim && !ecap_eim_support(iommu->ecap)) { printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, " " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); return -1; } } for_each_drhd_unit(drhd) { int ret; struct intel_iommu *iommu = drhd->iommu; ret = dmar_enable_qi(iommu); if (ret) { printk(KERN_ERR "DRHD %Lx: failed to enable queued, " " invalidation, ecap %Lx, ret %d\n", drhd->reg_base_addr, iommu->ecap, ret); return -1; } } for_each_drhd_unit(drhd) { struct intel_iommu *iommu = drhd->iommu; if (!ecap_ir_support(iommu->ecap)) continue; if (setup_intr_remapping(iommu, eim)) goto error; setup = 1; } if (!setup) goto error; intr_remapping_enabled = 1; pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; error: return -1; }