diff options
author | Glauber de Oliveira Costa <gcosta@redhat.com> | 2008-01-30 07:31:06 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:06 -0500 |
commit | 8f12dea6135d0a55b151dcb4c6bbe211f5f8d35d (patch) | |
tree | 3c4c486ffb318aa90e0bf75402d22348f7ae1525 | |
parent | c758ecf62ad94ddfeb4e7d8a5498bdcb2e3c85db (diff) |
x86: introduce native_read_tscp
Targetting paravirt, this patch introduces native_read_tscp, in
place of rdtscp() macro. When in a paravirt guest, this will
involve a function call, and thus, cannot be done in the vdso area.
These users then have to call the native version directly
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/kernel/vsyscall_64.c | 4 | ||||
-rw-r--r-- | arch/x86/vdso/vgetcpu.c | 4 | ||||
-rw-r--r-- | include/asm-x86/msr.h | 29 |
3 files changed, 25 insertions, 12 deletions
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 018f7cf33790..c4c5e765cd2c 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c | |||
@@ -190,7 +190,7 @@ time_t __vsyscall(1) vtime(time_t *t) | |||
190 | long __vsyscall(2) | 190 | long __vsyscall(2) |
191 | vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) | 191 | vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) |
192 | { | 192 | { |
193 | unsigned int dummy, p; | 193 | unsigned int p; |
194 | unsigned long j = 0; | 194 | unsigned long j = 0; |
195 | 195 | ||
196 | /* Fast cache - only recompute value once per jiffies and avoid | 196 | /* Fast cache - only recompute value once per jiffies and avoid |
@@ -205,7 +205,7 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) | |||
205 | p = tcache->blob[1]; | 205 | p = tcache->blob[1]; |
206 | } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { | 206 | } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { |
207 | /* Load per CPU data from RDTSCP */ | 207 | /* Load per CPU data from RDTSCP */ |
208 | rdtscp(dummy, dummy, p); | 208 | native_read_tscp(&p); |
209 | } else { | 209 | } else { |
210 | /* Load per CPU data from GDT */ | 210 | /* Load per CPU data from GDT */ |
211 | asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); | 211 | asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); |
diff --git a/arch/x86/vdso/vgetcpu.c b/arch/x86/vdso/vgetcpu.c index 3b1ae1abfba9..c8097f17f8a9 100644 --- a/arch/x86/vdso/vgetcpu.c +++ b/arch/x86/vdso/vgetcpu.c | |||
@@ -15,11 +15,11 @@ | |||
15 | 15 | ||
16 | long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) | 16 | long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) |
17 | { | 17 | { |
18 | unsigned int dummy, p; | 18 | unsigned int p; |
19 | 19 | ||
20 | if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) { | 20 | if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) { |
21 | /* Load per CPU data from RDTSCP */ | 21 | /* Load per CPU data from RDTSCP */ |
22 | rdtscp(dummy, dummy, p); | 22 | native_read_tscp(&p); |
23 | } else { | 23 | } else { |
24 | /* Load per CPU data from GDT */ | 24 | /* Load per CPU data from GDT */ |
25 | asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); | 25 | asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); |
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 0648b2d57a38..b6262e99fc8e 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h | |||
@@ -7,6 +7,27 @@ | |||
7 | # include <linux/types.h> | 7 | # include <linux/types.h> |
8 | #endif | 8 | #endif |
9 | 9 | ||
10 | #ifdef __KERNEL__ | ||
11 | #ifndef __ASSEMBLY__ | ||
12 | static inline unsigned long long native_read_tscp(int *aux) | ||
13 | { | ||
14 | unsigned long low, high; | ||
15 | asm volatile (".byte 0x0f,0x01,0xf9" | ||
16 | : "=a" (low), "=d" (high), "=c" (*aux)); | ||
17 | return low | ((u64)high >> 32); | ||
18 | } | ||
19 | |||
20 | #define rdtscp(low, high, aux) \ | ||
21 | do { \ | ||
22 | unsigned long long _val = native_read_tscp(&(aux)); \ | ||
23 | (low) = (u32)_val; \ | ||
24 | (high) = (u32)(_val >> 32); \ | ||
25 | } while (0) | ||
26 | |||
27 | #define rdtscpll(val, aux) (val) = native_read_tscp(&(aux)) | ||
28 | #endif | ||
29 | #endif | ||
30 | |||
10 | #ifdef __i386__ | 31 | #ifdef __i386__ |
11 | 32 | ||
12 | #ifdef __KERNEL__ | 33 | #ifdef __KERNEL__ |
@@ -178,8 +199,6 @@ static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) | |||
178 | #define rdtscl(low) \ | 199 | #define rdtscl(low) \ |
179 | __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") | 200 | __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") |
180 | 201 | ||
181 | #define rdtscp(low,high,aux) \ | ||
182 | __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) | ||
183 | 202 | ||
184 | #define rdtscll(val) do { \ | 203 | #define rdtscll(val) do { \ |
185 | unsigned int __a,__d; \ | 204 | unsigned int __a,__d; \ |
@@ -187,12 +206,6 @@ static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) | |||
187 | (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ | 206 | (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ |
188 | } while(0) | 207 | } while(0) |
189 | 208 | ||
190 | #define rdtscpll(val, aux) do { \ | ||
191 | unsigned long __a, __d; \ | ||
192 | __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ | ||
193 | (val) = (__d << 32) | __a; \ | ||
194 | } while (0) | ||
195 | |||
196 | #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) | 209 | #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) |
197 | 210 | ||
198 | #define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0) | 211 | #define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0) |