x86/hyperv: Add support for detecting nested hypervisor
authorJinank Jain <jinankjain@linux.microsoft.com>
Mon, 2 Jan 2023 07:12:51 +0000 (07:12 +0000)
committerWei Liu <wei.liu@kernel.org>
Thu, 12 Jan 2023 15:23:26 +0000 (15:23 +0000)
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: Jinank Jain <jinankjain@linux.microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/8e3e7112806e81d2292a66a56fe547162754ecea.1672639707.git.jinankjain@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
arch/x86/include/asm/hyperv-tlfs.h
arch/x86/kernel/cpu/mshyperv.c
drivers/hv/hv_common.c
include/asm-generic/mshyperv.h

index 08e822bd7aa601314980dfada7688407df539cbb..724a2589c0e7e5accb17a54b417d4982ba3b93df 100644 (file)
 /* 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)
 
index 46668e2554210a7251ab477ba74f6fa3063c9b81..f9b78d4829e3545ead373de981d14f3b86f07083 100644 (file)
@@ -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.
         */
index ae68298c0dcac59add8948c0510499b6958ea434..52a6f89ccdbd48dd85e981c3bc74e9f9cdffd47d 100644 (file)
 #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);
 
index d55d2833a37b7383a002596d9152166c30f52d8b..8845a2eca339dc0ad6f7cd1f9c9c0c7dafd48524 100644 (file)
@@ -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;