Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 May 2019 13:29:54 +0000 (UTC)
From:      "Stephen J. Kiernan" <stevek@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r348051 - in head/sys: kern sys x86/x86
Message-ID:  <201905211329.x4LDTsUh090903@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: stevek
Date: Tue May 21 13:29:53 2019
New Revision: 348051
URL: https://svnweb.freebsd.org/changeset/base/348051

Log:
  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

Modified:
  head/sys/kern/subr_param.c
  head/sys/sys/systm.h
  head/sys/x86/x86/identcpu.c

Modified: head/sys/kern/subr_param.c
==============================================================================
--- head/sys/kern/subr_param.c	Tue May 21 08:24:22 2019	(r348050)
+++ head/sys/kern/subr_param.c	Tue May 21 13:29:53 2019	(r348051)
@@ -146,15 +146,16 @@ SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CT
  * 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);
 

Modified: head/sys/sys/systm.h
==============================================================================
--- head/sys/sys/systm.h	Tue May 21 08:24:22 2019	(r348050)
+++ head/sys/sys/systm.h	Tue May 21 13:29:53 2019	(r348051)
@@ -79,7 +79,7 @@ extern int vm_guest;		/* Running as virtual machine gu
  */
 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

Modified: head/sys/x86/x86/identcpu.c
==============================================================================
--- head/sys/x86/x86/identcpu.c	Tue May 21 08:24:22 2019	(r348050)
+++ head/sys/x86/x86/identcpu.c	Tue May 21 13:29:53 2019	(r348051)
@@ -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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905211329.x4LDTsUh090903>