@@ -2013,8 +2013,8 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
2013
2013
return arm_smmu_cmdq_batch_submit (master -> smmu , & cmds );
2014
2014
}
2015
2015
2016
- int arm_smmu_atc_inv_domain (struct arm_smmu_domain * smmu_domain , int ssid ,
2017
- unsigned long iova , size_t size )
2016
+ static int __arm_smmu_atc_inv_domain (struct arm_smmu_domain * smmu_domain ,
2017
+ ioasid_t ssid , unsigned long iova , size_t size )
2018
2018
{
2019
2019
struct arm_smmu_master_domain * master_domain ;
2020
2020
int i ;
@@ -2042,8 +2042,6 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
2042
2042
if (!atomic_read (& smmu_domain -> nr_ats_masters ))
2043
2043
return 0 ;
2044
2044
2045
- arm_smmu_atc_inv_to_cmd (ssid , iova , size , & cmd );
2046
-
2047
2045
cmds .num = 0 ;
2048
2046
2049
2047
spin_lock_irqsave (& smmu_domain -> devices_lock , flags );
@@ -2054,6 +2052,16 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
2054
2052
if (!master -> ats_enabled )
2055
2053
continue ;
2056
2054
2055
+ /*
2056
+ * Non-zero ssid means SVA is co-opting the S1 domain to issue
2057
+ * invalidations for SVA PASIDs.
2058
+ */
2059
+ if (ssid != IOMMU_NO_PASID )
2060
+ arm_smmu_atc_inv_to_cmd (ssid , iova , size , & cmd );
2061
+ else
2062
+ arm_smmu_atc_inv_to_cmd (master_domain -> ssid , iova , size ,
2063
+ & cmd );
2064
+
2057
2065
for (i = 0 ; i < master -> num_streams ; i ++ ) {
2058
2066
cmd .atc .sid = master -> streams [i ].id ;
2059
2067
arm_smmu_cmdq_batch_add (smmu_domain -> smmu , & cmds , & cmd );
@@ -2064,6 +2072,19 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
2064
2072
return arm_smmu_cmdq_batch_submit (smmu_domain -> smmu , & cmds );
2065
2073
}
2066
2074
2075
+ static int arm_smmu_atc_inv_domain (struct arm_smmu_domain * smmu_domain ,
2076
+ unsigned long iova , size_t size )
2077
+ {
2078
+ return __arm_smmu_atc_inv_domain (smmu_domain , IOMMU_NO_PASID , iova ,
2079
+ size );
2080
+ }
2081
+
2082
+ int arm_smmu_atc_inv_domain_sva (struct arm_smmu_domain * smmu_domain ,
2083
+ ioasid_t ssid , unsigned long iova , size_t size )
2084
+ {
2085
+ return __arm_smmu_atc_inv_domain (smmu_domain , ssid , iova , size );
2086
+ }
2087
+
2067
2088
/* IO_PGTABLE API */
2068
2089
static void arm_smmu_tlb_inv_context (void * cookie )
2069
2090
{
@@ -2085,7 +2106,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
2085
2106
cmd .tlbi .vmid = smmu_domain -> s2_cfg .vmid ;
2086
2107
arm_smmu_cmdq_issue_cmd_with_sync (smmu , & cmd );
2087
2108
}
2088
- arm_smmu_atc_inv_domain (smmu_domain , IOMMU_NO_PASID , 0 , 0 );
2109
+ arm_smmu_atc_inv_domain (smmu_domain , 0 , 0 );
2089
2110
}
2090
2111
2091
2112
static void __arm_smmu_tlb_inv_range (struct arm_smmu_cmdq_ent * cmd ,
@@ -2183,7 +2204,7 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
2183
2204
* Unfortunately, this can't be leaf-only since we may have
2184
2205
* zapped an entire table.
2185
2206
*/
2186
- arm_smmu_atc_inv_domain (smmu_domain , IOMMU_NO_PASID , iova , size );
2207
+ arm_smmu_atc_inv_domain (smmu_domain , iova , size );
2187
2208
}
2188
2209
2189
2210
void arm_smmu_tlb_inv_range_asid (unsigned long iova , size_t size , int asid ,
@@ -2518,15 +2539,17 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
2518
2539
2519
2540
static struct arm_smmu_master_domain *
2520
2541
arm_smmu_find_master_domain (struct arm_smmu_domain * smmu_domain ,
2521
- struct arm_smmu_master * master )
2542
+ struct arm_smmu_master * master ,
2543
+ ioasid_t ssid )
2522
2544
{
2523
2545
struct arm_smmu_master_domain * master_domain ;
2524
2546
2525
2547
lockdep_assert_held (& smmu_domain -> devices_lock );
2526
2548
2527
2549
list_for_each_entry (master_domain , & smmu_domain -> devices ,
2528
2550
devices_elm ) {
2529
- if (master_domain -> master == master )
2551
+ if (master_domain -> master == master &&
2552
+ master_domain -> ssid == ssid )
2530
2553
return master_domain ;
2531
2554
}
2532
2555
return NULL ;
@@ -2559,7 +2582,8 @@ static void arm_smmu_remove_master_domain(struct arm_smmu_master *master,
2559
2582
return ;
2560
2583
2561
2584
spin_lock_irqsave (& smmu_domain -> devices_lock , flags );
2562
- master_domain = arm_smmu_find_master_domain (smmu_domain , master );
2585
+ master_domain = arm_smmu_find_master_domain (smmu_domain , master ,
2586
+ IOMMU_NO_PASID );
2563
2587
if (master_domain ) {
2564
2588
list_del (& master_domain -> devices_elm );
2565
2589
kfree (master_domain );
0 commit comments