Commit 7292f3aa authored by Anton Blanchard's avatar Anton Blanchard Committed by Linus Torvalds

[PATCH] ppc64: fix compat cpu affinity on big endian 64bit

Add compat sched affinity code.  We can argue about how
USE_COMPAT_ULONG_CPUMASK works now that the non compat interface has
changed.

The old non compat behaviour was to require a bitmap long enough in both
setaffinity and getaffinity, now its only required in getaffinity.  I could
do the same for the 32bit interfaces.
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 43c8585c
......@@ -412,16 +412,43 @@ compat_sys_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options,
}
}
/*
* for maximum compatability, we allow programs to use a single (compat)
* unsigned long bitmask if all cpus will fit. If not, you have to have
* at least the kernel size available.
*/
#define USE_COMPAT_ULONG_CPUMASK (NR_CPUS <= BITS_PER_COMPAT_LONG)
asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
unsigned int len,
compat_ulong_t __user *user_mask_ptr)
{
unsigned long kern_mask;
cpumask_t kern_mask;
mm_segment_t old_fs;
int ret;
if (get_user(kern_mask, user_mask_ptr))
return -EFAULT;
if (USE_COMPAT_ULONG_CPUMASK) {
compat_ulong_t user_mask;
if (len < sizeof(user_mask))
return -EINVAL;
if (get_user(user_mask, user_mask_ptr))
return -EFAULT;
cpus_addr(kern_mask)[0] = user_mask;
} else {
unsigned long *k;
if (len < sizeof(kern_mask))
return -EINVAL;
k = cpus_addr(kern_mask);
ret = compat_get_bitmap(k, user_mask_ptr,
sizeof(kern_mask) * BITS_PER_LONG);
if (ret)
return ret;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
......@@ -436,10 +463,14 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
compat_ulong_t __user *user_mask_ptr)
{
unsigned long kern_mask;
cpumask_t kern_mask;
mm_segment_t old_fs;
int ret;
if (len < (USE_COMPAT_ULONG_CPUMASK ? sizeof(compat_ulong_t)
: sizeof(kern_mask)))
return -EINVAL;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_sched_getaffinity(pid,
......@@ -447,10 +478,23 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
(unsigned long __user *) &kern_mask);
set_fs(old_fs);
if (ret > 0) {
ret = sizeof(compat_ulong_t);
if (put_user(kern_mask, user_mask_ptr))
if (ret < 0)
return ret;
if (USE_COMPAT_ULONG_CPUMASK) {
if (put_user(&cpus_addr(kern_mask)[0], user_mask_ptr))
return -EFAULT;
ret = sizeof(compat_ulong_t);
} else {
unsigned long *k;
k = cpus_addr(kern_mask);
ret = compat_put_bitmap(user_mask_ptr, k,
sizeof(kern_mask) * BITS_PER_LONG);
if (ret)
return ret;
ret = sizeof(kern_mask);
}
return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment