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]>


Reply via email to