git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/sysinfo/hypervisor.go (about) 1 // Copyright © 2016 Zlatko Čalušić 2 // 3 // Use of this source code is governed by an MIT-style license that can be found in the LICENSE file. 4 5 package sysinfo 6 7 import ( 8 "strings" 9 "unsafe" 10 11 "git.sr.ht/~pingoo/stdx/sysinfo/cpuid" 12 ) 13 14 // https://en.wikipedia.org/wiki/CPUID#EAX.3D0:_Get_vendor_ID 15 var hvmap = map[string]string{ 16 "bhyve bhyve ": "bhyve", 17 "KVMKVMKVM": "kvm", 18 "Microsoft Hv": "hyperv", 19 " lrpepyh vr": "parallels", 20 "VMwareVMware": "vmware", 21 "XenVMMXenVMM": "xenhvm", 22 } 23 24 func isHypervisorActive() bool { 25 var info [4]uint32 26 cpuid.CPUID(&info, 0x1) 27 return info[2]&(1<<31) != 0 28 } 29 30 func getHypervisorCpuid(ax uint32) string { 31 var info [4]uint32 32 cpuid.CPUID(&info, ax) 33 return hvmap[strings.TrimRight(string((*[12]byte)(unsafe.Pointer(&info[1]))[:]), "\000")] 34 } 35 36 func (si *SysInfo) getHypervisor() { 37 if !isHypervisorActive() { 38 if hypervisorType := slurpFile("/sys/hypervisor/type"); hypervisorType != "" { 39 if hypervisorType == "xen" { 40 si.Node.Hypervisor = "xenpv" 41 } 42 } 43 return 44 } 45 46 // KVM has been caught to move its real signature to this leaf, and put something completely different in the 47 // standard location. So this leaf must be checked first. 48 if hv := getHypervisorCpuid(0x40000100); hv != "" { 49 si.Node.Hypervisor = hv 50 return 51 } 52 53 if hv := getHypervisorCpuid(0x40000000); hv != "" { 54 si.Node.Hypervisor = hv 55 return 56 } 57 58 // getBIOSInfo() must have run first, to detect BIOS vendor 59 if si.BIOS.Vendor == "Bochs" { 60 si.Node.Hypervisor = "bochs" 61 return 62 } 63 64 si.Node.Hypervisor = "unknown" 65 }