Commit 7896d77b authored by Anton Blanchard's avatar Anton Blanchard Committed by Linus Torvalds

[PATCH] ppc64: fix compat NUMA API on big endian 64bit

Switch the NUMA API to use compat_get_bitmap/compat_put_bitmap.  In order
to use compat_alloc_userspace instead of set_fs tricks, we have to do a few
copies.

This is what we are currently using on ppc64 but are willing to entertain
the idea of going to a 32bit bitmap, especially considering how much hoops
we have to go through to get it right in this patch.
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 5511cbde
...@@ -525,20 +525,82 @@ asmlinkage long sys_get_mempolicy(int __user *policy, ...@@ -525,20 +525,82 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
/* The other functions are compatible */
asmlinkage long compat_get_mempolicy(int __user *policy, asmlinkage long compat_get_mempolicy(int __user *policy,
unsigned __user *nmask, unsigned maxnode, compat_ulong_t __user *nmask,
unsigned addr, unsigned flags) compat_ulong_t maxnode,
compat_ulong_t addr, compat_ulong_t flags)
{ {
long err; long err;
unsigned long __user *nm = NULL; unsigned long __user *nm = NULL;
unsigned long nr_bits, alloc_size;
DECLARE_BITMAP(bm, MAX_NUMNODES);
nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
if (nmask) if (nmask)
nm = compat_alloc_user_space(ALIGN(maxnode-1, 64) / 8); nm = compat_alloc_user_space(alloc_size);
err = sys_get_mempolicy(policy, nm, maxnode, addr, flags);
if (!err && copy_in_user(nmask, nm, ALIGN(maxnode-1, 32)/8)) err = sys_get_mempolicy(policy, nm, nr_bits+1, addr, flags);
err = -EFAULT;
if (!err && nmask) {
err = copy_from_user(bm, nm, alloc_size);
/* ensure entire bitmap is zeroed */
err |= clear_user(nmask, ALIGN(maxnode-1, 8) / 8);
err |= compat_put_bitmap(nmask, bm, nr_bits);
}
return err; return err;
} }
asmlinkage long compat_set_mempolicy(int mode, compat_ulong_t __user *nmask,
compat_ulong_t maxnode)
{
long err;
unsigned long __user *nm = NULL;
unsigned long nr_bits, alloc_size;
DECLARE_BITMAP(bm, MAX_NUMNODES);
nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
if (nmask) {
err = compat_get_bitmap(bm, nmask, nr_bits);
nm = compat_alloc_user_space(alloc_size);
err |= copy_to_user(nm, bm, alloc_size);
}
if (err)
return -EFAULT;
return sys_set_mempolicy(mode, nm, nr_bits+1);
}
asmlinkage long compat_mbind(compat_ulong_t start, compat_ulong_t len,
compat_ulong_t mode, compat_ulong_t __user *nmask,
compat_ulong_t maxnode, compat_ulong_t flags)
{
long err;
unsigned long __user *nm = NULL;
unsigned long nr_bits, alloc_size;
DECLARE_BITMAP(bm, MAX_NUMNODES);
nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
if (nmask) {
err = compat_get_bitmap(bm, nmask, nr_bits);
nm = compat_alloc_user_space(alloc_size);
err |= copy_to_user(nm, bm, alloc_size);
}
if (err)
return -EFAULT;
return sys_mbind(start, len, mode, nm, nr_bits+1, flags);
}
#endif #endif
/* Return effective policy for a VMA */ /* Return effective policy for a VMA */
......
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