aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/kernel/vsyscall.c8
-rw-r--r--include/linux/getcpu.h12
-rw-r--r--kernel/sys.c8
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. */
10struct getcpu_cache { 14struct 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}