Intel IOMMU Suspend/Resume Support - Interrupt Remapping
This patch enables suspend/resume for interrupt remapping. During suspend, interrupt remapping is disabled. When resume, interrupt remapping is enabled again. Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
committed by
David Woodhouse
parent
eb4a52bc66
commit
b24696bc55
@@ -470,7 +470,7 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
|
||||
/*
|
||||
* Disable Interrupt Remapping.
|
||||
*/
|
||||
static void disable_intr_remapping(struct intel_iommu *iommu)
|
||||
static void iommu_disable_intr_remapping(struct intel_iommu *iommu)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 sts;
|
||||
@@ -478,6 +478,12 @@ static void disable_intr_remapping(struct intel_iommu *iommu)
|
||||
if (!ecap_ir_support(iommu->ecap))
|
||||
return;
|
||||
|
||||
/*
|
||||
* global invalidation of interrupt entry cache before disabling
|
||||
* interrupt-remapping.
|
||||
*/
|
||||
qi_global_iec(iommu);
|
||||
|
||||
spin_lock_irqsave(&iommu->register_lock, flags);
|
||||
|
||||
sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
|
||||
@@ -511,7 +517,7 @@ int __init enable_intr_remapping(int eim)
|
||||
* Disable intr remapping and queued invalidation, if already
|
||||
* enabled prior to OS handover.
|
||||
*/
|
||||
disable_intr_remapping(iommu);
|
||||
iommu_disable_intr_remapping(iommu);
|
||||
|
||||
dmar_disable_qi(iommu);
|
||||
}
|
||||
@@ -639,3 +645,54 @@ int __init parse_ioapics_under_ir(void)
|
||||
|
||||
return ir_supported;
|
||||
}
|
||||
|
||||
void disable_intr_remapping(void)
|
||||
{
|
||||
struct dmar_drhd_unit *drhd;
|
||||
struct intel_iommu *iommu = NULL;
|
||||
|
||||
/*
|
||||
* Disable Interrupt-remapping for all the DRHD's now.
|
||||
*/
|
||||
for_each_iommu(iommu, drhd) {
|
||||
if (!ecap_ir_support(iommu->ecap))
|
||||
continue;
|
||||
|
||||
iommu_disable_intr_remapping(iommu);
|
||||
}
|
||||
}
|
||||
|
||||
int reenable_intr_remapping(int eim)
|
||||
{
|
||||
struct dmar_drhd_unit *drhd;
|
||||
int setup = 0;
|
||||
struct intel_iommu *iommu = NULL;
|
||||
|
||||
for_each_iommu(iommu, drhd)
|
||||
if (iommu->qi)
|
||||
dmar_reenable_qi(iommu);
|
||||
|
||||
/*
|
||||
* Setup Interrupt-remapping for all the DRHD's now.
|
||||
*/
|
||||
for_each_iommu(iommu, drhd) {
|
||||
if (!ecap_ir_support(iommu->ecap))
|
||||
continue;
|
||||
|
||||
/* Set up interrupt remapping for iommu.*/
|
||||
iommu_set_intr_remapping(iommu, eim);
|
||||
setup = 1;
|
||||
}
|
||||
|
||||
if (!setup)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
/*
|
||||
* handle error condition gracefully here!
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user