x86, dmar: routines for disabling queued invalidation and intr remapping
Impact: new interfaces (not yet used) Routines for disabling queued invalidation and interrupt remapping. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
parent
9d783ba042
commit
eba67e5da6
@ -753,6 +753,42 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
|
|||||||
return qi_submit_sync(&desc, iommu);
|
return qi_submit_sync(&desc, iommu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable Queued Invalidation interface.
|
||||||
|
*/
|
||||||
|
void dmar_disable_qi(struct intel_iommu *iommu)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
u32 sts;
|
||||||
|
cycles_t start_time = get_cycles();
|
||||||
|
|
||||||
|
if (!ecap_qis(iommu->ecap))
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&iommu->register_lock, flags);
|
||||||
|
|
||||||
|
sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
|
||||||
|
if (!(sts & DMA_GSTS_QIES))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Give a chance to HW to complete the pending invalidation requests.
|
||||||
|
*/
|
||||||
|
while ((readl(iommu->reg + DMAR_IQT_REG) !=
|
||||||
|
readl(iommu->reg + DMAR_IQH_REG)) &&
|
||||||
|
(DMAR_OPERATION_TIMEOUT > (get_cycles() - start_time)))
|
||||||
|
cpu_relax();
|
||||||
|
|
||||||
|
iommu->gcmd &= ~DMA_GCMD_QIE;
|
||||||
|
|
||||||
|
writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
|
||||||
|
|
||||||
|
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl,
|
||||||
|
!(sts & DMA_GSTS_QIES), sts);
|
||||||
|
end:
|
||||||
|
spin_unlock_irqrestore(&iommu->register_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable Queued Invalidation interface. This is a must to support
|
* Enable Queued Invalidation interface. This is a must to support
|
||||||
* interrupt-remapping. Also used by DMA-remapping, which replaces
|
* interrupt-remapping. Also used by DMA-remapping, which replaces
|
||||||
|
@ -467,6 +467,33 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable Interrupt Remapping.
|
||||||
|
*/
|
||||||
|
static void disable_intr_remapping(struct intel_iommu *iommu)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
u32 sts;
|
||||||
|
|
||||||
|
if (!ecap_ir_support(iommu->ecap))
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&iommu->register_lock, flags);
|
||||||
|
|
||||||
|
sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
|
||||||
|
if (!(sts & DMA_GSTS_IRES))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
iommu->gcmd &= ~DMA_GCMD_IRE;
|
||||||
|
writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
|
||||||
|
|
||||||
|
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
|
||||||
|
readl, !(sts & DMA_GSTS_IRES), sts);
|
||||||
|
|
||||||
|
end:
|
||||||
|
spin_unlock_irqrestore(&iommu->register_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
int __init enable_intr_remapping(int eim)
|
int __init enable_intr_remapping(int eim)
|
||||||
{
|
{
|
||||||
struct dmar_drhd_unit *drhd;
|
struct dmar_drhd_unit *drhd;
|
||||||
|
@ -321,6 +321,7 @@ extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);
|
|||||||
extern int alloc_iommu(struct dmar_drhd_unit *drhd);
|
extern int alloc_iommu(struct dmar_drhd_unit *drhd);
|
||||||
extern void free_iommu(struct intel_iommu *iommu);
|
extern void free_iommu(struct intel_iommu *iommu);
|
||||||
extern int dmar_enable_qi(struct intel_iommu *iommu);
|
extern int dmar_enable_qi(struct intel_iommu *iommu);
|
||||||
|
extern void dmar_disable_qi(struct intel_iommu *iommu);
|
||||||
extern void qi_global_iec(struct intel_iommu *iommu);
|
extern void qi_global_iec(struct intel_iommu *iommu);
|
||||||
|
|
||||||
extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
|
extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
|
||||||
|
Loading…
Reference in New Issue
Block a user