From: Yuho Choi <oss.patchbox@gmail.com>
To: Wei Liu <wei.liu@kernel.org>,
Haiyang Zhang <haiyangz@microsoft.com>,
Dexuan Cui <decui@microsoft.com>
Cc: Nuno Das Neves <nunodasneves@linux.microsoft.com>,
Easwar Hariharan <easwar.hariharan@linux.microsoft.com>,
Praveen K Paladugu <prapal@linux.microsoft.com>,
Tianyu Lan <tiala@microsoft.com>,
linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
Yuho Choi <oss.patchbox@gmail.com>,
stable@vger.kernel.org
Subject: [PATCH v2] mshv: Don't free overlay pages after a failed unmap
Date: Sun, 1 Nov 2026 21:57:42 -0500 [thread overview]
Message-ID: <20261102025754.257856-2-oss.patchbox@gmail.com> (raw)
On L1VH partitions where the VMM can provide overlay GPFNs, the kernel
allocates the VP state and stats pages and supplies them to the
hypervisor as overlay locations through hv_map_vp_state_page() and
hv_map_stats_page(). The hypervisor may write intercept messages,
register state, and statistics to these pages. Only a successful
HVCALL_UNMAP_VP_STATE_PAGE or HVCALL_UNMAP_STATS_PAGE confirms that the
corresponding overlay has been revoked.
hv_unmap_vp_state_page() and hv_unmap_stats_page() free the overlay
page regardless of the hypercall result. If the unmap fails, revocation
is unconfirmed, but dropping the driver's page reference may still
allow the page to be returned to the allocator and reused. A subsequent
hypervisor write through a retained overlay could then corrupt an
unrelated kernel or user allocation.
Free an overlay page only after the unmap hypercall succeeds. On failure,
leak the page rather than return memory that the hypervisor may still be
able to access. This matches how the rest of drivers/hv handles pages
whose state is unknown after a failed hypervisor operation; for example,
hv_free_page() leaks a page that could not be re-encrypted. Log the
leaked page in both helpers, as some of their callers discard the
return value.
Fixes: 19c515c27cee ("mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH")
Fixes: d62313bdf596 ("mshv: Introduce new hypercall to map stats page for L1VH partitions")
Cc: stable@vger.kernel.org
Signed-off-by: Yuho Choi <oss.patchbox@gmail.com>
---
v2:
- Also log a failed stats page unmap before leaking the page (Wei Liu).
- Rebased on v7.4-rc1.
Compile-tested with x86_64 defconfig, CONFIG_HYPERV=y,
CONFIG_MSHV_ROOT=m, and W=1. Not tested on an L1VH system.
drivers/hv/mshv_root_hv_call.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index b8d199f95299..e761addda50e 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -643,8 +643,18 @@ int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
{
int ret = hv_call_unmap_vp_state_page(partition_id, vp_index, type, input_vtl);
- if (mshv_use_overlay_gpfn() && state_page)
- __free_page(state_page);
+ if (mshv_use_overlay_gpfn() && state_page) {
+ /*
+ * If the unmap failed, the hypervisor may still be using the
+ * page as an overlay. Leak it rather than handing it back to
+ * the page allocator.
+ */
+ if (ret)
+ pr_err("%s: failed to unmap partition %llu vp %u state page type %u, leaking page: %d\n",
+ __func__, partition_id, vp_index, type, ret);
+ else
+ __free_page(state_page);
+ }
return ret;
}
@@ -995,8 +1005,18 @@ int hv_unmap_stats_page(enum hv_stats_object_type type,
ret = hv_call_unmap_stats_page(type, identity);
- if (mshv_use_overlay_gpfn() && page_addr)
- __free_page(virt_to_page(page_addr));
+ if (mshv_use_overlay_gpfn() && page_addr) {
+ /*
+ * If the unmap failed, the hypervisor may still be updating the
+ * overlay page. Leak it rather than handing it back to the page
+ * allocator.
+ */
+ if (ret)
+ pr_err("%s: failed to unmap stats page type %u, leaking page: %d\n",
+ __func__, type, ret);
+ else
+ __free_page(virt_to_page(page_addr));
+ }
return ret;
}
--
2.43.0
reply other threads:[~2026-11-02 2:58 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261102025754.257856-2-oss.patchbox@gmail.com \
--to=oss.patchbox@gmail.com \
--cc=decui@microsoft.com \
--cc=easwar.hariharan@linux.microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nunodasneves@linux.microsoft.com \
--cc=prapal@linux.microsoft.com \
--cc=stable@vger.kernel.org \
--cc=tiala@microsoft.com \
--cc=wei.liu@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®