On 11/17/2025 1:52 AM, Anirudh Rayabharam wrote: > From: Anirudh Rayabharam (Microsoft) <[email protected]> > > Allow MSHV_ROOT_HVCALL IOCTL on the /dev/mshv fd. This IOCTL would > execute a passthrough hypercall targeting the root/parent partition > i.e. HV_PARTITION_ID_SELF. >
I think it's worth taking a moment to check and perhaps explain in the commit message/a comment any security implications of the VMM process being able to call these hypercalls on the root/parent partition. One implication would be: can the VMM process influence other processes in the root partition via these hypercalls, e.g. HVCALL_SET_VP_REGISTERS? I would think that the hypervisor itself disallows this but we should check. We can ask the hypervisor team what they think, and check the hypervisor code. Specifically we should check on any hypercall that could possibly influence partition state, i.e.: HVCALL_SET_PARTITION_PROPERTY HVCALL_SET_VP_REGISTERS HVCALL_INSTALL_INTERCEPT HVCALL_CLEAR_VIRTUAL_INTERRUPT HVCALL_REGISTER_INTERCEPT_RESULT HVCALL_ASSERT_VIRTUAL_INTERRUPT HVCALL_SIGNAL_EVENT_DIRECT HVCALL_POST_MESSAGE_DIRECT If it turns out there is something risky we are enabling here, we can introduce a new array of hypercalls to restrict which ones can be called on HV_PARTITION_ID_SELF. > This will be useful for the VMM to query things like supported > synthetic processor features, supported VMM capabiliites etc. > > While at it, add HVCALL_GET_PARTITION_PROPERTY_EX to the allowed list of > passthrough hypercalls. > > Signed-off-by: Anirudh Rayabharam (Microsoft) <[email protected]> > --- > > v2: rebased on latest hyperv-next > > --- > drivers/hv/mshv_root_main.c | 11 ++++++++--- > 1 file changed, 8 insertions(+), 3 deletions(-) > > diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c > index 45c7a5fea1cf..671c4d18520a 100644 > --- a/drivers/hv/mshv_root_main.c > +++ b/drivers/hv/mshv_root_main.c > @@ -122,6 +122,7 @@ static struct miscdevice mshv_dev = { > */ > static u16 mshv_passthru_hvcalls[] = { > HVCALL_GET_PARTITION_PROPERTY, > + HVCALL_GET_PARTITION_PROPERTY_EX, > HVCALL_SET_PARTITION_PROPERTY, > HVCALL_INSTALL_INTERCEPT, > HVCALL_GET_VP_REGISTERS, > @@ -160,6 +161,7 @@ static int mshv_ioctl_passthru_hvcall(struct > mshv_partition *partition, > void *input_pg = NULL; > void *output_pg = NULL; > u16 reps_completed; > + u64 pt_id = partition ? partition->pt_id : HV_PARTITION_ID_SELF; > > if (copy_from_user(&args, user_args, sizeof(args))) > return -EFAULT; > @@ -181,7 +183,7 @@ static int mshv_ioctl_passthru_hvcall(struct > mshv_partition *partition, > is_async = mshv_hvcall_is_async(args.code); > if (is_async) { > /* async hypercalls can only be called from partition fd */ > - if (!partition_locked) > + if (!partition || !partition_locked) > return -EINVAL; > ret = mshv_init_async_handler(partition); > if (ret) > @@ -209,7 +211,7 @@ static int mshv_ioctl_passthru_hvcall(struct > mshv_partition *partition, > * NOTE: This only works because all the allowed hypercalls' input > * structs begin with a u64 partition_id field. > */ > - *(u64 *)input_pg = partition->pt_id; > + *(u64 *)input_pg = pt_id; > > reps_completed = 0; > do { > @@ -238,7 +240,7 @@ static int mshv_ioctl_passthru_hvcall(struct > mshv_partition *partition, > ret = hv_result_to_errno(status); > else > ret = hv_call_deposit_pages(NUMA_NO_NODE, > - partition->pt_id, 1); > + pt_id, 1); nit: Can these arguments just all go on a single line now? > } while (!ret); > > args.status = hv_result(status); > @@ -2050,6 +2052,9 @@ static long mshv_dev_ioctl(struct file *filp, unsigned > int ioctl, > case MSHV_CREATE_PARTITION: > return mshv_ioctl_create_partition((void __user *)arg, > misc->this_device); > + case MSHV_ROOT_HVCALL: > + return mshv_ioctl_passthru_hvcall(NULL, false, > + (void __user *)arg); > } > > return -ENOTTY; > > base-commit: db7df69995ffbe806d60ad46d5fb9d959da9e549
