Commit c4bdf94f authored by Jinank Jain's avatar Jinank Jain Committed by Wei Liu
Browse files

x86/hyperv: Add support for detecting nested hypervisor



Detect if Linux is running as a nested hypervisor in the root
partition for Microsoft Hypervisor, using flags provided by MSHV.
Expose a new variable hv_nested that is used later for decisions
specific to the nested use case.

Signed-off-by: default avatarJinank Jain <jinankjain@linux.microsoft.com>
Reviewed-by: default avatarMichael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/8e3e7112806e81d2292a66a56fe547162754ecea.1672639707.git.jinankjain@linux.microsoft.com


Signed-off-by: default avatarWei Liu <wei.liu@kernel.org>
parent b7bfaa76
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -116,6 +116,9 @@
/* Recommend using the newer ExProcessorMasks interface */
#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED		BIT(11)

/* Indicates that the hypervisor is nested within a Hyper-V partition. */
#define HV_X64_HYPERV_NESTED				BIT(12)

/* Recommend using enlightened VMCS */
#define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED		BIT(14)

+7 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@

/* Is Linux running as the root partition? */
bool hv_root_partition;
/* Is Linux running on nested Microsoft Hypervisor */
bool hv_nested;
struct ms_hyperv_info ms_hyperv;

#if IS_ENABLED(CONFIG_HYPERV)
@@ -301,6 +303,11 @@ static void __init ms_hyperv_init_platform(void)
		pr_info("Hyper-V: running as root partition\n");
	}

	if (ms_hyperv.hints & HV_X64_HYPERV_NESTED) {
		hv_nested = true;
		pr_info("Hyper-V: running on a nested hypervisor\n");
	}

	/*
	 * Extract host information.
	 */
+6 −3
Original line number Diff line number Diff line
@@ -25,17 +25,20 @@
#include <asm/mshyperv.h>

/*
 * hv_root_partition and ms_hyperv are defined here with other Hyper-V
 * specific globals so they are shared across all architectures and are
 * hv_root_partition, ms_hyperv and hv_nested are defined here with other
 * Hyper-V specific globals so they are shared across all architectures and are
 * built only when CONFIG_HYPERV is defined.  But on x86,
 * ms_hyperv_init_platform() is built even when CONFIG_HYPERV is not
 * defined, and it uses these two variables.  So mark them as __weak
 * defined, and it uses these three variables.  So mark them as __weak
 * here, allowing for an overriding definition in the module containing
 * ms_hyperv_init_platform().
 */
bool __weak hv_root_partition;
EXPORT_SYMBOL_GPL(hv_root_partition);

bool __weak hv_nested;
EXPORT_SYMBOL_GPL(hv_nested);

struct ms_hyperv_info __weak ms_hyperv;
EXPORT_SYMBOL_GPL(ms_hyperv);

+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ struct ms_hyperv_info {
	u64 shared_gpa_boundary;
};
extern struct ms_hyperv_info ms_hyperv;
extern bool hv_nested;

extern void * __percpu *hyperv_pcpu_input_arg;
extern void * __percpu *hyperv_pcpu_output_arg;