summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2004-09-13 00:05:30 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-09-13 00:05:30 -0700
commit7d783796ed8e974fc82bed4ce4aec3dfa1f6a9b6 (patch)
tree14f8e113d7305f778b95c93386deee75096bf6ae
parent2d3399ab54c9763fcba314d0b33ab82e1580d7aa (diff)
[PATCH] Backward compatibility for compat sched_getaffinity
The follow patch special cases the NR_CPUS <= BITS_PER_COMPAT_LONG case. Without this patch, a 32bit task would be required to have a 64bit cpumask no matter what value of NR_CPUS are used. With this patch a compat long sized bitmask is allowed if NR_CPUS is small enough to fit within it. Of course applications should be using the glibc wrappers that use an opaque cpu_mask_t type, but there could be older applications using the syscalls directly. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--kernel/compat.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 9f3f23fd2788..33880d224077 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -446,8 +446,12 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
int ret;
cpumask_t mask;
unsigned long *k;
+ unsigned int min_length = sizeof(cpumask_t);
- if (len < sizeof(cpumask_t))
+ if (NR_CPUS <= BITS_PER_COMPAT_LONG)
+ min_length = sizeof(compat_ulong_t);
+
+ if (len < min_length)
return -EINVAL;
ret = sched_getaffinity(pid, &mask);
@@ -455,11 +459,11 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
return ret;
k = cpus_addr(mask);
- ret = compat_put_bitmap(user_mask_ptr, k, sizeof(cpumask_t) * 8);
+ ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8);
if (ret)
return ret;
- return sizeof(cpumask_t);
+ return min_length;
}
static int get_compat_itimerspec(struct itimerspec *dst,