mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/msr: Split out tsc.h
The TSC functionality is only related to MSRs by write_tsc(), and this really does not want to be available as widely as is currently is. asm/time.h shouldn't be including asm/msr.h, but this turns out to be sufficiently tangled that I've chosen to break it out into it's own patch. No functional change. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
9e54444371
commit
2b3d1c8a30
3 files changed
+50
-39
No files matched your search
@@ -98,45 +98,6 @@ static inline void msr_split(struct cpu_user_regs *regs, uint64_t val)
|
||||
regs->rax = (uint32_t)val;
|
||||
}
|
||||
|
||||
static inline uint64_t rdtsc(void)
|
||||
{
|
||||
uint64_t low, high;
|
||||
|
||||
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
|
||||
|
||||
return (high << 32) | low;
|
||||
}
|
||||
|
||||
static inline uint64_t rdtsc_ordered(void)
|
||||
{
|
||||
uint64_t low, high, aux;
|
||||
|
||||
/*
|
||||
* The RDTSC instruction is not serializing. Make it dispatch serializing
|
||||
* for the purposes here by issuing LFENCE (or MFENCE if necessary) ahead
|
||||
* of it.
|
||||
*
|
||||
* RDTSCP, otoh, "does wait until all previous instructions have executed
|
||||
* and all previous loads are globally visible" (SDM) / "forces all older
|
||||
* instructions to retire before reading the timestamp counter" (APM).
|
||||
*/
|
||||
alternative_io_2("lfence; rdtsc",
|
||||
"mfence; rdtsc", X86_FEATURE_MFENCE_RDTSC,
|
||||
"rdtscp", X86_FEATURE_RDTSCP,
|
||||
ASM_OUTPUT2("=a" (low), "=d" (high), "=c" (aux)),
|
||||
/* no inputs */);
|
||||
|
||||
return (high << 32) | low;
|
||||
}
|
||||
|
||||
#define __write_tsc(val) wrmsrl(MSR_IA32_TSC, val)
|
||||
#define write_tsc(val) ({ \
|
||||
/* Reliable TSCs are in lockstep across all CPUs. We should \
|
||||
* never write to them. */ \
|
||||
ASSERT(!boot_cpu_has(X86_FEATURE_TSC_RELIABLE)); \
|
||||
__write_tsc(val); \
|
||||
})
|
||||
|
||||
#define rdpmc(counter,low,high) \
|
||||
__asm__ __volatile__("rdpmc" \
|
||||
: "=a" (low), "=d" (high) \
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define __X86_TIME_H__
|
||||
|
||||
#include <asm/msr.h>
|
||||
#include <asm/tsc.h>
|
||||
|
||||
typedef u64 cycles_t;
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef X86_TSC_H
|
||||
#define X86_TSC_H
|
||||
|
||||
#include <asm/alternative.h>
|
||||
|
||||
static inline uint64_t rdtsc(void)
|
||||
{
|
||||
uint64_t low, high;
|
||||
|
||||
asm volatile ( "rdtsc" : "=a" (low), "=d" (high) );
|
||||
|
||||
return (high << 32) | low;
|
||||
}
|
||||
|
||||
static inline uint64_t rdtsc_ordered(void)
|
||||
{
|
||||
uint64_t low, high, aux;
|
||||
|
||||
/*
|
||||
* The RDTSC instruction is not serializing. Make it dispatch serializing
|
||||
* for the purposes here by issuing LFENCE (or MFENCE if necessary) ahead
|
||||
* of it.
|
||||
*
|
||||
* RDTSCP, otoh, "does wait until all previous instructions have executed
|
||||
* and all previous loads are globally visible" (SDM) / "forces all older
|
||||
* instructions to retire before reading the timestamp counter" (APM).
|
||||
*/
|
||||
alternative_io_2("lfence; rdtsc",
|
||||
"mfence; rdtsc", X86_FEATURE_MFENCE_RDTSC,
|
||||
"rdtscp", X86_FEATURE_RDTSCP,
|
||||
ASM_OUTPUT2("=a" (low), "=d" (high), "=c" (aux)),
|
||||
/* no inputs */);
|
||||
|
||||
return (high << 32) | low;
|
||||
}
|
||||
|
||||
#define __write_tsc(val) wrmsrl(MSR_IA32_TSC, val)
|
||||
|
||||
/*
|
||||
* Reliable TSCs are in lockstep across all CPUs. We should never write to
|
||||
* them.
|
||||
*/
|
||||
#define write_tsc(val) ({ \
|
||||
ASSERT(!boot_cpu_has(X86_FEATURE_TSC_RELIABLE)); \
|
||||
__write_tsc(val); \
|
||||
})
|
||||
|
||||
#endif /* X86_TSC_H */
|
||||