Skip to content

Commit

Permalink
iommu/vt-d: Add a helper to flush cache for updating present pasid entry
Browse files Browse the repository at this point in the history
Generalize the logic for flushing pasid-related cache upon changes to
bits other than SSADE and P which requires a different flow according
to VT-d spec.

No functional change is intended.

Reviewed-by: Lu Baolu <[email protected]>
Reviewed-by: Kevin Tian <[email protected]>
Signed-off-by: Yi Liu <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lu Baolu <[email protected]>
Signed-off-by: Joerg Roedel <[email protected]>
  • Loading branch information
yiliu1765 authored and joergroedel committed Nov 8, 2024
1 parent b45a377 commit 9bd008f
Showing 1 changed file with 34 additions and 18 deletions.
52 changes: 34 additions & 18 deletions drivers/iommu/intel/pasid.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,39 @@ static void pasid_flush_caches(struct intel_iommu *iommu,
}
}

/*
* This function is supposed to be used after caller updates the fields
* except for the SSADE and P bit of a pasid table entry. It does the
* below:
* - Flush cacheline if needed
* - Flush the caches per Table 28 ”Guidance to Software for Invalidations“
* of VT-d spec 5.0.
*/
static void intel_pasid_flush_present(struct intel_iommu *iommu,
struct device *dev,
u32 pasid, u16 did,
struct pasid_entry *pte)
{
if (!ecap_coherent(iommu->ecap))
clflush_cache_range(pte, sizeof(*pte));

/*
* VT-d spec 5.0 table28 states guides for cache invalidation:
*
* - PASID-selective-within-Domain PASID-cache invalidation
* - PASID-selective PASID-based IOTLB invalidation
* - If (pasid is RID_PASID)
* - Global Device-TLB invalidation to affected functions
* Else
* - PASID-based Device-TLB invalidation (with S=1 and
* Addr[63:12]=0x7FFFFFFF_FFFFF) to affected functions
*/
pasid_cache_invalidation_with_pasid(iommu, did, pasid);
qi_flush_piotlb(iommu, did, pasid, 0, -1, 0);

devtlb_invalidation_with_pasid(iommu, dev, pasid);
}

/*
* Set up the scalable mode pasid table entry for first only
* translation type.
Expand Down Expand Up @@ -526,24 +559,7 @@ void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu,
did = pasid_get_domain_id(pte);
spin_unlock(&iommu->lock);

if (!ecap_coherent(iommu->ecap))
clflush_cache_range(pte, sizeof(*pte));

/*
* VT-d spec 3.4 table23 states guides for cache invalidation:
*
* - PASID-selective-within-Domain PASID-cache invalidation
* - PASID-selective PASID-based IOTLB invalidation
* - If (pasid is RID_PASID)
* - Global Device-TLB invalidation to affected functions
* Else
* - PASID-based Device-TLB invalidation (with S=1 and
* Addr[63:12]=0x7FFFFFFF_FFFFF) to affected functions
*/
pasid_cache_invalidation_with_pasid(iommu, did, pasid);
qi_flush_piotlb(iommu, did, pasid, 0, -1, 0);

devtlb_invalidation_with_pasid(iommu, dev, pasid);
intel_pasid_flush_present(iommu, dev, pasid, did, pte);
}

/**
Expand Down

0 comments on commit 9bd008f

Please sign in to comment.