1/*- 2 * Copyright (c) 2015 Martin Lucina. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 14 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <hw/types.h> 27#include <hw/kernel.h> 28 29#include <arch/x86/hypervisor.h> 30 31int hypervisor_detect(void) 32{ 33 uint32_t eax, ebx, ecx, edx; 34 35 /* 36 * First check for generic "hypervisor present" bit. 37 */ 38 x86_cpuid(0x0, &eax, &ebx, &ecx, &edx); 39 if (eax >= 0x1) { 40 x86_cpuid(0x1, &eax, &ebx, &ecx, &edx); 41 if (!(ecx & (1 << 31))) 42 return 0; 43 } 44 else 45 return 0; 46 47 /* 48 * CPUID leaf at 0x40000000 returns hypervisor vendor signature. 49 * Source: https://lkml.org/lkml/2008/10/1/246 50 */ 51 x86_cpuid(0x40000000, &eax, &ebx, &ecx, &edx); 52 if (!(eax >= 0x40000000)) 53 return 0; 54 /* Xen: "XenVMMXenVMM" */ 55 if (ebx == 0x566e6558 && ecx == 0x65584d4d && edx == 0x4d4d566e) 56 return HYPERVISOR_XEN; 57 /* VMware: "VMwareVMware" */ 58 else if (ebx == 0x61774d56 && ecx == 0x4d566572 && edx == 0x65726177) 59 return HYPERVISOR_VMWARE; 60 /* Hyper-V: "Microsoft Hv" */ 61 else if (ebx == 0x7263694d && ecx == 0x666f736f && edx == 0x76482074) 62 return HYPERVISOR_HYPERV; 63 /* KVM: "KVMKVMKVM\0\0\0" */ 64 else if (ebx == 0x4b4d564b && ecx == 0x564b4d56 && edx == 0x0000004d) 65 return HYPERVISOR_KVM; 66 67 return 0; 68} 69