diff options
author | Andre Przywara <andre.przywara@amd.com> | 2009-09-19 00:30:49 +0200 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2009-10-04 14:46:34 +0200 |
commit | 1b050077d2d72b15c73257c13e2e46932786f7e2 (patch) | |
tree | dc42c285ca15dc1901ef7f6ae268d583521300d5 /target-i386/op_helper.c | |
parent | d9f4bb27dbff2e40ec2e36eb8017c9dedce77f30 (diff) |
target-i386: add RDTSCP support
RDTSCP reads the time stamp counter and atomically also the content
of a 32-bit MSR, which can be freely set by the OS. This allows CPU
local data to be queried by userspace.
Linux uses this to allow a fast implementation of the getcpu()
syscall, which uses the vsyscall page to avoid a context switch.
AMD CPUs since K8RevF and Intel CPUs since Nehalem support this
instruction.
RDTSCP is guarded by the RDTSCP CPUID bit (Fn8000_0001:EDX[27]).
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-i386/op_helper.c')
-rw-r--r-- | target-i386/op_helper.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index 33d44b0037..ef0acfcf0b 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -2969,6 +2969,12 @@ void helper_rdtsc(void) EDX = (uint32_t)(val >> 32); } +void helper_rdtscp(void) +{ + helper_rdtsc(); + ECX = (uint32_t)(env->tsc_aux); +} + void helper_rdpmc(void) { if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { @@ -3107,6 +3113,9 @@ void helper_wrmsr(void) && (val == 0 || val == ~(uint64_t)0)) env->mcg_ctl = val; break; + case MSR_TSC_AUX: + env->tsc_aux = val; + break; default: if ((uint32_t)ECX >= MSR_MC0_CTL && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) { @@ -3177,6 +3186,9 @@ void helper_rdmsr(void) case MSR_KERNELGSBASE: val = env->kernelgsbase; break; + case MSR_TSC_AUX: + val = env->tsc_aux; + break; #endif case MSR_MTRRphysBase(0): case MSR_MTRRphysBase(1): |