aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorNuno Das Neves <nunodasneves@linux.microsoft.com>2025-09-02 16:48:33 -0700
committerWei Liu <wei.liu@kernel.org>2025-09-08 22:10:51 +0000
commitf26c9306dff818bbf4ef545c5a5ee0eca7149922 (patch)
tree95dfd921f7c67f09e5def2dcb4472869e334f8e4 /drivers/hv
parentclocksource: hyper-v: Skip unnecessary checks for the root partition (diff)
downloadlinux-f26c9306dff818bbf4ef545c5a5ee0eca7149922.tar.gz
linux-f26c9306dff818bbf4ef545c5a5ee0eca7149922.zip
mshv: Add support for a new parent partition configuration
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 <nunodasneves@linux.microsoft.com> Acked-by: Wei Liu <wei.liu@kernel.org> Reviewed-by: Michael Kelley <mhklinux@outlook.com> Signed-off-by: Wei Liu <wei.liu@kernel.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/hv_common.c22
-rw-r--r--drivers/hv/mshv_root_main.c26
2 files changed, 26 insertions, 22 deletions
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 49898d10faff..e109a620c83f 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -257,7 +257,7 @@ static void hv_kmsg_dump_register(void)
static inline bool hv_output_page_exists(void)
{
- return hv_root_partition() || IS_ENABLED(CONFIG_HYPERV_VTL_MODE);
+ return hv_parent_partition() || IS_ENABLED(CONFIG_HYPERV_VTL_MODE);
}
void __init hv_get_partition_id(void)
@@ -377,7 +377,7 @@ int __init hv_common_init(void)
BUG_ON(!hyperv_pcpu_output_arg);
}
- if (hv_root_partition()) {
+ if (hv_parent_partition()) {
hv_synic_eventring_tail = alloc_percpu(u8 *);
BUG_ON(!hv_synic_eventring_tail);
}
@@ -531,7 +531,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);
@@ -558,7 +558,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;
@@ -729,13 +729,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 72df774e410a..aa20a5c96afa 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)
@@ -2074,9 +2068,13 @@ static int __init hv_retrieve_scheduler_type(enum hv_scheduler_type *out)
/* Retrieve and stash the supported scheduler type */
static int __init mshv_retrieve_scheduler_type(struct device *dev)
{
- int ret;
+ int ret = 0;
+
+ if (hv_l1vh_partition())
+ hv_scheduler_type = HV_SCHEDULER_TYPE_CORE_SMT;
+ else
+ ret = hv_retrieve_scheduler_type(&hv_scheduler_type);
- ret = hv_retrieve_scheduler_type(&hv_scheduler_type);
if (ret)
return ret;
@@ -2203,9 +2201,6 @@ static int __init mshv_root_partition_init(struct device *dev)
{
int err;
- if (mshv_retrieve_scheduler_type(dev))
- return -ENODEV;
-
err = root_scheduler_init(dev);
if (err)
return err;
@@ -2227,7 +2222,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))
@@ -2264,7 +2259,12 @@ static int __init mshv_parent_partition_init(void)
mshv_cpuhp_online = ret;
- ret = mshv_root_partition_init(dev);
+ ret = mshv_retrieve_scheduler_type(dev);
+ if (ret)
+ goto remove_cpu_state;
+
+ if (hv_root_partition())
+ ret = mshv_root_partition_init(dev);
if (ret)
goto remove_cpu_state;