diff options
Diffstat (limited to 'kernel/compat.c')
-rw-r--r-- | kernel/compat.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index d4898aad6cfa..6952dd057300 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -982,4 +982,37 @@ asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_pages, | |||
982 | } | 982 | } |
983 | return sys_move_pages(pid, nr_pages, pages, nodes, status, flags); | 983 | return sys_move_pages(pid, nr_pages, pages, nodes, status, flags); |
984 | } | 984 | } |
985 | |||
986 | asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, | ||
987 | compat_ulong_t maxnode, | ||
988 | const compat_ulong_t __user *old_nodes, | ||
989 | const compat_ulong_t __user *new_nodes) | ||
990 | { | ||
991 | unsigned long __user *old = NULL; | ||
992 | unsigned long __user *new = NULL; | ||
993 | nodemask_t tmp_mask; | ||
994 | unsigned long nr_bits; | ||
995 | unsigned long size; | ||
996 | |||
997 | nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES); | ||
998 | size = ALIGN(nr_bits, BITS_PER_LONG) / 8; | ||
999 | if (old_nodes) { | ||
1000 | if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits)) | ||
1001 | return -EFAULT; | ||
1002 | old = compat_alloc_user_space(new_nodes ? size * 2 : size); | ||
1003 | if (new_nodes) | ||
1004 | new = old + size / sizeof(unsigned long); | ||
1005 | if (copy_to_user(old, nodes_addr(tmp_mask), size)) | ||
1006 | return -EFAULT; | ||
1007 | } | ||
1008 | if (new_nodes) { | ||
1009 | if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits)) | ||
1010 | return -EFAULT; | ||
1011 | if (new == NULL) | ||
1012 | new = compat_alloc_user_space(size); | ||
1013 | if (copy_to_user(new, nodes_addr(tmp_mask), size)) | ||
1014 | return -EFAULT; | ||
1015 | } | ||
1016 | return sys_migrate_pages(pid, nr_bits + 1, old, new); | ||
1017 | } | ||
985 | #endif | 1018 | #endif |