WIP: update tizen_qemu_defconfig
[platform/kernel/linux-starfive.git] / fs / exec.c
index 349a5da..283012e 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -198,33 +198,39 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                int write)
 {
        struct page *page;
+       struct vm_area_struct *vma = bprm->vma;
+       struct mm_struct *mm = bprm->mm;
        int ret;
-       unsigned int gup_flags = FOLL_FORCE;
 
-#ifdef CONFIG_STACK_GROWSUP
-       if (write) {
-               ret = expand_downwards(bprm->vma, pos);
-               if (ret < 0)
+       /*
+        * Avoid relying on expanding the stack down in GUP (which
+        * does not work for STACK_GROWSUP anyway), and just do it
+        * by hand ahead of time.
+        */
+       if (write && pos < vma->vm_start) {
+               mmap_write_lock(mm);
+               ret = expand_downwards(vma, pos);
+               if (unlikely(ret < 0)) {
+                       mmap_write_unlock(mm);
                        return NULL;
-       }
-#endif
-
-       if (write)
-               gup_flags |= FOLL_WRITE;
+               }
+               mmap_write_downgrade(mm);
+       } else
+               mmap_read_lock(mm);
 
        /*
         * We are doing an exec().  'current' is the process
-        * doing the exec and bprm->mm is the new process's mm.
+        * doing the exec and 'mm' is the new process's mm.
         */
-       mmap_read_lock(bprm->mm);
-       ret = get_user_pages_remote(bprm->mm, pos, 1, gup_flags,
+       ret = get_user_pages_remote(mm, pos, 1,
+                       write ? FOLL_WRITE : 0,
                        &page, NULL, NULL);
-       mmap_read_unlock(bprm->mm);
+       mmap_read_unlock(mm);
        if (ret <= 0)
                return NULL;
 
        if (write)
-               acct_arg_size(bprm, vma_pages(bprm->vma));
+               acct_arg_size(bprm, vma_pages(vma));
 
        return page;
 }
@@ -854,7 +860,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
                stack_base = vma->vm_start - stack_expand;
 #endif
        current->mm->start_stack = bprm->p;
-       ret = expand_stack(vma, stack_base);
+       ret = expand_stack_locked(vma, stack_base);
        if (ret)
                ret = -EFAULT;
 
@@ -1012,7 +1018,6 @@ static int exec_mmap(struct mm_struct *mm)
        active_mm = tsk->active_mm;
        tsk->active_mm = mm;
        tsk->mm = mm;
-       lru_gen_add_mm(mm);
        /*
         * This prevents preemption while active_mm is being loaded and
         * it and mm are being updated, which could cause problems for
@@ -1025,6 +1030,7 @@ static int exec_mmap(struct mm_struct *mm)
        activate_mm(active_mm, mm);
        if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM))
                local_irq_enable();
+       lru_gen_add_mm(mm);
        task_unlock(tsk);
        lru_gen_use_mm(mm);
        if (old_mm) {
@@ -1197,11 +1203,11 @@ static int unshare_sighand(struct task_struct *me)
                        return -ENOMEM;
 
                refcount_set(&newsighand->count, 1);
-               memcpy(newsighand->action, oldsighand->action,
-                      sizeof(newsighand->action));
 
                write_lock_irq(&tasklist_lock);
                spin_lock(&oldsighand->siglock);
+               memcpy(newsighand->action, oldsighand->action,
+                      sizeof(newsighand->action));
                rcu_assign_pointer(me->sighand, newsighand);
                spin_unlock(&oldsighand->siglock);
                write_unlock_irq(&tasklist_lock);