Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Common hypervisor code
0003  *
0004  * Copyright (C) 2008, VMware, Inc.
0005  * Author : Alok N Kataria <akataria@vmware.com>
0006  *
0007  * This program is free software; you can redistribute it and/or modify
0008  * it under the terms of the GNU General Public License as published by
0009  * the Free Software Foundation; either version 2 of the License, or
0010  * (at your option) any later version.
0011  *
0012  * This program is distributed in the hope that it will be useful, but
0013  * WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
0015  * NON INFRINGEMENT.  See the GNU General Public License for more
0016  * details.
0017  *
0018  * You should have received a copy of the GNU General Public License
0019  * along with this program; if not, write to the Free Software
0020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0021  *
0022  */
0023 
0024 #include <linux/init.h>
0025 #include <linux/export.h>
0026 #include <asm/processor.h>
0027 #include <asm/hypervisor.h>
0028 
0029 static const __initconst struct hypervisor_x86 * const hypervisors[] =
0030 {
0031 #ifdef CONFIG_XEN_PV
0032     &x86_hyper_xen_pv,
0033 #endif
0034 #ifdef CONFIG_XEN_PVHVM
0035     &x86_hyper_xen_hvm,
0036 #endif
0037     &x86_hyper_vmware,
0038     &x86_hyper_ms_hyperv,
0039 #ifdef CONFIG_KVM_GUEST
0040     &x86_hyper_kvm,
0041 #endif
0042 #ifdef CONFIG_JAILHOUSE_GUEST
0043     &x86_hyper_jailhouse,
0044 #endif
0045 #ifdef CONFIG_ACRN_GUEST
0046     &x86_hyper_acrn,
0047 #endif
0048 };
0049 
0050 enum x86_hypervisor_type x86_hyper_type;
0051 EXPORT_SYMBOL(x86_hyper_type);
0052 
0053 bool __initdata nopv;
0054 static __init int parse_nopv(char *arg)
0055 {
0056     nopv = true;
0057     return 0;
0058 }
0059 early_param("nopv", parse_nopv);
0060 
0061 static inline const struct hypervisor_x86 * __init
0062 detect_hypervisor_vendor(void)
0063 {
0064     const struct hypervisor_x86 *h = NULL, * const *p;
0065     uint32_t pri, max_pri = 0;
0066 
0067     for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
0068         if (unlikely(nopv) && !(*p)->ignore_nopv)
0069             continue;
0070 
0071         pri = (*p)->detect();
0072         if (pri > max_pri) {
0073             max_pri = pri;
0074             h = *p;
0075         }
0076     }
0077 
0078     if (h)
0079         pr_info("Hypervisor detected: %s\n", h->name);
0080 
0081     return h;
0082 }
0083 
0084 static void __init copy_array(const void *src, void *target, unsigned int size)
0085 {
0086     unsigned int i, n = size / sizeof(void *);
0087     const void * const *from = (const void * const *)src;
0088     const void **to = (const void **)target;
0089 
0090     for (i = 0; i < n; i++)
0091         if (from[i])
0092             to[i] = from[i];
0093 }
0094 
0095 void __init init_hypervisor_platform(void)
0096 {
0097     const struct hypervisor_x86 *h;
0098 
0099     h = detect_hypervisor_vendor();
0100 
0101     if (!h)
0102         return;
0103 
0104     copy_array(&h->init, &x86_init.hyper, sizeof(h->init));
0105     copy_array(&h->runtime, &x86_platform.hyper, sizeof(h->runtime));
0106 
0107     x86_hyper_type = h->type;
0108     x86_init.hyper.init_platform();
0109 }