Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 138784
b: refs/heads/master
c: eba67e5
h: refs/heads/master
v: v3
  • Loading branch information
Suresh Siddha authored and H. Peter Anvin committed Mar 17, 2009
1 parent d3e0bee commit a7eb87c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9d783ba042771284fb4ee5013c3d94220755ae7f
refs/heads/master: eba67e5da6e971993b2899d2cdf459ce77d3dbc5
36 changes: 36 additions & 0 deletions trunk/drivers/pci/dmar.c
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,42 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
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
* interrupt-remapping. Also used by DMA-remapping, which replaces
Expand Down
27 changes: 27 additions & 0 deletions trunk/drivers/pci/intr_remapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,33 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
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)
{
struct dmar_drhd_unit *drhd;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/intel-iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 void free_iommu(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 int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
Expand Down

0 comments on commit a7eb87c

Please sign in to comment.