From: Nuno Das Neves <nunodasne...@linux.microsoft.com> Sent: Tuesday, August 19, 2025 12:29 AM > > Detect booting as an "L1VH" partition. This is a new scenario very > similar to root partition where the mshv_root driver can be used to > create and manage guest partitions. > > It mostly works the same as root partition, but there are some > differences in how various features are handled. hv_l1vh_partition() > is introduced to handle these cases. Add hv_parent_partition() > which returns true for either case, replacing some hv_root_partition() > checks. > > Signed-off-by: Nuno Das Neves <nunodasne...@linux.microsoft.com> > --- > drivers/hv/hv_common.c | 20 ++++++++++++-------- > drivers/hv/mshv_root_main.c | 22 ++++++++++++++-------- > include/asm-generic/mshyperv.h | 11 +++++++++++ > 3 files changed, 37 insertions(+), 16 deletions(-) > > diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c > index cbe4a954ad46..a6839593ca31 100644 > --- a/drivers/hv/hv_common.c > +++ b/drivers/hv/hv_common.c > @@ -357,7 +357,7 @@ int __init hv_common_init(void) > hyperv_pcpu_arg = alloc_percpu(void *); > BUG_ON(!hyperv_pcpu_arg); > > - if (hv_root_partition()) { > + if (hv_parent_partition()) { > hv_synic_eventring_tail = alloc_percpu(u8 *); > BUG_ON(!hv_synic_eventring_tail); > } > @@ -506,7 +506,7 @@ int hv_common_cpu_init(unsigned int cpu) > if (msr_vp_index > hv_max_vp_index) > hv_max_vp_index = msr_vp_index; > > - if (hv_root_partition()) { > + if (hv_parent_partition()) { > synic_eventring_tail = (u8 > **)this_cpu_ptr(hv_synic_eventring_tail); > *synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, > sizeof(u8), flags); > @@ -532,7 +532,7 @@ int hv_common_cpu_die(unsigned int cpu) > * originally allocated memory is reused in hv_common_cpu_init(). > */ > > - if (hv_root_partition()) { > + if (hv_parent_partition()) { > synic_eventring_tail = this_cpu_ptr(hv_synic_eventring_tail); > kfree(*synic_eventring_tail); > *synic_eventring_tail = NULL; > @@ -703,13 +703,17 @@ void hv_identify_partition_type(void) > * the root partition setting if also a Confidential VM. > */ > if ((ms_hyperv.priv_high & HV_CREATE_PARTITIONS) && > - (ms_hyperv.priv_high & HV_CPU_MANAGEMENT) && > !(ms_hyperv.priv_high & HV_ISOLATION)) { > - pr_info("Hyper-V: running as root partition\n"); > - if (IS_ENABLED(CONFIG_MSHV_ROOT)) > - hv_curr_partition_type = HV_PARTITION_TYPE_ROOT; > - else > + > + if (!IS_ENABLED(CONFIG_MSHV_ROOT)) { > pr_crit("Hyper-V: CONFIG_MSHV_ROOT not enabled!\n"); > + } else if (ms_hyperv.priv_high & HV_CPU_MANAGEMENT) { > + pr_info("Hyper-V: running as root partition\n"); > + hv_curr_partition_type = HV_PARTITION_TYPE_ROOT; > + } else { > + pr_info("Hyper-V: running as L1VH partition\n"); > + hv_curr_partition_type = HV_PARTITION_TYPE_L1VH; > + } > } > } > > diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c > index aca3331ad516..7c710703cd96 100644 > --- a/drivers/hv/mshv_root_main.c > +++ b/drivers/hv/mshv_root_main.c > @@ -37,12 +37,6 @@ MODULE_AUTHOR("Microsoft"); > MODULE_LICENSE("GPL"); > MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface > /dev/mshv"); > > -/* TODO move this to mshyperv.h when needed outside driver */ > -static inline bool hv_parent_partition(void) > -{ > - return hv_root_partition(); > -} > - > /* TODO move this to another file when debugfs code is added */ > enum hv_stats_vp_counters { /* HV_THREAD_COUNTER */ > #if defined(CONFIG_X86) > @@ -2190,6 +2184,15 @@ struct notifier_block mshv_reboot_nb = { > .notifier_call = mshv_reboot_notify, > }; > > +static int __init mshv_l1vh_partition_init(struct device *dev) > +{ > + hv_scheduler_type = HV_SCHEDULER_TYPE_CORE_SMT; > + dev_info(dev, "Hypervisor using %s\n", > + scheduler_type_to_string(hv_scheduler_type)); > + > + return 0; > +}
I'm a bit late reviewing this patch, but I have a suggestion. With this function added, setting hv_scheduler_type and outputting the message is now in two places: here and in mshv_retrieve_scheduler_type(). Instead, check for root vs. L1VH in mshv_retrieve_scheduler_type(), and either call hv_retrieve_scheduler_type(), or force to HV_SCHEDULER_TYPE_CORE_SMT. Then the rest of the code in mshv_retrieve_scheduler_type(), including outputting the message, just works. That puts all the logic about the scheduler type in one place. Then move the call to mshv_retrieve_scheduler_type() directly into mshv_parent_partition_init() just before if (hv_root_partition()) ret = mshv_root_partition_init(dev); mshv_l1vh_partition_init() is no longer needed. Independent of the suggestion, everything else looks good. Reviewed-by: Michael Kelley <mhkli...@outlook.com> > + > static void mshv_root_partition_exit(void) > { > unregister_reboot_notifier(&mshv_reboot_nb); > @@ -2224,7 +2227,7 @@ static int __init mshv_parent_partition_init(void) > struct device *dev; > union hv_hypervisor_version_info version_info; > > - if (!hv_root_partition() || is_kdump_kernel()) > + if (!hv_parent_partition() || is_kdump_kernel()) > return -ENODEV; > > if (hv_get_hypervisor_version(&version_info)) > @@ -2261,7 +2264,10 @@ static int __init mshv_parent_partition_init(void) > > mshv_cpuhp_online = ret; > > - ret = mshv_root_partition_init(dev); > + if (hv_root_partition()) > + ret = mshv_root_partition_init(dev); > + else > + ret = mshv_l1vh_partition_init(dev); > if (ret) > goto remove_cpu_state; > > diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h > index dbbacd47ca35..f0f0eacb2eef 100644 > --- a/include/asm-generic/mshyperv.h > +++ b/include/asm-generic/mshyperv.h > @@ -31,6 +31,7 @@ > enum hv_partition_type { > HV_PARTITION_TYPE_GUEST, > HV_PARTITION_TYPE_ROOT, > + HV_PARTITION_TYPE_L1VH, > }; > > struct ms_hyperv_info { > @@ -457,12 +458,22 @@ static inline bool hv_root_partition(void) > { > return hv_curr_partition_type == HV_PARTITION_TYPE_ROOT; > } > +static inline bool hv_l1vh_partition(void) > +{ > + return hv_curr_partition_type == HV_PARTITION_TYPE_L1VH; > +} > +static inline bool hv_parent_partition(void) > +{ > + return hv_root_partition() || hv_l1vh_partition(); > +} > int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages); > int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id); > int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags); > > #else /* CONFIG_MSHV_ROOT */ > static inline bool hv_root_partition(void) { return false; } > +static inline bool hv_l1vh_partition(void) { return false; } > +static inline bool hv_parent_partition(void) { return false; } > static inline int hv_call_deposit_pages(int node, u64 partition_id, u32 > num_pages) > { > return -EOPNOTSUPP; > -- > 2.34.1