xref: /linux/arch/x86/kernel/cpu/hypervisor.c (revision 0991d22d5e7fad3ea4f504a1eb0ccb4707135f64)
188b094fbSAlok Kataria /*
288b094fbSAlok Kataria  * Common hypervisor code
388b094fbSAlok Kataria  *
488b094fbSAlok Kataria  * Copyright (C) 2008, VMware, Inc.
588b094fbSAlok Kataria  * Author : Alok N Kataria <akataria@vmware.com>
688b094fbSAlok Kataria  *
788b094fbSAlok Kataria  * This program is free software; you can redistribute it and/or modify
888b094fbSAlok Kataria  * it under the terms of the GNU General Public License as published by
988b094fbSAlok Kataria  * the Free Software Foundation; either version 2 of the License, or
1088b094fbSAlok Kataria  * (at your option) any later version.
1188b094fbSAlok Kataria  *
1288b094fbSAlok Kataria  * This program is distributed in the hope that it will be useful, but
1388b094fbSAlok Kataria  * WITHOUT ANY WARRANTY; without even the implied warranty of
1488b094fbSAlok Kataria  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
1588b094fbSAlok Kataria  * NON INFRINGEMENT.  See the GNU General Public License for more
1688b094fbSAlok Kataria  * details.
1788b094fbSAlok Kataria  *
1888b094fbSAlok Kataria  * You should have received a copy of the GNU General Public License
1988b094fbSAlok Kataria  * along with this program; if not, write to the Free Software
2088b094fbSAlok Kataria  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2188b094fbSAlok Kataria  *
2288b094fbSAlok Kataria  */
2388b094fbSAlok Kataria 
24186f4360SPaul Gortmaker #include <linux/init.h>
25186f4360SPaul Gortmaker #include <linux/export.h>
2688b094fbSAlok Kataria #include <asm/processor.h>
274e42ebd5SHannes Eder #include <asm/hypervisor.h>
2888b094fbSAlok Kataria 
29e08cae41SH. Peter Anvin static const __initconst struct hypervisor_x86 * const hypervisors[] =
3088b094fbSAlok Kataria {
31a71dbdaaSBoris Ostrovsky #ifdef CONFIG_XEN
32*0991d22dSVitaly Kuznetsov 	&x86_hyper_xen_pv,
33*0991d22dSVitaly Kuznetsov 	&x86_hyper_xen_hvm,
34b43275d6SJeremy Fitzhardinge #endif
3524a42baeSAnupam Chanda 	&x86_hyper_vmware,
3624a42baeSAnupam Chanda 	&x86_hyper_ms_hyperv,
37d63d3e62SAvi Kivity #ifdef CONFIG_KVM_GUEST
38fc73373bSPrarit Bhargava 	&x86_hyper_kvm,
39d63d3e62SAvi Kivity #endif
40e08cae41SH. Peter Anvin };
4188b094fbSAlok Kataria 
42e08cae41SH. Peter Anvin const struct hypervisor_x86 *x86_hyper;
4396f6e775SH. Peter Anvin EXPORT_SYMBOL(x86_hyper);
44e08cae41SH. Peter Anvin 
45e08cae41SH. Peter Anvin static inline void __init
46e08cae41SH. Peter Anvin detect_hypervisor_vendor(void)
47eca0cd02SAlok Kataria {
48e08cae41SH. Peter Anvin 	const struct hypervisor_x86 *h, * const *p;
499df56f19SJason Wang 	uint32_t pri, max_pri = 0;
50e08cae41SH. Peter Anvin 
51e08cae41SH. Peter Anvin 	for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
52e08cae41SH. Peter Anvin 		h = *p;
539df56f19SJason Wang 		pri = h->detect();
549df56f19SJason Wang 		if (pri != 0 && pri > max_pri) {
559df56f19SJason Wang 			max_pri = pri;
56e08cae41SH. Peter Anvin 			x86_hyper = h;
57e08cae41SH. Peter Anvin 		}
58e08cae41SH. Peter Anvin 	}
599df56f19SJason Wang 
609df56f19SJason Wang 	if (max_pri)
611b74dde7SChen Yucong 		pr_info("Hypervisor detected: %s\n", x86_hyper->name);
62eca0cd02SAlok Kataria }
63eca0cd02SAlok Kataria 
64148f9bb8SPaul Gortmaker void init_hypervisor(struct cpuinfo_x86 *c)
6588b094fbSAlok Kataria {
66e08cae41SH. Peter Anvin 	if (x86_hyper && x86_hyper->set_cpu_features)
67e08cae41SH. Peter Anvin 		x86_hyper->set_cpu_features(c);
6888b094fbSAlok Kataria }
692d826404SThomas Gleixner 
702d826404SThomas Gleixner void __init init_hypervisor_platform(void)
712d826404SThomas Gleixner {
72e08cae41SH. Peter Anvin 
73e08cae41SH. Peter Anvin 	detect_hypervisor_vendor();
74e08cae41SH. Peter Anvin 
75e08cae41SH. Peter Anvin 	if (!x86_hyper)
76e08cae41SH. Peter Anvin 		return;
77e08cae41SH. Peter Anvin 
782d826404SThomas Gleixner 	init_hypervisor(&boot_cpu_data);
79e08cae41SH. Peter Anvin 
80e08cae41SH. Peter Anvin 	if (x86_hyper->init_platform)
81e08cae41SH. Peter Anvin 		x86_hyper->init_platform();
822d826404SThomas Gleixner }
834cca6ea0SAlok N Kataria 
844cca6ea0SAlok N Kataria bool __init hypervisor_x2apic_available(void)
854cca6ea0SAlok N Kataria {
864cca6ea0SAlok N Kataria 	return x86_hyper                   &&
874cca6ea0SAlok N Kataria 	       x86_hyper->x2apic_available &&
884cca6ea0SAlok N Kataria 	       x86_hyper->x2apic_available();
894cca6ea0SAlok N Kataria }
9047ae4b05SJuergen Gross 
9147ae4b05SJuergen Gross void hypervisor_pin_vcpu(int cpu)
9247ae4b05SJuergen Gross {
9347ae4b05SJuergen Gross 	if (!x86_hyper)
9447ae4b05SJuergen Gross 		return;
9547ae4b05SJuergen Gross 
9647ae4b05SJuergen Gross 	if (x86_hyper->pin_vcpu)
9747ae4b05SJuergen Gross 		x86_hyper->pin_vcpu(cpu);
9847ae4b05SJuergen Gross 	else
9947ae4b05SJuergen Gross 		WARN_ONCE(1, "vcpu pinning requested but not supported!\n");
10047ae4b05SJuergen Gross }
101