select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_UID16
        select HAVE_VIRT_CPU_ACCOUNTING_GEN
 +      select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
        select IRQ_FORCED_THREADING
+       select LOCK_MM_AND_FIND_VMA
        select MODULES_USE_ELF_REL
        select NEED_DMA_MAP_STATE
        select OF_EARLY_FLATTREE if OF
 
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_USER_RETURN_NOTIFIER
        select HAVE_GENERIC_VDSO
 +      select HOTPLUG_PARALLEL                 if SMP && X86_64
        select HOTPLUG_SMT                      if SMP
 +      select HOTPLUG_SPLIT_STARTUP            if SMP && X86_32
        select IRQ_FORCED_THREADING
+       select LOCK_MM_AND_FIND_VMA
        select NEED_PER_CPU_EMBED_FIRST_CHUNK
        select NEED_PER_CPU_PAGE_FIRST_CHUNK
        select NEED_SG_DMA_LENGTH
 
  
        /*
         * 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);
 +                      &page, NULL);
-       mmap_read_unlock(bprm->mm);
+       mmap_read_unlock(mm);
        if (ret <= 0)
                return NULL;
  
 
        if (mmap_read_lock_killable(mm))
                return 0;
  
 -      /* We might need to expand the stack to access it */
 -      vma = vma_lookup(mm, addr);
 -      if (!vma) {
 -              vma = expand_stack(mm, addr);
 -              if (!vma)
 -                      return 0;
 -      }
 -
        /* ignore errors, just check how much was successfully transferred */
        while (len) {
 -              int bytes, ret, offset;
 +              int bytes, offset;
                void *maddr;
 -              struct page *page = NULL;
 +              struct vm_area_struct *vma = NULL;
 +              struct page *page = get_user_page_vma_remote(mm, addr,
 +                                                           gup_flags, &vma);
 +
 +              if (IS_ERR_OR_NULL(page)) {
- #ifndef CONFIG_HAVE_IOREMAP_PROT
-                       break;
- #else
-                       int res = 0;
++                      /* We might need to expand the stack to access it */
++                      vma = vma_lookup(mm, addr);
++                      if (!vma) {
++                              vma = expand_stack(mm, addr);
++
++                              /* mmap_lock was dropped on failure */
++                              if (!vma)
++                                      return buf - old_buf;
++
++                              /* Try again if stack expansion worked */
++                              continue;
++                      }
++
  
 -              ret = get_user_pages_remote(mm, addr, 1,
 -                              gup_flags, &page, &vma, NULL);
 -              if (ret <= 0) {
 -#ifndef CONFIG_HAVE_IOREMAP_PROT
 -                      break;
 -#else
                        /*
                         * Check if this is a VM_IO | VM_PFNMAP VMA, which
                         * we can access using slightly different code.
                         */
--                      vma = vma_lookup(mm, addr);
--                      if (!vma)
--                              break;
++                      bytes = 0;
++#ifdef CONFIG_HAVE_IOREMAP_PROT
                        if (vma->vm_ops && vma->vm_ops->access)
-                               res = vma->vm_ops->access(vma, addr, buf,
 -                              ret = vma->vm_ops->access(vma, addr, buf,
--                                                        len, write);
-                       if (res <= 0)
 -                      if (ret <= 0)
--                              break;
-                       bytes = res;
 -                      bytes = ret;
++                              bytes = vma->vm_ops->access(vma, addr, buf,
++                                                          len, write);
  #endif
++                      if (bytes <= 0)
++                              break;
                } else {
                        bytes = len;
                        offset = addr & (PAGE_SIZE-1);