From 9f10e5bf62f7b9937afeee8ff0a491f87438e2a2 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 09:57:06 +0200 Subject: iommu/vt-d: Cleanup log messages Give them a common prefix that can be grepped for and improve the wording here and there. Tested-by: ZhenHua Li Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'drivers/iommu/intel_irq_remapping.c') diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 5709ae9c3e77..3fe3fc78060c 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -1,3 +1,6 @@ + +#define pr_fmt(fmt) "DMAR-IR: " fmt + #include #include #include @@ -100,8 +103,7 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) } if (mask > ecap_max_handle_mask(iommu->ecap)) { - printk(KERN_ERR - "Requested mask %x exceeds the max invalidation handle" + pr_err("Requested mask %x exceeds the max invalidation handle" " mask value %Lx\n", mask, ecap_max_handle_mask(iommu->ecap)); return -1; @@ -333,7 +335,7 @@ static int set_ioapic_sid(struct irte *irte, int apic) up_read(&dmar_global_lock); if (sid == 0) { - pr_warning("Failed to set source-id of IOAPIC (%d)\n", apic); + pr_warn("Failed to set source-id of IOAPIC (%d)\n", apic); return -1; } @@ -360,7 +362,7 @@ static int set_hpet_sid(struct irte *irte, u8 id) up_read(&dmar_global_lock); if (sid == 0) { - pr_warning("Failed to set source-id of HPET block (%d)\n", id); + pr_warn("Failed to set source-id of HPET block (%d)\n", id); return -1; } @@ -580,7 +582,7 @@ static void __init intel_cleanup_irq_remapping(void) } if (x2apic_supported()) - pr_warn("Failed to enable irq remapping. You are vulnerable to irq-injection attacks.\n"); + pr_warn("Failed to enable irq remapping. You are vulnerable to irq-injection attacks.\n"); } static int __init intel_prepare_irq_remapping(void) @@ -589,8 +591,7 @@ static int __init intel_prepare_irq_remapping(void) struct intel_iommu *iommu; if (irq_remap_broken) { - printk(KERN_WARNING - "This system BIOS has enabled interrupt remapping\n" + 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" @@ -606,7 +607,7 @@ static int __init intel_prepare_irq_remapping(void) return -ENODEV; if (parse_ioapics_under_ir() != 1) { - printk(KERN_INFO "Not enabling interrupt remapping\n"); + pr_info("Not enabling interrupt remapping\n"); goto error; } @@ -667,8 +668,8 @@ static int __init intel_enable_irq_remapping(void) */ for_each_iommu(iommu, drhd) 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); + pr_info("DRHD %Lx: EIM not supported by DRHD, " + " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); eim = 0; } eim_mode = eim; @@ -682,7 +683,7 @@ static int __init intel_enable_irq_remapping(void) int ret = dmar_enable_qi(iommu); if (ret) { - printk(KERN_ERR "DRHD %Lx: failed to enable queued, " + pr_err("DRHD %Lx: failed to enable queued, " " invalidation, ecap %Lx, ret %d\n", drhd->reg_base_addr, iommu->ecap, ret); goto error; @@ -1145,14 +1146,12 @@ static int intel_msi_alloc_irq(struct pci_dev *dev, int irq, int nvec) down_read(&dmar_global_lock); iommu = map_dev_to_ir(dev); if (!iommu) { - printk(KERN_ERR - "Unable to map PCI %s to iommu\n", pci_name(dev)); + pr_err("Unable to map PCI %s to iommu\n", pci_name(dev)); index = -ENOENT; } else { index = alloc_irte(iommu, irq, nvec); if (index < 0) { - printk(KERN_ERR - "Unable to allocate %d IRTE for PCI %s\n", + pr_err("Unable to allocate %d IRTE for PCI %s\n", nvec, pci_name(dev)); index = -ENOSPC; } -- cgit v1.2.3 From 23256d0b350014a05c1edf0f355546aa1ff2eb55 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 14:15:49 +0200 Subject: 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: ZhenHua Li Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 47 +++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'drivers/iommu/intel_irq_remapping.c') diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 3fe3fc78060c..12250f72be0b 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -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(); -- cgit v1.2.3 From 9e4e49dfde3bfac48d431893863ac3b9d3f3774a Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 14:23:56 +0200 Subject: iommu/vt-d: Move QI initializationt to intel_setup_irq_remapping QI needs to be enabled when we program the irq remapping table to hardware in the prepare phase later. Tested-by: ZhenHua Li Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 92 ++++++++++++++----------------------- 1 file changed, 35 insertions(+), 57 deletions(-) (limited to 'drivers/iommu/intel_irq_remapping.c') diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 12250f72be0b..46d17e19a461 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -507,12 +507,35 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu) ir_table->base = page_address(pages); ir_table->bitmap = bitmap; iommu->ir_table = ir_table; + + /* + * If the queued invalidation is already initialized, + * shouldn't disable it. + */ + if (!iommu->qi) { + /* + * Clear previous faults. + */ + dmar_fault(-1, iommu); + dmar_disable_qi(iommu); + + if (dmar_enable_qi(iommu)) { + pr_err("Failed to enable queued invalidation\n"); + goto out_free_bitmap; + } + } + return 0; +out_free_bitmap: + kfree(bitmap); out_free_pages: __free_pages(pages, INTR_REMAP_PAGE_ORDER); out_free_table: kfree(ir_table); + + iommu->ir_table = NULL; + return -ENOMEM; } @@ -637,10 +660,14 @@ static int __init intel_prepare_irq_remapping(void) 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)) + /* 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; @@ -655,42 +682,9 @@ static int __init intel_enable_irq_remapping(void) struct intel_iommu *iommu; bool setup = false; - 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. - */ + for_each_iommu(iommu, drhd) iommu_disable_irq_remapping(iommu); - dmar_disable_qi(iommu); - } - - /* - * Enable queued invalidation for all the DRHD's. - */ - for_each_iommu(iommu, drhd) { - int ret = dmar_enable_qi(iommu); - - if (ret) { - pr_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. */ @@ -1242,28 +1236,12 @@ static int dmar_ir_add(struct dmar_drhd_unit *dmaru, struct intel_iommu *iommu) /* Setup Interrupt-remapping now. */ ret = intel_setup_irq_remapping(iommu); if (ret) { - pr_err("DRHD %Lx: failed to allocate resource\n", - iommu->reg_phys); - ir_remove_ioapic_hpet_scope(iommu); - return ret; - } - - if (!iommu->qi) { - /* Clear previous faults. */ - dmar_fault(-1, iommu); - iommu_disable_irq_remapping(iommu); - dmar_disable_qi(iommu); - } - - /* Enable queued invalidation */ - ret = dmar_enable_qi(iommu); - if (!ret) { - iommu_set_irq_remapping(iommu, eim); - } else { - pr_err("DRHD %Lx: failed to enable queued invalidation, ecap %Lx, ret %d\n", - iommu->reg_phys, iommu->ecap, ret); + pr_err("Failed to setup irq remapping for %s\n", + iommu->name); intel_teardown_irq_remapping(iommu); ir_remove_ioapic_hpet_scope(iommu); + } else { + iommu_set_irq_remapping(iommu, eim); } return ret; -- cgit v1.2.3 From c676f5876bc088ace35ece98042a3be6d8329530 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 14:25:53 +0200 Subject: iommu/vt-d: Disable IRQ remapping in intel_prepare_irq_remapping Move it to this function for now, so that the copy routines for irq remapping take no effect yet. Tested-by: ZhenHua Li Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/iommu/intel_irq_remapping.c') diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 46d17e19a461..f1711836486f 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -654,6 +654,9 @@ static int __init intel_prepare_irq_remapping(void) pr_info("%s does not support EIM\n", iommu->name); eim = 0; } + + /* Disable IRQ remapping if it is already enabled */ + iommu_disable_irq_remapping(iommu); } eim_mode = eim; @@ -682,9 +685,6 @@ static int __init intel_enable_irq_remapping(void) struct intel_iommu *iommu; bool setup = false; - for_each_iommu(iommu, drhd) - iommu_disable_irq_remapping(iommu); - /* * Setup Interrupt-remapping for all the DRHD's now. */ -- cgit v1.2.3 From d4d1c0f3d6a9558fe3857853afdf2f93e1679c03 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 14:35:54 +0200 Subject: iommu/vt-d: Set IRTA in intel_setup_irq_remapping This way we can give the hardware the new IR table right after it has been allocated and initialized. Tested-by: ZhenHua Li Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers/iommu/intel_irq_remapping.c') diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index f1711836486f..84970281b754 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -428,9 +428,9 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev) static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) { + unsigned long flags; u64 addr; u32 sts; - unsigned long flags; addr = virt_to_phys((void *)iommu->ir_table->base); @@ -447,10 +447,16 @@ static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) raw_spin_unlock_irqrestore(&iommu->register_lock, flags); /* - * global invalidation of interrupt entry cache before enabling - * interrupt-remapping. + * Global invalidation of interrupt entry cache to make sure the + * hardware uses the new irq remapping table. */ qi_global_iec(iommu); +} + +static void iommu_enable_irq_remapping(struct intel_iommu *iommu) +{ + unsigned long flags; + u32 sts; raw_spin_lock_irqsave(&iommu->register_lock, flags); @@ -525,6 +531,8 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu) } } + iommu_set_irq_remapping(iommu, eim_mode); + return 0; out_free_bitmap: @@ -689,7 +697,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_mode); + iommu_enable_irq_remapping(iommu); setup = true; } @@ -926,6 +934,7 @@ static int reenable_irq_remapping(int eim) /* Set up interrupt remapping for iommu.*/ iommu_set_irq_remapping(iommu, eim); + iommu_enable_irq_remapping(iommu); setup = true; } @@ -1241,7 +1250,7 @@ static int dmar_ir_add(struct dmar_drhd_unit *dmaru, struct intel_iommu *iommu) intel_teardown_irq_remapping(iommu); ir_remove_ioapic_hpet_scope(iommu); } else { - iommu_set_irq_remapping(iommu, eim); + iommu_enable_irq_remapping(iommu); } return ret; -- cgit v1.2.3 From af3b358e48115588d905cc07a47b3f356e0d01d1 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 15:00:21 +0200 Subject: iommu/vt-d: Copy IR table from old kernel when in kdump mode When we are booting into a kdump kernel and find IR enabled, copy over the contents of the previous IR table so that spurious interrupts will not be target aborted. Tested-by: ZhenHua Li Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 70 +++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'drivers/iommu/intel_irq_remapping.c') diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 84970281b754..2a901219f953 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -54,8 +55,28 @@ static struct hpet_scope ir_hpet[MAX_HPET_TBS]; */ static DEFINE_RAW_SPINLOCK(irq_2_ir_lock); +static void iommu_disable_irq_remapping(struct intel_iommu *iommu); static int __init parse_ioapics_under_ir(void); +static bool ir_pre_enabled(struct intel_iommu *iommu) +{ + return (iommu->flags & VTD_FLAG_IRQ_REMAP_PRE_ENABLED); +} + +static void clear_ir_pre_enabled(struct intel_iommu *iommu) +{ + iommu->flags &= ~VTD_FLAG_IRQ_REMAP_PRE_ENABLED; +} + +static void init_ir_status(struct intel_iommu *iommu) +{ + u32 gsts; + + gsts = readl(iommu->reg + DMAR_GSTS_REG); + if (gsts & DMA_GSTS_IRES) + iommu->flags |= VTD_FLAG_IRQ_REMAP_PRE_ENABLED; +} + static struct irq_2_iommu *irq_2_iommu(unsigned int irq) { struct irq_cfg *cfg = irq_cfg(irq); @@ -426,6 +447,44 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev) return 0; } +static int iommu_load_old_irte(struct intel_iommu *iommu) +{ + struct irte *old_ir_table; + phys_addr_t irt_phys; + size_t size; + u64 irta; + + if (!is_kdump_kernel()) { + pr_warn("IRQ remapping was enabled on %s but we are not in kdump mode\n", + iommu->name); + clear_ir_pre_enabled(iommu); + iommu_disable_irq_remapping(iommu); + return -EINVAL; + } + + /* Check whether the old ir-table has the same size as ours */ + irta = dmar_readq(iommu->reg + DMAR_IRTA_REG); + if ((irta & INTR_REMAP_TABLE_REG_SIZE_MASK) + != INTR_REMAP_TABLE_REG_SIZE) + return -EINVAL; + + irt_phys = irta & VTD_PAGE_MASK; + size = INTR_REMAP_TABLE_ENTRIES*sizeof(struct irte); + + /* Map the old IR table */ + old_ir_table = ioremap_cache(irt_phys, size); + if (!old_ir_table) + return -ENOMEM; + + /* Copy data over */ + memcpy(iommu->ir_table->base, old_ir_table, size); + + __iommu_flush_cache(iommu, iommu->ir_table->base, size); + + return 0; +} + + static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) { unsigned long flags; @@ -531,6 +590,17 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu) } } + init_ir_status(iommu); + + if (ir_pre_enabled(iommu)) { + if (iommu_load_old_irte(iommu)) + pr_err("Failed to copy IR table for %s from previous kernel\n", + iommu->name); + else + pr_info("Copied IR table for %s from previous kernel\n", + iommu->name); + } + iommu_set_irq_remapping(iommu, eim_mode); return 0; -- cgit v1.2.3 From 7c3c9876d98a76b97d16c0f46cb108e95542b212 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 15:06:26 +0200 Subject: iommu/vt-d: Make sure copied over IR entries are not reused Walk over the copied entries and mark the present ones as allocated. Tested-by: ZhenHua Li Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/iommu/intel_irq_remapping.c') diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 2a901219f953..14e10de4a548 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -451,6 +451,7 @@ static int iommu_load_old_irte(struct intel_iommu *iommu) { struct irte *old_ir_table; phys_addr_t irt_phys; + unsigned int i; size_t size; u64 irta; @@ -481,6 +482,15 @@ static int iommu_load_old_irte(struct intel_iommu *iommu) __iommu_flush_cache(iommu, iommu->ir_table->base, size); + /* + * Now check the table for used entries and mark those as + * allocated in the bitmap + */ + for (i = 0; i < INTR_REMAP_TABLE_ENTRIES; i++) { + if (iommu->ir_table->base[i].present) + bitmap_set(iommu->ir_table->bitmap, i, 1); + } + return 0; } -- cgit v1.2.3 From 571dbbd4d044e11c78bc077acb3ccef4c77b096e Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 15:15:34 +0200 Subject: iommu/vt-d: Don't disable IR when it was previously enabled Keep it enabled in kdump kernel to guarantee interrupt delivery. Tested-by: ZhenHua Li Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/iommu/intel_irq_remapping.c') diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 14e10de4a548..47fcebf39e9e 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -742,9 +742,6 @@ static int __init intel_prepare_irq_remapping(void) pr_info("%s does not support EIM\n", iommu->name); eim = 0; } - - /* Disable IRQ remapping if it is already enabled */ - iommu_disable_irq_remapping(iommu); } eim_mode = eim; @@ -777,7 +774,8 @@ static int __init intel_enable_irq_remapping(void) * Setup Interrupt-remapping for all the DRHD's now. */ for_each_iommu(iommu, drhd) { - iommu_enable_irq_remapping(iommu); + if (!ir_pre_enabled(iommu)) + iommu_enable_irq_remapping(iommu); setup = true; } -- cgit v1.2.3