x86/hyperv: Move required MSRs check to initial platform probing

Explicitly check for MSR_HYPERCALL and MSR_VP_INDEX support when probing
for running as a Hyper-V guest instead of waiting until hyperv_init() to
detect the bogus configuration.  Add messages to give the admin a heads
up that they are likely running on a broken virtual machine setup.

At best, silently disabling Hyper-V is confusing and difficult to debug,
e.g. the kernel _says_ it's using all these fancy Hyper-V features, but
always falls back to the native versions.  At worst, the half baked setup
will crash/hang the kernel.

Reviewed-by: Vitaly Kuznetsov <[email protected]>
Signed-off-by: Sean Christopherson <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Wei Liu <[email protected]>
This commit is contained in:
Sean Christopherson authored and Wei Liu committed 2021-11-15 12:37:08 +00:00
1 parent daf972118c
commit f3e613e72f
2 files changed
+16 -13

No files matched your search

+1 -8
View File
@@ -386,20 +386,13 @@ static void __init hv_get_partition_id(void)
*/
void __init hyperv_init(void)
{
u64 guest_id, required_msrs;
u64 guest_id;
union hv_x64_msr_hypercall_contents hypercall_msr;
int cpuhp;
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
return;
/* Absolutely required MSRs */
required_msrs = HV_MSR_HYPERCALL_AVAILABLE |
HV_MSR_VP_INDEX_AVAILABLE;
if ((ms_hyperv.features & required_msrs) != required_msrs)
return;
if (hv_common_init())
return;
+15 -5
View File
@@ -163,12 +163,22 @@ static uint32_t __init ms_hyperv_platform(void)
cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
&eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);
if (eax >= HYPERV_CPUID_MIN &&
eax <= HYPERV_CPUID_MAX &&
!memcmp("Microsoft Hv", hyp_signature, 12))
return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS;
if (eax < HYPERV_CPUID_MIN || eax > HYPERV_CPUID_MAX ||
memcmp("Microsoft Hv", hyp_signature, 12))
return 0;
return 0;
/* HYPERCALL and VP_INDEX MSRs are mandatory for all features. */
eax = cpuid_eax(HYPERV_CPUID_FEATURES);
if (!(eax & HV_MSR_HYPERCALL_AVAILABLE)) {
pr_warn("x86/hyperv: HYPERCALL MSR not available.\n");
return 0;
}
if (!(eax & HV_MSR_VP_INDEX_AVAILABLE)) {
pr_warn("x86/hyperv: VP_INDEX MSR not available.\n");
return 0;
}
return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS;
}
static unsigned char hv_get_nmi_reason(void)