summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-09-30 01:47:55 +0200
committerAndi Kleen <andi@basil.nowhere.org>2006-09-30 01:47:55 +0200
commit34596dc9e59d7bece16fe5aba08116b49465da26 (patch)
tree75e09786a8ff8db3a69a5c82663f97d317e59e46
parent120b114237e2461fb4fa437c5c37edf014c916b9 (diff)
[PATCH] Define vsyscall cache as blob to make clearer that user space shouldn't use it
Signed-off-by: Andi Kleen <ak@suse.de>
-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)
We do this here because otherwise user space would do it on
its own in a likely inferior way (no access to jiffies).
If you don't like it pass NULL. */
- if (tcache && tcache->t0 == (j = __jiffies)) {
- p = tcache->t1;
+ if (tcache && tcache->blob[0] == (j = __jiffies)) {
+ p = tcache->blob[1];
} else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
/* Load per CPU data from RDTSCP */
rdtscp(dummy, dummy, p);
@@ -165,8 +165,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
}
if (tcache) {
- tcache->t0 = j;
- tcache->t1 = p;
+ tcache->blob[0] = j;
+ tcache->blob[1] = p;
}
if (cpu)
*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 @@
#ifndef _LINUX_GETCPU_H
#define _LINUX_GETCPU_H 1
-/* Cache for getcpu() to speed it up. Results might be upto a jiffie
+/* Cache for getcpu() to speed it up. Results might be a short time
out of date, but will be faster.
+
User programs should not refer to the contents of this structure.
- It is only a cache for vgetcpu(). It might change in future kernels.
+ I repeat they should not refer to it. If they do they will break
+ in future kernels.
+
+ It is only a private cache for vgetcpu(). It will change in future kernels.
The user program must store this information per thread (__thread)
If you want 100% accurate information pass NULL instead. */
struct getcpu_cache {
- unsigned long t0;
- unsigned long t1;
- unsigned long res[4];
+ unsigned long blob[128 / sizeof(long)];
};
#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,
* padding
*/
unsigned long t0, t1;
- get_user(t0, &cache->t0);
- get_user(t1, &cache->t1);
+ get_user(t0, &cache->blob[0]);
+ get_user(t1, &cache->blob[1]);
t0++;
t1++;
- put_user(t0, &cache->t0);
- put_user(t1, &cache->t1);
+ put_user(t0, &cache->blob[0]);
+ put_user(t1, &cache->blob[1]);
}
return err ? -EFAULT : 0;
}