RE: [PATCH v2 1/4] x86/hyperv: Load/save the Isolation Configuration leaf

2021-01-28 Thread Michael Kelley
From: Andrea Parri (Microsoft)  Sent: Tuesday, January 
26, 2021 3:57 AM
> 
> If bit 22 of Group B Features is set, the guest has access to the
> Isolation Configuration CPUID leaf.  On x86, the first four bits
> of EAX in this leaf provide the isolation type of the partition;
> we entail three isolation types: 'SNP' (hardware-based isolation),
> 'VBS' (software-based isolation), and 'NONE' (no isolation).
> 
> Signed-off-by: Andrea Parri (Microsoft) 
> Cc: Thomas Gleixner 
> Cc: Ingo Molnar 
> Cc: Borislav Petkov 
> Cc: "H. Peter Anvin" 
> Cc: Arnd Bergmann 
> Cc: x...@kernel.org
> Cc: linux-a...@vger.kernel.org
> ---
>  arch/x86/hyperv/hv_init.c  | 15 +++
>  arch/x86/include/asm/hyperv-tlfs.h | 15 +++
>  arch/x86/kernel/cpu/mshyperv.c |  9 +
>  include/asm-generic/hyperv-tlfs.h  |  1 +
>  include/asm-generic/mshyperv.h |  5 +
>  5 files changed, 45 insertions(+)
> 
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index e04d90af4c27c..dc94e95c57b98 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -10,6 +10,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -528,3 +529,17 @@ bool hv_is_hibernation_supported(void)
>   return acpi_sleep_state_supported(ACPI_STATE_S4);
>  }
>  EXPORT_SYMBOL_GPL(hv_is_hibernation_supported);
> +
> +enum hv_isolation_type hv_get_isolation_type(void)
> +{
> + if (!(ms_hyperv.hypercalls_features & HV_ISOLATION))
> + return HV_ISOLATION_TYPE_NONE;
> + return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b);
> +}
> +EXPORT_SYMBOL_GPL(hv_get_isolation_type);
> +
> +bool hv_is_isolation_supported(void)
> +{
> + return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE;
> +}
> +EXPORT_SYMBOL_GPL(hv_is_isolation_supported);
> diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
> b/arch/x86/include/asm/hyperv-tlfs.h
> index 6bf42aed387e3..6aed936e5e962 100644
> --- a/arch/x86/include/asm/hyperv-tlfs.h
> +++ b/arch/x86/include/asm/hyperv-tlfs.h
> @@ -22,6 +22,7 @@
>  #define HYPERV_CPUID_ENLIGHTMENT_INFO0x4004
>  #define HYPERV_CPUID_IMPLEMENT_LIMITS0x4005
>  #define HYPERV_CPUID_NESTED_FEATURES 0x400A
> +#define HYPERV_CPUID_ISOLATION_CONFIG0x400C
> 
>  #define HYPERV_CPUID_VIRT_STACK_INTERFACE0x4081
>  #define HYPERV_VS_INTERFACE_EAX_SIGNATURE0x31235356  /* "VS#1" */
> @@ -122,6 +123,20 @@
>  #define HV_X64_NESTED_GUEST_MAPPING_FLUSHBIT(18)
>  #define HV_X64_NESTED_MSR_BITMAP BIT(19)
> 
> +/* HYPERV_CPUID_ISOLATION_CONFIG.EAX bits. */
> +#define HV_PARAVISOR_PRESENT BIT(0)
> +
> +/* HYPERV_CPUID_ISOLATION_CONFIG.EBX bits. */
> +#define HV_ISOLATION_TYPEGENMASK(3, 0)
> +#define HV_SHARED_GPA_BOUNDARY_ACTIVEBIT(5)
> +#define HV_SHARED_GPA_BOUNDARY_BITS  GENMASK(11, 6)
> +
> +enum hv_isolation_type {
> + HV_ISOLATION_TYPE_NONE  = 0,
> + HV_ISOLATION_TYPE_VBS   = 1,
> + HV_ISOLATION_TYPE_SNP   = 2
> +};
> +
>  /* Hyper-V specific model specific registers (MSRs) */
> 
>  /* MSR used to identify the guest OS. */
> diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> index f628e3dc150f3..0d4aaf6694d01 100644
> --- a/arch/x86/kernel/cpu/mshyperv.c
> +++ b/arch/x86/kernel/cpu/mshyperv.c
> @@ -225,6 +225,7 @@ static void __init ms_hyperv_init_platform(void)
>* Extract the features and hints
>*/
>   ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES);
> + ms_hyperv.hypercalls_features = cpuid_ebx(HYPERV_CPUID_FEATURES);
>   ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
>   ms_hyperv.hints= cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
> 
> @@ -259,6 +260,14 @@ static void __init ms_hyperv_init_platform(void)
>   x86_platform.calibrate_cpu = hv_get_tsc_khz;
>   }
> 
> + if (ms_hyperv.hypercalls_features & HV_ISOLATION) {
> + ms_hyperv.isolation_config_a = 
> cpuid_eax(HYPERV_CPUID_ISOLATION_CONFIG);
> + ms_hyperv.isolation_config_b = 
> cpuid_ebx(HYPERV_CPUID_ISOLATION_CONFIG);
> +
> + pr_info("Hyper-V: Isolation Config: GroupA 0x%x, GroupB 0x%x\n",

Nit:  Let's put a space after the word "Group", so that we have
"Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n".

> + ms_hyperv.isolation_config_a, 
> ms_hyperv.isolation_config_b);
> + }
> +
>   if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) {
>   ms_hyperv.nested_features =
>   cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
> diff --git a/include/asm-generic/hyperv-tlfs.h 
> b/include/asm-generic/hyperv-tlfs.h
> index e73a11850055c..20d3cd9502043 100644
> --- a/include/asm-generic/hyperv-tlfs.h
> +++ b/include/asm-generic/hyperv-tlfs.h
> @@ 

[PATCH v2 1/4] x86/hyperv: Load/save the Isolation Configuration leaf

2021-01-26 Thread Andrea Parri (Microsoft)
If bit 22 of Group B Features is set, the guest has access to the
Isolation Configuration CPUID leaf.  On x86, the first four bits
of EAX in this leaf provide the isolation type of the partition;
we entail three isolation types: 'SNP' (hardware-based isolation),
'VBS' (software-based isolation), and 'NONE' (no isolation).

Signed-off-by: Andrea Parri (Microsoft) 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: Borislav Petkov 
Cc: "H. Peter Anvin" 
Cc: Arnd Bergmann 
Cc: x...@kernel.org
Cc: linux-a...@vger.kernel.org
---
 arch/x86/hyperv/hv_init.c  | 15 +++
 arch/x86/include/asm/hyperv-tlfs.h | 15 +++
 arch/x86/kernel/cpu/mshyperv.c |  9 +
 include/asm-generic/hyperv-tlfs.h  |  1 +
 include/asm-generic/mshyperv.h |  5 +
 5 files changed, 45 insertions(+)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index e04d90af4c27c..dc94e95c57b98 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -528,3 +529,17 @@ bool hv_is_hibernation_supported(void)
return acpi_sleep_state_supported(ACPI_STATE_S4);
 }
 EXPORT_SYMBOL_GPL(hv_is_hibernation_supported);
