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
2017-11-27 09:11:46 +01:00
# ifdef CONFIG_JAILHOUSE_GUEST
& x86_hyper_jailhouse ,
# endif
2019-04-30 11:45:24 +08:00
# ifdef CONFIG_ACRN_GUEST
& x86_hyper_acrn ,
# endif
2010-05-07 16:57:28 -07:00
} ;
2008-10-27 10:41:46 -07:00
2017-11-09 14:27:36 +01:00
enum x86_hypervisor_type x86_hyper_type ;
EXPORT_SYMBOL ( x86_hyper_type ) ;
2010-05-07 16:57:28 -07:00
2019-07-11 20:02:09 +08:00
bool __initdata nopv ;
static __init int parse_nopv ( char * arg )
{
nopv = true ;
return 0 ;
}
early_param ( " nopv " , parse_nopv ) ;
2017-11-09 14:27:35 +01:00
static inline const struct hypervisor_x86 * __init
2010-05-07 16:57:28 -07:00
detect_hypervisor_vendor ( void )
2008-10-31 12:01:58 -07:00
{
2017-11-09 14:27:35 +01:00
const struct hypervisor_x86 * h = NULL , * 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 + + ) {
2019-07-11 20:02:09 +08:00
if ( unlikely ( nopv ) & & ! ( * p ) - > ignore_nopv )
continue ;
2017-11-09 14:27:35 +01:00
pri = ( * p ) - > detect ( ) ;
if ( pri > max_pri ) {
2013-07-25 16:54:35 +08:00
max_pri = pri ;
2017-11-09 14:27:35 +01:00
h = * p ;
2010-05-07 16:57:28 -07:00
}
}
2013-07-25 16:54:35 +08:00
2017-11-09 14:27:35 +01:00
if ( h )
pr_info ( " Hypervisor detected: %s \n " , h - > name ) ;
return h ;
2008-10-31 12:01:58 -07:00
}
2017-11-09 14:27:35 +01:00
static void __init copy_array ( const void * src , void * target , unsigned int size )
2009-08-20 17:06:25 +02:00
{
2017-11-09 14:27:35 +01:00
unsigned int i , n = size / sizeof ( void * ) ;
const void * const * from = ( const void * const * ) src ;
const void * * to = ( const void * * ) target ;
2010-05-07 16:57:28 -07:00
2017-11-09 14:27:35 +01:00
for ( i = 0 ; i < n ; i + + )
if ( from [ i ] )
to [ i ] = from [ i ] ;
2009-08-20 17:06:25 +02:00
}
2013-01-17 15:44:42 -08:00
2017-11-09 14:27:35 +01:00
void __init init_hypervisor_platform ( void )
2013-01-17 15:44:42 -08:00
{
2017-11-09 14:27:35 +01:00
const struct hypervisor_x86 * h ;
2016-08-29 08:48:43 +02:00
2017-11-09 14:27:35 +01:00
h = detect_hypervisor_vendor ( ) ;
if ( ! h )
2016-08-29 08:48:43 +02:00
return ;
2017-11-09 14:27:35 +01:00
copy_array ( & h - > init , & x86_init . hyper , sizeof ( h - > init ) ) ;
copy_array ( & h - > runtime , & x86_platform . hyper , sizeof ( h - > runtime ) ) ;
2017-11-09 14:27:36 +01:00
x86_hyper_type = h - > type ;
2017-11-09 14:27:35 +01:00
x86_init . hyper . init_platform ( ) ;
2016-08-29 08:48:43 +02:00
}