|
@@ -974,20 +974,6 @@ static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static void clear_context_table(struct intel_iommu *iommu, u8 bus, u8 devfn)
|
|
|
-{
|
|
|
- struct context_entry *context;
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
- spin_lock_irqsave(&iommu->lock, flags);
|
|
|
- context = iommu_context_addr(iommu, bus, devfn, 0);
|
|
|
- if (context) {
|
|
|
- context_clear_entry(context);
|
|
|
- __iommu_flush_cache(iommu, context, sizeof(*context));
|
|
|
- }
|
|
|
- spin_unlock_irqrestore(&iommu->lock, flags);
|
|
|
-}
|
|
|
-
|
|
|
static void free_context_table(struct intel_iommu *iommu)
|
|
|
{
|
|
|
int i;
|
|
@@ -2361,13 +2347,33 @@ static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long i
|
|
|
|
|
|
static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
|
|
|
{
|
|
|
+ unsigned long flags;
|
|
|
+ struct context_entry *context;
|
|
|
+ u16 did_old;
|
|
|
+
|
|
|
if (!iommu)
|
|
|
return;
|
|
|
|
|
|
- clear_context_table(iommu, bus, devfn);
|
|
|
- iommu->flush.flush_context(iommu, 0, 0, 0,
|
|
|
- DMA_CCMD_GLOBAL_INVL);
|
|
|
- iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
|
|
|
+ spin_lock_irqsave(&iommu->lock, flags);
|
|
|
+ context = iommu_context_addr(iommu, bus, devfn, 0);
|
|
|
+ if (!context) {
|
|
|
+ spin_unlock_irqrestore(&iommu->lock, flags);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ did_old = context_domain_id(context);
|
|
|
+ context_clear_entry(context);
|
|
|
+ __iommu_flush_cache(iommu, context, sizeof(*context));
|
|
|
+ spin_unlock_irqrestore(&iommu->lock, flags);
|
|
|
+ iommu->flush.flush_context(iommu,
|
|
|
+ did_old,
|
|
|
+ (((u16)bus) << 8) | devfn,
|
|
|
+ DMA_CCMD_MASK_NOBIT,
|
|
|
+ DMA_CCMD_DEVICE_INVL);
|
|
|
+ iommu->flush.flush_iotlb(iommu,
|
|
|
+ did_old,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ DMA_TLB_DSI_FLUSH);
|
|
|
}
|
|
|
|
|
|
static inline void unlink_domain_info(struct device_domain_info *info)
|