@@ -260,42 +260,66 @@ static void s390_iommu_iotlb_sync_map(struct iommu_domain *domain,
260260 rcu_read_unlock ();
261261}
262262
263- static int s390_iommu_update_trans (struct s390_domain * s390_domain ,
264- phys_addr_t pa , dma_addr_t dma_addr ,
265- unsigned long nr_pages , int flags )
263+ static int s390_iommu_validate_trans (struct s390_domain * s390_domain ,
264+ phys_addr_t pa , dma_addr_t dma_addr ,
265+ unsigned long nr_pages , int flags )
266266{
267267 phys_addr_t page_addr = pa & PAGE_MASK ;
268268 unsigned long irq_flags , i ;
269269 unsigned long * entry ;
270- int rc = 0 ;
270+ int rc ;
271271
272272 if (!nr_pages )
273273 return 0 ;
274274
275275 spin_lock_irqsave (& s390_domain -> dma_table_lock , irq_flags );
276276 for (i = 0 ; i < nr_pages ; i ++ ) {
277277 entry = dma_walk_cpu_trans (s390_domain -> dma_table , dma_addr );
278- if (!entry ) {
278+ if (unlikely ( !entry ) ) {
279279 rc = - ENOMEM ;
280280 goto undo_cpu_trans ;
281281 }
282282 dma_update_cpu_trans (entry , page_addr , flags );
283283 page_addr += PAGE_SIZE ;
284284 dma_addr += PAGE_SIZE ;
285285 }
286+ spin_unlock_irqrestore (& s390_domain -> dma_table_lock , irq_flags );
287+
288+ return 0 ;
286289
287290undo_cpu_trans :
288- if (rc && ((flags & ZPCI_PTE_VALID_MASK ) == ZPCI_PTE_VALID )) {
289- flags = ZPCI_PTE_INVALID ;
290- while (i -- > 0 ) {
291- page_addr -= PAGE_SIZE ;
292- dma_addr -= PAGE_SIZE ;
293- entry = dma_walk_cpu_trans (s390_domain -> dma_table ,
294- dma_addr );
295- if (!entry )
296- break ;
297- dma_update_cpu_trans (entry , page_addr , flags );
291+ while (i -- > 0 ) {
292+ dma_addr -= PAGE_SIZE ;
293+ entry = dma_walk_cpu_trans (s390_domain -> dma_table ,
294+ dma_addr );
295+ if (!entry )
296+ break ;
297+ dma_update_cpu_trans (entry , 0 , ZPCI_PTE_INVALID );
298+ }
299+ spin_unlock_irqrestore (& s390_domain -> dma_table_lock , irq_flags );
300+
301+ return rc ;
302+ }
303+
304+ static int s390_iommu_invalidate_trans (struct s390_domain * s390_domain ,
305+ dma_addr_t dma_addr , unsigned long nr_pages )
306+ {
307+ unsigned long irq_flags , i ;
308+ unsigned long * entry ;
309+ int rc = 0 ;
310+
311+ if (!nr_pages )
312+ return 0 ;
313+
314+ spin_lock_irqsave (& s390_domain -> dma_table_lock , irq_flags );
315+ for (i = 0 ; i < nr_pages ; i ++ ) {
316+ entry = dma_walk_cpu_trans (s390_domain -> dma_table , dma_addr );
317+ if (unlikely (!entry )) {
318+ rc = - EINVAL ;
319+ break ;
298320 }
321+ dma_update_cpu_trans (entry , 0 , ZPCI_PTE_INVALID );
322+ dma_addr += PAGE_SIZE ;
299323 }
300324 spin_unlock_irqrestore (& s390_domain -> dma_table_lock , irq_flags );
301325
@@ -308,8 +332,8 @@ static int s390_iommu_map_pages(struct iommu_domain *domain,
308332 int prot , gfp_t gfp , size_t * mapped )
309333{
310334 struct s390_domain * s390_domain = to_s390_domain (domain );
311- int flags = ZPCI_PTE_VALID , rc = 0 ;
312335 size_t size = pgcount << __ffs (pgsize );
336+ int flags = ZPCI_PTE_VALID , rc = 0 ;
313337
314338 if (pgsize != SZ_4K )
315339 return - EINVAL ;
@@ -327,8 +351,8 @@ static int s390_iommu_map_pages(struct iommu_domain *domain,
327351 if (!(prot & IOMMU_WRITE ))
328352 flags |= ZPCI_TABLE_PROTECTED ;
329353
330- rc = s390_iommu_update_trans (s390_domain , paddr , iova ,
331- pgcount , flags );
354+ rc = s390_iommu_validate_trans (s390_domain , paddr , iova ,
355+ pgcount , flags );
332356 if (!rc )
333357 * mapped = size ;
334358
@@ -373,20 +397,13 @@ static size_t s390_iommu_unmap_pages(struct iommu_domain *domain,
373397{
374398 struct s390_domain * s390_domain = to_s390_domain (domain );
375399 size_t size = pgcount << __ffs (pgsize );
376- int flags = ZPCI_PTE_INVALID ;
377- phys_addr_t paddr ;
378400 int rc ;
379401
380402 if (WARN_ON (iova < s390_domain -> domain .geometry .aperture_start ||
381403 (iova + size - 1 ) > s390_domain -> domain .geometry .aperture_end ))
382404 return 0 ;
383405
384- paddr = s390_iommu_iova_to_phys (domain , iova );
385- if (!paddr )
386- return 0 ;
387-
388- rc = s390_iommu_update_trans (s390_domain , paddr , iova ,
389- pgcount , flags );
406+ rc = s390_iommu_invalidate_trans (s390_domain , iova , pgcount );
390407 if (rc )
391408 return 0 ;
392409
0 commit comments