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