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);
 }
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to