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.c64
1 files changed, 34 insertions, 30 deletions
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 4fa90006ac68..bea8d3e24f50 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -26,6 +26,12 @@
26#include <asm/processor.h> 26#include <asm/processor.h>
27#include <asm/hypervisor.h> 27#include <asm/hypervisor.h>
28 28
29extern const struct hypervisor_x86 x86_hyper_vmware;
30extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
31extern const struct hypervisor_x86 x86_hyper_xen_pv;
32extern const struct hypervisor_x86 x86_hyper_xen_hvm;
33extern const struct hypervisor_x86 x86_hyper_kvm;
34
29static const __initconst struct hypervisor_x86 * const hypervisors[] = 35static const __initconst struct hypervisor_x86 * const hypervisors[] =
30{ 36{
31#ifdef CONFIG_XEN_PV 37#ifdef CONFIG_XEN_PV
@@ -41,54 +47,52 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] =
41#endif 47#endif
42}; 48};
43 49
44const struct hypervisor_x86 *x86_hyper; 50enum x86_hypervisor_type x86_hyper_type;
45EXPORT_SYMBOL(x86_hyper); 51EXPORT_SYMBOL(x86_hyper_type);
46 52
47static inline void __init 53static inline const struct hypervisor_x86 * __init
48detect_hypervisor_vendor(void) 54detect_hypervisor_vendor(void)
49{ 55{
50 const struct hypervisor_x86 *h, * const *p; 56 const struct hypervisor_x86 *h = NULL, * const *p;
51 uint32_t pri, max_pri = 0; 57 uint32_t pri, max_pri = 0;
52 58
53 for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) { 59 for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
54 h = *p; 60 pri = (*p)->detect();
55 pri = h->detect(); 61 if (pri > max_pri) {
56 if (pri != 0 && pri > max_pri) {
57 max_pri = pri; 62 max_pri = pri;
58 x86_hyper = h; 63 h = *p;
59 } 64 }
60 } 65 }
61 66
62 if (max_pri) 67 if (h)
63 pr_info("Hypervisor detected: %s\n", x86_hyper->name); 68 pr_info("Hypervisor detected: %s\n", h->name);
69
70 return h;
64} 71}
65 72
66void __init init_hypervisor_platform(void) 73static void __init copy_array(const void *src, void *target, unsigned int size)
67{ 74{
75 unsigned int i, n = size / sizeof(void *);
76 const void * const *from = (const void * const *)src;
77 const void **to = (const void **)target;
68 78
69 detect_hypervisor_vendor(); 79 for (i = 0; i < n; i++)
70 80 if (from[i])
71 if (!x86_hyper) 81 to[i] = from[i];
72 return;
73
74 if (x86_hyper->init_platform)
75 x86_hyper->init_platform();
76} 82}
77 83
78bool __init hypervisor_x2apic_available(void) 84void __init init_hypervisor_platform(void)
79{ 85{
80 return x86_hyper && 86 const struct hypervisor_x86 *h;
81 x86_hyper->x2apic_available &&
82 x86_hyper->x2apic_available();
83}
84 87
85void hypervisor_pin_vcpu(int cpu) 88 h = detect_hypervisor_vendor();
86{ 89
87 if (!x86_hyper) 90 if (!h)
88 return; 91 return;
89 92
90 if (x86_hyper->pin_vcpu) 93 copy_array(&h->init, &x86_init.hyper, sizeof(h->init));
91 x86_hyper->pin_vcpu(cpu); 94 copy_array(&h->runtime, &x86_platform.hyper, sizeof(h->runtime));
92 else 95
93 WARN_ONCE(1, "vcpu pinning requested but not supported!\n"); 96 x86_hyper_type = h->type;
97 x86_init.hyper.init_platform();
94} 98}