@@ -260,42 +260,66 @@ static void s390_iommu_iotlb_sync_map(struct iommu_domain *domain,
260
260
rcu_read_unlock ();
261
261
}
262
262
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 )
266
266
{
267
267
phys_addr_t page_addr = pa & PAGE_MASK ;
268
268
unsigned long irq_flags , i ;
269
269
unsigned long * entry ;
270
- int rc = 0 ;
270
+ int rc ;
271
271
272
272
if (!nr_pages )
273
273
return 0 ;
274
274
275
275
spin_lock_irqsave (& s390_domain -> dma_table_lock , irq_flags );
276
276
for (i = 0 ; i < nr_pages ; i ++ ) {
277
277
entry = dma_walk_cpu_trans (s390_domain -> dma_table , dma_addr );
278
- if (!entry ) {
278
+ if (unlikely ( !entry ) ) {
279
279
rc = - ENOMEM ;
280
280
goto undo_cpu_trans ;
281
281
}
282
282
dma_update_cpu_trans (entry , page_addr , flags );
283
283
page_addr += PAGE_SIZE ;
284
284
dma_addr += PAGE_SIZE ;
285
285
}
286
+ spin_unlock_irqrestore (& s390_domain -> dma_table_lock , irq_flags );
287
+
288
+ return 0 ;
286
289
287
290
undo_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 ;
298
320
}
321
+ dma_update_cpu_trans (entry , 0 , ZPCI_PTE_INVALID );
322
+ dma_addr += PAGE_SIZE ;
299
323
}
300
324
spin_unlock_irqrestore (& s390_domain -> dma_table_lock , irq_flags );
301
325
@@ -308,8 +332,8 @@ static int s390_iommu_map_pages(struct iommu_domain *domain,
308
332
int prot , gfp_t gfp , size_t * mapped )
309
333
{
310
334
struct s390_domain * s390_domain = to_s390_domain (domain );
311
- int flags = ZPCI_PTE_VALID , rc = 0 ;
312
335
size_t size = pgcount << __ffs (pgsize );
336
+ int flags = ZPCI_PTE_VALID , rc = 0 ;
313
337
314
338
if (pgsize != SZ_4K )
315
339
return - EINVAL ;
@@ -327,8 +351,8 @@ static int s390_iommu_map_pages(struct iommu_domain *domain,
327
351
if (!(prot & IOMMU_WRITE ))
328
352
flags |= ZPCI_TABLE_PROTECTED ;
329
353
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 );
332
356
if (!rc )
333
357
* mapped = size ;
334
358
@@ -373,20 +397,13 @@ static size_t s390_iommu_unmap_pages(struct iommu_domain *domain,
373
397
{
374
398
struct s390_domain * s390_domain = to_s390_domain (domain );
375
399
size_t size = pgcount << __ffs (pgsize );
376
- int flags = ZPCI_PTE_INVALID ;
377
- phys_addr_t paddr ;
378
400
int rc ;
379
401
380
402
if (WARN_ON (iova < s390_domain -> domain .geometry .aperture_start ||
381
403
(iova + size - 1 ) > s390_domain -> domain .geometry .aperture_end ))
382
404
return 0 ;
383
405
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 );
390
407
if (rc )
391
408
return 0 ;
392
409
0 commit comments