Merge tag 'backlight-next-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee...
[linux-block.git] / kernel / sys.c
index 351de791630205d0000a5c354a2f9b0ff2e5c39a..72cdb16e26366b17308b698abb7e91dcc12eb67d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/highuid.h>
 #include <linux/fs.h>
 #include <linux/kmod.h>
+#include <linux/ksm.h>
 #include <linux/perf_event.h>
 #include <linux/resource.h>
 #include <linux/kernel.h>
@@ -2388,6 +2389,16 @@ static inline int prctl_get_mdwe(unsigned long arg2, unsigned long arg3,
                PR_MDWE_REFUSE_EXEC_GAIN : 0;
 }
 
+static int prctl_get_auxv(void __user *addr, unsigned long len)
+{
+       struct mm_struct *mm = current->mm;
+       unsigned long size = min_t(unsigned long, sizeof(mm->saved_auxv), len);
+
+       if (size && copy_to_user(addr, mm->saved_auxv, size))
+               return -EFAULT;
+       return sizeof(mm->saved_auxv);
+}
+
 SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                unsigned long, arg4, unsigned long, arg5)
 {
@@ -2518,6 +2529,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                        else
                                return -EINVAL;
                        break;
+       case PR_GET_AUXV:
+               if (arg4 || arg5)
+                       return -EINVAL;
+               error = prctl_get_auxv((void __user *)arg2, arg3);
+               break;
                default:
                        return -EINVAL;
                }
@@ -2672,6 +2688,32 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
        case PR_SET_VMA:
                error = prctl_set_vma(arg2, arg3, arg4, arg5);
                break;
+#ifdef CONFIG_KSM
+       case PR_SET_MEMORY_MERGE:
+               if (arg3 || arg4 || arg5)
+                       return -EINVAL;
+               if (mmap_write_lock_killable(me->mm))
+                       return -EINTR;
+
+               if (arg2) {
+                       error = ksm_enable_merge_any(me->mm);
+               } else {
+                       /*
+                        * TODO: we might want disable KSM on all VMAs and
+                        * trigger unsharing to completely disable KSM.
+                        */
+                       clear_bit(MMF_VM_MERGE_ANY, &me->mm->flags);
+                       error = 0;
+               }
+               mmap_write_unlock(me->mm);
+               break;
+       case PR_GET_MEMORY_MERGE:
+               if (arg2 || arg3 || arg4 || arg5)
+                       return -EINVAL;
+
+               error = !!test_bit(MMF_VM_MERGE_ANY, &me->mm->flags);
+               break;
+#endif
        default:
                error = -EINVAL;
                break;