Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
void __init enable_IR_x2apic(void)
{
    unsigned long flags;
    struct IO_APIC_route_entry **ioapic_entries = NULL;
    int ret, x2apic_enabled = 0;
    int dmar_table_init_ret = 0;

#ifdef CONFIG_INTR_REMAP
    dmar_table_init_ret = dmar_table_init();
    if (dmar_table_init_ret)
        pr_debug("dmar_table_init() failed with %d:\n",
                 dmar_table_init_ret);
#endif

    ioapic_entries = alloc_ioapic_entries();
    if (!ioapic_entries) {
        pr_err("Allocate ioapic_entries failed\n");
        goto out;
    }

    ret = save_IO_APIC_setup(ioapic_entries);
    if (ret) {
        pr_info("Saving IO-APIC state failed: %d\n", ret);
        goto out;
    }

    local_irq_save(flags);
    mask_8259A();
    mask_IO_APIC_setup(ioapic_entries);

    if (dmar_table_init_ret)
        ret = 0;
    else
        ret = enable_IR();

    if (!ret) {

        if (max_physical_apicid > 255 || !kvm_para_available())
            goto nox2apic;

        x2apic_force_phys();
    }

    x2apic_enabled = 1;

    if (x2apic_supported() && !x2apic_mode) {
        x2apic_mode = 1;
        enable_x2apic();
        pr_info("Enabled x2apic\n");
    }

nox2apic:
    if (!ret)
        restore_IO_APIC_setup(ioapic_entries);
    unmask_8259A();
    local_irq_restore(flags);

out:
    if (ioapic_entries)
        free_ioapic_entries(ioapic_entries);

    if (x2apic_enabled)
        return;

    if (x2apic_preenabled)
        panic("x2apic: enabled by BIOS but kernel init failed.");
    else if (cpu_has_x2apic)
        pr_info("Not enabling x2apic, Intr-remapping init failed.\n");
}