update hdmi driver: support 480p
[firefly-linux-kernel-4.4.55.git] / kernel / compat.c
index f6c204f07ea6084c4849d52358d6b1b2aab1f0da..8bc557869d90a9b5ebc47f6de0b5abca05aaa203 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/posix-timers.h>
 #include <linux/times.h>
 #include <linux/ptrace.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 
@@ -494,29 +495,26 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
 {
        int ret;
        cpumask_var_t mask;
-       unsigned long *k;
-       unsigned int min_length = cpumask_size();
-
-       if (nr_cpu_ids <= BITS_PER_COMPAT_LONG)
-               min_length = sizeof(compat_ulong_t);
 
-       if (len < min_length)
+       if ((len * BITS_PER_BYTE) < nr_cpu_ids)
+               return -EINVAL;
+       if (len & (sizeof(compat_ulong_t)-1))
                return -EINVAL;
 
        if (!alloc_cpumask_var(&mask, GFP_KERNEL))
                return -ENOMEM;
 
        ret = sched_getaffinity(pid, mask);
-       if (ret < 0)
-               goto out;
+       if (ret == 0) {
+               size_t retlen = min_t(size_t, len, cpumask_size());
 
-       k = cpumask_bits(mask);
-       ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8);
-       if (ret == 0)
-               ret = min_length;
-
-out:
+               if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
+                       ret = -EFAULT;
+               else
+                       ret = retlen;
+       }
        free_cpumask_var(mask);
+
        return ret;
 }
 
@@ -1139,3 +1137,24 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
 
        return 0;
 }
+
+/*
+ * Allocate user-space memory for the duration of a single system call,
+ * in order to marshall parameters inside a compat thunk.
+ */
+void __user *compat_alloc_user_space(unsigned long len)
+{
+       void __user *ptr;
+
+       /* If len would occupy more than half of the entire compat space... */
+       if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
+               return NULL;
+
+       ptr = arch_compat_alloc_user_space(len);
+
+       if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
+               return NULL;
+
+       return ptr;
+}
+EXPORT_SYMBOL_GPL(compat_alloc_user_space);