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)
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);
}
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);
* 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;
* 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;
+ }
}
}
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)
/* 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;
{
int err;
- if (mshv_retrieve_scheduler_type(dev))
- return -ENODEV;
-
err = root_scheduler_init(dev);
if (err)
return err;
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))
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;
enum hv_partition_type {
HV_PARTITION_TYPE_GUEST,
HV_PARTITION_TYPE_ROOT,
+ HV_PARTITION_TYPE_L1VH,
};
struct ms_hyperv_info {
{
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;