@@ -545,6 +545,8 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
545
545
long npage ;
546
546
int ret = 0 , prot = 0 ;
547
547
uint64_t mask ;
548
+ struct vfio_dma * dma = NULL ;
549
+ unsigned long pfn ;
548
550
549
551
end = map -> iova + map -> size ;
550
552
@@ -587,8 +589,6 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
587
589
}
588
590
589
591
for (iova = map -> iova ; iova < end ; iova += size , vaddr += size ) {
590
- struct vfio_dma * dma = NULL ;
591
- unsigned long pfn ;
592
592
long i ;
593
593
594
594
/* Pin a contiguous chunk of memory */
@@ -597,16 +597,15 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
597
597
if (npage <= 0 ) {
598
598
WARN_ON (!npage );
599
599
ret = (int )npage ;
600
- break ;
600
+ goto out ;
601
601
}
602
602
603
603
/* Verify pages are not already mapped */
604
604
for (i = 0 ; i < npage ; i ++ ) {
605
605
if (iommu_iova_to_phys (iommu -> domain ,
606
606
iova + (i << PAGE_SHIFT ))) {
607
- vfio_unpin_pages (pfn , npage , prot , true);
608
607
ret = - EBUSY ;
609
- break ;
608
+ goto out_unpin ;
610
609
}
611
610
}
612
611
@@ -616,8 +615,7 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
616
615
if (ret ) {
617
616
if (ret != - EBUSY ||
618
617
map_try_harder (iommu , iova , pfn , npage , prot )) {
619
- vfio_unpin_pages (pfn , npage , prot , true);
620
- break ;
618
+ goto out_unpin ;
621
619
}
622
620
}
623
621
@@ -672,9 +670,8 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
672
670
dma = kzalloc (sizeof (* dma ), GFP_KERNEL );
673
671
if (!dma ) {
674
672
iommu_unmap (iommu -> domain , iova , size );
675
- vfio_unpin_pages (pfn , npage , prot , true);
676
673
ret = - ENOMEM ;
677
- break ;
674
+ goto out_unpin ;
678
675
}
679
676
680
677
dma -> size = size ;
@@ -685,16 +682,21 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,
685
682
}
686
683
}
687
684
688
- if (ret ) {
689
- struct vfio_dma * tmp ;
690
- iova = map -> iova ;
691
- size = map -> size ;
692
- while ((tmp = vfio_find_dma (iommu , iova , size ))) {
693
- int r = vfio_remove_dma_overlap (iommu , iova ,
694
- & size , tmp );
695
- if (WARN_ON (r || !size ))
696
- break ;
697
- }
685
+ WARN_ON (ret );
686
+ mutex_unlock (& iommu -> lock );
687
+ return ret ;
688
+
689
+ out_unpin :
690
+ vfio_unpin_pages (pfn , npage , prot , true);
691
+
692
+ out :
693
+ iova = map -> iova ;
694
+ size = map -> size ;
695
+ while ((dma = vfio_find_dma (iommu , iova , size ))) {
696
+ int r = vfio_remove_dma_overlap (iommu , iova ,
697
+ & size , dma );
698
+ if (WARN_ON (r || !size ))
699
+ break ;
698
700
}
699
701
700
702
mutex_unlock (& iommu -> lock );
0 commit comments