@@ -2200,8 +2200,7 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
2200
2200
return arm_smmu_sva_domain_alloc ();
2201
2201
2202
2202
if (type != IOMMU_DOMAIN_UNMANAGED &&
2203
- type != IOMMU_DOMAIN_DMA &&
2204
- type != IOMMU_DOMAIN_IDENTITY )
2203
+ type != IOMMU_DOMAIN_DMA )
2205
2204
return NULL ;
2206
2205
2207
2206
/*
@@ -2309,11 +2308,6 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
2309
2308
struct arm_smmu_domain * smmu_domain = to_smmu_domain (domain );
2310
2309
struct arm_smmu_device * smmu = smmu_domain -> smmu ;
2311
2310
2312
- if (domain -> type == IOMMU_DOMAIN_IDENTITY ) {
2313
- smmu_domain -> stage = ARM_SMMU_DOMAIN_BYPASS ;
2314
- return 0 ;
2315
- }
2316
-
2317
2311
/* Restrict the stage to what we can actually support */
2318
2312
if (!(smmu -> features & ARM_SMMU_FEAT_TRANS_S1 ))
2319
2313
smmu_domain -> stage = ARM_SMMU_DOMAIN_S2 ;
@@ -2511,7 +2505,7 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
2511
2505
struct arm_smmu_domain * smmu_domain ;
2512
2506
unsigned long flags ;
2513
2507
2514
- if (!domain )
2508
+ if (!domain || !( domain -> type & __IOMMU_DOMAIN_PAGING ) )
2515
2509
return ;
2516
2510
2517
2511
smmu_domain = to_smmu_domain (domain );
@@ -2574,15 +2568,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
2574
2568
2575
2569
arm_smmu_detach_dev (master );
2576
2570
2577
- /*
2578
- * The SMMU does not support enabling ATS with bypass. When the STE is
2579
- * in bypass (STE.Config[2:0] == 0b100), ATS Translation Requests and
2580
- * Translated transactions are denied as though ATS is disabled for the
2581
- * stream (STE.EATS == 0b00), causing F_BAD_ATS_TREQ and
2582
- * F_TRANSL_FORBIDDEN events (IHI0070Ea 5.2 Stream Table Entry).
2583
- */
2584
- if (smmu_domain -> stage != ARM_SMMU_DOMAIN_BYPASS )
2585
- master -> ats_enabled = arm_smmu_ats_supported (master );
2571
+ master -> ats_enabled = arm_smmu_ats_supported (master );
2586
2572
2587
2573
spin_lock_irqsave (& smmu_domain -> devices_lock , flags );
2588
2574
list_add (& master -> domain_head , & smmu_domain -> devices );
@@ -2619,13 +2605,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
2619
2605
arm_smmu_write_ctx_desc (master , IOMMU_NO_PASID ,
2620
2606
NULL );
2621
2607
break ;
2622
- case ARM_SMMU_DOMAIN_BYPASS :
2623
- arm_smmu_make_bypass_ste (& target );
2624
- arm_smmu_install_ste_for_dev (master , & target );
2625
- if (master -> cd_table .cdtab )
2626
- arm_smmu_write_ctx_desc (master , IOMMU_NO_PASID ,
2627
- NULL );
2628
- break ;
2629
2608
}
2630
2609
2631
2610
arm_smmu_enable_ats (master , smmu_domain );
@@ -2641,6 +2620,60 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
2641
2620
return ret ;
2642
2621
}
2643
2622
2623
+ static int arm_smmu_attach_dev_ste (struct device * dev ,
2624
+ struct arm_smmu_ste * ste )
2625
+ {
2626
+ struct arm_smmu_master * master = dev_iommu_priv_get (dev );
2627
+
2628
+ if (arm_smmu_master_sva_enabled (master ))
2629
+ return - EBUSY ;
2630
+
2631
+ /*
2632
+ * Do not allow any ASID to be changed while are working on the STE,
2633
+ * otherwise we could miss invalidations.
2634
+ */
2635
+ mutex_lock (& arm_smmu_asid_lock );
2636
+
2637
+ /*
2638
+ * The SMMU does not support enabling ATS with bypass/abort. When the
2639
+ * STE is in bypass (STE.Config[2:0] == 0b100), ATS Translation Requests
2640
+ * and Translated transactions are denied as though ATS is disabled for
2641
+ * the stream (STE.EATS == 0b00), causing F_BAD_ATS_TREQ and
2642
+ * F_TRANSL_FORBIDDEN events (IHI0070Ea 5.2 Stream Table Entry).
2643
+ */
2644
+ arm_smmu_detach_dev (master );
2645
+
2646
+ arm_smmu_install_ste_for_dev (master , ste );
2647
+ mutex_unlock (& arm_smmu_asid_lock );
2648
+
2649
+ /*
2650
+ * This has to be done after removing the master from the
2651
+ * arm_smmu_domain->devices to avoid races updating the same context
2652
+ * descriptor from arm_smmu_share_asid().
2653
+ */
2654
+ if (master -> cd_table .cdtab )
2655
+ arm_smmu_write_ctx_desc (master , IOMMU_NO_PASID , NULL );
2656
+ return 0 ;
2657
+ }
2658
+
2659
+ static int arm_smmu_attach_dev_identity (struct iommu_domain * domain ,
2660
+ struct device * dev )
2661
+ {
2662
+ struct arm_smmu_ste ste ;
2663
+
2664
+ arm_smmu_make_bypass_ste (& ste );
2665
+ return arm_smmu_attach_dev_ste (dev , & ste );
2666
+ }
2667
+
2668
+ static const struct iommu_domain_ops arm_smmu_identity_ops = {
2669
+ .attach_dev = arm_smmu_attach_dev_identity ,
2670
+ };
2671
+
2672
+ static struct iommu_domain arm_smmu_identity_domain = {
2673
+ .type = IOMMU_DOMAIN_IDENTITY ,
2674
+ .ops = & arm_smmu_identity_ops ,
2675
+ };
2676
+
2644
2677
static int arm_smmu_map_pages (struct iommu_domain * domain , unsigned long iova ,
2645
2678
phys_addr_t paddr , size_t pgsize , size_t pgcount ,
2646
2679
int prot , gfp_t gfp , size_t * mapped )
@@ -3030,6 +3063,7 @@ static void arm_smmu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
3030
3063
}
3031
3064
3032
3065
static struct iommu_ops arm_smmu_ops = {
3066
+ .identity_domain = & arm_smmu_identity_domain ,
3033
3067
.capable = arm_smmu_capable ,
3034
3068
.domain_alloc = arm_smmu_domain_alloc ,
3035
3069
.probe_device = arm_smmu_probe_device ,
0 commit comments