@@ -347,7 +347,7 @@ static struct iommu_dev_data *alloc_dev_data(struct amd_iommu *iommu, u16 devid)
347
347
return dev_data ;
348
348
}
349
349
350
- static struct iommu_dev_data * search_dev_data (struct amd_iommu * iommu , u16 devid )
350
+ struct iommu_dev_data * search_dev_data (struct amd_iommu * iommu , u16 devid )
351
351
{
352
352
struct iommu_dev_data * dev_data ;
353
353
struct llist_node * node ;
@@ -2845,12 +2845,12 @@ static int amd_iommu_set_dirty_tracking(struct iommu_domain *domain,
2845
2845
bool enable )
2846
2846
{
2847
2847
struct protection_domain * pdomain = to_pdomain (domain );
2848
- struct dev_table_entry * dev_table ;
2848
+ struct dev_table_entry * dte ;
2849
2849
struct iommu_dev_data * dev_data ;
2850
2850
bool domain_flush = false;
2851
2851
struct amd_iommu * iommu ;
2852
2852
unsigned long flags ;
2853
- u64 pte_root ;
2853
+ u64 new ;
2854
2854
2855
2855
spin_lock_irqsave (& pdomain -> lock , flags );
2856
2856
if (!(pdomain -> dirty_tracking ^ enable )) {
@@ -2859,16 +2859,15 @@ static int amd_iommu_set_dirty_tracking(struct iommu_domain *domain,
2859
2859
}
2860
2860
2861
2861
list_for_each_entry (dev_data , & pdomain -> dev_list , list ) {
2862
+ spin_lock (& dev_data -> dte_lock );
2862
2863
iommu = get_amd_iommu_from_dev_data (dev_data );
2863
-
2864
- dev_table = get_dev_table (iommu );
2865
- pte_root = dev_table [dev_data -> devid ].data [0 ];
2866
-
2867
- pte_root = (enable ? pte_root | DTE_FLAG_HAD :
2868
- pte_root & ~DTE_FLAG_HAD );
2864
+ dte = & get_dev_table (iommu )[dev_data -> devid ];
2865
+ new = dte -> data [0 ];
2866
+ new = (enable ? new | DTE_FLAG_HAD : new & ~DTE_FLAG_HAD );
2867
+ dte -> data [0 ] = new ;
2868
+ spin_unlock (& dev_data -> dte_lock );
2869
2869
2870
2870
/* Flush device DTE */
2871
- dev_table [dev_data -> devid ].data [0 ] = pte_root ;
2872
2871
device_flush_dte (dev_data );
2873
2872
domain_flush = true;
2874
2873
}
@@ -3135,17 +3134,23 @@ static void iommu_flush_irt_and_complete(struct amd_iommu *iommu, u16 devid)
3135
3134
static void set_dte_irq_entry (struct amd_iommu * iommu , u16 devid ,
3136
3135
struct irq_remap_table * table )
3137
3136
{
3138
- u64 dte ;
3139
- struct dev_table_entry * dev_table = get_dev_table (iommu );
3137
+ u64 new ;
3138
+ struct dev_table_entry * dte = & get_dev_table (iommu )[devid ];
3139
+ struct iommu_dev_data * dev_data = search_dev_data (iommu , devid );
3140
+
3141
+ if (dev_data )
3142
+ spin_lock (& dev_data -> dte_lock );
3140
3143
3141
- dte = dev_table [devid ].data [2 ];
3142
- dte &= ~DTE_IRQ_PHYS_ADDR_MASK ;
3143
- dte |= iommu_virt_to_phys (table -> table );
3144
- dte |= DTE_IRQ_REMAP_INTCTL ;
3145
- dte |= DTE_INTTABLEN ;
3146
- dte |= DTE_IRQ_REMAP_ENABLE ;
3144
+ new = READ_ONCE (dte -> data [2 ]);
3145
+ new &= ~DTE_IRQ_PHYS_ADDR_MASK ;
3146
+ new |= iommu_virt_to_phys (table -> table );
3147
+ new |= DTE_IRQ_REMAP_INTCTL ;
3148
+ new |= DTE_INTTABLEN ;
3149
+ new |= DTE_IRQ_REMAP_ENABLE ;
3150
+ WRITE_ONCE (dte -> data [2 ], new );
3147
3151
3148
- dev_table [devid ].data [2 ] = dte ;
3152
+ if (dev_data )
3153
+ spin_unlock (& dev_data -> dte_lock );
3149
3154
}
3150
3155
3151
3156
static struct irq_remap_table * get_irq_table (struct amd_iommu * iommu , u16 devid )
0 commit comments