On Mon, May 11, 2026 at 08:29:50AM -0700, Stanislav Kinsburskii wrote:
> On Mon, May 11, 2026 at 02:26:45PM +0000, Anirudh Rayabharam wrote:
> > On Thu, May 07, 2026 at 03:44:32PM +0000, Stanislav Kinsburskii wrote:
> > > mshv_partition_ioctl_create_vp() called anon_inode_getfd() before
> > > publishing the new VP into partition->pt_vp_array. anon_inode_getfd()
> > > includes fd_install(), so the fd was live in current->files before the
> > > publish ran.
> > >
> > > A concurrent MSHV_RUN_VP ioctl on that fd does not serialise against the
> > > in-progress MSHV_CREATE_VP — it takes vp->vp_mutex, not the partition
> > > mutex. Once the VP starts running and traps, mshv_intercept_isr() can
> > > look
> > > up partition->pt_vp_array[vp_index] and observe NULL, silently dropping
> > > the
> > > intercept message.
> > >
> > > Split the fd creation: reserve an fd with get_unused_fd_flags(), create
> > > the
> > > file with anon_inode_getfile(), publish the VP via smp_store_release(),
> > > and
> > > finally call fd_install() as the userspace-visibility commit point.
> > >
> > > Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose
> > > /dev/mshv to VMMs")
> > > Signed-off-by: Stanislav Kinsburskii <[email protected]>
> > > ---
> > > drivers/hv/mshv_root_main.c | 29 ++++++++++++++++++++++-------
> > > 1 file changed, 22 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
> > > index e32f6e0f9f637..1c18d1c1f7947 100644
> > > --- a/drivers/hv/mshv_root_main.c
> > > +++ b/drivers/hv/mshv_root_main.c
> > > @@ -1142,6 +1142,8 @@ mshv_partition_ioctl_create_vp(struct
> > > mshv_partition *partition,
> > > struct mshv_vp *vp;
> > > struct page *intercept_msg_page, *register_page, *ghcb_page;
> > > struct hv_stats_page *stats_pages[2];
> > > + struct file *file;
> > > + int fd;
> > > long ret;
> > >
> > > if (copy_from_user(&args, arg, sizeof(args)))
> > > @@ -1214,14 +1216,18 @@ mshv_partition_ioctl_create_vp(struct
> > > mshv_partition *partition,
> > > if (ret)
> > > goto put_partition;
> > >
> > > - /*
> > > - * Keep anon_inode_getfd last: it installs fd in the file struct and
> > > - * thus makes the state accessible in user space.
> > > - */
> > > - ret = anon_inode_getfd("mshv_vp", &mshv_vp_fops, vp,
> > > - O_RDWR | O_CLOEXEC);
> >
> > Why not just move this anon_inode_getfd() after the smp_store_release()
> > call?
> >
>
> Because anon_inode_getfd() can still fail at the fd-table step after the
> VP is already visible to lockless ISR readers, and unpublishing it would
> require a grace-period wait under pt_mutex while ISRs may have already
> observed and acted on the doomed VP. The split form keeps every failable
> step before the publish, so failure paths stay simple and the publish
> itself cannot fail.
Reviewed-by: Anirudh Rayabharam (Microsoft) <[email protected]>