summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorsudheer <none@none>2008-05-14 11:33:14 -0700
committersudheer <none@none>2008-05-14 11:33:14 -0700
commit15363b274f574a3aaa00c35e555e9c365d84d2af (patch)
treea74693a632b8ba1f7dc843348f3a5c1bb3ad787c /usr/src
parentcc85acda94d03f2a4939f6bc285d24effc27f179 (diff)
downloadillumos-joyent-15363b274f574a3aaa00c35e555e9c365d84d2af.tar.gz
6671782 rdtsc synchronization change for Intel processors
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/i86pc/os/cpuid.c5
-rw-r--r--usr/src/uts/i86pc/os/mlsetup.c2
-rw-r--r--usr/src/uts/intel/ia32/ml/i86_subr.s16
-rw-r--r--usr/src/uts/intel/sys/x86_archext.h3
4 files changed, 25 insertions, 1 deletions
diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c
index 61e51263c3..ea47049c76 100644
--- a/usr/src/uts/i86pc/os/cpuid.c
+++ b/usr/src/uts/i86pc/os/cpuid.c
@@ -3808,6 +3808,11 @@ patch_tsc_read(int flag)
(void) memcpy((void *)tsc_read,
(void *)&_tsc_mfence_start, cnt);
break;
+ case X86_TSC_LFENCE:
+ cnt = &_tsc_lfence_end - &_tsc_lfence_start;
+ (void) memcpy((void *)tsc_read,
+ (void *)&_tsc_lfence_start, cnt);
+ break;
default:
break;
}
diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c
index 6ba5f6e1f6..e150ebc8b9 100644
--- a/usr/src/uts/i86pc/os/mlsetup.c
+++ b/usr/src/uts/i86pc/os/mlsetup.c
@@ -190,7 +190,7 @@ mlsetup(struct regs *rp)
patch_tsc_read(X86_TSC_MFENCE);
else if (cpuid_getvendor(CPU) == X86_VENDOR_Intel &&
cpuid_getfamily(CPU) <= 6 && (x86_feature & X86_SSE2) != 0)
- patch_tsc_read(X86_TSC_MFENCE);
+ patch_tsc_read(X86_TSC_LFENCE);
#endif /* !__xpv */
diff --git a/usr/src/uts/intel/ia32/ml/i86_subr.s b/usr/src/uts/intel/ia32/ml/i86_subr.s
index 2e528f3534..76e47fcf6a 100644
--- a/usr/src/uts/intel/ia32/ml/i86_subr.s
+++ b/usr/src/uts/intel/ia32/ml/i86_subr.s
@@ -809,6 +809,15 @@ _no_rdtsc_start:
ret
.globl _no_rdtsc_end
_no_rdtsc_end:
+ .globl _tsc_lfence_start
+_tsc_lfence_start:
+ lfence
+ rdtsc
+ shlq $32, %rdx
+ orq %rdx, %rax
+ ret
+ .globl _tsc_lfence_end
+_tsc_lfence_end:
SET_SIZE(tsc_read)
#else /* __i386 */
@@ -840,6 +849,13 @@ _no_rdtsc_start:
ret
.globl _no_rdtsc_end
_no_rdtsc_end:
+ .globl _tsc_lfence_start
+_tsc_lfence_start:
+ lfence
+ rdtsc
+ ret
+ .globl _tsc_lfence_end
+_tsc_lfence_end:
SET_SIZE(tsc_read)
#endif /* __i386 */
diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h
index 7a65c28743..8dad09d1d7 100644
--- a/usr/src/uts/intel/sys/x86_archext.h
+++ b/usr/src/uts/intel/sys/x86_archext.h
@@ -337,6 +337,7 @@ extern "C" {
#define X86_NO_TSC 0x0
#define X86_HAVE_TSCP 0x1
#define X86_TSC_MFENCE 0x2
+#define X86_TSC_LFENCE 0x4
#define FMT_X86_FEATURE \
"\20" \
@@ -587,6 +588,8 @@ extern char _tscp_start;
extern char _tscp_end;
extern char _no_rdtsc_start;
extern char _no_rdtsc_end;
+extern char _tsc_lfence_start;
+extern char _tsc_lfence_end;
#endif
extern uint_t workaround_errata(struct cpu *);