Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/x86/identcpu.c
Show First 20 Lines • Show All 1,299 Lines • ▼ Show 20 Lines | if (tsc_is_invariant) | ||||
return; | return; | ||||
tsc_post_tag = EVENTHANDLER_REGISTER(cpufreq_post_change, | tsc_post_tag = EVENTHANDLER_REGISTER(cpufreq_post_change, | ||||
tsc_freq_changed, NULL, EVENTHANDLER_PRI_ANY); | tsc_freq_changed, NULL, EVENTHANDLER_PRI_ANY); | ||||
} | } | ||||
SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL); | SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL); | ||||
static const char *const vm_bnames[] = { | static struct { | ||||
"QEMU", /* QEMU */ | const char *const vm_bname; | ||||
cem: Rather than tagging the `vm_bname` pointer as `const`, I'd just tag the entire array as const. | |||||
"Plex86", /* Plex86 */ | int vm_guest; | ||||
"Bochs", /* Bochs */ | } vm_bnames[] = { | ||||
"Xen", /* Xen */ | { "QEMU", VM_GUEST_VM }, /* QEMU */ | ||||
"BHYVE", /* bhyve */ | { "Plex86", VM_GUEST_VM }, /* Plex86 */ | ||||
"Seabios", /* KVM */ | { "Bochs", VM_GUEST_VM }, /* Bochs */ | ||||
NULL | { "Xen", VM_GUEST_XEN }, /* Xen */ | ||||
{ "BHYVE", VM_GUEST_BHYVE }, /* bhyve */ | |||||
{ "Seabios", VM_GUEST_KVM }, /* KVM */ | |||||
}; | }; | ||||
static const char *const vm_pnames[] = { | static struct { | ||||
"VMware Virtual Platform", /* VMWare VM */ | const char *const vm_pname; | ||||
"Virtual Machine", /* Microsoft VirtualPC */ | int vm_guest; | ||||
"VirtualBox", /* Sun xVM VirtualBox */ | } vm_pnames[] = { | ||||
"Parallels Virtual Platform", /* Parallels VM */ | { "VMware Virtual Platform", VM_GUEST_VMWARE }, | ||||
"KVM", /* KVM */ | { "Virtual Machine", VM_GUEST_VM }, /* Microsoft VirtualPC */ | ||||
NULL | { "VirtualBox", VM_GUEST_VBOX }, | ||||
{ "Parallels Virtual Platform", VM_GUEST_PARALLELS }, | |||||
{ "KVM", VM_GUEST_KVM }, | |||||
}; | }; | ||||
static struct { | static struct { | ||||
const char *vm_cpuid; | const char *vm_cpuid; | ||||
int vm_guest; | int vm_guest; | ||||
} vm_cpuids[] = { | } vm_cpuids[] = { | ||||
{ "XENXENXEN", VM_GUEST_XEN }, /* XEN */ | { "XENXENXEN", VM_GUEST_XEN }, /* XEN */ | ||||
{ "Microsoft Hv", VM_GUEST_HV }, /* Microsoft Hyper-V */ | { "Microsoft Hv", VM_GUEST_HV }, /* Microsoft Hyper-V */ | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | if (regs[0] >= leaf) { | ||||
} | } | ||||
/* | /* | ||||
* If this is the first entry or we found a | * If this is the first entry or we found a | ||||
* specific hypervisor, record the base, high value, | * specific hypervisor, record the base, high value, | ||||
* and vendor identifier. | * and vendor identifier. | ||||
*/ | */ | ||||
if (vm_guest != VM_GUEST_VM || leaf == 0x40000000) { | if (vm_guest != VM_GUEST_VM || leaf == 0x40000000) { | ||||
hv_high = leaf; | hv_base = leaf; | ||||
hv_high = regs[0]; | |||||
((u_int *)&hv_vendor)[0] = regs[1]; | ((u_int *)&hv_vendor)[0] = regs[1]; | ||||
((u_int *)&hv_vendor)[1] = regs[2]; | ((u_int *)&hv_vendor)[1] = regs[2]; | ||||
((u_int *)&hv_vendor)[2] = regs[3]; | ((u_int *)&hv_vendor)[2] = regs[3]; | ||||
hv_vendor[12] = '\0'; | hv_vendor[12] = '\0'; | ||||
/* | /* | ||||
* If we found a specific hypervisor, then | * If we found a specific hypervisor, then | ||||
* we are finished. | * we are finished. | ||||
Show All 13 Lines | identify_hypervisor(void) | ||||
int i; | int i; | ||||
/* | /* | ||||
* If CPUID2_HV is set, we are running in a hypervisor environment. | * If CPUID2_HV is set, we are running in a hypervisor environment. | ||||
*/ | */ | ||||
if (cpu_feature2 & CPUID2_HV) { | if (cpu_feature2 & CPUID2_HV) { | ||||
vm_guest = VM_GUEST_VM; | vm_guest = VM_GUEST_VM; | ||||
identify_hypervisor_cpuid_base(); | identify_hypervisor_cpuid_base(); | ||||
/* If we have a definitive vendor, we can return now. */ | |||||
if (*hv_vendor) | |||||
cemUnsubmitted Not Done Inline Actionsstyle(9) nit: compare non-bool values against a zero value for conditional expressions cem: style(9) nit: compare non-bool values against a zero value for conditional expressions | |||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Examine SMBIOS strings for older hypervisors. | * Examine SMBIOS strings for older hypervisors. | ||||
*/ | */ | ||||
p = kern_getenv("smbios.system.serial"); | p = kern_getenv("smbios.system.serial"); | ||||
if (p != NULL) { | if (p != NULL) { | ||||
if (strncmp(p, "VMware-", 7) == 0 || strncmp(p, "VMW", 3) == 0) { | if (strncmp(p, "VMware-", 7) == 0 || strncmp(p, "VMW", 3) == 0) { | ||||
vmware_hvcall(VMW_HVCMD_GETVERSION, regs); | vmware_hvcall(VMW_HVCMD_GETVERSION, regs); | ||||
if (regs[1] == VMW_HVMAGIC) { | if (regs[1] == VMW_HVMAGIC) { | ||||
vm_guest = VM_GUEST_VMWARE; | vm_guest = VM_GUEST_VMWARE; | ||||
freeenv(p); | freeenv(p); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
freeenv(p); | freeenv(p); | ||||
} | } | ||||
/* | /* | ||||
* XXX: Some of these entries may not be needed since they were | * XXX: Some of these entries may not be needed since they were | ||||
* added to FreeBSD before the checks above. | * added to FreeBSD before the checks above. | ||||
*/ | */ | ||||
p = kern_getenv("smbios.bios.vendor"); | p = kern_getenv("smbios.bios.vendor"); | ||||
if (p != NULL) { | if (p != NULL) { | ||||
for (i = 0; vm_bnames[i] != NULL; i++) | for (i = 0; i < nitems(vm_bnames); i++) | ||||
if (strcmp(p, vm_bnames[i]) == 0) { | if (strcmp(p, vm_bnames[i].vm_bname) == 0) { | ||||
vm_guest = VM_GUEST_VM; | vm_guest = vm_bnames[i].vm_guest; | ||||
freeenv(p); | freeenv(p); | ||||
return; | return; | ||||
} | } | ||||
freeenv(p); | freeenv(p); | ||||
} | } | ||||
p = kern_getenv("smbios.system.product"); | p = kern_getenv("smbios.system.product"); | ||||
if (p != NULL) { | if (p != NULL) { | ||||
cemUnsubmitted Not Done Inline ActionsMaybe we want to return early if vm_guest isn't the generic VM_GUEST_VM? Maybe not a real problem, but I'm imagining detecting a more specific VM type via vm_bname and then overriding it with a less-specific generic VM type via vm_pname. Feel free to leave as-is. cem: Maybe we want to return early if `vm_guest` isn't the generic `VM_GUEST_VM`?
Maybe not a real… | |||||
stevekAuthorUnsubmitted Done Inline ActionsYes, probably each block should check if the vm_guest we find. If it is not VM_GUEST_VM, return early, as we found a specific hypervisor. Otherwise, let it continue, as there could be another check that could find a more-specific one. I'm not sure if there will be any case like that, but it would seem reasonable to do that. stevek: Yes, probably each block should check if the vm_guest we find. If it is not VM_GUEST_VM, return… | |||||
for (i = 0; vm_pnames[i] != NULL; i++) | for (i = 0; i < nitems(vm_pnames); i++) | ||||
if (strcmp(p, vm_pnames[i]) == 0) { | if (strcmp(p, vm_pnames[i].vm_pname) == 0) { | ||||
vm_guest = VM_GUEST_VM; | vm_guest = vm_pnames[i].vm_guest; | ||||
freeenv(p); | freeenv(p); | ||||
return; | return; | ||||
} | } | ||||
freeenv(p); | freeenv(p); | ||||
} | } | ||||
} | } | ||||
bool | bool | ||||
▲ Show 20 Lines • Show All 1,145 Lines • Show Last 20 Lines |
Rather than tagging the vm_bname pointer as const, I'd just tag the entire array as const. (Of course, the string value it points to should remain const.)
That'd look something like:
Same idea for vm_pnames