git: 2fee87562948 - main - abstract out the vm detection via smbios..

From: John-Mark Gurney <jmg_at_FreeBSD.org>
Date: Fri, 03 Mar 2023 00:55:47 UTC
The branch main has been updated by jmg:

URL: https://cgit.FreeBSD.org/src/commit/?id=2fee8756294820ff9ec6f8d17324e7d8a0a45040

commit 2fee8756294820ff9ec6f8d17324e7d8a0a45040
Author:     John-Mark Gurney <jmg@FreeBSD.org>
AuthorDate: 2023-02-23 20:59:50 +0000
Commit:     John-Mark Gurney <jmg@FreeBSD.org>
CommitDate: 2023-03-03 00:54:21 +0000

    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
---
 sys/amd64/amd64/machdep.c    |   3 ++
 sys/arm64/arm64/machdep.c    |   4 ++
 sys/conf/files.arm64         |   2 +
 sys/conf/files.x86           |   1 +
 sys/dev/smbios/smbios.h      |   4 ++
 sys/dev/smbios/smbios_subr.c | 104 +++++++++++++++++++++++++++++++++++++++++++
 sys/i386/i386/machdep.c      |   3 ++
 sys/x86/x86/identcpu.c       |  57 ------------------------
 8 files changed, 121 insertions(+), 57 deletions(-)

diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index f33f2c6509f0..480db1ed2c31 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -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();
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index 2eaf4ef14390..19fa7cd913a0 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -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);
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index 02447db830dc..684cb8cb23ba 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -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
diff --git a/sys/conf/files.x86 b/sys/conf/files.x86
index 0a32c888cdb2..8774139eee3a 100644
--- a/sys/conf/files.x86
+++ b/sys/conf/files.x86
@@ -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
diff --git a/sys/dev/smbios/smbios.h b/sys/dev/smbios/smbios.h
index ec216b676f2b..e766b54f7dc1 100644
--- a/sys/dev/smbios/smbios.h
+++ b/sys/dev/smbios/smbios.h
@@ -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_ */
diff --git a/sys/dev/smbios/smbios_subr.c b/sys/dev/smbios/smbios_subr.c
new file mode 100644
index 000000000000..c28bf0e4983f
--- /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 <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);
+	}
+}
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index e9de8ef602e7..8e3b21dbe195 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -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();
diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c
index 2a009d7ec10a..42cca3250481 100644
--- a/sys/x86/x86/identcpu.c
+++ b/sys/x86/x86/identcpu.c
@@ -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