2008-10-27 10:41:46 -07:00
/*
* Common hypervisor code
*
* Copyright ( C ) 2008 , VMware , Inc .
* Author : Alok N Kataria < akataria @ vmware . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE , GOOD TITLE or
* NON INFRINGEMENT . See the GNU General Public License for more
* details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
*/
2016-07-13 20:18:56 -04:00
# include <linux/init.h>
# include <linux/export.h>
2008-10-27 10:41:46 -07:00
# include <asm/processor.h>
2008-11-21 22:56:17 +01:00
# include <asm/hypervisor.h>
2008-10-27 10:41:46 -07:00
2010-05-07 16:57:28 -07:00
static const __initconst struct hypervisor_x86 * const hypervisors [ ] =
2008-10-27 10:41:46 -07:00
{
2017-03-14 18:35:38 +01:00
# ifdef CONFIG_XEN_PV
2017-03-14 18:35:36 +01:00
& x86_hyper_xen_pv ,
2017-03-14 18:35:38 +01:00
# endif
# ifdef CONFIG_XEN_PVHVM
2017-03-14 18:35:36 +01:00
& x86_hyper_xen_hvm ,
2010-07-26 10:38:45 -07:00
# endif
2011-07-08 11:42:50 -07:00
& x86_hyper_vmware ,
& x86_hyper_ms_hyperv ,
2012-07-18 11:48:50 +03:00
# ifdef CONFIG_KVM_GUEST
2012-07-06 13:47:39 -04:00
& x86_hyper_kvm ,
2012-07-18 11:48:50 +03:00
# endif
2010-05-07 16:57:28 -07:00
} ;
2008-10-27 10:41:46 -07:00
2010-05-07 16:57:28 -07:00
const struct hypervisor_x86 * x86_hyper ;
2010-05-09 01:10:34 -07:00
EXPORT_SYMBOL ( x86_hyper ) ;
2010-05-07 16:57:28 -07:00
static inline void __init
detect_hypervisor_vendor ( void )
2008-10-31 12:01:58 -07:00
{
2010-05-07 16:57:28 -07:00
const struct hypervisor_x86 * h , * const * p ;
2013-07-25 16:54:35 +08:00
uint32_t pri , max_pri = 0 ;
2010-05-07 16:57:28 -07:00
for ( p = hypervisors ; p < hypervisors + ARRAY_SIZE ( hypervisors ) ; p + + ) {
h = * p ;
2013-07-25 16:54:35 +08:00
pri = h - > detect ( ) ;
if ( pri ! = 0 & & pri > max_pri ) {
max_pri = pri ;
2010-05-07 16:57:28 -07:00
x86_hyper = h ;
}
}
2013-07-25 16:54:35 +08:00
if ( max_pri )
2016-02-02 11:45:02 +08:00
pr_info ( " Hypervisor detected: %s \n " , x86_hyper - > name ) ;
2008-10-31 12:01:58 -07:00
}
2009-08-20 17:06:25 +02:00
void __init init_hypervisor_platform ( void )
{
2010-05-07 16:57:28 -07:00
detect_hypervisor_vendor ( ) ;
if ( ! x86_hyper )
return ;
if ( x86_hyper - > init_platform )
x86_hyper - > init_platform ( ) ;
2009-08-20 17:06:25 +02:00
}
2013-01-17 15:44:42 -08:00
bool __init hypervisor_x2apic_available ( void )
{
return x86_hyper & &
x86_hyper - > x2apic_available & &
x86_hyper - > x2apic_available ( ) ;
}
2016-08-29 08:48:43 +02:00
void hypervisor_pin_vcpu ( int cpu )
{
if ( ! x86_hyper )
return ;
if ( x86_hyper - > pin_vcpu )
x86_hyper - > pin_vcpu ( cpu ) ;
else
WARN_ONCE ( 1 , " vcpu pinning requested but not supported! \n " ) ;
}