Commit 1531a6a6 authored by Suresh Siddha's avatar Suresh Siddha Committed by H. Peter Anvin

x86, dmar: start with sane state while enabling dma and interrupt-remapping

Impact: cleanup/sanitization

Start from a sane state while enabling dma and interrupt-remapping, by
clearing the previous recorded faults and disabling previously
enabled queued invalidation and interrupt-remapping.
Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent eba67e5d
...@@ -982,7 +982,7 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type, ...@@ -982,7 +982,7 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
} }
#define PRIMARY_FAULT_REG_LEN (16) #define PRIMARY_FAULT_REG_LEN (16)
static irqreturn_t dmar_fault(int irq, void *dev_id) irqreturn_t dmar_fault(int irq, void *dev_id)
{ {
struct intel_iommu *iommu = dev_id; struct intel_iommu *iommu = dev_id;
int reg, fault_index; int reg, fault_index;
...@@ -1074,9 +1074,6 @@ int dmar_set_interrupt(struct intel_iommu *iommu) ...@@ -1074,9 +1074,6 @@ int dmar_set_interrupt(struct intel_iommu *iommu)
return 0; return 0;
} }
/* Force fault register is cleared */
dmar_fault(irq, iommu);
ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu); ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu);
if (ret) if (ret)
printk(KERN_ERR "IOMMU: can't request irq\n"); printk(KERN_ERR "IOMMU: can't request irq\n");
......
...@@ -1855,11 +1855,40 @@ static int __init init_dmars(void) ...@@ -1855,11 +1855,40 @@ static int __init init_dmars(void)
} }
} }
/*
* Start from the sane iommu hardware state.
*/
for_each_drhd_unit(drhd) { for_each_drhd_unit(drhd) {
if (drhd->ignored) if (drhd->ignored)
continue; continue;
iommu = drhd->iommu; iommu = drhd->iommu;
/*
* If the queued invalidation is already initialized by us
* (for example, while enabling interrupt-remapping) then
* we got the things already rolling from a sane state.
*/
if (iommu->qi)
continue;
/*
* Clear any previous faults.
*/
dmar_fault(-1, iommu);
/*
* Disable queued invalidation if supported and already enabled
* before OS handover.
*/
dmar_disable_qi(iommu);
}
for_each_drhd_unit(drhd) {
if (drhd->ignored)
continue;
iommu = drhd->iommu;
if (dmar_enable_qi(iommu)) { if (dmar_enable_qi(iommu)) {
/* /*
* Queued Invalidate not enabled, use Register Based * Queued Invalidate not enabled, use Register Based
......
...@@ -499,6 +499,23 @@ int __init enable_intr_remapping(int eim) ...@@ -499,6 +499,23 @@ int __init enable_intr_remapping(int eim)
struct dmar_drhd_unit *drhd; struct dmar_drhd_unit *drhd;
int setup = 0; int setup = 0;
for_each_drhd_unit(drhd) {
struct intel_iommu *iommu = drhd->iommu;
/*
* Clear previous faults.
*/
dmar_fault(-1, iommu);
/*
* Disable intr remapping and queued invalidation, if already
* enabled prior to OS handover.
*/
disable_intr_remapping(iommu);
dmar_disable_qi(iommu);
}
/* /*
* check for the Interrupt-remapping support * check for the Interrupt-remapping support
*/ */
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/msi.h> #include <linux/msi.h>
#include <linux/irqreturn.h>
#if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
struct intel_iommu; struct intel_iommu;
...@@ -125,6 +126,7 @@ extern void dmar_msi_mask(unsigned int irq); ...@@ -125,6 +126,7 @@ extern void dmar_msi_mask(unsigned int irq);
extern void dmar_msi_read(int irq, struct msi_msg *msg); extern void dmar_msi_read(int irq, struct msi_msg *msg);
extern void dmar_msi_write(int irq, struct msi_msg *msg); extern void dmar_msi_write(int irq, struct msi_msg *msg);
extern int dmar_set_interrupt(struct intel_iommu *iommu); extern int dmar_set_interrupt(struct intel_iommu *iommu);
extern irqreturn_t dmar_fault(int irq, void *dev_id);
extern int arch_setup_dmar_msi(unsigned int irq); extern int arch_setup_dmar_msi(unsigned int irq);
#ifdef CONFIG_DMAR #ifdef CONFIG_DMAR
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment