abstract out the vm detection via smbios..

This makes the detection of VMs common between platforms that
have SMBios.

Reviewed by:		imp, kib
Differential Revision:	https://reviews.freebsd.org/D38800
This commit is contained in:
John-Mark Gurney 2023-02-23 20:59:50 +00:00
parent cfe244cb37
commit 2fee875629
No known key found for this signature in database
GPG Key ID: 205F0B33DD006ADA
8 changed files with 121 additions and 57 deletions

View File

@ -117,6 +117,8 @@ __FBSDID("$FreeBSD$");
#include <net/netisr.h>
#include <dev/smbios/smbios.h>
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cputypes.h>
@ -1315,6 +1317,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
identify_cpu1();
identify_hypervisor();
identify_hypervisor_smbios();
identify_cpu_fixup_bsp();
identify_cpu2();
initializecpucache();

View File

@ -100,6 +100,8 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/openfirm.h>
#endif
#include <dev/smbios/smbios.h>
enum arm64_bus arm64_bus_method = ARM64_BUS_NONE;
/*
@ -873,6 +875,8 @@ initarm(struct arm64_bootparams *abp)
kmdp = preload_search_by_type("elf64 kernel");
identify_cpu(0);
identify_hypervisor_smbios();
update_special_regs(0);
link_elf_ireloc(kmdp);

View File

@ -103,6 +103,8 @@ arm64/coresight/coresight_tmc.c standard
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

View File

@ -292,6 +292,7 @@ dev/qat_c2xxx/qat.c optional qat_c2xxx
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

View File

@ -91,4 +91,8 @@ smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
}
}
#ifdef _KERNEL
void identify_hypervisor_smbios(void);
#endif
#endif /* _SMBIOS_H_ */

View File

@ -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 <sys/param.h>
#include <sys/systm.h>
#include <dev/smbios/smbios.h>
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);
}
}

View File

@ -116,6 +116,8 @@ __FBSDID("$FreeBSD$");
#include <net/netisr.h>
#include <dev/smbios/smbios.h>
#include <machine/bootinfo.h>
#include <machine/clock.h>
#include <machine/cpu.h>
@ -1433,6 +1435,7 @@ init386(int first)
}
identify_hypervisor();
identify_hypervisor_smbios();
/* Init basic tunables, hz etc */
init_param1();

View File

@ -1342,29 +1342,6 @@ hook_tsc_freq(void *arg __unused)
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 @@ identify_hypervisor(void)
{
u_int regs[4];
char *p;
int i;
/*
* If CPUID2_HV is set, we are running in a hypervisor environment.
@ -1475,39 +1451,6 @@ identify_hypervisor(void)
}
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