Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133544099
D1010.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D1010.diff
View Options
Index: head/sys/amd64/include/md_var.h
===================================================================
--- head/sys/amd64/include/md_var.h
+++ head/sys/amd64/include/md_var.h
@@ -62,6 +62,8 @@
extern u_int cpu_mon_min_size;
extern u_int cpu_mon_max_size;
extern char ctx_switch_xsave[];
+extern u_int hv_high;
+extern char hv_vendor[];
extern char kstack[];
extern char sigcode[];
extern int szsigcode;
Index: head/sys/i386/include/md_var.h
===================================================================
--- head/sys/i386/include/md_var.h
+++ head/sys/i386/include/md_var.h
@@ -64,6 +64,8 @@
#if defined(I586_CPU) && !defined(NO_F00F_HACK)
extern int has_f00f_bug;
#endif
+extern u_int hv_high;
+extern char hv_vendor[];
extern char kstack[];
extern char sigcode[];
extern int szsigcode;
Index: head/sys/kern/subr_param.c
===================================================================
--- head/sys/kern/subr_param.c
+++ head/sys/kern/subr_param.c
@@ -99,7 +99,11 @@
long maxswzone; /* max swmeta KVA storage */
long maxbcache; /* max buffer cache KVA storage */
long maxpipekva; /* Limit on pipe KVA */
-int vm_guest; /* Running as virtual machine guest? */
+#ifdef XEN
+int vm_guest = VM_GUEST_XEN;
+#else
+int vm_guest = VM_GUEST_NO; /* Running as virtual machine guest? */
+#endif
u_long maxtsiz; /* max text size */
u_long dfldsiz; /* initial data size limit */
u_long maxdsiz; /* max data size */
@@ -136,7 +140,7 @@
"Amount to grow stack on a stack fault");
SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING,
NULL, 0, sysctl_kern_vm_guest, "A",
- "Virtual machine guest detected? (none|generic|xen)");
+ "Virtual machine guest detected?");
/*
* These have to be allocated somewhere; allocating
@@ -154,73 +158,18 @@
"generic",
"xen",
"hv",
+ "vmware",
NULL
};
CTASSERT(nitems(vm_guest_sysctl_names) - 1 == VM_LAST);
-#ifndef XEN
-static const char *const vm_bnames[] = {
- "QEMU", /* QEMU */
- "Plex86", /* Plex86 */
- "Bochs", /* Bochs */
- "Xen", /* Xen */
- "BHYVE", /* bhyve */
- "Seabios", /* KVM */
- NULL
-};
-
-static const char *const vm_pnames[] = {
- "VMware Virtual Platform", /* VMWare VM */
- "Virtual Machine", /* Microsoft VirtualPC */
- "VirtualBox", /* Sun xVM VirtualBox */
- "Parallels Virtual Platform", /* Parallels VM */
- "KVM", /* KVM */
- NULL
-};
-
-
-/*
- * Detect known Virtual Machine hosts by inspecting the emulated BIOS.
- */
-static enum VM_GUEST
-detect_virtual(void)
-{
- char *sysenv;
- int i;
-
- sysenv = kern_getenv("smbios.bios.vendor");
- if (sysenv != NULL) {
- for (i = 0; vm_bnames[i] != NULL; i++)
- if (strcmp(sysenv, vm_bnames[i]) == 0) {
- freeenv(sysenv);
- return (VM_GUEST_VM);
- }
- freeenv(sysenv);
- }
- sysenv = kern_getenv("smbios.system.product");
- if (sysenv != NULL) {
- for (i = 0; vm_pnames[i] != NULL; i++)
- if (strcmp(sysenv, vm_pnames[i]) == 0) {
- freeenv(sysenv);
- return (VM_GUEST_VM);
- }
- freeenv(sysenv);
- }
- return (VM_GUEST_NO);
-}
-#endif
-
/*
* Boot time overrides that are not scaled against main memory
*/
void
init_param1(void)
{
-#ifndef XEN
- vm_guest = detect_virtual();
-#else
- vm_guest = VM_GUEST_XEN;
-#endif
+
hz = -1;
TUNABLE_INT_FETCH("kern.hz", &hz);
if (hz == -1)
Index: head/sys/sys/systm.h
===================================================================
--- head/sys/sys/systm.h
+++ head/sys/sys/systm.h
@@ -73,7 +73,7 @@
* Keep in sync with vm_guest_sysctl_names[].
*/
enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV,
- VM_LAST };
+ VM_GUEST_VMWARE, VM_LAST };
#if defined(WITNESS) || defined(INVARIANTS)
void kassert_panic(const char *fmt, ...) __printflike(1, 2);
Index: head/sys/x86/include/vmware.h
===================================================================
--- head/sys/x86/include/vmware.h
+++ head/sys/x86/include/vmware.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2011-2014 Jung-uk Kim <jkim@FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _X86_VMWARE_H_
+#define _X86_VMWARE_H_
+
+#define VMW_HVMAGIC 0x564d5868
+#define VMW_HVPORT 0x5658
+#define VMW_HVCMD_GETVERSION 10
+#define VMW_HVCMD_GETHZ 45
+
+static __inline void
+vmware_hvcall(u_int cmd, u_int *p)
+{
+
+ __asm __volatile("inl %w3, %0"
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (VMW_HVMAGIC), "1" (UINT_MAX), "2" (cmd), "3" (VMW_HVPORT)
+ : "memory");
+}
+
+#endif /* !_X86_VMWARE_H_ */
Index: head/sys/x86/x86/identcpu.c
===================================================================
--- head/sys/x86/x86/identcpu.c
+++ head/sys/x86/x86/identcpu.c
@@ -47,6 +47,7 @@
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/eventhandler.h>
+#include <sys/limits.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
@@ -63,6 +64,7 @@
#include <amd64/vmm/intel/vmx_controls.h>
#include <x86/isa/icu.h>
+#include <x86/vmware.h>
#ifdef __i386__
#define IDENTBLUE_CYRIX486 0
@@ -76,6 +78,7 @@
static void print_AMD_info(void);
static void print_INTEL_info(void);
static void print_INTEL_TLB(u_int data);
+static void print_hypervisor_info(void);
static void print_svm_info(void);
static void print_via_padlock_info(void);
static void print_vmx_info(void);
@@ -120,6 +123,11 @@
SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
&hw_clockrate, 0, "CPU instruction clock rate");
+u_int hv_high;
+char hv_vendor[16];
+SYSCTL_STRING(_hw, OID_AUTO, hv_vendor, CTLFLAG_RD, hv_vendor, 0,
+ "Hypervisor vendor");
+
static eventhandler_tag tsc_post_tag;
static char cpu_brand[48];
@@ -949,7 +957,6 @@
if (tsc_perf_stat)
printf(", performance statistics");
}
-
}
#ifdef __i386__
} else if (cpu_vendor_id == CPU_VENDOR_CYRIX) {
@@ -967,17 +974,18 @@
if (*cpu_vendor || cpu_id)
printf("\n");
- if (!bootverbose)
- return;
-
- if (cpu_vendor_id == CPU_VENDOR_AMD)
- print_AMD_info();
- else if (cpu_vendor_id == CPU_VENDOR_INTEL)
- print_INTEL_info();
+ if (bootverbose) {
+ if (cpu_vendor_id == CPU_VENDOR_AMD)
+ print_AMD_info();
+ else if (cpu_vendor_id == CPU_VENDOR_INTEL)
+ print_INTEL_info();
#ifdef __i386__
- else if (cpu_vendor_id == CPU_VENDOR_TRANSMETA)
- print_transmeta_info();
+ else if (cpu_vendor_id == CPU_VENDOR_TRANSMETA)
+ print_transmeta_info();
#endif
+ }
+
+ print_hypervisor_info();
}
void
@@ -1182,6 +1190,99 @@
SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL);
+#ifndef XEN
+static const char *const vm_bnames[] = {
+ "QEMU", /* QEMU */
+ "Plex86", /* Plex86 */
+ "Bochs", /* Bochs */
+ "Xen", /* Xen */
+ "BHYVE", /* bhyve */
+ "Seabios", /* KVM */
+ NULL
+};
+
+static const char *const vm_pnames[] = {
+ "VMware Virtual Platform", /* VMWare VM */
+ "Virtual Machine", /* Microsoft VirtualPC */
+ "VirtualBox", /* Sun xVM VirtualBox */
+ "Parallels Virtual Platform", /* Parallels VM */
+ "KVM", /* KVM */
+ NULL
+};
+
+static void
+identify_hypervisor(void)
+{
+ u_int regs[4];
+ char *p;
+ int i;
+
+ /*
+ * [RFC] CPUID usage for interaction between Hypervisors and Linux.
+ * http://lkml.org/lkml/2008/10/1/246
+ *
+ * KB1009458: Mechanisms to determine if software is running in
+ * a VMware virtual machine
+ * http://kb.vmware.com/kb/1009458
+ */
+ if (cpu_feature2 & CPUID2_HV) {
+ vm_guest = VM_GUEST_VM;
+ do_cpuid(0x40000000, regs);
+ if (regs[0] >= 0x40000000) {
+ hv_high = regs[0];
+ ((u_int *)&hv_vendor)[0] = regs[1];
+ ((u_int *)&hv_vendor)[1] = regs[2];
+ ((u_int *)&hv_vendor)[2] = regs[3];
+ hv_vendor[12] = '\0';
+ if (strcmp(hv_vendor, "VMwareVMware") == 0)
+ vm_guest = VM_GUEST_VMWARE;
+ }
+ return;
+ }
+
+ /*
+ * Examine SMBIOS strings for older hypervisors.
+ */
+ p = kern_getenv("smbios.system.serial");
+ if (p != NULL) {
+ if (strncmp(p, "VMware-", 7) == 0 || strncmp(p, "VMW", 3) == 0) {
+ vmware_hvcall(VMW_HVCMD_GETVERSION, regs);
+ if (regs[1] == VMW_HVMAGIC) {
+ vm_guest = VM_GUEST_VMWARE;
+ freeenv(p);
+ return;
+ }
+ }
+ 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; vm_bnames[i] != NULL; i++)
+ if (strcmp(p, vm_bnames[i]) == 0) {
+ vm_guest = VM_GUEST_VM;
+ freeenv(p);
+ return;
+ }
+ freeenv(p);
+ }
+ p = kern_getenv("smbios.system.product");
+ if (p != NULL) {
+ for (i = 0; vm_pnames[i] != NULL; i++)
+ if (strcmp(p, vm_pnames[i]) == 0) {
+ vm_guest = VM_GUEST_VM;
+ freeenv(p);
+ return;
+ }
+ freeenv(p);
+ }
+}
+#endif
+
/*
* Final stage of CPU identification.
*/
@@ -1213,6 +1314,9 @@
cpu_feature2 = regs[2];
#endif
+#ifndef XEN
+ identify_hypervisor();
+#endif
cpu_vendor_id = find_cpu_vendor_id();
/*
@@ -2046,3 +2150,11 @@
);
}
}
+
+static void
+print_hypervisor_info(void)
+{
+
+ if (*hv_vendor)
+ printf("Hypervisor: Origin = \"%s\"\n", hv_vendor);
+}
Index: head/sys/x86/x86/tsc.c
===================================================================
--- head/sys/x86/x86/tsc.c
+++ head/sys/x86/x86/tsc.c
@@ -47,6 +47,7 @@
#include <machine/cputypes.h>
#include <machine/md_var.h>
#include <machine/specialreg.h>
+#include <x86/vmware.h>
#include "cpufreq_if.h"
@@ -102,72 +103,11 @@
800, /* quality (adjusted in code) */
};
-#define VMW_HVMAGIC 0x564d5868
-#define VMW_HVPORT 0x5658
-#define VMW_HVCMD_GETVERSION 10
-#define VMW_HVCMD_GETHZ 45
-
-static __inline void
-vmware_hvcall(u_int cmd, u_int *p)
-{
-
- __asm __volatile("inl %w3, %0"
- : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
- : "0" (VMW_HVMAGIC), "1" (UINT_MAX), "2" (cmd), "3" (VMW_HVPORT)
- : "memory");
-}
-
-static int
+static void
tsc_freq_vmware(void)
{
- char hv_sig[13];
u_int regs[4];
- char *p;
- u_int hv_high;
- int i;
- /*
- * [RFC] CPUID usage for interaction between Hypervisors and Linux.
- * http://lkml.org/lkml/2008/10/1/246
- *
- * KB1009458: Mechanisms to determine if software is running in
- * a VMware virtual machine
- * http://kb.vmware.com/kb/1009458
- */
- hv_high = 0;
- if ((cpu_feature2 & CPUID2_HV) != 0) {
- do_cpuid(0x40000000, regs);
- hv_high = regs[0];
- for (i = 1, p = hv_sig; i < 4; i++, p += sizeof(regs) / 4)
- memcpy(p, ®s[i], sizeof(regs[i]));
- *p = '\0';
- if (bootverbose) {
- /*
- * HV vendor ID string
- * ------------+--------------
- * KVM "KVMKVMKVM"
- * Microsoft "Microsoft Hv"
- * VMware "VMwareVMware"
- * Xen "XenVMMXenVMM"
- */
- printf("Hypervisor: Origin = \"%s\"\n", hv_sig);
- }
- if (strncmp(hv_sig, "VMwareVMware", 12) != 0)
- return (0);
- } else {
- p = kern_getenv("smbios.system.serial");
- if (p == NULL)
- return (0);
- if (strncmp(p, "VMware-", 7) != 0 &&
- strncmp(p, "VMW", 3) != 0) {
- freeenv(p);
- return (0);
- }
- freeenv(p);
- vmware_hvcall(VMW_HVCMD_GETVERSION, regs);
- if (regs[1] != VMW_HVMAGIC)
- return (0);
- }
if (hv_high >= 0x40000010) {
do_cpuid(0x40000010, regs);
tsc_freq = regs[0] * 1000;
@@ -177,7 +117,6 @@
tsc_freq = regs[0] | ((uint64_t)regs[1] << 32);
}
tsc_is_invariant = 1;
- return (1);
}
static void
@@ -261,8 +200,10 @@
}
}
- if (tsc_freq_vmware())
+ if (vm_guest == VM_GUEST_VMWARE) {
+ tsc_freq_vmware();
return;
+ }
switch (cpu_vendor_id) {
case CPU_VENDOR_AMD:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Oct 27, 1:28 PM (1 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24296140
Default Alt Text
D1010.diff (12 KB)
Attached To
Mode
D1010: Rework hypervisor detection.
Attached
Detach File
Event Timeline
Log In to Comment