@@ -2200,8 +2200,7 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
22002200 return arm_smmu_sva_domain_alloc ();
22012201
22022202 if (type != IOMMU_DOMAIN_UNMANAGED &&
2203- type != IOMMU_DOMAIN_DMA &&
2204- type != IOMMU_DOMAIN_IDENTITY )
2203+ type != IOMMU_DOMAIN_DMA )
22052204 return NULL ;
22062205
22072206 /*
@@ -2309,11 +2308,6 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
23092308 struct arm_smmu_domain * smmu_domain = to_smmu_domain (domain );
23102309 struct arm_smmu_device * smmu = smmu_domain -> smmu ;
23112310
2312- if (domain -> type == IOMMU_DOMAIN_IDENTITY ) {
2313- smmu_domain -> stage = ARM_SMMU_DOMAIN_BYPASS ;
2314- return 0 ;
2315- }
2316-
23172311 /* Restrict the stage to what we can actually support */
23182312 if (!(smmu -> features & ARM_SMMU_FEAT_TRANS_S1 ))
23192313 smmu_domain -> stage = ARM_SMMU_DOMAIN_S2 ;
@@ -2511,7 +2505,7 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
25112505 struct arm_smmu_domain * smmu_domain ;
25122506 unsigned long flags ;
25132507
2514- if (!domain )
2508+ if (!domain || !( domain -> type & __IOMMU_DOMAIN_PAGING ) )
25152509 return ;
25162510
25172511 smmu_domain = to_smmu_domain (domain );
@@ -2574,15 +2568,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
25742568
25752569 arm_smmu_detach_dev (master );
25762570
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 );
25862572
25872573 spin_lock_irqsave (& smmu_domain -> devices_lock , flags );
25882574 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)
26192605 arm_smmu_write_ctx_desc (master , IOMMU_NO_PASID ,
26202606 NULL );
26212607 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 ;
26292608 }
26302609
26312610 arm_smmu_enable_ats (master , smmu_domain );
@@ -2641,6 +2620,60 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
26412620 return ret ;
26422621}
26432622
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+
26442677static int arm_smmu_map_pages (struct iommu_domain * domain , unsigned long iova ,
26452678 phys_addr_t paddr , size_t pgsize , size_t pgcount ,
26462679 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)
30303063}
30313064
30323065static struct iommu_ops arm_smmu_ops = {
3066+ .identity_domain = & arm_smmu_identity_domain ,
30333067 .capable = arm_smmu_capable ,
30343068 .domain_alloc = arm_smmu_domain_alloc ,
30353069 .probe_device = arm_smmu_probe_device ,
0 commit comments