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; |
