Page MenuHomeFreeBSD

D49084.1775995259.diff
No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None

D49084.1775995259.diff

diff --git a/sys/dev/smbios/smbios_subr.c b/sys/dev/smbios/smbios_subr.c
--- a/sys/dev/smbios/smbios_subr.c
+++ b/sys/dev/smbios/smbios_subr.c
@@ -39,11 +39,13 @@
#include <dev/smbios/smbios.h>
-static const struct {
- const char *vm_bname;
+struct name_guest {
+ const char *name;
int vm_guest;
-} vm_bnames[] = {
- { "QEMU", VM_GUEST_VM }, /* QEMU */
+};
+
+static const struct name_guest vm_bnames[] = {
+ { "QEMU", VM_GUEST_QEMU }, /* QEMU */
{ "Plex86", VM_GUEST_VM }, /* Plex86 */
{ "Bochs", VM_GUEST_VM }, /* Bochs */
{ "Xen", VM_GUEST_XEN }, /* Xen */
@@ -51,23 +53,72 @@
{ "Seabios", VM_GUEST_KVM }, /* KVM */
};
-static const struct {
- const char *vm_pname;
- int vm_guest;
-} vm_pnames[] = {
+static const struct name_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 },
};
+static const struct name_guest vm_pname_prefixes[] = {
+ { "QEMU", VM_GUEST_QEMU },
+ { "Parallels", VM_GUEST_PARALLELS },
+};
+
+static const struct name_guest vm_mnames[] = {
+ { "QEMU", VM_GUEST_QEMU },
+};
+
+
+typedef bool match_func(const char *_provided, const char *_known);
+
+static bool
+name_match(const char *provided, const char *known)
+{
+ return (strcmp(provided, known) == 0);
+}
+
+static bool
+prefix_match(const char *provided, const char *known)
+{
+ return (strncmp(provided, known, strlen(known)) == 0);
+}
+
+static int
+match_in_map(const char *const name, const struct name_guest *const map,
+ const size_t map_len, match_func *const match)
+{
+ for (size_t i = 0; i < map_len; ++i)
+ if (match(name, map[i].name))
+ return (map[i].vm_guest);
+ return (VM_GUEST_NO);
+}
+
+static int
+name_to_guest(const char *const name, const struct name_guest *const map,
+ const size_t map_size)
+{
+ return (match_in_map(name, map, map_size, name_match));
+}
+
+#define NAME_TO_GUEST(name, map) \
+ (name_to_guest((name), (map), nitems(map)))
+
+static int
+prefix_to_guest(const char *const name, const struct name_guest *const map,
+ const size_t map_len)
+{
+ return (match_in_map(name, map, map_len, prefix_match));
+}
+
+#define PREFIX_TO_GUEST(name, map) \
+ (prefix_to_guest((name), (map), nitems(map)))
+
void
identify_hypervisor_smbios(void)
{
- char *p;
- int i;
+ char *p = NULL;
+ int cand;
/*
* Some platforms, e.g., amd64, have other ways of detecting what kind
@@ -77,36 +128,44 @@
if (vm_guest != VM_GUEST_NO && vm_guest != VM_GUEST_VM)
return;
- /*
- * 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");
+ p = kern_getenv("smbios.system.maker");
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;
- }
+ cand = NAME_TO_GUEST(p, vm_mnames);
+ if (cand != VM_GUEST_NO)
+ goto found;
+
freeenv(p);
+ p = NULL;
}
+
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;
- }
+ cand = NAME_TO_GUEST(p, vm_pnames);
+ if (cand != VM_GUEST_NO)
+ goto found;
+
+ cand = PREFIX_TO_GUEST(p, vm_pname_prefixes);
+ if (cand != VM_GUEST_NO)
+ goto found;
+
freeenv(p);
+ p = NULL;
}
+
+ p = kern_getenv("smbios.bios.vendor");
+ if (p != NULL) {
+ cand = NAME_TO_GUEST(p, vm_bnames);
+ if (cand != VM_GUEST_NO)
+ goto found;
+
+ freeenv(p);
+ p = NULL;
+ }
+
+ return;
+
+found:
+ MPASS(cand != VM_GUEST_NO);
+ vm_guest = cand;
+ freeenv(p);
}
diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
--- a/sys/kern/subr_param.c
+++ b/sys/kern/subr_param.c
@@ -158,6 +158,7 @@
[VM_GUEST_VBOX] = "vbox",
[VM_GUEST_PARALLELS] = "parallels",
[VM_GUEST_NVMM] = "nvmm",
+ [VM_GUEST_QEMU] = "qemu",
};
_Static_assert(nitems(vm_guest_sysctl_names) == VM_GUEST_LAST,
"new vm guest type not added to vm_guest_sysctl_names");
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -79,7 +79,8 @@
*/
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_GUEST_PARALLELS, VM_GUEST_NVMM, VM_GUEST_LAST };
+ VM_GUEST_PARALLELS, VM_GUEST_NVMM, VM_GUEST_QEMU,
+ VM_GUEST_LAST };
#endif /* KERNEL */

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 12, 12:00 PM (4 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28331006
Default Alt Text
D49084.1775995259.diff (4 KB)

Event Timeline