Commit 9bd008f1 authored by Yi Liu's avatar Yi Liu Committed by Joerg Roedel
Browse files

iommu/vt-d: Add a helper to flush cache for updating present pasid entry



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: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Signed-off-by: default avatarYi Liu <yi.l.liu@intel.com>
Link: https://lore.kernel.org/r/20241107122234.7424-3-yi.l.liu@intel.com


Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent b45a3777
Loading
Loading
Loading
Loading
+34 −18
Original line number Diff line number Diff line
@@ -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.
@@ -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);
}

/**