The older detection methods (smbios.bios.vendor and smbios.system.product)
are able to determine some virtual machines, but the vm_guest variable was still only being set to VM_GUEST_VM. Since we do know what some of them specifically are, we can set vm_guest appropriately. Also, if we see the CPUID has the HV flag, but we were unable to find a definitive vendor in the Hypervisor CPUID Information Leaf, fall back to the older detection methods, as they may be able to determine a specific HV type. Add VM_GUEST_PARALLELS value to VM_GUEST for Parallels. Approved by: cem Differential Revision: https://reviews.freebsd.org/D20305
This commit is contained in:
parent
7c7d049637
commit
1177d38ce1
@ -146,15 +146,16 @@ SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING,
|
||||
* corresponding enum VM_GUEST members.
|
||||
*/
|
||||
static const char *const vm_guest_sysctl_names[] = {
|
||||
"none",
|
||||
"generic",
|
||||
"xen",
|
||||
"hv",
|
||||
"vmware",
|
||||
"kvm",
|
||||
"bhyve",
|
||||
"vbox",
|
||||
NULL
|
||||
[VM_GUEST_NO] = "none",
|
||||
[VM_GUEST_VM] = "generic",
|
||||
[VM_GUEST_XEN] = "xen",
|
||||
[VM_GUEST_HV] = "hv",
|
||||
[VM_GUEST_VMWARE] = "vmware",
|
||||
[VM_GUEST_KVM] = "kvm",
|
||||
[VM_GUEST_BHYVE] = "bhyve",
|
||||
[VM_GUEST_VBOX] = "vbox",
|
||||
[VM_GUEST_PARALLELS] = "parallels",
|
||||
[VM_LAST] = NULL
|
||||
};
|
||||
CTASSERT(nitems(vm_guest_sysctl_names) - 1 == VM_LAST);
|
||||
|
||||
|
@ -79,7 +79,7 @@ extern int vm_guest; /* Running as virtual machine guest? */
|
||||
*/
|
||||
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
|
||||
|
@ -1305,23 +1305,27 @@ hook_tsc_freq(void *arg __unused)
|
||||
|
||||
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 const struct {
|
||||
const char * 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 const struct {
|
||||
const char * 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 {
|
||||
@ -1413,7 +1417,10 @@ identify_hypervisor(void)
|
||||
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 != '\0')
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1438,19 +1445,27 @@ identify_hypervisor(void)
|
||||
*/
|
||||
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;
|
||||
freeenv(p);
|
||||
return;
|
||||
for (i = 0; i < nitems(vm_bnames); i++)
|
||||
if (strcmp(p, vm_bnames[i].vm_bname) == 0) {
|
||||
vm_guest = vm_bnames[i].vm_guest;
|
||||
/* If we have a specific match, return */
|
||||
if (vm_guest != VM_GUEST_VM) {
|
||||
freeenv(p);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* We are done with bnames, but there might be
|
||||
* a more specific match in the pnames
|
||||
*/
|
||||
break;
|
||||
}
|
||||
freeenv(p);
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -2586,7 +2601,7 @@ static void
|
||||
print_hypervisor_info(void)
|
||||
{
|
||||
|
||||
if (*hv_vendor)
|
||||
if (*hv_vendor != '\0')
|
||||
printf("Hypervisor: Origin = \"%s\"\n", hv_vendor);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user