diff options
-rw-r--r-- | drivers/vfio/vfio_iommu_type1.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 98231d10890c..a9807dea3887 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c | |||
@@ -436,6 +436,12 @@ static int vfio_remove_dma_overlap(struct vfio_iommu *iommu, dma_addr_t start, | |||
436 | } | 436 | } |
437 | 437 | ||
438 | /* Split existing */ | 438 | /* Split existing */ |
439 | |||
440 | /* | ||
441 | * Allocate our tracking structure early even though it may not | ||
442 | * be used. An Allocation failure later loses track of pages and | ||
443 | * is more difficult to unwind. | ||
444 | */ | ||
439 | split = kzalloc(sizeof(*split), GFP_KERNEL); | 445 | split = kzalloc(sizeof(*split), GFP_KERNEL); |
440 | if (!split) | 446 | if (!split) |
441 | return -ENOMEM; | 447 | return -ENOMEM; |
@@ -443,12 +449,9 @@ static int vfio_remove_dma_overlap(struct vfio_iommu *iommu, dma_addr_t start, | |||
443 | offset = start - dma->iova; | 449 | offset = start - dma->iova; |
444 | 450 | ||
445 | ret = vfio_unmap_unpin(iommu, dma, start, size); | 451 | ret = vfio_unmap_unpin(iommu, dma, start, size); |
446 | if (ret) | 452 | if (ret || !*size) { |
447 | return ret; | ||
448 | |||
449 | if (!*size) { | ||
450 | kfree(split); | 453 | kfree(split); |
451 | return -EINVAL; | 454 | return ret; |
452 | } | 455 | } |
453 | 456 | ||
454 | tmp = dma->size; | 457 | tmp = dma->size; |