diff options
-rw-r--r-- | arch/x86_64/kernel/vsyscall.c | 8 | ||||
-rw-r--r-- | include/linux/getcpu.h | 12 | ||||
-rw-r--r-- | kernel/sys.c | 8 |
3 files changed, 15 insertions, 13 deletions
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index ac48c3857ddb..07c086382059 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c | |||
@@ -155,8 +155,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) | |||
155 | We do this here because otherwise user space would do it on | 155 | We do this here because otherwise user space would do it on |
156 | its own in a likely inferior way (no access to jiffies). | 156 | its own in a likely inferior way (no access to jiffies). |
157 | If you don't like it pass NULL. */ | 157 | If you don't like it pass NULL. */ |
158 | if (tcache && tcache->t0 == (j = __jiffies)) { | 158 | if (tcache && tcache->blob[0] == (j = __jiffies)) { |
159 | p = tcache->t1; | 159 | p = tcache->blob[1]; |
160 | } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { | 160 | } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { |
161 | /* Load per CPU data from RDTSCP */ | 161 | /* Load per CPU data from RDTSCP */ |
162 | rdtscp(dummy, dummy, p); | 162 | rdtscp(dummy, dummy, p); |
@@ -165,8 +165,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) | |||
165 | asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); | 165 | asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); |
166 | } | 166 | } |
167 | if (tcache) { | 167 | if (tcache) { |
168 | tcache->t0 = j; | 168 | tcache->blob[0] = j; |
169 | tcache->t1 = p; | 169 | tcache->blob[1] = p; |
170 | } | 170 | } |
171 | if (cpu) | 171 | if (cpu) |
172 | *cpu = p & 0xfff; | 172 | *cpu = p & 0xfff; |
diff --git a/include/linux/getcpu.h b/include/linux/getcpu.h index 031ed3780e45..c7372d7a97be 100644 --- a/include/linux/getcpu.h +++ b/include/linux/getcpu.h | |||
@@ -1,16 +1,18 @@ | |||
1 | #ifndef _LINUX_GETCPU_H | 1 | #ifndef _LINUX_GETCPU_H |
2 | #define _LINUX_GETCPU_H 1 | 2 | #define _LINUX_GETCPU_H 1 |
3 | 3 | ||
4 | /* Cache for getcpu() to speed it up. Results might be upto a jiffie | 4 | /* Cache for getcpu() to speed it up. Results might be a short time |
5 | out of date, but will be faster. | 5 | out of date, but will be faster. |
6 | |||
6 | User programs should not refer to the contents of this structure. | 7 | User programs should not refer to the contents of this structure. |
7 | It is only a cache for vgetcpu(). It might change in future kernels. | 8 | I repeat they should not refer to it. If they do they will break |
9 | in future kernels. | ||
10 | |||
11 | It is only a private cache for vgetcpu(). It will change in future kernels. | ||
8 | The user program must store this information per thread (__thread) | 12 | The user program must store this information per thread (__thread) |
9 | If you want 100% accurate information pass NULL instead. */ | 13 | If you want 100% accurate information pass NULL instead. */ |
10 | struct getcpu_cache { | 14 | struct getcpu_cache { |
11 | unsigned long t0; | 15 | unsigned long blob[128 / sizeof(long)]; |
12 | unsigned long t1; | ||
13 | unsigned long res[4]; | ||
14 | }; | 16 | }; |
15 | 17 | ||
16 | #endif | 18 | #endif |
diff --git a/kernel/sys.c b/kernel/sys.c index 8647061c084a..b88806c66244 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -2083,12 +2083,12 @@ asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep, | |||
2083 | * padding | 2083 | * padding |
2084 | */ | 2084 | */ |
2085 | unsigned long t0, t1; | 2085 | unsigned long t0, t1; |
2086 | get_user(t0, &cache->t0); | 2086 | get_user(t0, &cache->blob[0]); |
2087 | get_user(t1, &cache->t1); | 2087 | get_user(t1, &cache->blob[1]); |
2088 | t0++; | 2088 | t0++; |
2089 | t1++; | 2089 | t1++; |
2090 | put_user(t0, &cache->t0); | 2090 | put_user(t0, &cache->blob[0]); |
2091 | put_user(t1, &cache->t1); | 2091 | put_user(t1, &cache->blob[1]); |
2092 | } | 2092 | } |
2093 | return err ? -EFAULT : 0; | 2093 | return err ? -EFAULT : 0; |
2094 | } | 2094 | } |