diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index 3f92b94..7275e41 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h @@ -49,6 +49,7 @@ #define X86_FEATURE_MP (1*32+19) /* MP Capable. */ #define X86_FEATURE_NX (1*32+20) /* Execute Disable */ #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ +#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */ #define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ #define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ #define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */ diff --git a/include/asm-x86_64/tsc.h b/include/asm-x86_64/tsc.h index 9a0a368..7db952d 100644 --- a/include/asm-x86_64/tsc.h +++ b/include/asm-x86_64/tsc.h @@ -34,22 +34,28 @@ static inline cycles_t get_cycles(void) /* Like get_cycles, but make sure the CPU is synchronized. */ static __always_inline cycles_t get_cycles_sync(void) { - unsigned long long ret; -#ifdef X86_FEATURE_SYNC_RDTSC + unsigned int a, d; unsigned eax; +#ifdef X86_FEATURE_SYNC_RDTSC /* * Don't do an additional sync on CPUs where we know * RDTSC is already synchronous: */ alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC, "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); + /* We use RDTSCP if it is available, no extra CPUID required then */ + alternative_add_one(ASM_NOP2, X86_FEATURE_RDTSCP); #else - sync_core(); + /* no CPUID required if we use RDTSCP */ + alternative_io("cpuid", ASM_NOP2, X86_FEATURE_RDTSCP, + "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); #endif - rdtscll(ret); - return ret; + alternative_io("rdtsc\n" ASM_NOP1, "rdtscp", X86_FEATURE_RDTSCP, + ALTERNATIVE_OUTPUT2("=a" (a), "=d" (d)), "0" (1) : "ecx","memory"); + + return ((unsigned long long)a) | ((unsigned long long)d) << 32; } extern void tsc_init(void);