summaryrefslogtreecommitdiff
path: root/drivers/hv
diff options
context:
space:
mode:
authorStanislav Kinsburskii <skinsburskii@linux.microsoft.com>2026-03-17 15:04:55 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-04-11 14:29:22 +0200
commita7d149152bc5a9119854331c57be35ad31fdf5cc (patch)
tree8125eba84b52801442f84451b107047b297f46f1 /drivers/hv
parent77f7fda6217637cf34163fdd87dc414a13823af5 (diff)
mshv: Fix error handling in mshv_region_pin
[ Upstream commit c0e296f257671ba10249630fe58026f29e4804d9 ] The current error handling has two issues: First, pin_user_pages_fast() can return a short pin count (less than requested but greater than zero) when it cannot pin all requested pages. This is treated as success, leading to partially pinned regions being used, which causes memory corruption. Second, when an error occurs mid-loop, already pinned pages from the current batch are not properly accounted for before calling mshv_region_invalidate_pages(), causing a page reference leak. Treat short pins as errors and fix partial batch accounting before cleanup. Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Reviewed-by: Michael Kelley <mhklinux@outlook.com> Signed-off-by: Wei Liu <wei.liu@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/mshv_regions.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/hv/mshv_regions.c b/drivers/hv/mshv_regions.c
index adba3564d9f1..baa864cac375 100644
--- a/drivers/hv/mshv_regions.c
+++ b/drivers/hv/mshv_regions.c
@@ -314,15 +314,17 @@ int mshv_region_pin(struct mshv_mem_region *region)
ret = pin_user_pages_fast(userspace_addr, nr_pages,
FOLL_WRITE | FOLL_LONGTERM,
pages);
- if (ret < 0)
+ if (ret != nr_pages)
goto release_pages;
}
return 0;
release_pages:
+ if (ret > 0)
+ done_count += ret;
mshv_region_invalidate_pages(region, 0, done_count);
- return ret;
+ return ret < 0 ? ret : -ENOMEM;
}
static int mshv_region_chunk_unmap(struct mshv_mem_region *region,