summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2013-06-10 21:07:35 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2013-06-10 21:07:47 +0000
commit9162aa20aa4aa82ef715609015d0e5db1501a076 (patch)
tree4e21824c1ca95b6c73238511157b599009925df7
parent0ac0f8872e81cc808f500f5e9eb48c5e1fdd831b (diff)
parent79ec9da85c2648e2e165ce68612ad0cb6e185618 (diff)
downloadillumos-joyent-9162aa20aa4aa82ef715609015d0e5db1501a076.tar.gz
[illumos-gate merge]
commit 79ec9da85c2648e2e165ce68612ad0cb6e185618 3506 Use "hypervisor" CPUID bit to detect hypervisor environment commit 7e0955bbb1c326d78038afe0d108c8ae4934a78a 3505 Creating LU unconditionally enables write cache on backing store device commit 6e6d5868f52089b9026785bd90257a3d3f6e5ee2 3805 arc shouldn't cache freed blocks
-rw-r--r--usr/src/uts/common/fs/zfs/arc.c28
-rw-r--r--usr/src/uts/common/fs/zfs/sys/arc.h3
-rw-r--r--usr/src/uts/common/fs/zfs/zio.c1
-rw-r--r--usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c51
-rw-r--r--usr/src/uts/i86pc/os/cpuid.c93
-rw-r--r--usr/src/uts/i86pc/os/cpuid_subr.c4
-rw-r--r--usr/src/uts/i86pc/os/microcode.c16
-rw-r--r--usr/src/uts/i86pc/os/mlsetup.c5
-rw-r--r--usr/src/uts/i86pc/os/startup.c7
-rw-r--r--usr/src/uts/i86pc/os/timestamp.c8
-rw-r--r--usr/src/uts/intel/ia32/ml/i86_subr.s71
-rw-r--r--usr/src/uts/intel/sys/x86_archext.h35
12 files changed, 211 insertions, 111 deletions
diff --git a/usr/src/uts/common/fs/zfs/arc.c b/usr/src/uts/common/fs/zfs/arc.c
index 712e990cc8..81ee2e3ff3 100644
--- a/usr/src/uts/common/fs/zfs/arc.c
+++ b/usr/src/uts/common/fs/zfs/arc.c
@@ -3131,6 +3131,34 @@ arc_set_callback(arc_buf_t *buf, arc_evict_func_t *func, void *private)
}
/*
+ * Notify the arc that a block was freed, and thus will never be used again.
+ */
+void
+arc_freed(spa_t *spa, const blkptr_t *bp)
+{
+ arc_buf_hdr_t *hdr;
+ kmutex_t *hash_lock;
+ uint64_t guid = spa_load_guid(spa);
+
+ hdr = buf_hash_find(guid, BP_IDENTITY(bp), BP_PHYSICAL_BIRTH(bp),
+ &hash_lock);
+ if (hdr == NULL)
+ return;
+ if (HDR_BUF_AVAILABLE(hdr)) {
+ arc_buf_t *buf = hdr->b_buf;
+ add_reference(hdr, hash_lock, FTAG);
+ hdr->b_flags &= ~ARC_BUF_AVAILABLE;
+ mutex_exit(hash_lock);
+
+ arc_release(buf, FTAG);
+ (void) arc_buf_remove_ref(buf, FTAG);
+ } else {
+ mutex_exit(hash_lock);
+ }
+
+}
+
+/*
* This is used by the DMU to let the ARC know that a buffer is
* being evicted, so the ARC should clean up. If this arc buf
* is not yet in the evicted state, it will be put there.
diff --git a/usr/src/uts/common/fs/zfs/sys/arc.h b/usr/src/uts/common/fs/zfs/sys/arc.h
index 6a22c216a7..b40c60b9bf 100644
--- a/usr/src/uts/common/fs/zfs/sys/arc.h
+++ b/usr/src/uts/common/fs/zfs/sys/arc.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
*/
@@ -110,6 +110,7 @@ zio_t *arc_write(zio_t *pio, spa_t *spa, uint64_t txg,
blkptr_t *bp, arc_buf_t *buf, boolean_t l2arc, boolean_t l2arc_compress,
const zio_prop_t *zp, arc_done_func_t *ready, arc_done_func_t *done,
void *private, int priority, int zio_flags, const zbookmark_t *zb);
+void arc_freed(spa_t *spa, const blkptr_t *bp);
void arc_set_callback(arc_buf_t *buf, arc_evict_func_t *func, void *private);
int arc_buf_evict(arc_buf_t *buf);
diff --git a/usr/src/uts/common/fs/zfs/zio.c b/usr/src/uts/common/fs/zfs/zio.c
index 9adaf3b974..425dcb3100 100644
--- a/usr/src/uts/common/fs/zfs/zio.c
+++ b/usr/src/uts/common/fs/zfs/zio.c
@@ -721,6 +721,7 @@ zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
ASSERT(spa_sync_pass(spa) < zfs_sync_pass_deferred_free);
metaslab_check_free(spa, bp);
+ arc_freed(spa, bp);
zio = zio_create(pio, spa, txg, bp, NULL, BP_GET_PSIZE(bp),
NULL, NULL, ZIO_TYPE_FREE, ZIO_PRIORITY_FREE, flags,
diff --git a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
index 64ff9c93a5..2556c67e37 100644
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
@@ -18,10 +18,10 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/conf.h>
@@ -1719,7 +1719,6 @@ sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
char *namebuf;
sbd_lu_t *sl;
stmf_lu_t *lu;
- sbd_status_t sret;
char *p;
int sz;
int alloc_sz;
@@ -1835,11 +1834,6 @@ sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
if (slu->slu_write_protected) {
sl->sl_flags |= SL_WRITE_PROTECTED;
}
- if (slu->slu_writeback_cache_disable) {
- sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE |
- SL_SAVED_WRITE_CACHE_DISABLE;
- }
-
if (slu->slu_blksize_valid) {
if ((slu->slu_blksize & (slu->slu_blksize - 1)) ||
(slu->slu_blksize > (32 * 1024)) ||
@@ -1876,27 +1870,30 @@ sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
}
/*
- * set write cache disable on the device
- * if it fails, we'll support it using sync/flush
+ * Check if we were explicitly asked to disable/enable write
+ * cache on the device, otherwise get current device setting.
*/
- if (slu->slu_writeback_cache_disable) {
- (void) sbd_wcd_set(1, sl);
- wcd = 1;
- /*
- * Attempt to set it to enable, if that fails and it was explicitly set
- * return an error, otherwise get the current setting and use that
- */
- } else {
- sret = sbd_wcd_set(0, sl);
- if (slu->slu_writeback_cache_disable_valid &&
- sret != SBD_SUCCESS) {
- *err_ret = SBD_RET_WRITE_CACHE_SET_FAILED;
- ret = EFAULT;
- goto scm_err_out;
- }
- if (sret != SBD_SUCCESS) {
- sbd_wcd_get(&wcd, sl);
+ if (slu->slu_writeback_cache_disable_valid) {
+ if (slu->slu_writeback_cache_disable) {
+ /*
+ * Set write cache disable on the device. If it fails,
+ * we'll support it using sync/flush.
+ */
+ (void) sbd_wcd_set(1, sl);
+ wcd = 1;
+ } else {
+ /*
+ * Set write cache enable on the device. If it fails,
+ * return an error.
+ */
+ if (sbd_wcd_set(0, sl) != SBD_SUCCESS) {
+ *err_ret = SBD_RET_WRITE_CACHE_SET_FAILED;
+ ret = EFAULT;
+ goto scm_err_out;
+ }
}
+ } else {
+ sbd_wcd_get(&wcd, sl);
}
if (wcd) {
diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c
index b5cb7674c4..644e4ba35a 100644
--- a/usr/src/uts/i86pc/os/cpuid.c
+++ b/usr/src/uts/i86pc/os/cpuid.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Copyright (c) 2010, Intel Corporation.
@@ -220,7 +221,7 @@ uint64_t xsave_bv_all = (XFEATURE_LEGACY_FP | XFEATURE_SSE);
boolean_t xsave_force_disable = B_FALSE;
/*
- * This is set to platform type Solaris is running on.
+ * This is set to platform type we are running on.
*/
static int platform_type = -1;
@@ -597,20 +598,20 @@ cpuid_free_space(cpu_t *cpu)
}
#if !defined(__xpv)
-
/*
* Determine the type of the underlying platform. This is used to customize
* initialization of various subsystems (e.g. TSC). determine_platform() must
* only ever be called once to prevent two processors from seeing different
- * values of platform_type, it must be called before cpuid_pass1(), the
- * earliest consumer to execute.
+ * values of platform_type. Must be called before cpuid_pass1(), the earliest
+ * consumer to execute (uses _cpuid_chiprev --> synth_amd_info --> get_hwenv).
*/
void
determine_platform(void)
{
struct cpuid_regs cp;
- char *xen_str;
- uint32_t xen_signature[4], base;
+ uint32_t base;
+ uint32_t regs[4];
+ char *hvstr = (char *)regs;
ASSERT(platform_type == -1);
@@ -620,31 +621,75 @@ determine_platform(void)
return;
/*
- * In a fully virtualized domain, Xen's pseudo-cpuid function
- * returns a string representing the Xen signature in %ebx, %ecx,
- * and %edx. %eax contains the maximum supported cpuid function.
- * We need at least a (base + 2) leaf value to do what we want
- * to do. Try different base values, since the hypervisor might
- * use a different one depending on whether hyper-v emulation
- * is switched on by default or not.
+ * If Hypervisor CPUID bit is set, try to determine hypervisor
+ * vendor signature, and set platform type accordingly.
+ *
+ * References:
+ * http://lkml.org/lkml/2008/10/1/246
+ * http://kb.vmware.com/kb/1009458
+ */
+ cp.cp_eax = 0x1;
+ (void) __cpuid_insn(&cp);
+ if ((cp.cp_ecx & CPUID_INTC_ECX_HV) != 0) {
+ cp.cp_eax = 0x40000000;
+ (void) __cpuid_insn(&cp);
+ regs[0] = cp.cp_ebx;
+ regs[1] = cp.cp_ecx;
+ regs[2] = cp.cp_edx;
+ regs[3] = 0;
+ if (strcmp(hvstr, HVSIG_XEN_HVM) == 0) {
+ platform_type = HW_XEN_HVM;
+ return;
+ }
+ if (strcmp(hvstr, HVSIG_VMWARE) == 0) {
+ platform_type = HW_VMWARE;
+ return;
+ }
+ if (strcmp(hvstr, HVSIG_KVM) == 0) {
+ platform_type = HW_KVM;
+ return;
+ }
+ if (strcmp(hvstr, HVSIG_MICROSOFT) == 0)
+ platform_type = HW_MICROSOFT;
+ } else {
+ /*
+ * Check older VMware hardware versions. VMware hypervisor is
+ * detected by performing an IN operation to VMware hypervisor
+ * port and checking that value returned in %ebx is VMware
+ * hypervisor magic value.
+ *
+ * References: http://kb.vmware.com/kb/1009458
+ */
+ vmware_port(VMWARE_HVCMD_GETVERSION, regs);
+ if (regs[1] == VMWARE_HVMAGIC) {
+ platform_type = HW_VMWARE;
+ return;
+ }
+ }
+
+ /*
+ * Check Xen hypervisor. In a fully virtualized domain,
+ * Xen's pseudo-cpuid function returns a string representing the
+ * Xen signature in %ebx, %ecx, and %edx. %eax contains the maximum
+ * supported cpuid function. We need at least a (base + 2) leaf value
+ * to do what we want to do. Try different base values, since the
+ * hypervisor might use a different one depending on whether Hyper-V
+ * emulation is switched on by default or not.
*/
for (base = 0x40000000; base < 0x40010000; base += 0x100) {
cp.cp_eax = base;
(void) __cpuid_insn(&cp);
- xen_signature[0] = cp.cp_ebx;
- xen_signature[1] = cp.cp_ecx;
- xen_signature[2] = cp.cp_edx;
- xen_signature[3] = 0;
- xen_str = (char *)xen_signature;
- if (strcmp("XenVMMXenVMM", xen_str) == 0 &&
+ regs[0] = cp.cp_ebx;
+ regs[1] = cp.cp_ecx;
+ regs[2] = cp.cp_edx;
+ regs[3] = 0;
+ if (strcmp(hvstr, HVSIG_XEN_HVM) == 0 &&
cp.cp_eax >= (base + 2)) {
- platform_type = HW_XEN_HVM;
+ platform_type &= ~HW_NATIVE;
+ platform_type |= HW_XEN_HVM;
return;
}
}
-
- if (vmware_platform()) /* running under vmware hypervisor? */
- platform_type = HW_VMWARE;
}
int
@@ -2366,7 +2411,7 @@ fabricate_brandstr(struct cpuid_info *cpi)
* the other cpus.
*
* Fixup the brand string, and collect any information from cpuid
- * that requires dynamicically allocated storage to represent.
+ * that requires dynamically allocated storage to represent.
*/
/*ARGSUSED*/
void
diff --git a/usr/src/uts/i86pc/os/cpuid_subr.c b/usr/src/uts/i86pc/os/cpuid_subr.c
index 84a62625db..8d0321c3c9 100644
--- a/usr/src/uts/i86pc/os/cpuid_subr.c
+++ b/usr/src/uts/i86pc/os/cpuid_subr.c
@@ -22,6 +22,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -391,7 +393,7 @@ synth_amd_info(uint_t family, uint_t model, uint_t step,
#endif
platform = get_hwenv();
- if ((platform == HW_XEN_HVM) || (platform == HW_VMWARE)) {
+ if ((platform & HW_VIRTUAL) != 0) {
*skt_p = X86_SOCKET_UNKNOWN;
} else if (family == 0xf) {
*skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
diff --git a/usr/src/uts/i86pc/os/microcode.c b/usr/src/uts/i86pc/os/microcode.c
index c5c6a16790..e59bdb8530 100644
--- a/usr/src/uts/i86pc/os/microcode.c
+++ b/usr/src/uts/i86pc/os/microcode.c
@@ -22,6 +22,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/asm_linkage.h>
@@ -202,17 +204,21 @@ ucode_free(processorid_t id, void* buf, size_t size)
* We also assume that we don't support a mix of Intel and
* AMD processors in the same box.
*
- * An i86xpv guest domain can't update the microcode.
+ * An i86xpv guest domain or VM can't update the microcode.
*/
+
+#define XPVDOMU_OR_HVM \
+ ((hwenv == HW_XEN_PV && !is_controldom()) || (hwenv & HW_VIRTUAL) != 0)
+
/*ARGSUSED*/
static int
ucode_capable_amd(cpu_t *cp)
{
int hwenv = get_hwenv();
- if (hwenv == HW_XEN_HVM || (hwenv == HW_XEN_PV && !is_controldom())) {
+ if (XPVDOMU_OR_HVM)
return (0);
- }
+
return (cpuid_getfamily(cp) >= 0x10);
}
@@ -221,9 +227,9 @@ ucode_capable_intel(cpu_t *cp)
{
int hwenv = get_hwenv();
- if (hwenv == HW_XEN_HVM || (hwenv == HW_XEN_PV && !is_controldom())) {
+ if (XPVDOMU_OR_HVM)
return (0);
- }
+
return (cpuid_getfamily(cp) >= 6);
}
diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c
index dc79a04af2..351ed3d2c9 100644
--- a/usr/src/uts/i86pc/os/mlsetup.c
+++ b/usr/src/uts/i86pc/os/mlsetup.c
@@ -195,8 +195,7 @@ mlsetup(struct regs *rp)
cpuid_pass1(cpu[0], x86_featureset);
#if !defined(__xpv)
-
- if (get_hwenv() == HW_XEN_HVM)
+ if ((get_hwenv() & HW_XEN_HVM) != 0)
xen_hvm_init();
/*
@@ -218,7 +217,7 @@ mlsetup(struct regs *rp)
* The Xen hypervisor does not correctly report whether rdtscp is
* supported or not, so we must assume that it is not.
*/
- if (get_hwenv() != HW_XEN_HVM &&
+ if ((get_hwenv() & HW_XEN_HVM) == 0 &&
is_x86_feature(x86_featureset, X86FSET_TSCP))
patch_tsc_read(X86_HAVE_TSCP);
else if (cpuid_getvendor(CPU) == X86_VENDOR_AMD &&
diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c
index 2495390555..0fa6290b83 100644
--- a/usr/src/uts/i86pc/os/startup.c
+++ b/usr/src/uts/i86pc/os/startup.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Copyright (c) 2010, Intel Corporation.
@@ -1534,7 +1535,7 @@ startup_modules(void)
*/
microfind();
- if (get_hwenv() == HW_XEN_HVM)
+ if ((get_hwenv() & HW_XEN_HVM) != 0)
update_default_path();
#endif
@@ -1663,7 +1664,7 @@ startup_modules(void)
* Initialize a handle for the boot cpu - others will initialize
* as they startup. Do not do this if we know we are in an HVM domU.
*/
- if ((get_hwenv() != HW_XEN_HVM) &&
+ if ((get_hwenv() & HW_XEN_HVM) == 0 &&
(hdl = cmi_init(CMI_HDL_NATIVE, cmi_ntv_hwchipid(CPU),
cmi_ntv_hwcoreid(CPU), cmi_ntv_hwstrandid(CPU))) != NULL &&
is_x86_feature(x86_featureset, X86FSET_MCA)) {
@@ -2298,7 +2299,7 @@ post_startup(void)
* Startup the memory scrubber.
* XXPV This should be running somewhere ..
*/
- if (get_hwenv() != HW_XEN_HVM)
+ if ((get_hwenv() & HW_VIRTUAL) == 0)
memscrub_init();
#endif
}
diff --git a/usr/src/uts/i86pc/os/timestamp.c b/usr/src/uts/i86pc/os/timestamp.c
index 380ed6785f..afd64e9620 100644
--- a/usr/src/uts/i86pc/os/timestamp.c
+++ b/usr/src/uts/i86pc/os/timestamp.c
@@ -22,6 +22,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -432,8 +434,7 @@ tsc_sync_master(processorid_t slave)
int hwtype;
hwtype = get_hwenv();
- if (!tsc_master_slave_sync_needed || hwtype == HW_XEN_HVM ||
- hwtype == HW_VMWARE)
+ if (!tsc_master_slave_sync_needed || (hwtype & HW_VIRTUAL) != 0)
return;
flags = clear_int_flag();
@@ -512,8 +513,7 @@ tsc_sync_slave(void)
int hwtype;
hwtype = get_hwenv();
- if (!tsc_master_slave_sync_needed || hwtype == HW_XEN_HVM ||
- hwtype == HW_VMWARE)
+ if (!tsc_master_slave_sync_needed || (hwtype & HW_VIRTUAL) != 0)
return;
flags = clear_int_flag();
diff --git a/usr/src/uts/intel/ia32/ml/i86_subr.s b/usr/src/uts/intel/ia32/ml/i86_subr.s
index e79eabd119..13a9757aa2 100644
--- a/usr/src/uts/intel/ia32/ml/i86_subr.s
+++ b/usr/src/uts/intel/ia32/ml/i86_subr.s
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -4339,62 +4340,58 @@ mfence_insn(void)
#endif /* __lint */
/*
- * This is how VMware lets the guests figure that they are running
- * on top of VMWare platform :
- * Write 0xA in the ECX register and put the I/O port address value of
- * 0x564D5868 in the EAX register. Then read a word from port 0x5658.
- * If VMWare is installed than this code will be executed correctly and
- * the EBX register will contain the same I/O port address value of 0x564D5868.
- * If VMWare is not installed then OS will return an exception on port access.
+ * VMware implements an I/O port that programs can query to detect if software
+ * is running in a VMware hypervisor. This hypervisor port behaves differently
+ * depending on magic values in certain registers and modifies some registers
+ * as a side effect.
+ *
+ * References: http://kb.vmware.com/kb/1009458
*/
+
#if defined(__lint)
-int
-vmware_platform(void) { return (1); }
+/* ARGSUSED */
+void
+vmware_port(int cmd, uint32_t *regs) { return; }
#else
#if defined(__amd64)
- ENTRY(vmware_platform)
+ ENTRY(vmware_port)
pushq %rbx
- xorl %ebx, %ebx
- movl $0x564d5868, %eax
- movl $0xa, %ecx
- movl $0x5658, %edx
+ movl $VMWARE_HVMAGIC, %eax
+ movl $0xffffffff, %ebx
+ movl %edi, %ecx
+ movl $VMWARE_HVPORT, %edx
inl (%dx)
- movl $0x564d5868, %ecx
- xorl %eax, %eax
- cmpl %ecx, %ebx
- jne 1f
- incl %eax
-1:
+ movl %eax, (%rsi)
+ movl %ebx, 4(%rsi)
+ movl %ecx, 8(%rsi)
+ movl %edx, 12(%rsi)
popq %rbx
ret
- SET_SIZE(vmware_platform)
+ SET_SIZE(vmware_port)
#elif defined(__i386)
- ENTRY(vmware_platform)
+ ENTRY(vmware_port)
pushl %ebx
- pushl %ecx
- pushl %edx
- xorl %ebx, %ebx
- movl $0x564d5868, %eax
- movl $0xa, %ecx
- movl $0x5658, %edx
+ pushl %esi
+ movl $VMWARE_HVMAGIC, %eax
+ movl $0xffffffff, %ebx
+ movl 12(%esp), %ecx
+ movl $VMWARE_HVPORT, %edx
inl (%dx)
- movl $0x564d5868, %ecx
- xorl %eax, %eax
- cmpl %ecx, %ebx
- jne 1f
- incl %eax
-1:
- popl %edx
- popl %ecx
+ movl 16(%esp), %esi
+ movl %eax, (%esi)
+ movl %ebx, 4(%esi)
+ movl %ecx, 8(%esi)
+ movl %edx, 12(%esi)
+ popl %esi
popl %ebx
ret
- SET_SIZE(vmware_platform)
+ SET_SIZE(vmware_port)
#endif /* __i386 */
#endif /* __lint */
diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h
index f2754a1431..5b3ec638e3 100644
--- a/usr/src/uts/intel/sys/x86_archext.h
+++ b/usr/src/uts/intel/sys/x86_archext.h
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Copyright (c) 2010, Intel Corporation.
@@ -125,6 +126,7 @@ extern "C" {
#define CPUID_INTC_ECX_AVX 0x10000000 /* AVX supported */
#define CPUID_INTC_ECX_F16C 0x20000000 /* F16C supported */
#define CPUID_INTC_ECX_RDRAND 0x40000000 /* RDRAND supported */
+#define CPUID_INTC_ECX_HV 0x80000000 /* Hypervisor */
#define FMT_CPUID_INTC_ECX \
"\20" \
@@ -770,7 +772,7 @@ extern int cpuid_deep_cstates_supported(void);
extern int cpuid_arat_supported(void);
extern int cpuid_iepb_supported(struct cpu *);
extern int cpuid_deadline_tsc_supported(void);
-extern int vmware_platform(void);
+extern void vmware_port(int, uint32_t *);
#endif
struct cpu_ucode_info;
@@ -831,16 +833,37 @@ extern int is_controldom(void);
extern void xsave_setup_msr(struct cpu *);
/*
+ * Hypervisor signatures
+ */
+#define HVSIG_XEN_HVM "XenVMMXenVMM"
+#define HVSIG_VMWARE "VMwareVMware"
+#define HVSIG_KVM "KVMKVMKVM"
+#define HVSIG_MICROSOFT "Microsoft Hv"
+
+/*
* Defined hardware environments
*/
-#define HW_NATIVE 0x00 /* Running on bare metal */
-#define HW_XEN_PV 0x01 /* Running on Xen Hypervisor paravirutualized */
-#define HW_XEN_HVM 0x02 /* Running on Xen hypervisor HVM */
-#define HW_VMWARE 0x03 /* Running on VMware hypervisor */
+#define HW_NATIVE (1 << 0) /* Running on bare metal */
+#define HW_XEN_PV (1 << 1) /* Running on Xen PVM */
+
+#define HW_XEN_HVM (1 << 2) /* Running on Xen HVM */
+#define HW_VMWARE (1 << 3) /* Running on VMware hypervisor */
+#define HW_KVM (1 << 4) /* Running on KVM hypervisor */
+#define HW_MICROSOFT (1 << 5) /* Running on Microsoft hypervisor */
+
+#define HW_VIRTUAL (HW_XEN_HVM | HW_VMWARE | HW_KVM | HW_MICROSOFT)
#endif /* _KERNEL */
-#endif
+#endif /* !_ASM */
+
+/*
+ * VMware hypervisor related defines
+ */
+#define VMWARE_HVMAGIC 0x564d5868
+#define VMWARE_HVPORT 0x5658
+#define VMWARE_HVCMD_GETVERSION 0x0a
+#define VMWARE_HVCMD_GETTSCFREQ 0x2d
#ifdef __cplusplus
}