From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
To: Anirudh Rayabharam <anirudh@anirudhrb.com>
Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
decui@microsoft.com, longli@microsoft.com,
linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 02/18] mshv: Fix mshv_prepare_pinned_region error path for unencrypted partitions
Date: Wed, 13 May 2026 10:31:04 -0700 [thread overview]
Message-ID: <agS1WOIXIkyHxW4E@skinsburskii.localdomain> (raw)
In-Reply-To: <20260513-roaring-gentle-kiwi-21bccd@anirudhrb>
On Wed, May 13, 2026 at 11:15:37AM +0000, Anirudh Rayabharam wrote:
> On Mon, May 11, 2026 at 08:06:44AM -0700, Stanislav Kinsburskii wrote:
> > On Mon, May 11, 2026 at 01:48:56PM +0000, Anirudh Rayabharam wrote:
> > > On Thu, May 07, 2026 at 03:43:09PM +0000, Stanislav Kinsburskii wrote:
> > > > mshv_prepare_pinned_region() returns 0 (success) when mshv_region_map()
> > > > fails on an unencrypted partition. The condition on the error path:
> > > >
> > > > if (ret && mshv_partition_encrypted(partition))
> > > >
> > > > only handles map failures for encrypted partitions — if the partition is
> > > > not encrypted and the map fails, execution falls through to 'return 0',
> > > > silently ignoring the error.
> > > >
> > > > Additionally, calling mshv_region_invalidate() inline on map failure
> > > > zeroes the mreg_pages array before the caller's cleanup path
> > > > (mshv_region_destroy) can call mshv_region_unmap(). Since unmap skips
> > > > pages where mreg_pages[offset] is NULL, this can leave stale SLAT
> > > > mappings for partially-mapped pages.
> > > >
> > > > Fix by returning immediately on success and falling through to error
> > > > return on failure. For unencrypted partitions, the caller's
> > > > mshv_region_destroy() handles unmap followed by invalidate in the
> > > > correct order. For encrypted partitions where re-sharing fails, zero
> > > > the page array without unpinning — the pages are inaccessible to the
> > > > host and must not be unpinned, but zeroing prevents
> > > > mshv_region_destroy() from attempting to unpin them.
> > >
> > > mshv_region_destroy() calls mshv_region_invalidate() which calls
> > > mshv_region_invalidate_pages() which just does:
> > >
> > > static void mshv_region_invalidate_pages(struct mshv_mem_region *region,
> > > u64 page_offset, u64 page_count)
> > > {
> > > if (region->mreg_type == MSHV_REGION_TYPE_MEM_PINNED)
> > > unpin_user_pages(region->mreg_pages + page_offset, page_count);
> > >
> > > memset(region->mreg_pages + page_offset, 0,
> > > page_count * sizeof(struct page *));
> > > }
> > >
> > > It doesn't checked for zeroed pages before unpinning.
> > >
> > > >
> > > > Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs")
> > > > Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> > > > ---
> > > > drivers/hv/mshv_root_main.c | 26 ++++++++++++++++----------
> > > > 1 file changed, 16 insertions(+), 10 deletions(-)
> > > >
> > > > diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
> > > > index 665d565899c15..7e4252b6bc65c 100644
> > > > --- a/drivers/hv/mshv_root_main.c
> > > > +++ b/drivers/hv/mshv_root_main.c
> > > > @@ -1360,32 +1360,38 @@ static int mshv_prepare_pinned_region(struct mshv_mem_region *region)
> > > > pt_err(partition,
> > > > "Failed to unshare memory region (guest_pfn: %llu): %d\n",
> > > > region->start_gfn, ret);
> > > > - goto invalidate_region;
> > > > + goto err_out;
> > > > }
> > > > }
> > > >
> > > > ret = mshv_region_map(region);
> > > > - if (ret && mshv_partition_encrypted(partition)) {
> > > > + if (ret)
> > > > + goto share_region;
> > > > +
> > > > + return 0;
> > > > +
> > > > +share_region:
> > > > + if (mshv_partition_encrypted(partition)) {
> > > > int shrc;
> > > >
> > > > shrc = mshv_region_share(region);
> > > > if (!shrc)
> > > > - goto invalidate_region;
> > > > + goto err_out;
> > > >
> > > > pt_err(partition,
> > > > "Failed to share memory region (guest_pfn: %llu): %d\n",
> > > > region->start_gfn, shrc);
> > > > /*
> > > > - * Don't unpin if marking shared failed because pages are no
> > > > - * longer mapped in the host, ie root, anymore.
> > > > + * Re-sharing failed — the pages remain inaccessible to the
> > > > + * host. Zero the page array so that mshv_region_destroy()
> > > > + * won't attempt to unpin them (leaking the page references
> > > > + * is intentional; unpinning host-inaccessible pages would be
> > > > + * unsafe).
> > > > */
> > >
> > > Actually, mshv_region_destroy() also does mshv_region_share(). Maybe we
> > > can remove it from here altogether. Either way, should this zeroing
> > > logic be added there too so as not to crash the host by unpinning pages
> > > that weren't marked shared?
> > >
> >
> > Indeed.
> > The issue with all this code is that we are leaking state in
> > mshv_region_pin if we wimply return from it: we don't know if the pages
> > are pinned or unshared (or mapped) in the destruction callback.
> > We should either introduce a state variable to track this or just don't
> > call the generic mshv_region_put on case of region creation error.
> > The latter approch make mshv_map_user_memory idempotent and thus looks
> > like a better way forward.
> > What do you think?
>
I tried to say, that there can be two apporaches to solving this issue:
1. Either make sure mshv_region_pus() can destroy a partially created
region (tha'ts what this patch is doing) or
2. Make mshv_map_user_region be idempotent by not calling mshv_region_put() if the region was not
fully created and destroy the partioally created parts of it on
error paths. This would require preserving some state in the region
struct to know if the region was pinned or shared or mapped.
This looks like a leaner apporach, but it requires additional state
tracking and more code changes.
Thanks,
Stanislav
> I'm not sure I follow the latter approach. Omitting mshv_region_put()
> would cause a dangling reference to the mshv_region right?
>
> Thanks,
> Anirudh.
next prev parent reply other threads:[~2026-05-13 17:31 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-07 15:42 [PATCH v4 00/18] mshv: Bug fixes across the mshv_root module Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 01/18] mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access Stanislav Kinsburskii
2026-05-11 3:46 ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 02/18] mshv: Fix mshv_prepare_pinned_region error path for unencrypted partitions Stanislav Kinsburskii
2026-05-11 13:48 ` Anirudh Rayabharam
2026-05-11 15:06 ` Stanislav Kinsburskii
2026-05-13 11:15 ` Anirudh Rayabharam
2026-05-13 17:31 ` Stanislav Kinsburskii [this message]
2026-05-11 15:12 ` Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 03/18] mshv: Fix race in mshv_irqfd_deassign Stanislav Kinsburskii
2026-05-11 13:57 ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 04/18] mshv: Add NULL check for vp in mshv_try_assert_irq_fast Stanislav Kinsburskii
2026-05-11 3:24 ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 05/18] mshv: irqfd: Reject routing updates that invalidate resampler binding Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 06/18] mshv: Fix broken seqcount read protection Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 07/18] mshv: Consolidate irqfd interrupt injection paths Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 08/18] mshv: Fix level-triggered check on uninitialized data Stanislav Kinsburskii
2026-05-13 12:14 ` Anirudh Rayabharam
2026-05-13 17:38 ` Stanislav Kinsburskii
2026-05-14 5:49 ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 09/18] mshv: Fix duplicate GSI detection for GSI 0 Stanislav Kinsburskii
2026-05-13 11:36 ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 10/18] mshv: portid_table: Make mshv_portid_lookup() RCU-aware by contract Stanislav Kinsburskii
2026-05-13 11:20 ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 11/18] mshv: Fix sleeping under spinlock in mshv_portid_alloc Stanislav Kinsburskii
2026-05-11 3:33 ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 12/18] mshv: Use kfree_rcu in mshv_portid_free Stanislav Kinsburskii
2026-05-13 11:22 ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 13/18] mshv: Add missing vp_index bounds check in intercept ISR Stanislav Kinsburskii
2026-05-13 5:32 ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 14/18] mshv: Order pt_vp_array publish against irqfd assertion path Stanislav Kinsburskii
2026-05-13 9:57 ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 15/18] mshv: Defer mshv_vp free to an RCU grace period Stanislav Kinsburskii
2026-05-13 10:11 ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 16/18] mshv: Validate scheduler message bounds from hypervisor Stanislav Kinsburskii
2026-05-13 11:12 ` Anirudh Rayabharam
2026-05-13 17:39 ` Stanislav Kinsburskii
2026-05-14 5:49 ` Anirudh Rayabharam
2026-05-14 15:17 ` Stanislav Kinsburskii
2026-05-07 15:44 ` [PATCH v4 17/18] mshv: Publish VP to pt_vp_array before installing the file descriptor Stanislav Kinsburskii
2026-05-11 14:26 ` Anirudh Rayabharam
2026-05-11 15:29 ` Stanislav Kinsburskii
2026-05-12 12:46 ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 18/18] mshv: Fix missing error code on VP allocation failure Stanislav Kinsburskii
2026-05-11 3:35 ` Anirudh Rayabharam
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=agS1WOIXIkyHxW4E@skinsburskii.localdomain \
--to=skinsburskii@linux.microsoft.com \
--cc=anirudh@anirudhrb.com \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kys@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=longli@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