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 .
*
*/
2010-05-09 22:46:54 -07:00
# include <linux/module.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
/*
* Hypervisor detect order . This is specified explicitly here because
* some hypervisors might implement compatibility modes for other
* hypervisors and therefore need to be detected in specific sequence .
*/
static const __initconst struct hypervisor_x86 * const hypervisors [ ] =
2008-10-27 10:41:46 -07:00
{
2010-05-07 16:57:28 -07:00
& x86_hyper_vmware ,
& x86_hyper_ms_hyperv ,
2010-07-29 14:37:48 +01:00
# ifdef CONFIG_XEN_PVHVM
2010-05-14 12:39:33 +01:00
& x86_hyper_xen_hvm ,
2010-07-26 10:38:45 -07: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 ;
for ( p = hypervisors ; p < hypervisors + ARRAY_SIZE ( hypervisors ) ; p + + ) {
h = * p ;
if ( h - > detect ( ) ) {
x86_hyper = h ;
printk ( KERN_INFO " Hypervisor detected: %s \n " , h - > name ) ;
break ;
}
}
2008-10-31 12:01:58 -07:00
}
2008-10-27 10:41:46 -07:00
void __cpuinit init_hypervisor ( struct cpuinfo_x86 * c )
{
2010-05-07 16:57:28 -07:00
if ( x86_hyper & & x86_hyper - > set_cpu_features )
x86_hyper - > set_cpu_features ( c ) ;
2008-10-27 10:41:46 -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 ;
2009-08-20 17:06:25 +02:00
init_hypervisor ( & boot_cpu_data ) ;
2010-05-07 16:57:28 -07:00
if ( x86_hyper - > init_platform )
x86_hyper - > init_platform ( ) ;
2009-08-20 17:06:25 +02:00
}