Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113/* * 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. * */
#include <linux/init.h>#include <linux/export.h>#include <asm/processor.h>#include <asm/hypervisor.h>
static const __initconst struct hypervisor_x86 * const hypervisors[] ={#ifdef CONFIG_XEN_PV &x86_hyper_xen_pv,#endif#ifdef CONFIG_XEN_PVHVM &x86_hyper_xen_hvm,#endif &x86_hyper_vmware, &x86_hyper_ms_hyperv,#ifdef CONFIG_KVM_GUEST &x86_hyper_kvm,#endif#ifdef CONFIG_JAILHOUSE_GUEST &x86_hyper_jailhouse,#endif#ifdef CONFIG_ACRN_GUEST &x86_hyper_acrn,#endif#ifdef CONFIG_BHYVE_GUEST &x86_hyper_bhyve,#endif};
enum x86_hypervisor_type x86_hyper_type;EXPORT_SYMBOL(x86_hyper_type);
bool __initdata nopv;static __init int parse_nopv(char *arg){ nopv = true; return 0;}early_param("nopv", parse_nopv);
static inline const struct hypervisor_x86 * __initdetect_hypervisor_vendor(void){ const struct hypervisor_x86 *h = NULL, * const *p; uint32_t pri, max_pri = 0;
for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) { if (unlikely(nopv) && !(*p)->ignore_nopv) continue;
pri = (*p)->detect(); if (pri > max_pri) { max_pri = pri; h = *p; } }
if (h) pr_info("Hypervisor detected: %s\n", h->name);
return h;}
static void __init copy_array(const void *src, void *target, unsigned int size){ unsigned int i, n = size / sizeof(void *); const void * const *from = (const void * const *)src; const void **to = (const void **)target;
for (i = 0; i < n; i++) if (from[i]) to[i] = from[i];}
void __init init_hypervisor_platform(void){ const struct hypervisor_x86 *h;
h = detect_hypervisor_vendor();
if (!h) return;
copy_array(&h->init, &x86_init.hyper, sizeof(h->init)); copy_array(&h->runtime, &x86_platform.hyper, sizeof(h->runtime));
x86_hyper_type = h->type; x86_init.hyper.init_platform();}