ACPICA: Add acpi_gpe_count global to track the number of GPE events
[sfrench/cifs-2.6.git] / kernel / compat.c
index 126dee9530aacc13a37d304ee8a4b54f69355a82..6952dd057300f637e68a059ba1f299d8464ae9f8 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/security.h>
 #include <linux/timex.h>
 #include <linux/migrate.h>
+#include <linux/posix-timers.h>
 
 #include <asm/uaccess.h>
 
@@ -601,6 +602,30 @@ long compat_sys_clock_getres(clockid_t which_clock,
        return err;
 } 
 
+static long compat_clock_nanosleep_restart(struct restart_block *restart)
+{
+       long err;
+       mm_segment_t oldfs;
+       struct timespec tu;
+       struct compat_timespec *rmtp = (struct compat_timespec *)(restart->arg1);
+
+       restart->arg1 = (unsigned long) &tu;
+       oldfs = get_fs();
+       set_fs(KERNEL_DS);
+       err = clock_nanosleep_restart(restart);
+       set_fs(oldfs);
+
+       if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
+           put_compat_timespec(&tu, rmtp))
+               return -EFAULT;
+
+       if (err == -ERESTART_RESTARTBLOCK) {
+               restart->fn = compat_clock_nanosleep_restart;
+               restart->arg1 = (unsigned long) rmtp;
+       }
+       return err;
+}
+
 long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
                            struct compat_timespec __user *rqtp,
                            struct compat_timespec __user *rmtp)
@@ -608,6 +633,7 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
        long err;
        mm_segment_t oldfs;
        struct timespec in, out; 
+       struct restart_block *restart;
 
        if (get_compat_timespec(&in, rqtp)) 
                return -EFAULT;
@@ -618,9 +644,16 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
                                  (struct timespec __user *) &in,
                                  (struct timespec __user *) &out);
        set_fs(oldfs);
+
        if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
            put_compat_timespec(&out, rmtp))
                return -EFAULT;
+
+       if (err == -ERESTART_RESTARTBLOCK) {
+               restart = &current_thread_info()->restart_block;
+               restart->fn = compat_clock_nanosleep_restart;
+               restart->arg1 = (unsigned long) rmtp;
+       }
        return err;     
 } 
 
@@ -645,7 +678,7 @@ int get_compat_sigevent(struct sigevent *event,
                ? -EFAULT : 0;
 }
 
-long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
                       unsigned long bitmap_size)
 {
        int i, j;
@@ -949,4 +982,37 @@ asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_pages,
        }
        return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
 }
+
+asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
+                       compat_ulong_t maxnode,
+                       const compat_ulong_t __user *old_nodes,
+                       const compat_ulong_t __user *new_nodes)
+{
+       unsigned long __user *old = NULL;
+       unsigned long __user *new = NULL;
+       nodemask_t tmp_mask;
+       unsigned long nr_bits;
+       unsigned long size;
+
+       nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES);
+       size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
+       if (old_nodes) {
+               if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits))
+                       return -EFAULT;
+               old = compat_alloc_user_space(new_nodes ? size * 2 : size);
+               if (new_nodes)
+                       new = old + size / sizeof(unsigned long);
+               if (copy_to_user(old, nodes_addr(tmp_mask), size))
+                       return -EFAULT;
+       }
+       if (new_nodes) {
+               if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits))
+                       return -EFAULT;
+               if (new == NULL)
+                       new = compat_alloc_user_space(size);
+               if (copy_to_user(new, nodes_addr(tmp_mask), size))
+                       return -EFAULT;
+       }
+       return sys_migrate_pages(pid, nr_bits + 1, old, new);
+}
 #endif