cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hypervisor.c (2617B)


      1/*
      2 * Common hypervisor code
      3 *
      4 * Copyright (C) 2008, VMware, Inc.
      5 * Author : Alok N Kataria <akataria@vmware.com>
      6 *
      7 * This program is free software; you can redistribute it and/or modify
      8 * it under the terms of the GNU General Public License as published by
      9 * the Free Software Foundation; either version 2 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * This program is distributed in the hope that it will be useful, but
     13 * WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
     15 * NON INFRINGEMENT.  See the GNU General Public License for more
     16 * details.
     17 *
     18 * You should have received a copy of the GNU General Public License
     19 * along with this program; if not, write to the Free Software
     20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21 *
     22 */
     23
     24#include <linux/init.h>
     25#include <linux/export.h>
     26#include <asm/processor.h>
     27#include <asm/hypervisor.h>
     28
     29static const __initconst struct hypervisor_x86 * const hypervisors[] =
     30{
     31#ifdef CONFIG_XEN_PV
     32	&x86_hyper_xen_pv,
     33#endif
     34#ifdef CONFIG_XEN_PVHVM
     35	&x86_hyper_xen_hvm,
     36#endif
     37	&x86_hyper_vmware,
     38	&x86_hyper_ms_hyperv,
     39#ifdef CONFIG_KVM_GUEST
     40	&x86_hyper_kvm,
     41#endif
     42#ifdef CONFIG_JAILHOUSE_GUEST
     43	&x86_hyper_jailhouse,
     44#endif
     45#ifdef CONFIG_ACRN_GUEST
     46	&x86_hyper_acrn,
     47#endif
     48};
     49
     50enum x86_hypervisor_type x86_hyper_type;
     51EXPORT_SYMBOL(x86_hyper_type);
     52
     53bool __initdata nopv;
     54static __init int parse_nopv(char *arg)
     55{
     56	nopv = true;
     57	return 0;
     58}
     59early_param("nopv", parse_nopv);
     60
     61static inline const struct hypervisor_x86 * __init
     62detect_hypervisor_vendor(void)
     63{
     64	const struct hypervisor_x86 *h = NULL, * const *p;
     65	uint32_t pri, max_pri = 0;
     66
     67	for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
     68		if (unlikely(nopv) && !(*p)->ignore_nopv)
     69			continue;
     70
     71		pri = (*p)->detect();
     72		if (pri > max_pri) {
     73			max_pri = pri;
     74			h = *p;
     75		}
     76	}
     77
     78	if (h)
     79		pr_info("Hypervisor detected: %s\n", h->name);
     80
     81	return h;
     82}
     83
     84static void __init copy_array(const void *src, void *target, unsigned int size)
     85{
     86	unsigned int i, n = size / sizeof(void *);
     87	const void * const *from = (const void * const *)src;
     88	const void **to = (const void **)target;
     89
     90	for (i = 0; i < n; i++)
     91		if (from[i])
     92			to[i] = from[i];
     93}
     94
     95void __init init_hypervisor_platform(void)
     96{
     97	const struct hypervisor_x86 *h;
     98
     99	h = detect_hypervisor_vendor();
    100
    101	if (!h)
    102		return;
    103
    104	copy_array(&h->init, &x86_init.hyper, sizeof(h->init));
    105	copy_array(&h->runtime, &x86_platform.hyper, sizeof(h->runtime));
    106
    107	x86_hyper_type = h->type;
    108	x86_init.hyper.init_platform();
    109}