Index: sys/kern/subr_param.c =================================================================== --- sys/kern/subr_param.c +++ sys/kern/subr_param.c @@ -154,6 +154,7 @@ "kvm", "bhyve", "vbox", + "parallels", NULL }; CTASSERT(nitems(vm_guest_sysctl_names) - 1 == VM_LAST); Index: sys/sys/systm.h =================================================================== --- sys/sys/systm.h +++ sys/sys/systm.h @@ -79,7 +79,7 @@ */ 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_GUEST_VBOX, - VM_LAST }; + VM_GUEST_PARALLELS, VM_LAST }; /* * These functions need to be declared before the KASSERT macro is invoked in Index: sys/x86/x86/identcpu.c =================================================================== --- sys/x86/x86/identcpu.c +++ sys/x86/x86/identcpu.c @@ -1305,23 +1305,27 @@ SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL); -static const char *const vm_bnames[] = { - "QEMU", /* QEMU */ - "Plex86", /* Plex86 */ - "Bochs", /* Bochs */ - "Xen", /* Xen */ - "BHYVE", /* bhyve */ - "Seabios", /* KVM */ - NULL +static struct { + const char *const vm_bname; + int vm_guest; +} vm_bnames[] = { + { "QEMU", VM_GUEST_VM }, /* QEMU */ + { "Plex86", VM_GUEST_VM }, /* Plex86 */ + { "Bochs", VM_GUEST_VM }, /* Bochs */ + { "Xen", VM_GUEST_XEN }, /* Xen */ + { "BHYVE", VM_GUEST_BHYVE }, /* bhyve */ + { "Seabios", VM_GUEST_KVM }, /* KVM */ }; -static const char *const vm_pnames[] = { - "VMware Virtual Platform", /* VMWare VM */ - "Virtual Machine", /* Microsoft VirtualPC */ - "VirtualBox", /* Sun xVM VirtualBox */ - "Parallels Virtual Platform", /* Parallels VM */ - "KVM", /* KVM */ - NULL +static struct { + const char *const vm_pname; + int vm_guest; +} vm_pnames[] = { + { "VMware Virtual Platform", VM_GUEST_VMWARE }, + { "Virtual Machine", VM_GUEST_VM }, /* Microsoft VirtualPC */ + { "VirtualBox", VM_GUEST_VBOX }, + { "Parallels Virtual Platform", VM_GUEST_PARALLELS }, + { "KVM", VM_GUEST_KVM }, }; static struct { @@ -1382,7 +1386,8 @@ * and vendor identifier. */ if (vm_guest != VM_GUEST_VM || leaf == 0x40000000) { - hv_high = leaf; + 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]; @@ -1412,7 +1417,10 @@ if (cpu_feature2 & CPUID2_HV) { vm_guest = VM_GUEST_VM; identify_hypervisor_cpuid_base(); - return; + + /* If we have a definitive vendor, we can return now. */ + if (*hv_vendor) + return; } /* @@ -1437,9 +1445,9 @@ */ p = kern_getenv("smbios.bios.vendor"); if (p != NULL) { - for (i = 0; vm_bnames[i] != NULL; i++) - if (strcmp(p, vm_bnames[i]) == 0) { - vm_guest = VM_GUEST_VM; + for (i = 0; i < nitems(vm_bnames); i++) + if (strcmp(p, vm_bnames[i].vm_bname) == 0) { + vm_guest = vm_bnames[i].vm_guest; freeenv(p); return; } @@ -1447,9 +1455,9 @@ } p = kern_getenv("smbios.system.product"); if (p != NULL) { - for (i = 0; vm_pnames[i] != NULL; i++) - if (strcmp(p, vm_pnames[i]) == 0) { - vm_guest = VM_GUEST_VM; + for (i = 0; i < nitems(vm_pnames); i++) + if (strcmp(p, vm_pnames[i].vm_pname) == 0) { + vm_guest = vm_pnames[i].vm_guest; freeenv(p); return; }