Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144644191
D49084.1775995259.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D49084.1775995259.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D49084: VM detection: Add QEMU; Add prefix match; Change prioritization
Attached
Detach File
Event Timeline
Log In to Comment