[PATCH 16/17] iommu/vt-d: Copy old irte in intel_setup_irq_remapping

From: Joerg Roedel
Date: Fri Jun 05 2015 - 10:12:12 EST


From: Joerg Roedel <jroedel@xxxxxxx>

Copy over the old irq remapping table in the
intel_setup_irq_remapping function. The reason is that
intel_enable_irq_remapping runs with irqs disabled and thus
we can not safely call ioremap. Therefore we need to copy in
the prepare stage when irqs are still enabled.

Tested-by: Baoquan He <bhe@xxxxxxxxxx>
Signed-off-by: Joerg Roedel <jroedel@xxxxxxx>
---
drivers/iommu/intel_irq_remapping.c | 40 ++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index f7b02ca..07a8e82 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -24,6 +24,7 @@
static int iommu_load_old_irte(struct intel_iommu *iommu);
static int __iommu_update_old_irte(struct intel_iommu *iommu, int index);
static void iommu_check_pre_ir_status(struct intel_iommu *iommu);
+static void iommu_disable_irq_remapping(struct intel_iommu *iommu);

struct ioapic_scope {
struct intel_iommu *iommu;
@@ -538,6 +539,26 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu)
}
}

+ iommu_check_pre_ir_status(iommu);
+
+ if (!is_kdump_kernel() && iommu->pre_enabled_ir) {
+ iommu_disable_irq_remapping(iommu);
+ iommu->pre_enabled_ir = 0;
+ pr_warn("IRQ remapping was enabled on %s but we are not in kdump mode\n",
+ iommu->name);
+ }
+
+ if (iommu->pre_enabled_ir) {
+ 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;

out_free_pages:
@@ -682,28 +703,11 @@ static int __init intel_enable_irq_remapping(void)
struct intel_iommu *iommu;
bool setup = false;

- for_each_iommu(iommu, drhd) {
- iommu_check_pre_ir_status(iommu);
-
- if (!is_kdump_kernel() && iommu->pre_enabled_ir) {
- iommu_disable_irq_remapping(iommu);
- iommu->pre_enabled_ir = 0;
- pr_warn("IRQ remapping was enabled on %s but we are not in kdump mode\n",
- iommu->name);
- }
- }
-
/*
* Setup Interrupt-remapping for all the DRHD's now.
*/
for_each_iommu(iommu, drhd) {
- if (iommu->pre_enabled_ir) {
- iommu_load_old_irte(iommu);
- } else {
- iommu_set_irq_remapping(iommu, eim_mode);
- iommu_enable_irq_remapping(iommu);
- }
-
+ iommu_enable_irq_remapping(iommu);
setup = true;
}

--
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/