12fee8756SJohn-Mark Gurney /*-
22fee8756SJohn-Mark Gurney * Copyright 2014 John Baldwin
32fee8756SJohn-Mark Gurney * Copyright 2019 Stephen J. Kiernan
42fee8756SJohn-Mark Gurney * All rights reserved.
52fee8756SJohn-Mark Gurney *
62fee8756SJohn-Mark Gurney * Redistribution and use in source and binary forms, with or without
72fee8756SJohn-Mark Gurney * modification, are permitted provided that the following conditions
82fee8756SJohn-Mark Gurney * are met:
92fee8756SJohn-Mark Gurney * 1. Redistributions of source code must retain the above copyright
102fee8756SJohn-Mark Gurney * notice, this list of conditions and the following disclaimer.
112fee8756SJohn-Mark Gurney * 2. Redistributions in binary form must reproduce the above copyright
122fee8756SJohn-Mark Gurney * notice, this list of conditions and the following disclaimer in the
132fee8756SJohn-Mark Gurney * documentation and/or other materials provided with the distribution.
142fee8756SJohn-Mark Gurney * 3. All advertising materials mentioning features or use of this software
152fee8756SJohn-Mark Gurney * must display the following acknowledgement:
162fee8756SJohn-Mark Gurney * This product includes software developed by the University of
172fee8756SJohn-Mark Gurney * California, Berkeley and its contributors.
182fee8756SJohn-Mark Gurney * 4. Neither the name of the University nor the names of its contributors
192fee8756SJohn-Mark Gurney * may be used to endorse or promote products derived from this software
202fee8756SJohn-Mark Gurney * without specific prior written permission.
212fee8756SJohn-Mark Gurney *
222fee8756SJohn-Mark Gurney * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
232fee8756SJohn-Mark Gurney * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
242fee8756SJohn-Mark Gurney * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
252fee8756SJohn-Mark Gurney * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
262fee8756SJohn-Mark Gurney * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
272fee8756SJohn-Mark Gurney * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
282fee8756SJohn-Mark Gurney * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
292fee8756SJohn-Mark Gurney * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
302fee8756SJohn-Mark Gurney * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
312fee8756SJohn-Mark Gurney * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
322fee8756SJohn-Mark Gurney * SUCH DAMAGE.
332fee8756SJohn-Mark Gurney *
342fee8756SJohn-Mark Gurney * from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
352fee8756SJohn-Mark Gurney */
362fee8756SJohn-Mark Gurney
372fee8756SJohn-Mark Gurney #include <sys/param.h>
382fee8756SJohn-Mark Gurney #include <sys/systm.h>
392fee8756SJohn-Mark Gurney
402fee8756SJohn-Mark Gurney #include <dev/smbios/smbios.h>
412fee8756SJohn-Mark Gurney
422fee8756SJohn-Mark Gurney static const struct {
432fee8756SJohn-Mark Gurney const char *vm_bname;
442fee8756SJohn-Mark Gurney int vm_guest;
452fee8756SJohn-Mark Gurney } vm_bnames[] = {
462fee8756SJohn-Mark Gurney { "QEMU", VM_GUEST_VM }, /* QEMU */
472fee8756SJohn-Mark Gurney { "Plex86", VM_GUEST_VM }, /* Plex86 */
482fee8756SJohn-Mark Gurney { "Bochs", VM_GUEST_VM }, /* Bochs */
492fee8756SJohn-Mark Gurney { "Xen", VM_GUEST_XEN }, /* Xen */
502fee8756SJohn-Mark Gurney { "BHYVE", VM_GUEST_BHYVE }, /* bhyve */
512fee8756SJohn-Mark Gurney { "Seabios", VM_GUEST_KVM }, /* KVM */
522fee8756SJohn-Mark Gurney };
532fee8756SJohn-Mark Gurney
542fee8756SJohn-Mark Gurney static const struct {
552fee8756SJohn-Mark Gurney const char *vm_pname;
562fee8756SJohn-Mark Gurney int vm_guest;
572fee8756SJohn-Mark Gurney } vm_pnames[] = {
582fee8756SJohn-Mark Gurney { "VMware Virtual Platform", VM_GUEST_VMWARE },
592fee8756SJohn-Mark Gurney { "Virtual Machine", VM_GUEST_VM }, /* Microsoft VirtualPC */
602fee8756SJohn-Mark Gurney { "QEMU Virtual Machine", VM_GUEST_VM },
612fee8756SJohn-Mark Gurney { "VirtualBox", VM_GUEST_VBOX },
622fee8756SJohn-Mark Gurney { "Parallels Virtual Platform", VM_GUEST_PARALLELS },
632fee8756SJohn-Mark Gurney { "KVM", VM_GUEST_KVM },
642fee8756SJohn-Mark Gurney };
652fee8756SJohn-Mark Gurney
662fee8756SJohn-Mark Gurney void
identify_hypervisor_smbios(void)672fee8756SJohn-Mark Gurney identify_hypervisor_smbios(void)
682fee8756SJohn-Mark Gurney {
692fee8756SJohn-Mark Gurney char *p;
702fee8756SJohn-Mark Gurney int i;
712fee8756SJohn-Mark Gurney
722fee8756SJohn-Mark Gurney /*
73*f7a884cbSKyle Evans * Some platforms, e.g., amd64, have other ways of detecting what kind
74*f7a884cbSKyle Evans * of hypervisor we may be running under. Make sure we don't clobber a
75*f7a884cbSKyle Evans * more specific vm_guest that's been previously detected.
76*f7a884cbSKyle Evans */
77*f7a884cbSKyle Evans if (vm_guest != VM_GUEST_NO && vm_guest != VM_GUEST_VM)
78*f7a884cbSKyle Evans return;
79*f7a884cbSKyle Evans
80*f7a884cbSKyle Evans /*
812fee8756SJohn-Mark Gurney * XXX: Some of these entries may not be needed since they were
822fee8756SJohn-Mark Gurney * added to FreeBSD before the checks above.
832fee8756SJohn-Mark Gurney */
842fee8756SJohn-Mark Gurney p = kern_getenv("smbios.bios.vendor");
852fee8756SJohn-Mark Gurney if (p != NULL) {
862fee8756SJohn-Mark Gurney for (i = 0; i < nitems(vm_bnames); i++)
872fee8756SJohn-Mark Gurney if (strcmp(p, vm_bnames[i].vm_bname) == 0) {
882fee8756SJohn-Mark Gurney vm_guest = vm_bnames[i].vm_guest;
892fee8756SJohn-Mark Gurney /* If we have a specific match, return */
902fee8756SJohn-Mark Gurney if (vm_guest != VM_GUEST_VM) {
912fee8756SJohn-Mark Gurney freeenv(p);
922fee8756SJohn-Mark Gurney return;
932fee8756SJohn-Mark Gurney }
942fee8756SJohn-Mark Gurney /*
952fee8756SJohn-Mark Gurney * We are done with bnames, but there might be
962fee8756SJohn-Mark Gurney * a more specific match in the pnames
972fee8756SJohn-Mark Gurney */
982fee8756SJohn-Mark Gurney break;
992fee8756SJohn-Mark Gurney }
1002fee8756SJohn-Mark Gurney freeenv(p);
1012fee8756SJohn-Mark Gurney }
1022fee8756SJohn-Mark Gurney p = kern_getenv("smbios.system.product");
1032fee8756SJohn-Mark Gurney if (p != NULL) {
1042fee8756SJohn-Mark Gurney for (i = 0; i < nitems(vm_pnames); i++)
1052fee8756SJohn-Mark Gurney if (strcmp(p, vm_pnames[i].vm_pname) == 0) {
1062fee8756SJohn-Mark Gurney vm_guest = vm_pnames[i].vm_guest;
1072fee8756SJohn-Mark Gurney freeenv(p);
1082fee8756SJohn-Mark Gurney return;
1092fee8756SJohn-Mark Gurney }
1102fee8756SJohn-Mark Gurney freeenv(p);
1112fee8756SJohn-Mark Gurney }
1122fee8756SJohn-Mark Gurney }
113