@@ -347,7 +347,7 @@ static struct iommu_dev_data *alloc_dev_data(struct amd_iommu *iommu, u16 devid)
347347 return dev_data ;
348348}
349349
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 )
351351{
352352 struct iommu_dev_data * dev_data ;
353353 struct llist_node * node ;
@@ -2845,12 +2845,12 @@ static int amd_iommu_set_dirty_tracking(struct iommu_domain *domain,
28452845 bool enable )
28462846{
28472847 struct protection_domain * pdomain = to_pdomain (domain );
2848- struct dev_table_entry * dev_table ;
2848+ struct dev_table_entry * dte ;
28492849 struct iommu_dev_data * dev_data ;
28502850 bool domain_flush = false;
28512851 struct amd_iommu * iommu ;
28522852 unsigned long flags ;
2853- u64 pte_root ;
2853+ u64 new ;
28542854
28552855 spin_lock_irqsave (& pdomain -> lock , flags );
28562856 if (!(pdomain -> dirty_tracking ^ enable )) {
@@ -2859,16 +2859,15 @@ static int amd_iommu_set_dirty_tracking(struct iommu_domain *domain,
28592859 }
28602860
28612861 list_for_each_entry (dev_data , & pdomain -> dev_list , list ) {
2862+ spin_lock (& dev_data -> dte_lock );
28622863 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 );
28692869
28702870 /* Flush device DTE */
2871- dev_table [dev_data -> devid ].data [0 ] = pte_root ;
28722871 device_flush_dte (dev_data );
28732872 domain_flush = true;
28742873 }
@@ -3135,17 +3134,23 @@ static void iommu_flush_irt_and_complete(struct amd_iommu *iommu, u16 devid)
31353134static void set_dte_irq_entry (struct amd_iommu * iommu , u16 devid ,
31363135 struct irq_remap_table * table )
31373136{
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 );
31403143
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 );
31473151
3148- dev_table [devid ].data [2 ] = dte ;
3152+ if (dev_data )
3153+ spin_unlock (& dev_data -> dte_lock );
31493154}
31503155
31513156static struct irq_remap_table * get_irq_table (struct amd_iommu * iommu , u16 devid )
0 commit comments