Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23256d0b authored by Joerg Roedel's avatar Joerg Roedel
Browse files

iommu/vt-d: Move EIM detection to intel_prepare_irq_remapping



We need this to be detected already when we program the irq
remapping table pointer to hardware.

Tested-by: default avatarZhenHua Li <zhen-hual@hp.com>
Tested-by: default avatarBaoquan He <bhe@redhat.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 8939ddf6
Loading
Loading
Loading
Loading
+24 −23
Original line number Original line Diff line number Diff line
@@ -589,6 +589,7 @@ static int __init intel_prepare_irq_remapping(void)
{
{
	struct dmar_drhd_unit *drhd;
	struct dmar_drhd_unit *drhd;
	struct intel_iommu *iommu;
	struct intel_iommu *iommu;
	int eim = 0;


	if (irq_remap_broken) {
	if (irq_remap_broken) {
		pr_warn("This system BIOS has enabled interrupt remapping\n"
		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))
		if (!ecap_ir_support(iommu->ecap))
			goto error;
			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 */
	/* Do the allocations early */
	for_each_iommu(iommu, drhd)
	for_each_iommu(iommu, drhd)
		if (intel_setup_irq_remapping(iommu))
		if (intel_setup_irq_remapping(iommu))
@@ -633,13 +654,6 @@ static int __init intel_enable_irq_remapping(void)
	struct dmar_drhd_unit *drhd;
	struct dmar_drhd_unit *drhd;
	struct intel_iommu *iommu;
	struct intel_iommu *iommu;
	bool setup = false;
	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) {
	for_each_iommu(iommu, drhd) {
		/*
		/*
@@ -663,19 +677,6 @@ static int __init intel_enable_irq_remapping(void)
		dmar_disable_qi(iommu);
		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.
	 * 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.
	 * Setup Interrupt-remapping for all the DRHD's now.
	 */
	 */
	for_each_iommu(iommu, drhd) {
	for_each_iommu(iommu, drhd) {
		iommu_set_irq_remapping(iommu, eim);
		iommu_set_irq_remapping(iommu, eim_mode);
		setup = true;
		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;
	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:
error:
	intel_cleanup_irq_remapping();
	intel_cleanup_irq_remapping();