@@ -2293,6 +2293,8 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
2293
2293
case IOMMU_CAP_CACHE_COHERENCY :
2294
2294
/* Assume that a coherent TCU implies coherent TBUs */
2295
2295
return master -> smmu -> features & ARM_SMMU_FEAT_COHERENCY ;
2296
+ case IOMMU_CAP_ENFORCE_CACHE_COHERENCY :
2297
+ return arm_smmu_master_canwbs (master );
2296
2298
case IOMMU_CAP_NOEXEC :
2297
2299
case IOMMU_CAP_DEFERRED_FLUSH :
2298
2300
return true;
@@ -2303,6 +2305,26 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
2303
2305
}
2304
2306
}
2305
2307
2308
+ static bool arm_smmu_enforce_cache_coherency (struct iommu_domain * domain )
2309
+ {
2310
+ struct arm_smmu_domain * smmu_domain = to_smmu_domain (domain );
2311
+ struct arm_smmu_master_domain * master_domain ;
2312
+ unsigned long flags ;
2313
+ bool ret = true;
2314
+
2315
+ spin_lock_irqsave (& smmu_domain -> devices_lock , flags );
2316
+ list_for_each_entry (master_domain , & smmu_domain -> devices ,
2317
+ devices_elm ) {
2318
+ if (!arm_smmu_master_canwbs (master_domain -> master )) {
2319
+ ret = false;
2320
+ break ;
2321
+ }
2322
+ }
2323
+ smmu_domain -> enforce_cache_coherency = ret ;
2324
+ spin_unlock_irqrestore (& smmu_domain -> devices_lock , flags );
2325
+ return ret ;
2326
+ }
2327
+
2306
2328
struct arm_smmu_domain * arm_smmu_domain_alloc (void )
2307
2329
{
2308
2330
struct arm_smmu_domain * smmu_domain ;
@@ -2731,6 +2753,14 @@ static int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
2731
2753
* one of them.
2732
2754
*/
2733
2755
spin_lock_irqsave (& smmu_domain -> devices_lock , flags );
2756
+ if (smmu_domain -> enforce_cache_coherency &&
2757
+ !arm_smmu_master_canwbs (master )) {
2758
+ spin_unlock_irqrestore (& smmu_domain -> devices_lock ,
2759
+ flags );
2760
+ kfree (master_domain );
2761
+ return - EINVAL ;
2762
+ }
2763
+
2734
2764
if (state -> ats_enabled )
2735
2765
atomic_inc (& smmu_domain -> nr_ats_masters );
2736
2766
list_add (& master_domain -> devices_elm , & smmu_domain -> devices );
@@ -3493,6 +3523,7 @@ static struct iommu_ops arm_smmu_ops = {
3493
3523
.owner = THIS_MODULE ,
3494
3524
.default_domain_ops = & (const struct iommu_domain_ops ) {
3495
3525
.attach_dev = arm_smmu_attach_dev ,
3526
+ .enforce_cache_coherency = arm_smmu_enforce_cache_coherency ,
3496
3527
.set_dev_pasid = arm_smmu_s1_set_dev_pasid ,
3497
3528
.map_pages = arm_smmu_map_pages ,
3498
3529
.unmap_pages = arm_smmu_unmap_pages ,
0 commit comments