Commit 8de8af7e authored by K. Y. Srinivasan's avatar K. Y. Srinivasan Committed by Greg Kroah-Hartman

Drivers: hv: vmbus: Move the extracting of Hypervisor version information

As part of the effort to separate out architecture specific code,
extract hypervisor version information in an architecture specific
file.
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 63ed4e0c
...@@ -5,6 +5,25 @@ ...@@ -5,6 +5,25 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/hyperv.h> #include <asm/hyperv.h>
/*
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
* is set by CPUID(HVCPUID_VERSION_FEATURES).
*/
enum hv_cpuid_function {
HVCPUID_VERSION_FEATURES = 0x00000001,
HVCPUID_VENDOR_MAXFUNCTION = 0x40000000,
HVCPUID_INTERFACE = 0x40000001,
/*
* The remaining functions depend on the value of
* HVCPUID_INTERFACE
*/
HVCPUID_VERSION = 0x40000002,
HVCPUID_FEATURES = 0x40000003,
HVCPUID_ENLIGHTENMENT_INFO = 0x40000004,
HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005,
};
struct ms_hyperv_info { struct ms_hyperv_info {
u32 features; u32 features;
u32 misc_features; u32 misc_features;
......
...@@ -160,6 +160,11 @@ static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs) ...@@ -160,6 +160,11 @@ static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs)
static void __init ms_hyperv_init_platform(void) static void __init ms_hyperv_init_platform(void)
{ {
int hv_host_info_eax;
int hv_host_info_ebx;
int hv_host_info_ecx;
int hv_host_info_edx;
/* /*
* Extract the features and hints * Extract the features and hints
*/ */
...@@ -170,6 +175,21 @@ static void __init ms_hyperv_init_platform(void) ...@@ -170,6 +175,21 @@ static void __init ms_hyperv_init_platform(void)
pr_info("HyperV: features 0x%x, hints 0x%x\n", pr_info("HyperV: features 0x%x, hints 0x%x\n",
ms_hyperv.features, ms_hyperv.hints); ms_hyperv.features, ms_hyperv.hints);
/*
* Extract host information.
*/
if (cpuid_eax(HVCPUID_VENDOR_MAXFUNCTION) >= HVCPUID_VERSION) {
hv_host_info_eax = cpuid_eax(HVCPUID_VERSION);
hv_host_info_ebx = cpuid_ebx(HVCPUID_VERSION);
hv_host_info_ecx = cpuid_ecx(HVCPUID_VERSION);
hv_host_info_edx = cpuid_edx(HVCPUID_VERSION);
pr_info("Hyper-V Host Build:%d-%d.%d-%d-%d.%d\n",
hv_host_info_eax, hv_host_info_ebx >> 16,
hv_host_info_ebx & 0xFFFF, hv_host_info_ecx,
hv_host_info_edx >> 24, hv_host_info_edx & 0xFFFFFF);
}
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) { if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) {
/* /*
......
...@@ -221,10 +221,7 @@ int vmbus_connect(void) ...@@ -221,10 +221,7 @@ int vmbus_connect(void)
goto cleanup; goto cleanup;
vmbus_proto_version = version; vmbus_proto_version = version;
pr_info("Hyper-V Host Build:%d-%d.%d-%d-%d.%d; Vmbus version:%d.%d\n", pr_info("Vmbus version:%d.%d\n",
host_info_eax, host_info_ebx >> 16,
host_info_ebx & 0xFFFF, host_info_ecx,
host_info_edx >> 24, host_info_edx & 0xFFFFFF,
version >> 16, version & 0xFFFF); version >> 16, version & 0xFFFF);
kfree(msginfo); kfree(msginfo);
......
...@@ -42,51 +42,6 @@ struct hv_context hv_context = { ...@@ -42,51 +42,6 @@ struct hv_context hv_context = {
#define HV_MAX_MAX_DELTA_TICKS 0xffffffff #define HV_MAX_MAX_DELTA_TICKS 0xffffffff
#define HV_MIN_DELTA_TICKS 1 #define HV_MIN_DELTA_TICKS 1
/*
* query_hypervisor_info - Get version info of the windows hypervisor
*/
unsigned int host_info_eax;
unsigned int host_info_ebx;
unsigned int host_info_ecx;
unsigned int host_info_edx;
static int query_hypervisor_info(void)
{
unsigned int eax;
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
unsigned int max_leaf;
unsigned int op;
/*
* Its assumed that this is called after confirming that Viridian
* is present. Query id and revision.
*/
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
op = HVCPUID_VENDOR_MAXFUNCTION;
cpuid(op, &eax, &ebx, &ecx, &edx);
max_leaf = eax;
if (max_leaf >= HVCPUID_VERSION) {
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
op = HVCPUID_VERSION;
cpuid(op, &eax, &ebx, &ecx, &edx);
host_info_eax = eax;
host_info_ebx = ebx;
host_info_ecx = ecx;
host_info_edx = edx;
}
return max_leaf;
}
/* /*
* hv_init - Main initialization routine. * hv_init - Main initialization routine.
* *
...@@ -94,7 +49,6 @@ static int query_hypervisor_info(void) ...@@ -94,7 +49,6 @@ static int query_hypervisor_info(void)
*/ */
int hv_init(void) int hv_init(void)
{ {
int max_leaf;
union hv_x64_msr_hypercall_contents hypercall_msr; union hv_x64_msr_hypercall_contents hypercall_msr;
memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS);
...@@ -111,9 +65,6 @@ int hv_init(void) ...@@ -111,9 +65,6 @@ int hv_init(void)
memset(hv_context.clk_evt, 0, memset(hv_context.clk_evt, 0,
sizeof(void *) * NR_CPUS); sizeof(void *) * NR_CPUS);
max_leaf = query_hypervisor_info();
/* See if the hypercall page is already set */ /* See if the hypercall page is already set */
hypercall_msr.as_uint64 = 0; hypercall_msr.as_uint64 = 0;
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
......
...@@ -40,25 +40,6 @@ ...@@ -40,25 +40,6 @@
*/ */
#define HV_UTIL_NEGO_TIMEOUT 55 #define HV_UTIL_NEGO_TIMEOUT 55
/*
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
* is set by CPUID(HVCPUID_VERSION_FEATURES).
*/
enum hv_cpuid_function {
HVCPUID_VERSION_FEATURES = 0x00000001,
HVCPUID_VENDOR_MAXFUNCTION = 0x40000000,
HVCPUID_INTERFACE = 0x40000001,
/*
* The remaining functions depend on the value of
* HVCPUID_INTERFACE
*/
HVCPUID_VERSION = 0x40000002,
HVCPUID_FEATURES = 0x40000003,
HVCPUID_ENLIGHTENMENT_INFO = 0x40000004,
HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005,
};
#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE 0x400 #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE 0x400
#define HV_X64_MSR_CRASH_P0 0x40000100 #define HV_X64_MSR_CRASH_P0 0x40000100
...@@ -444,14 +425,6 @@ extern int hv_synic_cleanup(unsigned int cpu); ...@@ -444,14 +425,6 @@ extern int hv_synic_cleanup(unsigned int cpu);
extern void hv_synic_clockevents_cleanup(void); extern void hv_synic_clockevents_cleanup(void);
/*
* Host version information.
*/
extern unsigned int host_info_eax;
extern unsigned int host_info_ebx;
extern unsigned int host_info_ecx;
extern unsigned int host_info_edx;
/* Interface */ /* Interface */
......
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