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

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.comSigned-off-by: default avatarWei Liu <wei.liu@kernel.org>
parent b7bfaa76
...@@ -116,6 +116,9 @@ ...@@ -116,6 +116,9 @@
/* Recommend using the newer ExProcessorMasks interface */ /* Recommend using the newer ExProcessorMasks interface */
#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED BIT(11) #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 */ /* Recommend using enlightened VMCS */
#define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED BIT(14) #define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED BIT(14)
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
/* Is Linux running as the root partition? */ /* Is Linux running as the root partition? */
bool hv_root_partition; bool hv_root_partition;
/* Is Linux running on nested Microsoft Hypervisor */
bool hv_nested;
struct ms_hyperv_info ms_hyperv; struct ms_hyperv_info ms_hyperv;
#if IS_ENABLED(CONFIG_HYPERV) #if IS_ENABLED(CONFIG_HYPERV)
...@@ -301,6 +303,11 @@ static void __init ms_hyperv_init_platform(void) ...@@ -301,6 +303,11 @@ static void __init ms_hyperv_init_platform(void)
pr_info("Hyper-V: running as root partition\n"); 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. * Extract host information.
*/ */
......
...@@ -25,17 +25,20 @@ ...@@ -25,17 +25,20 @@
#include <asm/mshyperv.h> #include <asm/mshyperv.h>
/* /*
* hv_root_partition and ms_hyperv are defined here with other Hyper-V * hv_root_partition, ms_hyperv and hv_nested are defined here with other
* specific globals so they are shared across all architectures and are * Hyper-V specific globals so they are shared across all architectures and are
* built only when CONFIG_HYPERV is defined. But on x86, * built only when CONFIG_HYPERV is defined. But on x86,
* ms_hyperv_init_platform() is built even when CONFIG_HYPERV is not * 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 * here, allowing for an overriding definition in the module containing
* ms_hyperv_init_platform(). * ms_hyperv_init_platform().
*/ */
bool __weak hv_root_partition; bool __weak hv_root_partition;
EXPORT_SYMBOL_GPL(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; struct ms_hyperv_info __weak ms_hyperv;
EXPORT_SYMBOL_GPL(ms_hyperv); EXPORT_SYMBOL_GPL(ms_hyperv);
......
...@@ -48,6 +48,7 @@ struct ms_hyperv_info { ...@@ -48,6 +48,7 @@ struct ms_hyperv_info {
u64 shared_gpa_boundary; u64 shared_gpa_boundary;
}; };
extern struct ms_hyperv_info ms_hyperv; extern struct ms_hyperv_info ms_hyperv;
extern bool hv_nested;
extern void * __percpu *hyperv_pcpu_input_arg; extern void * __percpu *hyperv_pcpu_input_arg;
extern void * __percpu *hyperv_pcpu_output_arg; extern void * __percpu *hyperv_pcpu_output_arg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment