@@ -2005,13 +2005,14 @@ arm_smmu_atc_inv_to_cmd(int ssid, unsigned long iova, size_t size,
2005
2005
cmd -> atc .size = log2_span ;
2006
2006
}
2007
2007
2008
- static int arm_smmu_atc_inv_master (struct arm_smmu_master * master )
2008
+ static int arm_smmu_atc_inv_master (struct arm_smmu_master * master ,
2009
+ ioasid_t ssid )
2009
2010
{
2010
2011
int i ;
2011
2012
struct arm_smmu_cmdq_ent cmd ;
2012
2013
struct arm_smmu_cmdq_batch cmds ;
2013
2014
2014
- arm_smmu_atc_inv_to_cmd (IOMMU_NO_PASID , 0 , 0 , & cmd );
2015
+ arm_smmu_atc_inv_to_cmd (ssid , 0 , 0 , & cmd );
2015
2016
2016
2017
cmds .num = 0 ;
2017
2018
for (i = 0 ; i < master -> num_streams ; i ++ ) {
@@ -2494,7 +2495,7 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
2494
2495
/*
2495
2496
* ATC invalidation of PASID 0 causes the entire ATC to be flushed.
2496
2497
*/
2497
- arm_smmu_atc_inv_master (master );
2498
+ arm_smmu_atc_inv_master (master , IOMMU_NO_PASID );
2498
2499
if (pci_enable_ats (pdev , stu ))
2499
2500
dev_err (master -> dev , "Failed to enable ATS (STU %zu)\n" , stu );
2500
2501
}
@@ -2581,7 +2582,8 @@ to_smmu_domain_devices(struct iommu_domain *domain)
2581
2582
}
2582
2583
2583
2584
static void arm_smmu_remove_master_domain (struct arm_smmu_master * master ,
2584
- struct iommu_domain * domain )
2585
+ struct iommu_domain * domain ,
2586
+ ioasid_t ssid )
2585
2587
{
2586
2588
struct arm_smmu_domain * smmu_domain = to_smmu_domain_devices (domain );
2587
2589
struct arm_smmu_master_domain * master_domain ;
@@ -2591,8 +2593,7 @@ static void arm_smmu_remove_master_domain(struct arm_smmu_master *master,
2591
2593
return ;
2592
2594
2593
2595
spin_lock_irqsave (& smmu_domain -> devices_lock , flags );
2594
- master_domain = arm_smmu_find_master_domain (smmu_domain , master ,
2595
- IOMMU_NO_PASID );
2596
+ master_domain = arm_smmu_find_master_domain (smmu_domain , master , ssid );
2596
2597
if (master_domain ) {
2597
2598
list_del (& master_domain -> devices_elm );
2598
2599
kfree (master_domain );
@@ -2606,6 +2607,7 @@ struct arm_smmu_attach_state {
2606
2607
/* Inputs */
2607
2608
struct iommu_domain * old_domain ;
2608
2609
struct arm_smmu_master * master ;
2610
+ ioasid_t ssid ;
2609
2611
/* Resulting state */
2610
2612
bool ats_enabled ;
2611
2613
};
@@ -2663,6 +2665,7 @@ static int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
2663
2665
if (!master_domain )
2664
2666
return - ENOMEM ;
2665
2667
master_domain -> master = master ;
2668
+ master_domain -> ssid = state -> ssid ;
2666
2669
2667
2670
/*
2668
2671
* During prepare we want the current smmu_domain and new
@@ -2710,17 +2713,20 @@ static void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
2710
2713
2711
2714
if (state -> ats_enabled && !master -> ats_enabled ) {
2712
2715
arm_smmu_enable_ats (master );
2713
- } else if (master -> ats_enabled ) {
2716
+ } else if (state -> ats_enabled && master -> ats_enabled ) {
2714
2717
/*
2715
2718
* The translation has changed, flush the ATC. At this point the
2716
2719
* SMMU is translating for the new domain and both the old&new
2717
2720
* domain will issue invalidations.
2718
2721
*/
2719
- arm_smmu_atc_inv_master (master );
2722
+ arm_smmu_atc_inv_master (master , state -> ssid );
2723
+ } else if (!state -> ats_enabled && master -> ats_enabled ) {
2724
+ /* ATS is being switched off, invalidate the entire ATC */
2725
+ arm_smmu_atc_inv_master (master , IOMMU_NO_PASID );
2720
2726
}
2721
2727
master -> ats_enabled = state -> ats_enabled ;
2722
2728
2723
- arm_smmu_remove_master_domain (master , state -> old_domain );
2729
+ arm_smmu_remove_master_domain (master , state -> old_domain , state -> ssid );
2724
2730
}
2725
2731
2726
2732
static int arm_smmu_attach_dev (struct iommu_domain * domain , struct device * dev )
@@ -2732,6 +2738,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
2732
2738
struct arm_smmu_domain * smmu_domain = to_smmu_domain (domain );
2733
2739
struct arm_smmu_attach_state state = {
2734
2740
.old_domain = iommu_get_domain_for_dev (dev ),
2741
+ .ssid = IOMMU_NO_PASID ,
2735
2742
};
2736
2743
struct arm_smmu_master * master ;
2737
2744
struct arm_smmu_cd * cdptr ;
@@ -2829,6 +2836,7 @@ static int arm_smmu_attach_dev_ste(struct iommu_domain *domain,
2829
2836
struct arm_smmu_attach_state state = {
2830
2837
.master = master ,
2831
2838
.old_domain = iommu_get_domain_for_dev (dev ),
2839
+ .ssid = IOMMU_NO_PASID ,
2832
2840
};
2833
2841
2834
2842
if (arm_smmu_ssids_in_use (& master -> cd_table ))
0 commit comments