Page MenuHomeFreeBSD

D16305.id45560.diff
No OneTemporary

D16305.id45560.diff

Index: sys/kern/subr_param.c
===================================================================
--- sys/kern/subr_param.c
+++ sys/kern/subr_param.c
@@ -152,6 +152,7 @@
"vmware",
"kvm",
"bhyve",
+ "vbox",
NULL
};
CTASSERT(nitems(vm_guest_sysctl_names) - 1 == VM_LAST);
Index: sys/sys/systm.h
===================================================================
--- sys/sys/systm.h
+++ sys/sys/systm.h
@@ -78,7 +78,8 @@
* Keep in sync with vm_guest_sysctl_names[].
*/
enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV,
- VM_GUEST_VMWARE, VM_GUEST_KVM, VM_GUEST_BHYVE, VM_LAST };
+ VM_GUEST_VMWARE, VM_GUEST_KVM, VM_GUEST_BHYVE, VM_GUEST_VBOX,
+ VM_LAST };
#if defined(WITNESS) || defined(INVARIANT_SUPPORT)
void kassert_panic(const char *fmt, ...) __printflike(1, 2);
Index: sys/x86/include/x86_var.h
===================================================================
--- sys/x86/include/x86_var.h
+++ sys/x86/include/x86_var.h
@@ -68,6 +68,7 @@
extern u_int cpu_mon_max_size;
extern u_int cpu_maxphyaddr;
extern char ctx_switch_xsave[];
+extern u_int hv_base;
extern u_int hv_high;
extern char hv_vendor[];
extern char kstack[];
Index: sys/x86/x86/identcpu.c
===================================================================
--- sys/x86/x86/identcpu.c
+++ sys/x86/x86/identcpu.c
@@ -161,6 +161,7 @@
SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
&hw_clockrate, 0, "CPU instruction clock rate");
+u_int hv_base;
u_int hv_high;
char hv_vendor[16];
SYSCTL_STRING(_hw, OID_AUTO, hv_vendor, CTLFLAG_RD | CTLFLAG_MPSAFE, hv_vendor,
@@ -1255,6 +1256,71 @@
hw_clockrate = level->total_set.freq;
}
+static struct {
+ const char *vm_cpuid;
+ int vm_guest;
+} vm_cpuids[] = {
+ { "XENXENXEN", VM_GUEST_XEN }, /* XEN */
+ { "Microsoft Hv", VM_GUEST_HV }, /* Microsoft Hyper-V */
+ { "VMwareVMware", VM_GUEST_VMWARE }, /* VMware VM */
+ { "KVMKVMKVM", VM_GUEST_KVM }, /* KVM */
+ { "bhyve bhyve", VM_GUEST_BHYVE }, /* bhyve */
+ { "VBoxVBoxVBox", VM_GUEST_VBOX }, /* VirtualBox */
+};
+
+static void
+identify_hypervisor_cpuid_base(void)
+{
+ u_int leaf, regs[4];
+ int i;
+
+ /*
+ * [RFC] CPUID usage for interaction between Hypervisors and Linux.
+ * http://lkml.org/lkml/2008/10/1/246
+ *
+ * KB1009458: Mechanisms to determine if software is running in
+ * a VMware virtual machine
+ * http://kb.vmware.com/kb/1009458
+ */
+ for (leaf = 0x40000000; leaf < 0x40010000; leaf += 0x100) {
+ do_cpuid(leaf, regs);
+
+ /*
+ * KVM from Linux kernels prior to commit
+ * 57c22e5f35aa4b9b2fe11f73f3e62bbf9ef36190 set %eax
+ * to 0 rather than a valid hv_high value. Check for
+ * the KVM signature bytes and fixup %eax to the
+ * highest supported leaf in that case.
+ */
+ if (regs[0] == 0 && regs[1] == 0x4b4d564b &&
+ regs[2] == 0x564b4d56 && regs[3] == 0x0000004d)
+ regs[0] = leaf + 1;
+
+ if (regs[0] >= 0x40000000) {
+ for (i = 0; i < nitems(vm_cpuids); i++)
+ if (strncmp((const char *)&regs[1],
+ vm_cpuids[i].vm_cpuid, 12) == 0) {
+ vm_guest = vm_cpuids[i].vm_guest;
+ break;
+ }
+
+ /*
+ * If we found a specific hypervisor, record the
+ * base, high value, and vendor identifier.
+ */
+ if (vm_guest != VM_GUEST_VM) {
+ hv_base = leaf;
+ hv_high = regs[0];
+ ((u_int *)&hv_vendor)[0] = regs[1];
+ ((u_int *)&hv_vendor)[1] = regs[2];
+ ((u_int *)&hv_vendor)[2] = regs[3];
+ hv_vendor[12] = '\0';
+ return;
+ }
+ }
+ }
+}
+
static void
hook_tsc_freq(void *arg __unused)
{
@@ -1295,43 +1361,11 @@
int i;
/*
- * [RFC] CPUID usage for interaction between Hypervisors and Linux.
- * http://lkml.org/lkml/2008/10/1/246
- *
- * KB1009458: Mechanisms to determine if software is running in
- * a VMware virtual machine
- * http://kb.vmware.com/kb/1009458
+ * If CPUID2_HV is set, we are running in a hypervisor environment.
*/
if (cpu_feature2 & CPUID2_HV) {
vm_guest = VM_GUEST_VM;
- do_cpuid(0x40000000, regs);
-
- /*
- * KVM from Linux kernels prior to commit
- * 57c22e5f35aa4b9b2fe11f73f3e62bbf9ef36190 set %eax
- * to 0 rather than a valid hv_high value. Check for
- * the KVM signature bytes and fixup %eax to the
- * highest supported leaf in that case.
- */
- if (regs[0] == 0 && regs[1] == 0x4b4d564b &&
- regs[2] == 0x564b4d56 && regs[3] == 0x0000004d)
- regs[0] = 0x40000001;
-
- if (regs[0] >= 0x40000000) {
- hv_high = regs[0];
- ((u_int *)&hv_vendor)[0] = regs[1];
- ((u_int *)&hv_vendor)[1] = regs[2];
- ((u_int *)&hv_vendor)[2] = regs[3];
- hv_vendor[12] = '\0';
- if (strcmp(hv_vendor, "VMwareVMware") == 0)
- vm_guest = VM_GUEST_VMWARE;
- else if (strcmp(hv_vendor, "Microsoft Hv") == 0)
- vm_guest = VM_GUEST_HV;
- else if (strcmp(hv_vendor, "KVMKVMKVM") == 0)
- vm_guest = VM_GUEST_KVM;
- else if (strcmp(hv_vendor, "bhyve bhyve") == 0)
- vm_guest = VM_GUEST_BHYVE;
- }
+ identify_hypervisor_cpuid_base();
return;
}

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 6, 4:59 PM (16 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30986669
Default Alt Text
D16305.id45560.diff (4 KB)

Event Timeline