summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStanislav Kinsburskii <skinsburskii@linux.microsoft.com>2025-12-03 21:40:45 +0000
committerWei Liu <wei.liu@kernel.org>2025-12-05 23:20:16 +0000
commit6f6aed2c497e8d80d8ed6b5a87c6f65dc7548b8f (patch)
tree0f73f911024a4948fda0841e9ccb7f9e0b535e20 /drivers
parentdf4ff5f6cf7864714d66c65ec7df582240a596a4 (diff)
mshv: Centralize guest memory region destruction
Centralize guest memory region destruction to prevent resource leaks and inconsistent cleanup across unmap and partition destruction paths. Unify region removal, encrypted partition access recovery, and region invalidation to improve maintainability and reliability. Reduce code duplication and make future updates less error-prone by encapsulating cleanup logic in a single helper. Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Reviewed-by: Nuno Das Neves <nunodasneves@linux.microsoft.com> Reviewed-by: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com> Signed-off-by: Wei Liu <wei.liu@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hv/mshv_root_main.c65
1 files changed, 34 insertions, 31 deletions
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index fec82619684a..ec18984c3f2d 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -1356,13 +1356,42 @@ errout:
return ret;
}
+static void mshv_partition_destroy_region(struct mshv_mem_region *region)
+{
+ struct mshv_partition *partition = region->partition;
+ u32 unmap_flags = 0;
+ int ret;
+
+ hlist_del(&region->hnode);
+
+ if (mshv_partition_encrypted(partition)) {
+ ret = mshv_partition_region_share(region);
+ if (ret) {
+ pt_err(partition,
+ "Failed to regain access to memory, unpinning user pages will fail and crash the host error: %d\n",
+ ret);
+ return;
+ }
+ }
+
+ if (region->flags.large_pages)
+ unmap_flags |= HV_UNMAP_GPA_LARGE_PAGE;
+
+ /* ignore unmap failures and continue as process may be exiting */
+ hv_call_unmap_gpa_pages(partition->pt_id, region->start_gfn,
+ region->nr_pages, unmap_flags);
+
+ mshv_region_invalidate(region);
+
+ vfree(region);
+}
+
/* Called for unmapping both the guest ram and the mmio space */
static long
mshv_unmap_user_memory(struct mshv_partition *partition,
struct mshv_user_mem_region mem)
{
struct mshv_mem_region *region;
- u32 unmap_flags = 0;
if (!(mem.flags & BIT(MSHV_SET_MEM_BIT_UNMAP)))
return -EINVAL;
@@ -1377,18 +1406,8 @@ mshv_unmap_user_memory(struct mshv_partition *partition,
region->nr_pages != HVPFN_DOWN(mem.size))
return -EINVAL;
- hlist_del(&region->hnode);
+ mshv_partition_destroy_region(region);
- if (region->flags.large_pages)
- unmap_flags |= HV_UNMAP_GPA_LARGE_PAGE;
-
- /* ignore unmap failures and continue as process may be exiting */
- hv_call_unmap_gpa_pages(partition->pt_id, region->start_gfn,
- region->nr_pages, unmap_flags);
-
- mshv_region_invalidate(region);
-
- vfree(region);
return 0;
}
@@ -1724,8 +1743,8 @@ static void destroy_partition(struct mshv_partition *partition)
{
struct mshv_vp *vp;
struct mshv_mem_region *region;
- int i, ret;
struct hlist_node *n;
+ int i;
if (refcount_read(&partition->pt_ref_count)) {
pt_err(partition,
@@ -1789,25 +1808,9 @@ static void destroy_partition(struct mshv_partition *partition)
remove_partition(partition);
- /* Remove regions, regain access to the memory and unpin the pages */
hlist_for_each_entry_safe(region, n, &partition->pt_mem_regions,
- hnode) {
- hlist_del(&region->hnode);
-
- if (mshv_partition_encrypted(partition)) {
- ret = mshv_partition_region_share(region);
- if (ret) {
- pt_err(partition,
- "Failed to regain access to memory, unpinning user pages will fail and crash the host error: %d\n",
- ret);
- return;
- }
- }
-
- mshv_region_invalidate(region);
-
- vfree(region);
- }
+ hnode)
+ mshv_partition_destroy_region(region);
/* Withdraw and free all pages we deposited */
hv_call_withdraw_memory(U64_MAX, NUMA_NO_NODE, partition->pt_id);