aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/hypervisor.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/hypervisor.c')
-rw-r--r--arch/x86/kernel/cpu/hypervisor.c56
1 files changed, 34 insertions, 22 deletions
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index de3f4e0ce8eb..87381759d3cb 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -22,40 +22,52 @@
22 */ 22 */
23 23
24#include <asm/processor.h> 24#include <asm/processor.h>
25#include <asm/vmware.h>
26#include <asm/mshyperv.h>
27#include <asm/hypervisor.h> 25#include <asm/hypervisor.h>
28 26
29static inline void __cpuinit 27/*
30detect_hypervisor_vendor(struct cpuinfo_x86 *c) 28 * Hypervisor detect order. This is specified explicitly here because
29 * some hypervisors might implement compatibility modes for other
30 * hypervisors and therefore need to be detected in specific sequence.
31 */
32static const __initconst struct hypervisor_x86 * const hypervisors[] =
31{ 33{
32 if (vmware_platform()) 34 &x86_hyper_vmware,
33 c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE; 35 &x86_hyper_ms_hyperv,
34 else if (ms_hyperv_platform()) 36};
35 c->x86_hyper_vendor = X86_HYPER_VENDOR_MSFT;
36 else
37 c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
38}
39 37
40static inline void __cpuinit 38const struct hypervisor_x86 *x86_hyper;
41hypervisor_set_feature_bits(struct cpuinfo_x86 *c) 39
40static inline void __init
41detect_hypervisor_vendor(void)
42{ 42{
43 if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) 43 const struct hypervisor_x86 *h, * const *p;
44 vmware_set_feature_bits(c); 44
45 else if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_MSFT) 45 for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
46 ms_hyperv_set_feature_bits(c); 46 h = *p;
47 return; 47 if (h->detect()) {
48 x86_hyper = h;
49 printk(KERN_INFO "Hypervisor detected: %s\n", h->name);
50 break;
51 }
52 }
48} 53}
49 54
50void __cpuinit init_hypervisor(struct cpuinfo_x86 *c) 55void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
51{ 56{
52 detect_hypervisor_vendor(c); 57 if (x86_hyper && x86_hyper->set_cpu_features)
53 hypervisor_set_feature_bits(c); 58 x86_hyper->set_cpu_features(c);
54} 59}
55 60
56void __init init_hypervisor_platform(void) 61void __init init_hypervisor_platform(void)
57{ 62{
63
64 detect_hypervisor_vendor();
65
66 if (!x86_hyper)
67 return;
68
58 init_hypervisor(&boot_cpu_data); 69 init_hypervisor(&boot_cpu_data);
59 if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) 70
60 vmware_platform_setup(); 71 if (x86_hyper->init_platform)
72 x86_hyper->init_platform();
61} 73}