iommu/vt-d: Move EIM detection to intel_prepare_irq_remapping
authorJoerg Roedel <jroedel@suse.de>
Fri, 12 Jun 2015 12:15:49 +0000 (14:15 +0200)
committerJoerg Roedel <jroedel@suse.de>
Tue, 16 Jun 2015 08:59:35 +0000 (10:59 +0200)
We need this to be detected already when we program the irq
remapping table pointer to hardware.

Tested-by: ZhenHua Li <zhen-hual@hp.com>
Tested-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/intel_irq_remapping.c

index 3fe3fc78060c8feaf8304cd498e681b5eeb0f9e8..12250f72be0b601d1d79735cd426b5dd660efc67 100644 (file)
@@ -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();