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?
Thanks,
Anirudh.