diff options
author | Andi Kleen <ak@suse.de> | 2006-09-30 01:47:55 +0200 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-30 01:47:55 +0200 |
commit | 34596dc9e59d7bece16fe5aba08116b49465da26 (patch) | |
tree | 75e09786a8ff8db3a69a5c82663f97d317e59e46 | |
parent | 120b114237e2461fb4fa437c5c37edf014c916b9 (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.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 ac48c3857dd..07c08638205 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 031ed3780e4..c7372d7a97b 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 8647061c084..b88806c6624 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; } |