diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -117,6 +117,8 @@ #include +#include + #include #include #include @@ -1315,6 +1317,7 @@ identify_cpu1(); identify_hypervisor(); + identify_hypervisor_smbios(); identify_cpu_fixup_bsp(); identify_cpu2(); initializecpucache(); diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -100,6 +100,8 @@ #include #endif +#include + enum arm64_bus arm64_bus_method = ARM64_BUS_NONE; /* @@ -873,6 +875,8 @@ kmdp = preload_search_by_type("elf64 kernel"); identify_cpu(0); + identify_hypervisor_smbios(); + update_special_regs(0); link_elf_ireloc(kmdp); diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -103,6 +103,8 @@ arm64/coresight/coresight_tmc_acpi.c optional acpi arm64/coresight/coresight_tmc_fdt.c optional fdt +dev/smbios/smbios_subr.c standard + arm64/iommu/iommu.c optional iommu arm64/iommu/iommu_if.m optional iommu arm64/iommu/iommu_pmap.c optional iommu diff --git a/sys/conf/files.x86 b/sys/conf/files.x86 --- a/sys/conf/files.x86 +++ b/sys/conf/files.x86 @@ -292,6 +292,7 @@ dev/qat_c2xxx/qat_ae.c optional qat_c2xxx dev/qat_c2xxx/qat_c2xxx.c optional qat_c2xxx dev/qat_c2xxx/qat_hw15.c optional qat_c2xxx +dev/smbios/smbios_subr.c standard libkern/strcmp.c standard libkern/strncmp.c standard libkern/x86/crc32_sse42.c standard diff --git a/sys/dev/smbios/smbios.h b/sys/dev/smbios/smbios.h --- a/sys/dev/smbios/smbios.h +++ b/sys/dev/smbios/smbios.h @@ -91,4 +91,8 @@ } } +#ifdef _KERNEL +void identify_hypervisor_smbios(void); +#endif + #endif /* _SMBIOS_H_ */ diff --git a/sys/dev/smbios/smbios_subr.c b/sys/dev/smbios/smbios_subr.c new file mode 100644 --- /dev/null +++ b/sys/dev/smbios/smbios_subr.c @@ -0,0 +1,104 @@ +/*- + * Copyright 2014 John Baldwin + * Copyright 2019 Stephen J. Kiernan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp + */ + +#include +#include + +#include + +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 struct { + const char *vm_pname; + int vm_guest; +} vm_pnames[] = { + { "VMware Virtual Platform", VM_GUEST_VMWARE }, + { "Virtual Machine", VM_GUEST_VM }, /* Microsoft VirtualPC */ + { "QEMU Virtual Machine", VM_GUEST_VM }, + { "VirtualBox", VM_GUEST_VBOX }, + { "Parallels Virtual Platform", VM_GUEST_PARALLELS }, + { "KVM", VM_GUEST_KVM }, +}; + +void +identify_hypervisor_smbios(void) +{ + char *p; + int i; + + /* + * XXX: Some of these entries may not be needed since they were + * added to FreeBSD before the checks above. + */ + p = kern_getenv("smbios.bios.vendor"); + if (p != NULL) { + 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; i < nitems(vm_pnames); i++) + if (strcmp(p, vm_pnames[i].vm_pname) == 0) { + vm_guest = vm_pnames[i].vm_guest; + freeenv(p); + return; + } + freeenv(p); + } +} diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -116,6 +116,8 @@ #include +#include + #include #include #include @@ -1433,6 +1435,7 @@ } identify_hypervisor(); + identify_hypervisor_smbios(); /* Init basic tunables, hz etc */ init_param1(); diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c --- a/sys/x86/x86/identcpu.c +++ b/sys/x86/x86/identcpu.c @@ -1342,29 +1342,6 @@ SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, 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 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 { const char *vm_cpuid; int vm_guest; @@ -1446,7 +1423,6 @@ { u_int regs[4]; char *p; - int i; /* * If CPUID2_HV is set, we are running in a hypervisor environment. @@ -1475,39 +1451,6 @@ } freeenv(p); } - - /* - * XXX: Some of these entries may not be needed since they were - * added to FreeBSD before the checks above. - */ - p = kern_getenv("smbios.bios.vendor"); - if (p != NULL) { - 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; i < nitems(vm_pnames); i++) - if (strcmp(p, vm_pnames[i].vm_pname) == 0) { - vm_guest = vm_pnames[i].vm_guest; - freeenv(p); - return; - } - freeenv(p); - } } bool