+
+enum hv_isolation_type hv_get_isolation_type(void)
+{
+   if (!(ms_hyperv.hypercalls_features & HV_ISOLATION))
+   return HV_ISOLATION_TYPE_NONE;
+   return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b);
+}
+EXPORT_SYMBOL_GPL(hv_get_isolation_type);
+
+bool hv_is_isolation_supported(void)
+{
+   return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE;
+}
+EXPORT_SYMBOL_GPL(hv_is_isolation_supported);
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 6bf42aed387e3..6aed936e5e962 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -22,6 +22,7 @@
 #define HYPERV_CPUID_ENLIGHTMENT_INFO  0x4004
 #define HYPERV_CPUID_IMPLEMENT_LIMITS  0x4005
 #define HYPERV_CPUID_NESTED_FEATURES   0x400A
+#define HYPERV_CPUID_ISOLATION_CONFIG  0x400C
 
 #define HYPERV_CPUID_VIRT_STACK_INTERFACE  0x4081
 #define HYPERV_VS_INTERFACE_EAX_SIGNATURE  0x31235356  /* "VS#1" */
@@ -122,6 +123,20 @@
 #define HV_X64_NESTED_GUEST_MAPPING_FLUSH  BIT(18)
 #define HV_X64_NESTED_MSR_BITMAP   BIT(19)
 
+/* HYPERV_CPUID_ISOLATION_CONFIG.EAX bits. */
+#define HV_PARAVISOR_PRESENT   BIT(0)
+
+/* HYPERV_CPUID_ISOLATION_CONFIG.EBX bits. */
+#define HV_ISOLATION_TYPE  GENMASK(3, 0)
+#define HV_SHARED_GPA_BOUNDARY_ACTIVE  BIT(5)
+#define HV_SHARED_GPA_BOUNDARY_BITSGENMASK(11, 6)
+
+enum hv_isolation_type {
+   HV_ISOLATION_TYPE_NONE  = 0,
+   HV_ISOLATION_TYPE_VBS   = 1,
+   HV_ISOLATION_TYPE_SNP   = 2
+};
+
 /* Hyper-V specific model specific registers (MSRs) */
 
 /* MSR used to identify the guest OS. */
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index f628e3dc150f3..0d4aaf6694d01 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -225,6 +225,7 @@ static void __init ms_hyperv_init_platform(void)
 * Extract the features and hints
 */
ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES);
+   ms_hyperv.hypercalls_features = cpuid_ebx(HYPERV_CPUID_FEATURES);
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
ms_hyperv.hints= cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
 
@@ -259,6 +260,14 @@ static void __init ms_hyperv_init_platform(void)
x86_platform.calibrate_cpu = hv_get_tsc_khz;
}
 
+   if (ms_hyperv.hypercalls_features & HV_ISOLATION) {
+   ms_hyperv.isolation_config_a = 
cpuid_eax(HYPERV_CPUID_ISOLATION_CONFIG);
+   ms_hyperv.isolation_config_b = 
cpuid_ebx(HYPERV_CPUID_ISOLATION_CONFIG);
+
+   pr_info("Hyper-V: Isolation Config: GroupA 0x%x, GroupB 0x%x\n",
+   ms_hyperv.isolation_config_a, 
ms_hyperv.isolation_config_b);
+   }
+
if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) {
ms_hyperv.nested_features =
cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index e73a11850055c..20d3cd9502043 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -89,6 +89,7 @@
 #define HV_ACCESS_STATSBIT(8)
 #define HV_DEBUGGING   BIT(11)
 #define HV_CPU_POWER_MANAGEMENTBIT(12)
+#define HV_ISOLATION   BIT(22)
 
 
 /*
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index c57799684170c..c7f75b36f88ba 100644
---