summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--0000_README4
-rw-r--r--1010_linux-6.3.11.patch2476
2 files changed, 2480 insertions, 0 deletions
diff --git a/0000_README b/0000_README
index 79a95e0e..80499d11 100644
--- a/0000_README
+++ b/0000_README
@@ -83,6 +83,10 @@ Patch: 1009_linux-6.3.10.patch
From: https://www.kernel.org
Desc: Linux 6.3.10
+Patch: 1010_linux-6.3.11.patch
+From: https://www.kernel.org
+Desc: Linux 6.3.11
+
Patch: 1500_XATTR_USER_PREFIX.patch
From: https://bugs.gentoo.org/show_bug.cgi?id=470644
Desc: Support for namespace user.pax.* on tmpfs.
diff --git a/1010_linux-6.3.11.patch b/1010_linux-6.3.11.patch
new file mode 100644
index 00000000..3797a28d
--- /dev/null
+++ b/1010_linux-6.3.11.patch
@@ -0,0 +1,2476 @@
+diff --git a/Makefile b/Makefile
+index 47253ac6c85c1..34349623a76a7 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 3
+-SUBLEVEL = 10
++SUBLEVEL = 11
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+
+diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
+index 780d4673c3ca7..a40a61583b335 100644
+--- a/arch/alpha/Kconfig
++++ b/arch/alpha/Kconfig
+@@ -29,6 +29,7 @@ config ALPHA
+ select GENERIC_SMP_IDLE_THREAD
+ select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_MOD_ARCH_SPECIFIC
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_RELA
+ select ODD_RT_SIGACTION
+ select OLD_SIGSUSPEND
+diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
+index 7b01ae4f3bc6c..8c9850437e674 100644
+--- a/arch/alpha/mm/fault.c
++++ b/arch/alpha/mm/fault.c
+@@ -119,20 +119,12 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
+ flags |= FAULT_FLAG_USER;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+ retry:
+- mmap_read_lock(mm);
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (!vma)
+- goto bad_area;
+- if (vma->vm_start <= address)
+- goto good_area;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+- if (expand_stack(vma, address))
+- goto bad_area;
++ goto bad_area_nosemaphore;
+
+ /* Ok, we have a good vm_area for this memory access, so
+ we can handle it. */
+- good_area:
+ si_code = SEGV_ACCERR;
+ if (cause < 0) {
+ if (!(vma->vm_flags & VM_EXEC))
+@@ -192,6 +184,7 @@ retry:
+ bad_area:
+ mmap_read_unlock(mm);
+
++ bad_area_nosemaphore:
+ if (user_mode(regs))
+ goto do_sigsegv;
+
+diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
+index d9a13ccf89a3a..cb1074f74c3f1 100644
+--- a/arch/arc/Kconfig
++++ b/arch/arc/Kconfig
+@@ -41,6 +41,7 @@ config ARC
+ select HAVE_PERF_EVENTS
+ select HAVE_SYSCALL_TRACEPOINTS
+ select IRQ_DOMAIN
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_RELA
+ select OF
+ select OF_EARLY_FLATTREE
+diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
+index 5ca59a482632a..f59e722d147f9 100644
+--- a/arch/arc/mm/fault.c
++++ b/arch/arc/mm/fault.c
+@@ -113,15 +113,9 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+ retry:
+- mmap_read_lock(mm);
+-
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (!vma)
+- goto bad_area;
+- if (unlikely(address < vma->vm_start)) {
+- if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack(vma, address))
+- goto bad_area;
+- }
++ goto bad_area_nosemaphore;
+
+ /*
+ * vm_area is good, now check permissions for this memory access
+@@ -161,6 +155,7 @@ retry:
+ bad_area:
+ mmap_read_unlock(mm);
+
++bad_area_nosemaphore:
+ /*
+ * Major/minor page fault accounting
+ * (in case of retry we only land here once)
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index e24a9820e12fa..a04bb151a9028 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -125,6 +125,7 @@ config ARM
+ select HAVE_UID16
+ select HAVE_VIRT_CPU_ACCOUNTING_GEN
+ 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
+diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
+index 2418f1efabd87..0860eeba8bd34 100644
+--- a/arch/arm/mm/fault.c
++++ b/arch/arm/mm/fault.c
+@@ -232,37 +232,11 @@ static inline bool is_permission_fault(unsigned int fsr)
+ return false;
+ }
+
+-static vm_fault_t __kprobes
+-__do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int flags,
+- unsigned long vma_flags, struct pt_regs *regs)
+-{
+- struct vm_area_struct *vma = find_vma(mm, addr);
+- if (unlikely(!vma))
+- return VM_FAULT_BADMAP;
+-
+- if (unlikely(vma->vm_start > addr)) {
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- return VM_FAULT_BADMAP;
+- if (addr < FIRST_USER_ADDRESS)
+- return VM_FAULT_BADMAP;
+- if (expand_stack(vma, addr))
+- return VM_FAULT_BADMAP;
+- }
+-
+- /*
+- * ok, we have a good vm_area for this memory access, check the
+- * permissions on the VMA allow for the fault which occurred.
+- */
+- if (!(vma->vm_flags & vma_flags))
+- return VM_FAULT_BADACCESS;
+-
+- return handle_mm_fault(vma, addr & PAGE_MASK, flags, regs);
+-}
+-
+ static int __kprobes
+ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ {
+ struct mm_struct *mm = current->mm;
++ struct vm_area_struct *vma;
+ int sig, code;
+ vm_fault_t fault;
+ unsigned int flags = FAULT_FLAG_DEFAULT;
+@@ -301,31 +275,21 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
+
+- /*
+- * As per x86, we may deadlock here. However, since the kernel only
+- * validly references user space from well defined areas of the code,
+- * we can bug out early if this is from code which shouldn't.
+- */
+- if (!mmap_read_trylock(mm)) {
+- if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
+- goto no_context;
+ retry:
+- mmap_read_lock(mm);
+- } else {
+- /*
+- * The above down_read_trylock() might have succeeded in
+- * which case, we'll have missed the might_sleep() from
+- * down_read()
+- */
+- might_sleep();
+-#ifdef CONFIG_DEBUG_VM
+- if (!user_mode(regs) &&
+- !search_exception_tables(regs->ARM_pc))
+- goto no_context;
+-#endif
++ vma = lock_mm_and_find_vma(mm, addr, regs);
++ if (unlikely(!vma)) {
++ fault = VM_FAULT_BADMAP;
++ goto bad_area;
+ }
+
+- fault = __do_page_fault(mm, addr, flags, vm_flags, regs);
++ /*
++ * ok, we have a good vm_area for this memory access, check the
++ * permissions on the VMA allow for the fault which occurred.
++ */
++ if (!(vma->vm_flags & vm_flags))
++ fault = VM_FAULT_BADACCESS;
++ else
++ fault = handle_mm_fault(vma, addr & PAGE_MASK, flags, regs);
+
+ /* If we need to retry but a fatal signal is pending, handle the
+ * signal first. We do not need to release the mmap_lock because
+@@ -356,6 +320,7 @@ retry:
+ if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
+ return 0;
+
++bad_area:
+ /*
+ * If we are in kernel mode at this point, we
+ * have no context to handle this fault with.
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 1023e896d46b8..15e097206e1a3 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -219,6 +219,7 @@ config ARM64
+ select IRQ_DOMAIN
+ select IRQ_FORCED_THREADING
+ select KASAN_VMALLOC if KASAN
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_RELA
+ select NEED_DMA_MAP_STATE
+ select NEED_SG_DMA_LENGTH
+diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
+index d1136259b7b85..473575a75f557 100644
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -483,27 +483,14 @@ static void do_bad_area(unsigned long far, unsigned long esr,
+ #define VM_FAULT_BADMAP ((__force vm_fault_t)0x010000)
+ #define VM_FAULT_BADACCESS ((__force vm_fault_t)0x020000)
+
+-static vm_fault_t __do_page_fault(struct mm_struct *mm, unsigned long addr,
++static vm_fault_t __do_page_fault(struct mm_struct *mm,
++ struct vm_area_struct *vma, unsigned long addr,
+ unsigned int mm_flags, unsigned long vm_flags,
+ struct pt_regs *regs)
+ {
+- struct vm_area_struct *vma = find_vma(mm, addr);
+-
+- if (unlikely(!vma))
+- return VM_FAULT_BADMAP;
+-
+ /*
+ * Ok, we have a good vm_area for this memory access, so we can handle
+ * it.
+- */
+- if (unlikely(vma->vm_start > addr)) {
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- return VM_FAULT_BADMAP;
+- if (expand_stack(vma, addr))
+- return VM_FAULT_BADMAP;
+- }
+-
+- /*
+ * Check that the permissions on the VMA allow for the fault which
+ * occurred.
+ */
+@@ -535,6 +522,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
+ unsigned long vm_flags;
+ unsigned int mm_flags = FAULT_FLAG_DEFAULT;
+ unsigned long addr = untagged_addr(far);
++ struct vm_area_struct *vma;
+
+ if (kprobe_page_fault(regs, esr))
+ return 0;
+@@ -585,31 +573,14 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
+
+- /*
+- * As per x86, we may deadlock here. However, since the kernel only
+- * validly references user space from well defined areas of the code,
+- * we can bug out early if this is from code which shouldn't.
+- */
+- if (!mmap_read_trylock(mm)) {
+- if (!user_mode(regs) && !search_exception_tables(regs->pc))
+- goto no_context;
+ retry:
+- mmap_read_lock(mm);
+- } else {
+- /*
+- * The above mmap_read_trylock() might have succeeded in which
+- * case, we'll have missed the might_sleep() from down_read().
+- */
+- might_sleep();
+-#ifdef CONFIG_DEBUG_VM
+- if (!user_mode(regs) && !search_exception_tables(regs->pc)) {
+- mmap_read_unlock(mm);
+- goto no_context;
+- }
+-#endif
++ vma = lock_mm_and_find_vma(mm, addr, regs);
++ if (unlikely(!vma)) {
++ fault = VM_FAULT_BADMAP;
++ goto done;
+ }
+
+- fault = __do_page_fault(mm, addr, mm_flags, vm_flags, regs);
++ fault = __do_page_fault(mm, vma, addr, mm_flags, vm_flags, regs);
+
+ /* Quick path to respond to signals */
+ if (fault_signal_pending(fault, regs)) {
+@@ -628,6 +599,7 @@ retry:
+ }
+ mmap_read_unlock(mm);
+
++done:
+ /*
+ * Handle the "normal" (no error) case first.
+ */
+diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
+index dba02da6fa344..225df1674b33a 100644
+--- a/arch/csky/Kconfig
++++ b/arch/csky/Kconfig
+@@ -96,6 +96,7 @@ config CSKY
+ select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_STACKPROTECTOR
+ select HAVE_SYSCALL_TRACEPOINTS
++ select LOCK_MM_AND_FIND_VMA
+ select MAY_HAVE_SPARSE_IRQ
+ select MODULES_USE_ELF_RELA if MODULES
+ select OF
+diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c
+index e15f736cca4b4..a885518ce1dd2 100644
+--- a/arch/csky/mm/fault.c
++++ b/arch/csky/mm/fault.c
+@@ -97,13 +97,12 @@ static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_f
+ BUG();
+ }
+
+-static inline void bad_area(struct pt_regs *regs, struct mm_struct *mm, int code, unsigned long addr)
++static inline void bad_area_nosemaphore(struct pt_regs *regs, struct mm_struct *mm, int code, unsigned long addr)
+ {
+ /*
+ * Something tried to access memory that isn't in our memory map.
+ * Fix it, but check if it's kernel or user first.
+ */
+- mmap_read_unlock(mm);
+ /* User mode accesses just cause a SIGSEGV */
+ if (user_mode(regs)) {
+ do_trap(regs, SIGSEGV, code, addr);
+@@ -238,20 +237,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
+ if (is_write(regs))
+ flags |= FAULT_FLAG_WRITE;
+ retry:
+- mmap_read_lock(mm);
+- vma = find_vma(mm, addr);
++ vma = lock_mm_and_find_vma(mm, addr, regs);
+ if (unlikely(!vma)) {
+- bad_area(regs, mm, code, addr);
+- return;
+- }
+- if (likely(vma->vm_start <= addr))
+- goto good_area;
+- if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) {
+- bad_area(regs, mm, code, addr);
+- return;
+- }
+- if (unlikely(expand_stack(vma, addr))) {
+- bad_area(regs, mm, code, addr);
++ bad_area_nosemaphore(regs, mm, code, addr);
+ return;
+ }
+
+@@ -259,11 +247,11 @@ retry:
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it.
+ */
+-good_area:
+ code = SEGV_ACCERR;
+
+ if (unlikely(access_error(regs, vma))) {
+- bad_area(regs, mm, code, addr);
++ mmap_read_unlock(mm);
++ bad_area_nosemaphore(regs, mm, code, addr);
+ return;
+ }
+
+diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
+index 54eadf2651786..6726f4941015f 100644
+--- a/arch/hexagon/Kconfig
++++ b/arch/hexagon/Kconfig
+@@ -28,6 +28,7 @@ config HEXAGON
+ select GENERIC_SMP_IDLE_THREAD
+ select STACKTRACE_SUPPORT
+ select GENERIC_CLOCKEVENTS_BROADCAST
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_RELA
+ select GENERIC_CPU_DEVICES
+ select ARCH_WANT_LD_ORPHAN_WARN
+diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c
+index 4b578d02fd01a..7295ea3f8cc8d 100644
+--- a/arch/hexagon/mm/vm_fault.c
++++ b/arch/hexagon/mm/vm_fault.c
+@@ -57,21 +57,10 @@ void do_page_fault(unsigned long address, long cause, struct pt_regs *regs)
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+ retry:
+- mmap_read_lock(mm);
+- vma = find_vma(mm, address);
+- if (!vma)
+- goto bad_area;
++ vma = lock_mm_and_find_vma(mm, address, regs);
++ if (unlikely(!vma))
++ goto bad_area_nosemaphore;
+
+- if (vma->vm_start <= address)
+- goto good_area;
+-
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+-
+- if (expand_stack(vma, address))
+- goto bad_area;
+-
+-good_area:
+ /* Address space is OK. Now check access rights. */
+ si_code = SEGV_ACCERR;
+
+@@ -143,6 +132,7 @@ good_area:
+ bad_area:
+ mmap_read_unlock(mm);
+
++bad_area_nosemaphore:
+ if (user_mode(regs)) {
+ force_sig_fault(SIGSEGV, si_code, (void __user *)address);
+ return;
+diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
+index 85c4d9ac8686d..5458b52b40099 100644
+--- a/arch/ia64/mm/fault.c
++++ b/arch/ia64/mm/fault.c
+@@ -110,10 +110,12 @@ retry:
+ * register backing store that needs to expand upwards, in
+ * this case vma will be null, but prev_vma will ne non-null
+ */
+- if (( !vma && prev_vma ) || (address < vma->vm_start) )
+- goto check_expansion;
++ if (( !vma && prev_vma ) || (address < vma->vm_start) ) {
++ vma = expand_stack(mm, address);
++ if (!vma)
++ goto bad_area_nosemaphore;
++ }
+
+- good_area:
+ code = SEGV_ACCERR;
+
+ /* OK, we've got a good vm_area for this memory area. Check the access permissions: */
+@@ -177,35 +179,9 @@ retry:
+ mmap_read_unlock(mm);
+ return;
+
+- check_expansion:
+- if (!(prev_vma && (prev_vma->vm_flags & VM_GROWSUP) && (address == prev_vma->vm_end))) {
+- if (!vma)
+- goto bad_area;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+- if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
+- || REGION_OFFSET(address) >= RGN_MAP_LIMIT)
+- goto bad_area;
+- if (expand_stack(vma, address))
+- goto bad_area;
+- } else {
+- vma = prev_vma;
+- if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
+- || REGION_OFFSET(address) >= RGN_MAP_LIMIT)
+- goto bad_area;
+- /*
+- * Since the register backing store is accessed sequentially,
+- * we disallow growing it by more than a page at a time.
+- */
+- if (address > vma->vm_end + PAGE_SIZE - sizeof(long))
+- goto bad_area;
+- if (expand_upwards(vma, address))
+- goto bad_area;
+- }
+- goto good_area;
+-
+ bad_area:
+ mmap_read_unlock(mm);
++ bad_area_nosemaphore:
+ if ((isr & IA64_ISR_SP)
+ || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
+ {
+diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
+index 3e5d6acbf2409..085d87d7e91d9 100644
+--- a/arch/loongarch/Kconfig
++++ b/arch/loongarch/Kconfig
+@@ -125,6 +125,7 @@ config LOONGARCH
+ select HAVE_VIRT_CPU_ACCOUNTING_GEN if !SMP
+ select IRQ_FORCED_THREADING
+ select IRQ_LOONGARCH_CPU
++ select LOCK_MM_AND_FIND_VMA
+ select MMU_GATHER_MERGE_VMAS if MMU
+ select MODULES_USE_ELF_RELA if MODULES
+ select NEED_PER_CPU_EMBED_FIRST_CHUNK
+diff --git a/arch/loongarch/mm/fault.c b/arch/loongarch/mm/fault.c
+index 449087bd589d3..da5b6d518cdb1 100644
+--- a/arch/loongarch/mm/fault.c
++++ b/arch/loongarch/mm/fault.c
+@@ -169,22 +169,18 @@ static void __kprobes __do_page_fault(struct pt_regs *regs,
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+ retry:
+- mmap_read_lock(mm);
+- vma = find_vma(mm, address);
+- if (!vma)
+- goto bad_area;
+- if (vma->vm_start <= address)
+- goto good_area;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+- if (!expand_stack(vma, address))
+- goto good_area;
++ vma = lock_mm_and_find_vma(mm, address, regs);
++ if (unlikely(!vma))
++ goto bad_area_nosemaphore;
++ goto good_area;
++
+ /*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+ bad_area:
+ mmap_read_unlock(mm);
++bad_area_nosemaphore:
+ do_sigsegv(regs, write, address, si_code);
+ return;
+
+diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
+index 228128e45c673..c290c5c0cfb93 100644
+--- a/arch/m68k/mm/fault.c
++++ b/arch/m68k/mm/fault.c
+@@ -105,8 +105,9 @@ retry:
+ if (address + 256 < rdusp())
+ goto map_err;
+ }
+- if (expand_stack(vma, address))
+- goto map_err;
++ vma = expand_stack(mm, address);
++ if (!vma)
++ goto map_err_nosemaphore;
+
+ /*
+ * Ok, we have a good vm_area for this memory access, so
+@@ -196,10 +197,12 @@ bus_err:
+ goto send_sig;
+
+ map_err:
++ mmap_read_unlock(mm);
++map_err_nosemaphore:
+ current->thread.signo = SIGSEGV;
+ current->thread.code = SEGV_MAPERR;
+ current->thread.faddr = address;
+- goto send_sig;
++ return send_fault_sig(regs);
+
+ acc_err:
+ current->thread.signo = SIGSEGV;
+diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
+index 687714db6f4d0..d3c3c33b73a6e 100644
+--- a/arch/microblaze/mm/fault.c
++++ b/arch/microblaze/mm/fault.c
+@@ -192,8 +192,9 @@ retry:
+ && (kernel_mode(regs) || !store_updates_sp(regs)))
+ goto bad_area;
+ }
+- if (expand_stack(vma, address))
+- goto bad_area;
++ vma = expand_stack(mm, address);
++ if (!vma)
++ goto bad_area_nosemaphore;
+
+ good_area:
+ code = SEGV_ACCERR;
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index 5b3f1f1dfd164..2cc139f10c1d8 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -94,6 +94,7 @@ config MIPS
+ select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP
+ select IRQ_FORCED_THREADING
+ select ISA if EISA
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_REL if MODULES
+ select MODULES_USE_ELF_RELA if MODULES && 64BIT
+ select PERF_USE_VMALLOC
+diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
+index a27045f5a556d..d7878208bd3fa 100644
+--- a/arch/mips/mm/fault.c
++++ b/arch/mips/mm/fault.c
+@@ -99,21 +99,13 @@ static void __do_page_fault(struct pt_regs *regs, unsigned long write,
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+ retry:
+- mmap_read_lock(mm);
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (!vma)
+- goto bad_area;
+- if (vma->vm_start <= address)
+- goto good_area;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+- if (expand_stack(vma, address))
+- goto bad_area;
++ goto bad_area_nosemaphore;
+ /*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+-good_area:
+ si_code = SEGV_ACCERR;
+
+ if (write) {
+diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
+index a582f72104f39..1fb78865a4593 100644
+--- a/arch/nios2/Kconfig
++++ b/arch/nios2/Kconfig
+@@ -16,6 +16,7 @@ config NIOS2
+ select HAVE_ARCH_TRACEHOOK
+ select HAVE_ARCH_KGDB
+ select IRQ_DOMAIN
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_RELA
+ select OF
+ select OF_EARLY_FLATTREE
+diff --git a/arch/nios2/mm/fault.c b/arch/nios2/mm/fault.c
+index ca64eccea5511..e3fa9c15181df 100644
+--- a/arch/nios2/mm/fault.c
++++ b/arch/nios2/mm/fault.c
+@@ -86,27 +86,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+
+- if (!mmap_read_trylock(mm)) {
+- if (!user_mode(regs) && !search_exception_tables(regs->ea))
+- goto bad_area_nosemaphore;
+ retry:
+- mmap_read_lock(mm);
+- }
+-
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (!vma)
+- goto bad_area;
+- if (vma->vm_start <= address)
+- goto good_area;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+- if (expand_stack(vma, address))
+- goto bad_area;
++ goto bad_area_nosemaphore;
+ /*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+-good_area:
+ code = SEGV_ACCERR;
+
+ switch (cause) {
+diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c
+index 6734fee3134f4..a9dcd4381d1a1 100644
+--- a/arch/openrisc/mm/fault.c
++++ b/arch/openrisc/mm/fault.c
+@@ -127,8 +127,9 @@ retry:
+ if (address + PAGE_SIZE < regs->sp)
+ goto bad_area;
+ }
+- if (expand_stack(vma, address))
+- goto bad_area;
++ vma = expand_stack(mm, address);
++ if (!vma)
++ goto bad_area_nosemaphore;
+
+ /*
+ * Ok, we have a good vm_area for this memory access, so
+diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
+index 6941fdbf25173..a4c7c7630f48b 100644
+--- a/arch/parisc/mm/fault.c
++++ b/arch/parisc/mm/fault.c
+@@ -288,15 +288,19 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
+ retry:
+ mmap_read_lock(mm);
+ vma = find_vma_prev(mm, address, &prev_vma);
+- if (!vma || address < vma->vm_start)
+- goto check_expansion;
++ if (!vma || address < vma->vm_start) {
++ if (!prev_vma || !(prev_vma->vm_flags & VM_GROWSUP))
++ goto bad_area;
++ vma = expand_stack(mm, address);
++ if (!vma)
++ goto bad_area_nosemaphore;
++ }
++
+ /*
+ * Ok, we have a good vm_area for this memory access. We still need to
+ * check the access permissions.
+ */
+
+-good_area:
+-
+ if ((vma->vm_flags & acc_type) != acc_type)
+ goto bad_area;
+
+@@ -347,17 +351,13 @@ good_area:
+ mmap_read_unlock(mm);
+ return;
+
+-check_expansion:
+- vma = prev_vma;
+- if (vma && (expand_stack(vma, address) == 0))
+- goto good_area;
+-
+ /*
+ * Something tried to access memory that isn't in our memory map..
+ */
+ bad_area:
+ mmap_read_unlock(mm);
+
++bad_area_nosemaphore:
+ if (user_mode(regs)) {
+ int signo, si_code;
+
+@@ -449,7 +449,7 @@ handle_nadtlb_fault(struct pt_regs *regs)
+ {
+ unsigned long insn = regs->iir;
+ int breg, treg, xreg, val = 0;
+- struct vm_area_struct *vma, *prev_vma;
++ struct vm_area_struct *vma;
+ struct task_struct *tsk;
+ struct mm_struct *mm;
+ unsigned long address;
+@@ -485,7 +485,7 @@ handle_nadtlb_fault(struct pt_regs *regs)
+ /* Search for VMA */
+ address = regs->ior;
+ mmap_read_lock(mm);
+- vma = find_vma_prev(mm, address, &prev_vma);
++ vma = vma_lookup(mm, address);
+ mmap_read_unlock(mm);
+
+ /*
+@@ -494,7 +494,6 @@ handle_nadtlb_fault(struct pt_regs *regs)
+ */
+ acc_type = (insn & 0x40) ? VM_WRITE : VM_READ;
+ if (vma
+- && address >= vma->vm_start
+ && (vma->vm_flags & acc_type) == acc_type)
+ val = 1;
+ }
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index a6c4407d3ec83..4ab9b44e6c1c6 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -263,6 +263,7 @@ config PPC
+ select IRQ_DOMAIN
+ select IRQ_FORCED_THREADING
+ select KASAN_VMALLOC if KASAN && MODULES
++ select LOCK_MM_AND_FIND_VMA
+ select MMU_GATHER_PAGE_SIZE
+ select MMU_GATHER_RCU_TABLE_FREE
+ select MMU_GATHER_MERGE_VMAS
+diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c
+index 7c507fb48182b..f49fd873df8da 100644
+--- a/arch/powerpc/mm/copro_fault.c
++++ b/arch/powerpc/mm/copro_fault.c
+@@ -33,19 +33,11 @@ int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
+ if (mm->pgd == NULL)
+ return -EFAULT;
+
+- mmap_read_lock(mm);
+- ret = -EFAULT;
+- vma = find_vma(mm, ea);
++ vma = lock_mm_and_find_vma(mm, ea, NULL);
+ if (!vma)
+- goto out_unlock;
+-
+- if (ea < vma->vm_start) {
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto out_unlock;
+- if (expand_stack(vma, ea))
+- goto out_unlock;
+- }
++ return -EFAULT;
+
++ ret = -EFAULT;
+ is_write = dsisr & DSISR_ISSTORE;
+ if (is_write) {
+ if (!(vma->vm_flags & VM_WRITE))
+diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
+index af46aa88422bf..644e4ec6ce99d 100644
+--- a/arch/powerpc/mm/fault.c
++++ b/arch/powerpc/mm/fault.c
+@@ -84,11 +84,6 @@ static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code)
+ return __bad_area_nosemaphore(regs, address, si_code);
+ }
+
+-static noinline int bad_area(struct pt_regs *regs, unsigned long address)
+-{
+- return __bad_area(regs, address, SEGV_MAPERR);
+-}
+-
+ static noinline int bad_access_pkey(struct pt_regs *regs, unsigned long address,
+ struct vm_area_struct *vma)
+ {
+@@ -481,40 +476,12 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
+ * we will deadlock attempting to validate the fault against the
+ * address space. Luckily the kernel only validly references user
+ * space from well defined areas of code, which are listed in the
+- * exceptions table.
+- *
+- * As the vast majority of faults will be valid we will only perform
+- * the source reference check when there is a possibility of a deadlock.
+- * Attempt to lock the address space, if we cannot we then validate the
+- * source. If this is invalid we can skip the address space check,
+- * thus avoiding the deadlock.
++ * exceptions table. lock_mm_and_find_vma() handles that logic.
+ */
+- if (unlikely(!mmap_read_trylock(mm))) {
+- if (!is_user && !search_exception_tables(regs->nip))
+- return bad_area_nosemaphore(regs, address);
+-
+ retry:
+- mmap_read_lock(mm);
+- } else {
+- /*
+- * The above down_read_trylock() might have succeeded in
+- * which case we'll have missed the might_sleep() from
+- * down_read():
+- */
+- might_sleep();
+- }
+-
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (unlikely(!vma))
+- return bad_area(regs, address);
+-
+- if (unlikely(vma->vm_start > address)) {
+- if (unlikely(!(vma->vm_flags & VM_GROWSDOWN)))
+- return bad_area(regs, address);
+-
+- if (unlikely(expand_stack(vma, address)))
+- return bad_area(regs, address);
+- }
++ return bad_area_nosemaphore(regs, address);
+
+ if (unlikely(access_pkey_error(is_write, is_exec,
+ (error_code & DSISR_KEYFAULT), vma)))
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index b462ed7d41fe1..73671af406dca 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -119,6 +119,7 @@ config RISCV
+ select HAVE_SYSCALL_TRACEPOINTS
+ select IRQ_DOMAIN
+ select IRQ_FORCED_THREADING
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_RELA if MODULES
+ select MODULE_SECTIONS if MODULES
+ select OF
+diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
+index d5f3e501dffb3..89226458eab89 100644
+--- a/arch/riscv/mm/fault.c
++++ b/arch/riscv/mm/fault.c
+@@ -83,13 +83,13 @@ static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_f
+ BUG();
+ }
+
+-static inline void bad_area(struct pt_regs *regs, struct mm_struct *mm, int code, unsigned long addr)
++static inline void
++bad_area_nosemaphore(struct pt_regs *regs, int code, unsigned long addr)
+ {
+ /*
+ * Something tried to access memory that isn't in our memory map.
+ * Fix it, but check if it's kernel or user first.
+ */
+- mmap_read_unlock(mm);
+ /* User mode accesses just cause a SIGSEGV */
+ if (user_mode(regs)) {
+ do_trap(regs, SIGSEGV, code, addr);
+@@ -99,6 +99,15 @@ static inline void bad_area(struct pt_regs *regs, struct mm_struct *mm, int code
+ no_context(regs, addr);
+ }
+
++static inline void
++bad_area(struct pt_regs *regs, struct mm_struct *mm, int code,
++ unsigned long addr)
++{
++ mmap_read_unlock(mm);
++
++ bad_area_nosemaphore(regs, code, addr);
++}
++
+ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long addr)
+ {
+ pgd_t *pgd, *pgd_k;
+@@ -286,23 +295,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
+ else if (cause == EXC_INST_PAGE_FAULT)
+ flags |= FAULT_FLAG_INSTRUCTION;
+ retry:
+- mmap_read_lock(mm);
+- vma = find_vma(mm, addr);
++ vma = lock_mm_and_find_vma(mm, addr, regs);
+ if (unlikely(!vma)) {
+ tsk->thread.bad_cause = cause;
+- bad_area(regs, mm, code, addr);
+- return;
+- }
+- if (likely(vma->vm_start <= addr))
+- goto good_area;
+- if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) {
+- tsk->thread.bad_cause = cause;
+- bad_area(regs, mm, code, addr);
+- return;
+- }
+- if (unlikely(expand_stack(vma, addr))) {
+- tsk->thread.bad_cause = cause;
+- bad_area(regs, mm, code, addr);
++ bad_area_nosemaphore(regs, code, addr);
+ return;
+ }
+
+@@ -310,7 +306,6 @@ retry:
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it.
+ */
+-good_area:
+ code = SEGV_ACCERR;
+
+ if (unlikely(access_error(cause, vma))) {
+diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
+index a2632fd97d007..94e3970c48393 100644
+--- a/arch/s390/mm/fault.c
++++ b/arch/s390/mm/fault.c
+@@ -433,8 +433,9 @@ retry:
+ if (unlikely(vma->vm_start > address)) {
+ if (!(vma->vm_flags & VM_GROWSDOWN))
+ goto out_up;
+- if (expand_stack(vma, address))
+- goto out_up;
++ vma = expand_stack(mm, address);
++ if (!vma)
++ goto out;
+ }
+
+ /*
+diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
+index 0665ac0add0b4..101a0d094a667 100644
+--- a/arch/sh/Kconfig
++++ b/arch/sh/Kconfig
+@@ -56,6 +56,7 @@ config SUPERH
+ select HAVE_STACKPROTECTOR
+ select HAVE_SYSCALL_TRACEPOINTS
+ select IRQ_FORCED_THREADING
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_RELA
+ select NEED_SG_DMA_LENGTH
+ select NO_DMA if !MMU && !DMA_COHERENT
+diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
+index acd2f5e50bfcd..06e6b49529245 100644
+--- a/arch/sh/mm/fault.c
++++ b/arch/sh/mm/fault.c
+@@ -439,21 +439,9 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
+ }
+
+ retry:
+- mmap_read_lock(mm);
+-
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (unlikely(!vma)) {
+- bad_area(regs, error_code, address);
+- return;
+- }
+- if (likely(vma->vm_start <= address))
+- goto good_area;
+- if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) {
+- bad_area(regs, error_code, address);
+- return;
+- }
+- if (unlikely(expand_stack(vma, address))) {
+- bad_area(regs, error_code, address);
++ bad_area_nosemaphore(regs, error_code, address);
+ return;
+ }
+
+@@ -461,7 +449,6 @@ retry:
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+-good_area:
+ if (unlikely(access_error(error_code, vma))) {
+ bad_area_access_error(regs, error_code, address);
+ return;
+diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
+index 84437a4c65454..dbb1760cbe8c9 100644
+--- a/arch/sparc/Kconfig
++++ b/arch/sparc/Kconfig
+@@ -56,6 +56,7 @@ config SPARC32
+ select DMA_DIRECT_REMAP
+ select GENERIC_ATOMIC64
+ select HAVE_UID16
++ select LOCK_MM_AND_FIND_VMA
+ select OLD_SIGACTION
+ select ZONE_DMA
+
+diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
+index 179295b14664a..86a831ebd8c8e 100644
+--- a/arch/sparc/mm/fault_32.c
++++ b/arch/sparc/mm/fault_32.c
+@@ -143,28 +143,19 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
+ if (pagefault_disabled() || !mm)
+ goto no_context;
+
++ if (!from_user && address >= PAGE_OFFSET)
++ goto no_context;
++
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+
+ retry:
+- mmap_read_lock(mm);
+-
+- if (!from_user && address >= PAGE_OFFSET)
+- goto bad_area;
+-
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (!vma)
+- goto bad_area;
+- if (vma->vm_start <= address)
+- goto good_area;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+- if (expand_stack(vma, address))
+- goto bad_area;
++ goto bad_area_nosemaphore;
+ /*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+-good_area:
+ code = SEGV_ACCERR;
+ if (write) {
+ if (!(vma->vm_flags & VM_WRITE))
+@@ -321,17 +312,9 @@ static void force_user_fault(unsigned long address, int write)
+
+ code = SEGV_MAPERR;
+
+- mmap_read_lock(mm);
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, NULL);
+ if (!vma)
+- goto bad_area;
+- if (vma->vm_start <= address)
+- goto good_area;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+- if (expand_stack(vma, address))
+- goto bad_area;
+-good_area:
++ goto bad_area_nosemaphore;
+ code = SEGV_ACCERR;
+ if (write) {
+ if (!(vma->vm_flags & VM_WRITE))
+@@ -350,6 +333,7 @@ good_area:
+ return;
+ bad_area:
+ mmap_read_unlock(mm);
++bad_area_nosemaphore:
+ __do_fault_siginfo(code, SIGSEGV, tsk->thread.kregs, address);
+ return;
+
+diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
+index d91305de694c5..69ff07bc6c07d 100644
+--- a/arch/sparc/mm/fault_64.c
++++ b/arch/sparc/mm/fault_64.c
+@@ -383,8 +383,9 @@ continue_fault:
+ goto bad_area;
+ }
+ }
+- if (expand_stack(vma, address))
+- goto bad_area;
++ vma = expand_stack(mm, address);
++ if (!vma)
++ goto bad_area_nosemaphore;
+ /*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+@@ -487,8 +488,9 @@ exit_exception:
+ * Fix it, but check if it's kernel or user first..
+ */
+ bad_area:
+- insn = get_fault_insn(regs, insn);
+ mmap_read_unlock(mm);
++bad_area_nosemaphore:
++ insn = get_fault_insn(regs, insn);
+
+ handle_kernel_fault:
+ do_kernel_fault(regs, si_code, fault_code, insn, address);
+diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
+index d3ce21c4ca32a..6d8ae86ae978f 100644
+--- a/arch/um/kernel/trap.c
++++ b/arch/um/kernel/trap.c
+@@ -47,14 +47,15 @@ retry:
+ vma = find_vma(mm, address);
+ if (!vma)
+ goto out;
+- else if (vma->vm_start <= address)
++ if (vma->vm_start <= address)
+ goto good_area;
+- else if (!(vma->vm_flags & VM_GROWSDOWN))
++ if (!(vma->vm_flags & VM_GROWSDOWN))
+ goto out;
+- else if (is_user && !ARCH_IS_STACKGROW(address))
+- goto out;
+- else if (expand_stack(vma, address))
++ if (is_user && !ARCH_IS_STACKGROW(address))
+ goto out;
++ vma = expand_stack(mm, address);
++ if (!vma)
++ goto out_nosemaphore;
+
+ good_area:
+ *code_out = SEGV_ACCERR;
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index a825bf031f495..8e6db5262614e 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -274,6 +274,7 @@ config X86
+ select HAVE_GENERIC_VDSO
+ select HOTPLUG_SMT if SMP
+ 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
+diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
+index 78796b98a5449..9ba3c3dec6f30 100644
+--- a/arch/x86/include/asm/cpu.h
++++ b/arch/x86/include/asm/cpu.h
+@@ -98,4 +98,6 @@ extern u64 x86_read_arch_cap_msr(void);
+ int intel_find_matching_signature(void *mc, unsigned int csig, int cpf);
+ int intel_microcode_sanity_check(void *mc, bool print_err, int hdr_type);
+
++extern struct cpumask cpus_stop_mask;
++
+ #endif /* _ASM_X86_CPU_H */
+diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
+index b4dbb20dab1a1..4e8e64541395e 100644
+--- a/arch/x86/include/asm/smp.h
++++ b/arch/x86/include/asm/smp.h
+@@ -131,6 +131,8 @@ void wbinvd_on_cpu(int cpu);
+ int wbinvd_on_all_cpus(void);
+ void cond_wakeup_cpu0(void);
+
++void smp_kick_mwait_play_dead(void);
++
+ void native_smp_send_reschedule(int cpu);
+ void native_send_call_func_ipi(const struct cpumask *mask);
+ void native_send_call_func_single_ipi(int cpu);
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
+index 9eb457b103413..cedecba551630 100644
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -705,7 +705,7 @@ static enum ucode_state apply_microcode_amd(int cpu)
+ rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+
+ /* need to apply patch? */
+- if (rev >= mc_amd->hdr.patch_id) {
++ if (rev > mc_amd->hdr.patch_id) {
+ ret = UCODE_OK;
+ goto out;
+ }
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index b650cde3f64db..2fed8aafb5214 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -752,15 +752,26 @@ bool xen_set_default_idle(void)
+ }
+ #endif
+
++struct cpumask cpus_stop_mask;
++
+ void __noreturn stop_this_cpu(void *dummy)
+ {
++ struct cpuinfo_x86 *c = this_cpu_ptr(&cpu_info);
++ unsigned int cpu = smp_processor_id();
++
+ local_irq_disable();
++
+ /*
+- * Remove this CPU:
++ * Remove this CPU from the online mask and disable it
++ * unconditionally. This might be redundant in case that the reboot
++ * vector was handled late and stop_other_cpus() sent an NMI.
++ *
++ * According to SDM and APM NMIs can be accepted even after soft
++ * disabling the local APIC.
+ */
+- set_cpu_online(smp_processor_id(), false);
++ set_cpu_online(cpu, false);
+ disable_local_APIC();
+- mcheck_cpu_clear(this_cpu_ptr(&cpu_info));
++ mcheck_cpu_clear(c);
+
+ /*
+ * Use wbinvd on processors that support SME. This provides support
+@@ -774,8 +785,17 @@ void __noreturn stop_this_cpu(void *dummy)
+ * Test the CPUID bit directly because the machine might've cleared
+ * X86_FEATURE_SME due to cmdline options.
+ */
+- if (cpuid_eax(0x8000001f) & BIT(0))
++ if (c->extended_cpuid_level >= 0x8000001f && (cpuid_eax(0x8000001f) & BIT(0)))
+ native_wbinvd();
++
++ /*
++ * This brings a cache line back and dirties it, but
++ * native_stop_other_cpus() will overwrite cpus_stop_mask after it
++ * observed that all CPUs reported stop. This write will invalidate
++ * the related cache line on this CPU.
++ */
++ cpumask_clear_cpu(cpu, &cpus_stop_mask);
++
+ for (;;) {
+ /*
+ * Use native_halt() so that memory contents don't change
+diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
+index 375b33ecafa27..174d6232b87fd 100644
+--- a/arch/x86/kernel/smp.c
++++ b/arch/x86/kernel/smp.c
+@@ -21,12 +21,14 @@
+ #include <linux/interrupt.h>
+ #include <linux/cpu.h>
+ #include <linux/gfp.h>
++#include <linux/kexec.h>
+
+ #include <asm/mtrr.h>
+ #include <asm/tlbflush.h>
+ #include <asm/mmu_context.h>
+ #include <asm/proto.h>
+ #include <asm/apic.h>
++#include <asm/cpu.h>
+ #include <asm/idtentry.h>
+ #include <asm/nmi.h>
+ #include <asm/mce.h>
+@@ -146,34 +148,47 @@ static int register_stop_handler(void)
+
+ static void native_stop_other_cpus(int wait)
+ {
+- unsigned long flags;
+- unsigned long timeout;
++ unsigned int cpu = smp_processor_id();
++ unsigned long flags, timeout;
+
+ if (reboot_force)
+ return;
+
+- /*
+- * Use an own vector here because smp_call_function
+- * does lots of things not suitable in a panic situation.
+- */
++ /* Only proceed if this is the first CPU to reach this code */
++ if (atomic_cmpxchg(&stopping_cpu, -1, cpu) != -1)
++ return;
++
++ /* For kexec, ensure that offline CPUs are out of MWAIT and in HLT */
++ if (kexec_in_progress)
++ smp_kick_mwait_play_dead();
+
+ /*
+- * We start by using the REBOOT_VECTOR irq.
+- * The irq is treated as a sync point to allow critical
+- * regions of code on other cpus to release their spin locks
+- * and re-enable irqs. Jumping straight to an NMI might
+- * accidentally cause deadlocks with further shutdown/panic
+- * code. By syncing, we give the cpus up to one second to
+- * finish their work before we force them off with the NMI.
++ * 1) Send an IPI on the reboot vector to all other CPUs.
++ *
++ * The other CPUs should react on it after leaving critical
++ * sections and re-enabling interrupts. They might still hold
++ * locks, but there is nothing which can be done about that.
++ *
++ * 2) Wait for all other CPUs to report that they reached the
++ * HLT loop in stop_this_cpu()
++ *
++ * 3) If #2 timed out send an NMI to the CPUs which did not
++ * yet report
++ *
++ * 4) Wait for all other CPUs to report that they reached the
++ * HLT loop in stop_this_cpu()
++ *
++ * #3 can obviously race against a CPU reaching the HLT loop late.
++ * That CPU will have reported already and the "have all CPUs
++ * reached HLT" condition will be true despite the fact that the
++ * other CPU is still handling the NMI. Again, there is no
++ * protection against that as "disabled" APICs still respond to
++ * NMIs.
+ */
+- if (num_online_cpus() > 1) {
+- /* did someone beat us here? */
+- if (atomic_cmpxchg(&stopping_cpu, -1, safe_smp_processor_id()) != -1)
+- return;
+-
+- /* sync above data before sending IRQ */
+- wmb();
++ cpumask_copy(&cpus_stop_mask, cpu_online_mask);
++ cpumask_clear_cpu(cpu, &cpus_stop_mask);
+
++ if (!cpumask_empty(&cpus_stop_mask)) {
+ apic_send_IPI_allbutself(REBOOT_VECTOR);
+
+ /*
+@@ -183,24 +198,22 @@ static void native_stop_other_cpus(int wait)
+ * CPUs reach shutdown state.
+ */
+ timeout = USEC_PER_SEC;
+- while (num_online_cpus() > 1 && timeout--)
++ while (!cpumask_empty(&cpus_stop_mask) && timeout--)
+ udelay(1);
+ }
+
+ /* if the REBOOT_VECTOR didn't work, try with the NMI */
+- if (num_online_cpus() > 1) {
++ if (!cpumask_empty(&cpus_stop_mask)) {
+ /*
+ * If NMI IPI is enabled, try to register the stop handler
+ * and send the IPI. In any case try to wait for the other
+ * CPUs to stop.
+ */
+ if (!smp_no_nmi_ipi && !register_stop_handler()) {
+- /* Sync above data before sending IRQ */
+- wmb();
+-
+ pr_emerg("Shutting down cpus with NMI\n");
+
+- apic_send_IPI_allbutself(NMI_VECTOR);
++ for_each_cpu(cpu, &cpus_stop_mask)
++ apic->send_IPI(cpu, NMI_VECTOR);
+ }
+ /*
+ * Don't wait longer than 10 ms if the caller didn't
+@@ -208,7 +221,7 @@ static void native_stop_other_cpus(int wait)
+ * one or more CPUs do not reach shutdown state.
+ */
+ timeout = USEC_PER_MSEC * 10;
+- while (num_online_cpus() > 1 && (wait || timeout--))
++ while (!cpumask_empty(&cpus_stop_mask) && (wait || timeout--))
+ udelay(1);
+ }
+
+@@ -216,6 +229,12 @@ static void native_stop_other_cpus(int wait)
+ disable_local_APIC();
+ mcheck_cpu_clear(this_cpu_ptr(&cpu_info));
+ local_irq_restore(flags);
++
++ /*
++ * Ensure that the cpus_stop_mask cache lines are invalidated on
++ * the other CPUs. See comment vs. SME in stop_this_cpu().
++ */
++ cpumask_clear(&cpus_stop_mask);
+ }
+
+ /*
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
+index 9013bb28255a1..144c6f2c42306 100644
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -53,6 +53,7 @@
+ #include <linux/tboot.h>
+ #include <linux/gfp.h>
+ #include <linux/cpuidle.h>
++#include <linux/kexec.h>
+ #include <linux/numa.h>
+ #include <linux/pgtable.h>
+ #include <linux/overflow.h>
+@@ -101,6 +102,20 @@ EXPORT_PER_CPU_SYMBOL(cpu_die_map);
+ DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
+ EXPORT_PER_CPU_SYMBOL(cpu_info);
+
++struct mwait_cpu_dead {
++ unsigned int control;
++ unsigned int status;
++};
++
++#define CPUDEAD_MWAIT_WAIT 0xDEADBEEF
++#define CPUDEAD_MWAIT_KEXEC_HLT 0x4A17DEAD
++
++/*
++ * Cache line aligned data for mwait_play_dead(). Separate on purpose so
++ * that it's unlikely to be touched by other CPUs.
++ */
++static DEFINE_PER_CPU_ALIGNED(struct mwait_cpu_dead, mwait_cpu_dead);
++
+ /* Logical package management. We might want to allocate that dynamically */
+ unsigned int __max_logical_packages __read_mostly;
+ EXPORT_SYMBOL(__max_logical_packages);
+@@ -157,6 +172,10 @@ static void smp_callin(void)
+ {
+ int cpuid;
+
++ /* Mop up eventual mwait_play_dead() wreckage */
++ this_cpu_write(mwait_cpu_dead.status, 0);
++ this_cpu_write(mwait_cpu_dead.control, 0);
++
+ /*
+ * If waken up by an INIT in an 82489DX configuration
+ * cpu_callout_mask guarantees we don't get here before
+@@ -1750,10 +1769,10 @@ EXPORT_SYMBOL_GPL(cond_wakeup_cpu0);
+ */
+ static inline void mwait_play_dead(void)
+ {
++ struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead);
+ unsigned int eax, ebx, ecx, edx;
+ unsigned int highest_cstate = 0;
+ unsigned int highest_subcstate = 0;
+- void *mwait_ptr;
+ int i;
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
+@@ -1788,12 +1807,9 @@ static inline void mwait_play_dead(void)
+ (highest_subcstate - 1);
+ }
+
+- /*
+- * This should be a memory location in a cache line which is
+- * unlikely to be touched by other processors. The actual
+- * content is immaterial as it is not actually modified in any way.
+- */
+- mwait_ptr = &current_thread_info()->flags;
++ /* Set up state for the kexec() hack below */
++ md->status = CPUDEAD_MWAIT_WAIT;
++ md->control = CPUDEAD_MWAIT_WAIT;
+
+ wbinvd();
+
+@@ -1806,16 +1822,63 @@ static inline void mwait_play_dead(void)
+ * case where we return around the loop.
+ */
+ mb();
+- clflush(mwait_ptr);
++ clflush(md);
+ mb();
+- __monitor(mwait_ptr, 0, 0);
++ __monitor(md, 0, 0);
+ mb();
+ __mwait(eax, 0);
+
++ if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) {
++ /*
++ * Kexec is about to happen. Don't go back into mwait() as
++ * the kexec kernel might overwrite text and data including
++ * page tables and stack. So mwait() would resume when the
++ * monitor cache line is written to and then the CPU goes
++ * south due to overwritten text, page tables and stack.
++ *
++ * Note: This does _NOT_ protect against a stray MCE, NMI,
++ * SMI. They will resume execution at the instruction
++ * following the HLT instruction and run into the problem
++ * which this is trying to prevent.
++ */
++ WRITE_ONCE(md->status, CPUDEAD_MWAIT_KEXEC_HLT);
++ while(1)
++ native_halt();
++ }
++
+ cond_wakeup_cpu0();
+ }
+ }
+
++/*
++ * Kick all "offline" CPUs out of mwait on kexec(). See comment in
++ * mwait_play_dead().
++ */
++void smp_kick_mwait_play_dead(void)
++{
++ u32 newstate = CPUDEAD_MWAIT_KEXEC_HLT;
++ struct mwait_cpu_dead *md;
++ unsigned int cpu, i;
++
++ for_each_cpu_andnot(cpu, cpu_present_mask, cpu_online_mask) {
++ md = per_cpu_ptr(&mwait_cpu_dead, cpu);
++
++ /* Does it sit in mwait_play_dead() ? */
++ if (READ_ONCE(md->status) != CPUDEAD_MWAIT_WAIT)
++ continue;
++
++ /* Wait up to 5ms */
++ for (i = 0; READ_ONCE(md->status) != newstate && i < 1000; i++) {
++ /* Bring it out of mwait */
++ WRITE_ONCE(md->control, newstate);
++ udelay(5);
++ }
++
++ if (READ_ONCE(md->status) != newstate)
++ pr_err_once("CPU%u is stuck in mwait_play_dead()\n", cpu);
++ }
++}
++
+ void hlt_play_dead(void)
+ {
+ if (__this_cpu_read(cpu_info.x86) >= 4)
+diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
+index a498ae1fbe665..67954abb9fdcb 100644
+--- a/arch/x86/mm/fault.c
++++ b/arch/x86/mm/fault.c
+@@ -879,12 +879,6 @@ __bad_area(struct pt_regs *regs, unsigned long error_code,
+ __bad_area_nosemaphore(regs, error_code, address, pkey, si_code);
+ }
+
+-static noinline void
+-bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address)
+-{
+- __bad_area(regs, error_code, address, 0, SEGV_MAPERR);
+-}
+-
+ static inline bool bad_area_access_from_pkeys(unsigned long error_code,
+ struct vm_area_struct *vma)
+ {
+@@ -1333,51 +1327,10 @@ void do_user_addr_fault(struct pt_regs *regs,
+ }
+ #endif
+
+- /*
+- * Kernel-mode access to the user address space should only occur
+- * on well-defined single instructions listed in the exception
+- * tables. But, an erroneous kernel fault occurring outside one of
+- * those areas which also holds mmap_lock might deadlock attempting
+- * to validate the fault against the address space.
+- *
+- * Only do the expensive exception table search when we might be at
+- * risk of a deadlock. This happens if we
+- * 1. Failed to acquire mmap_lock, and
+- * 2. The access did not originate in userspace.
+- */
+- if (unlikely(!mmap_read_trylock(mm))) {
+- if (!user_mode(regs) && !search_exception_tables(regs->ip)) {
+- /*
+- * Fault from code in kernel from
+- * which we do not expect faults.
+- */
+- bad_area_nosemaphore(regs, error_code, address);
+- return;
+- }
+ retry:
+- mmap_read_lock(mm);
+- } else {
+- /*
+- * The above down_read_trylock() might have succeeded in
+- * which case we'll have missed the might_sleep() from
+- * down_read():
+- */
+- might_sleep();
+- }
+-
+- vma = find_vma(mm, address);
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (unlikely(!vma)) {
+- bad_area(regs, error_code, address);
+- return;
+- }
+- if (likely(vma->vm_start <= address))
+- goto good_area;
+- if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) {
+- bad_area(regs, error_code, address);
+- return;
+- }
+- if (unlikely(expand_stack(vma, address))) {
+- bad_area(regs, error_code, address);
++ bad_area_nosemaphore(regs, error_code, address);
+ return;
+ }
+
+@@ -1385,7 +1338,6 @@ retry:
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+-good_area:
+ if (unlikely(access_error(error_code, vma))) {
+ bad_area_access_error(regs, error_code, address, vma);
+ return;
+diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
+index bcb0c5d2abc2f..6d3c9257aa133 100644
+--- a/arch/xtensa/Kconfig
++++ b/arch/xtensa/Kconfig
+@@ -49,6 +49,7 @@ config XTENSA
+ select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_VIRT_CPU_ACCOUNTING_GEN
+ select IRQ_DOMAIN
++ select LOCK_MM_AND_FIND_VMA
+ select MODULES_USE_ELF_RELA
+ select PERF_USE_VMALLOC
+ select TRACE_IRQFLAGS_SUPPORT
+diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
+index faf7cf35a0ee3..d1eb8d6c5b826 100644
+--- a/arch/xtensa/mm/fault.c
++++ b/arch/xtensa/mm/fault.c
+@@ -130,23 +130,14 @@ void do_page_fault(struct pt_regs *regs)
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
+
+ retry:
+- mmap_read_lock(mm);
+- vma = find_vma(mm, address);
+-
++ vma = lock_mm_and_find_vma(mm, address, regs);
+ if (!vma)
+- goto bad_area;
+- if (vma->vm_start <= address)
+- goto good_area;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- goto bad_area;
+- if (expand_stack(vma, address))
+- goto bad_area;
++ goto bad_area_nosemaphore;
+
+ /* Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+
+-good_area:
+ code = SEGV_ACCERR;
+
+ if (is_write) {
+@@ -205,6 +196,7 @@ good_area:
+ */
+ bad_area:
+ mmap_read_unlock(mm);
++bad_area_nosemaphore:
+ if (user_mode(regs)) {
+ force_sig_fault(SIGSEGV, code, (void *) address);
+ return;
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index a7eb25066c274..48543d29050a2 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -1272,7 +1272,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
+ .online = amd_pstate_epp_cpu_online,
+ .suspend = amd_pstate_epp_suspend,
+ .resume = amd_pstate_epp_resume,
+- .name = "amd_pstate_epp",
++ .name = "amd-pstate-epp",
+ .attr = amd_pstate_epp_attr,
+ };
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index 14bce1fdec9fe..3e1c30c653a50 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -4364,7 +4364,7 @@ static const struct hid_device_id hidpp_devices[] = {
+ { /* wireless touchpad T651 */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
+ USB_DEVICE_ID_LOGITECH_T651),
+- .driver_data = HIDPP_QUIRK_CLASS_WTP },
++ .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
+ { /* Mouse Logitech Anywhere MX */
+ LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
+ { /* Mouse logitech M560 */
+diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
+index 197b1e7bf029e..b617aada50b06 100644
+--- a/drivers/hid/hidraw.c
++++ b/drivers/hid/hidraw.c
+@@ -272,7 +272,12 @@ static int hidraw_open(struct inode *inode, struct file *file)
+ goto out;
+ }
+
+- down_read(&minors_rwsem);
++ /*
++ * Technically not writing to the hidraw_table but a write lock is
++ * required to protect the device refcount. This is symmetrical to
++ * hidraw_release().
++ */
++ down_write(&minors_rwsem);
+ if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+ err = -ENODEV;
+ goto out_unlock;
+@@ -301,7 +306,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
+ spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags);
+ file->private_data = list;
+ out_unlock:
+- up_read(&minors_rwsem);
++ up_write(&minors_rwsem);
+ out:
+ if (err < 0)
+ kfree(list);
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index 9c30dd30537af..15cd0cabee2a9 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -1309,7 +1309,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
+ struct input_dev *pen_input = wacom->pen_input;
+ unsigned char *data = wacom->data;
+ int number_of_valid_frames = 0;
+- int time_interval = 15000000;
++ ktime_t time_interval = 15000000;
+ ktime_t time_packet_received = ktime_get();
+ int i;
+
+@@ -1343,7 +1343,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
+ if (number_of_valid_frames) {
+ if (wacom->hid_data.time_delayed)
+ time_interval = ktime_get() - wacom->hid_data.time_delayed;
+- time_interval /= number_of_valid_frames;
++ time_interval = div_u64(time_interval, number_of_valid_frames);
+ wacom->hid_data.time_delayed = time_packet_received;
+ }
+
+@@ -1354,7 +1354,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
+ bool range = frame[0] & 0x20;
+ bool invert = frame[0] & 0x10;
+ int frames_number_reversed = number_of_valid_frames - i - 1;
+- int event_timestamp = time_packet_received - frames_number_reversed * time_interval;
++ ktime_t event_timestamp = time_packet_received - frames_number_reversed * time_interval;
+
+ if (!valid)
+ continue;
+diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
+index 1a40bb8c5810c..ee21bb260f22f 100644
+--- a/drivers/hid/wacom_wac.h
++++ b/drivers/hid/wacom_wac.h
+@@ -324,7 +324,7 @@ struct hid_data {
+ int ps_connected;
+ bool pad_input_event_flag;
+ unsigned short sequence_number;
+- int time_delayed;
++ ktime_t time_delayed;
+ };
+
+ struct wacom_remote_data {
+diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c
+index 864e4ffb6aa94..261352a232716 100644
+--- a/drivers/iommu/amd/iommu_v2.c
++++ b/drivers/iommu/amd/iommu_v2.c
+@@ -485,8 +485,8 @@ static void do_fault(struct work_struct *work)
+ flags |= FAULT_FLAG_REMOTE;
+
+ mmap_read_lock(mm);
+- vma = find_extend_vma(mm, address);
+- if (!vma || address < vma->vm_start)
++ vma = vma_lookup(mm, address);
++ if (!vma)
+ /* failed to get a vma in the right range */
+ goto out;
+
+diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
+index 24bf9b2b58aa6..ed5f11eb92e56 100644
+--- a/drivers/iommu/iommu-sva.c
++++ b/drivers/iommu/iommu-sva.c
+@@ -203,7 +203,7 @@ iommu_sva_handle_iopf(struct iommu_fault *fault, void *data)
+
+ mmap_read_lock(mm);
+
+- vma = find_extend_vma(mm, prm->addr);
++ vma = vma_lookup(mm, prm->addr);
+ if (!vma)
+ /* Unmapped area */
+ goto out_put_mm;
+diff --git a/drivers/thermal/mediatek/auxadc_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c
+index 3372f7c29626c..ab730f9552d0e 100644
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -1142,12 +1142,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+
+- auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL);
+- if (IS_ERR(auxadc_base)) {
+- of_node_put(auxadc);
+- return PTR_ERR(auxadc_base);
+- }
+-
++ auxadc_base = of_iomap(auxadc, 0);
+ auxadc_phys_base = of_get_phys_base(auxadc);
+
+ of_node_put(auxadc);
+@@ -1163,12 +1158,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+
+- apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL);
+- if (IS_ERR(apmixed_base)) {
+- of_node_put(apmixedsys);
+- return PTR_ERR(apmixed_base);
+- }
+-
++ apmixed_base = of_iomap(apmixedsys, 0);
+ apmixed_phys_base = of_get_phys_base(apmixedsys);
+
+ of_node_put(apmixedsys);
+diff --git a/drivers/video/fbdev/core/sysimgblt.c b/drivers/video/fbdev/core/sysimgblt.c
+index 335e92b813fc4..665ef7a0a2495 100644
+--- a/drivers/video/fbdev/core/sysimgblt.c
++++ b/drivers/video/fbdev/core/sysimgblt.c
+@@ -189,7 +189,7 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p,
+ u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
+ u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
+ u32 bit_mask, eorx, shift;
+- const char *s = image->data, *src;
++ const u8 *s = image->data, *src;
+ u32 *dst;
+ const u32 *tab;
+ size_t tablen;
+diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
+index 8a884e795f6a7..3f6e7e5b7ead6 100644
+--- a/fs/binfmt_elf.c
++++ b/fs/binfmt_elf.c
+@@ -320,10 +320,10 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
+ * Grow the stack manually; some architectures have a limit on how
+ * far ahead a user-space access may be in order to grow the stack.
+ */
+- if (mmap_read_lock_killable(mm))
++ if (mmap_write_lock_killable(mm))
+ return -EINTR;
+- vma = find_extend_vma(mm, bprm->p);
+- mmap_read_unlock(mm);
++ vma = find_extend_vma_locked(mm, bprm->p);
++ mmap_write_unlock(mm);
+ if (!vma)
+ return -EFAULT;
+
+diff --git a/fs/exec.c b/fs/exec.c
+index 7c44d0c65b1b4..a0188e5c9ee20 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -199,33 +199,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 = 0;
+
+-#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;
+ }
+@@ -852,7 +858,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
+ stack_base = vma->vm_end - 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;
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index ced82b9c18e57..53bec6d4297bb 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2179,6 +2179,9 @@ void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to);
+ void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end);
+ int generic_error_remove_page(struct address_space *mapping, struct page *page);
+
++struct vm_area_struct *lock_mm_and_find_vma(struct mm_struct *mm,
++ unsigned long address, struct pt_regs *regs);
++
+ #ifdef CONFIG_MMU
+ extern vm_fault_t handle_mm_fault(struct vm_area_struct *vma,
+ unsigned long address, unsigned int flags,
+@@ -3063,16 +3066,11 @@ extern vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf);
+
+ extern unsigned long stack_guard_gap;
+ /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */
+-extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
++int expand_stack_locked(struct vm_area_struct *vma, unsigned long address);
++struct vm_area_struct *expand_stack(struct mm_struct * mm, unsigned long addr);
+
+ /* CONFIG_STACK_GROWSUP still needs to grow downwards at some places */
+-extern int expand_downwards(struct vm_area_struct *vma,
+- unsigned long address);
+-#if VM_GROWSUP
+-extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
+-#else
+- #define expand_upwards(vma, address) (0)
+-#endif
++int expand_downwards(struct vm_area_struct *vma, unsigned long address);
+
+ /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
+ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
+@@ -3167,7 +3165,8 @@ unsigned long change_prot_numa(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end);
+ #endif
+
+-struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
++struct vm_area_struct *find_extend_vma_locked(struct mm_struct *,
++ unsigned long addr);
+ int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
+ unsigned long pfn, unsigned long size, pgprot_t);
+ int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long addr,
+diff --git a/lib/maple_tree.c b/lib/maple_tree.c
+index a614129d43394..468d37bf512da 100644
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -4287,11 +4287,13 @@ done:
+
+ static inline void mas_wr_end_piv(struct ma_wr_state *wr_mas)
+ {
+- while ((wr_mas->mas->last > wr_mas->end_piv) &&
+- (wr_mas->offset_end < wr_mas->node_end))
+- wr_mas->end_piv = wr_mas->pivots[++wr_mas->offset_end];
++ while ((wr_mas->offset_end < wr_mas->node_end) &&
++ (wr_mas->mas->last > wr_mas->pivots[wr_mas->offset_end]))
++ wr_mas->offset_end++;
+
+- if (wr_mas->mas->last > wr_mas->end_piv)
++ if (wr_mas->offset_end < wr_mas->node_end)
++ wr_mas->end_piv = wr_mas->pivots[wr_mas->offset_end];
++ else
+ wr_mas->end_piv = wr_mas->mas->max;
+ }
+
+@@ -4448,7 +4450,6 @@ static inline void *mas_wr_store_entry(struct ma_wr_state *wr_mas)
+ }
+
+ /* At this point, we are at the leaf node that needs to be altered. */
+- wr_mas->end_piv = wr_mas->r_max;
+ mas_wr_end_piv(wr_mas);
+
+ if (!wr_mas->entry)
+diff --git a/mm/Kconfig b/mm/Kconfig
+index 4751031f3f052..ae3003a98d130 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -1202,6 +1202,10 @@ config LRU_GEN_STATS
+ This option has a per-memcg and per-node memory overhead.
+ # }
+
++config LOCK_MM_AND_FIND_VMA
++ bool
++ depends on !STACK_GROWSUP
++
+ source "mm/damon/Kconfig"
+
+ endmenu
+diff --git a/mm/gup.c b/mm/gup.c
+index eab18ba045dbe..eb0b96985c3c4 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1096,7 +1096,11 @@ static long __get_user_pages(struct mm_struct *mm,
+
+ /* first iteration or cross vma bound */
+ if (!vma || start >= vma->vm_end) {
+- vma = find_extend_vma(mm, start);
++ vma = find_vma(mm, start);
++ if (vma && (start < vma->vm_start)) {
++ WARN_ON_ONCE(vma->vm_flags & VM_GROWSDOWN);
++ vma = NULL;
++ }
+ if (!vma && in_gate_area(mm, start)) {
+ ret = get_gate_page(mm, start & PAGE_MASK,
+ gup_flags, &vma,
+@@ -1265,9 +1269,13 @@ int fixup_user_fault(struct mm_struct *mm,
+ fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
+
+ retry:
+- vma = find_extend_vma(mm, address);
+- if (!vma || address < vma->vm_start)
++ vma = find_vma(mm, address);
++ if (!vma)
++ return -EFAULT;
++ if (address < vma->vm_start ) {
++ WARN_ON_ONCE(vma->vm_flags & VM_GROWSDOWN);
+ return -EFAULT;
++ }
+
+ if (!vma_permits_fault(vma, fault_flags))
+ return -EFAULT;
+diff --git a/mm/memory.c b/mm/memory.c
+index 01a23ad48a042..2c2caae6fb3b6 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -5230,6 +5230,125 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
+ }
+ EXPORT_SYMBOL_GPL(handle_mm_fault);
+
++#ifdef CONFIG_LOCK_MM_AND_FIND_VMA
++#include <linux/extable.h>
++
++static inline bool get_mmap_lock_carefully(struct mm_struct *mm, struct pt_regs *regs)
++{
++ /* Even if this succeeds, make it clear we *might* have slept */
++ if (likely(mmap_read_trylock(mm))) {
++ might_sleep();
++ return true;
++ }
++
++ if (regs && !user_mode(regs)) {
++ unsigned long ip = instruction_pointer(regs);
++ if (!search_exception_tables(ip))
++ return false;
++ }
++
++ return !mmap_read_lock_killable(mm);
++}
++
++static inline bool mmap_upgrade_trylock(struct mm_struct *mm)
++{
++ /*
++ * We don't have this operation yet.
++ *
++ * It should be easy enough to do: it's basically a
++ * atomic_long_try_cmpxchg_acquire()
++ * from RWSEM_READER_BIAS -> RWSEM_WRITER_LOCKED, but
++ * it also needs the proper lockdep magic etc.
++ */
++ return false;
++}
++
++static inline bool upgrade_mmap_lock_carefully(struct mm_struct *mm, struct pt_regs *regs)
++{
++ mmap_read_unlock(mm);
++ if (regs && !user_mode(regs)) {
++ unsigned long ip = instruction_pointer(regs);
++ if (!search_exception_tables(ip))
++ return false;
++ }
++ return !mmap_write_lock_killable(mm);
++}
++
++/*
++ * Helper for page fault handling.
++ *
++ * This is kind of equivalend to "mmap_read_lock()" followed
++ * by "find_extend_vma()", except it's a lot more careful about
++ * the locking (and will drop the lock on failure).
++ *
++ * For example, if we have a kernel bug that causes a page
++ * fault, we don't want to just use mmap_read_lock() to get
++ * the mm lock, because that would deadlock if the bug were
++ * to happen while we're holding the mm lock for writing.
++ *
++ * So this checks the exception tables on kernel faults in
++ * order to only do this all for instructions that are actually
++ * expected to fault.
++ *
++ * We can also actually take the mm lock for writing if we
++ * need to extend the vma, which helps the VM layer a lot.
++ */
++struct vm_area_struct *lock_mm_and_find_vma(struct mm_struct *mm,
++ unsigned long addr, struct pt_regs *regs)
++{
++ struct vm_area_struct *vma;
++
++ if (!get_mmap_lock_carefully(mm, regs))
++ return NULL;
++
++ vma = find_vma(mm, addr);
++ if (likely(vma && (vma->vm_start <= addr)))
++ return vma;
++
++ /*
++ * Well, dang. We might still be successful, but only
++ * if we can extend a vma to do so.
++ */
++ if (!vma || !(vma->vm_flags & VM_GROWSDOWN)) {
++ mmap_read_unlock(mm);
++ return NULL;
++ }
++
++ /*
++ * We can try to upgrade the mmap lock atomically,
++ * in which case we can continue to use the vma
++ * we already looked up.
++ *
++ * Otherwise we'll have to drop the mmap lock and
++ * re-take it, and also look up the vma again,
++ * re-checking it.
++ */
++ if (!mmap_upgrade_trylock(mm)) {
++ if (!upgrade_mmap_lock_carefully(mm, regs))
++ return NULL;
++
++ vma = find_vma(mm, addr);
++ if (!vma)
++ goto fail;
++ if (vma->vm_start <= addr)
++ goto success;
++ if (!(vma->vm_flags & VM_GROWSDOWN))
++ goto fail;
++ }
++
++ if (expand_stack_locked(vma, addr))
++ goto fail;
++
++success:
++ mmap_write_downgrade(mm);
++ return vma;
++
++fail:
++ mmap_write_unlock(mm);
++ return NULL;
++}
++#endif
++
+ #ifndef __PAGETABLE_P4D_FOLDED
+ /*
+ * Allocate p4d page table.
+@@ -5501,6 +5620,14 @@ int __access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf,
+ 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;
+diff --git a/mm/mmap.c b/mm/mmap.c
+index eefa6f0cda28e..c9328a6c7d43d 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1898,7 +1898,7 @@ static int acct_stack_growth(struct vm_area_struct *vma,
+ * PA-RISC uses this for its stack; IA64 for its Register Backing Store.
+ * vma is the last one with address > vma->vm_end. Have to extend vma.
+ */
+-int expand_upwards(struct vm_area_struct *vma, unsigned long address)
++static int expand_upwards(struct vm_area_struct *vma, unsigned long address)
+ {
+ struct mm_struct *mm = vma->vm_mm;
+ struct vm_area_struct *next;
+@@ -1990,6 +1990,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
+
+ /*
+ * vma is the first one with address < vma->vm_start. Have to extend vma.
++ * mmap_lock held for writing.
+ */
+ int expand_downwards(struct vm_area_struct *vma, unsigned long address)
+ {
+@@ -1998,16 +1999,20 @@ int expand_downwards(struct vm_area_struct *vma, unsigned long address)
+ struct vm_area_struct *prev;
+ int error = 0;
+
++ if (!(vma->vm_flags & VM_GROWSDOWN))
++ return -EFAULT;
++
+ address &= PAGE_MASK;
+- if (address < mmap_min_addr)
++ if (address < mmap_min_addr || address < FIRST_USER_ADDRESS)
+ return -EPERM;
+
+ /* Enforce stack_guard_gap */
+ prev = mas_prev(&mas, 0);
+ /* Check that both stack segments have the same anon_vma? */
+- if (prev && !(prev->vm_flags & VM_GROWSDOWN) &&
+- vma_is_accessible(prev)) {
+- if (address - prev->vm_end < stack_guard_gap)
++ if (prev) {
++ if (!(prev->vm_flags & VM_GROWSDOWN) &&
++ vma_is_accessible(prev) &&
++ (address - prev->vm_end < stack_guard_gap))
+ return -ENOMEM;
+ }
+
+@@ -2087,13 +2092,12 @@ static int __init cmdline_parse_stack_guard_gap(char *p)
+ __setup("stack_guard_gap=", cmdline_parse_stack_guard_gap);
+
+ #ifdef CONFIG_STACK_GROWSUP
+-int expand_stack(struct vm_area_struct *vma, unsigned long address)
++int expand_stack_locked(struct vm_area_struct *vma, unsigned long address)
+ {
+ return expand_upwards(vma, address);
+ }
+
+-struct vm_area_struct *
+-find_extend_vma(struct mm_struct *mm, unsigned long addr)
++struct vm_area_struct *find_extend_vma_locked(struct mm_struct *mm, unsigned long addr)
+ {
+ struct vm_area_struct *vma, *prev;
+
+@@ -2101,20 +2105,23 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
+ vma = find_vma_prev(mm, addr, &prev);
+ if (vma && (vma->vm_start <= addr))
+ return vma;
+- if (!prev || expand_stack(prev, addr))
++ if (!prev)
++ return NULL;
++ if (expand_stack_locked(prev, addr))
+ return NULL;
+ if (prev->vm_flags & VM_LOCKED)
+ populate_vma_page_range(prev, addr, prev->vm_end, NULL);
+ return prev;
+ }
+ #else
+-int expand_stack(struct vm_area_struct *vma, unsigned long address)
++int expand_stack_locked(struct vm_area_struct *vma, unsigned long address)
+ {
++ if (unlikely(!(vma->vm_flags & VM_GROWSDOWN)))
++ return -EINVAL;
+ return expand_downwards(vma, address);
+ }
+
+-struct vm_area_struct *
+-find_extend_vma(struct mm_struct *mm, unsigned long addr)
++struct vm_area_struct *find_extend_vma_locked(struct mm_struct *mm, unsigned long addr)
+ {
+ struct vm_area_struct *vma;
+ unsigned long start;
+@@ -2125,10 +2132,8 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
+ return NULL;
+ if (vma->vm_start <= addr)
+ return vma;
+- if (!(vma->vm_flags & VM_GROWSDOWN))
+- return NULL;
+ start = vma->vm_start;
+- if (expand_stack(vma, addr))
++ if (expand_stack_locked(vma, addr))
+ return NULL;
+ if (vma->vm_flags & VM_LOCKED)
+ populate_vma_page_range(vma, addr, start, NULL);
+@@ -2136,7 +2141,91 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
+ }
+ #endif
+
+-EXPORT_SYMBOL_GPL(find_extend_vma);
++/*
++ * IA64 has some horrid mapping rules: it can expand both up and down,
++ * but with various special rules.
++ *
++ * We'll get rid of this architecture eventually, so the ugliness is
++ * temporary.
++ */
++#ifdef CONFIG_IA64
++static inline bool vma_expand_ok(struct vm_area_struct *vma, unsigned long addr)
++{
++ return REGION_NUMBER(addr) == REGION_NUMBER(vma->vm_start) &&
++ REGION_OFFSET(addr) < RGN_MAP_LIMIT;
++}
++
++/*
++ * IA64 stacks grow down, but there's a special register backing store
++ * that can grow up. Only sequentially, though, so the new address must
++ * match vm_end.
++ */
++static inline int vma_expand_up(struct vm_area_struct *vma, unsigned long addr)
++{
++ if (!vma_expand_ok(vma, addr))
++ return -EFAULT;
++ if (vma->vm_end != (addr & PAGE_MASK))
++ return -EFAULT;
++ return expand_upwards(vma, addr);
++}
++
++static inline bool vma_expand_down(struct vm_area_struct *vma, unsigned long addr)
++{
++ if (!vma_expand_ok(vma, addr))
++ return -EFAULT;
++ return expand_downwards(vma, addr);
++}
++
++#elif defined(CONFIG_STACK_GROWSUP)
++
++#define vma_expand_up(vma,addr) expand_upwards(vma, addr)
++#define vma_expand_down(vma, addr) (-EFAULT)
++
++#else
++
++#define vma_expand_up(vma,addr) (-EFAULT)
++#define vma_expand_down(vma, addr) expand_downwards(vma, addr)
++
++#endif
++
++/*
++ * expand_stack(): legacy interface for page faulting. Don't use unless
++ * you have to.
++ *
++ * This is called with the mm locked for reading, drops the lock, takes
++ * the lock for writing, tries to look up a vma again, expands it if
++ * necessary, and downgrades the lock to reading again.
++ *
++ * If no vma is found or it can't be expanded, it returns NULL and has
++ * dropped the lock.
++ */
++struct vm_area_struct *expand_stack(struct mm_struct *mm, unsigned long addr)
++{
++ struct vm_area_struct *vma, *prev;
++
++ mmap_read_unlock(mm);
++ if (mmap_write_lock_killable(mm))
++ return NULL;
++
++ vma = find_vma_prev(mm, addr, &prev);
++ if (vma && vma->vm_start <= addr)
++ goto success;
++
++ if (prev && !vma_expand_up(prev, addr)) {
++ vma = prev;
++ goto success;
++ }
++
++ if (vma && !vma_expand_down(vma, addr))
++ goto success;
++
++ mmap_write_unlock(mm);
++ return NULL;
++
++success:
++ mmap_write_downgrade(mm);
++ return vma;
++}
+
+ /*
+ * Ok - we have the memory areas we should free on a maple tree so release them,
+@@ -2280,19 +2369,6 @@ int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
+ return __split_vma(vmi, vma, addr, new_below);
+ }
+
+-static inline int munmap_sidetree(struct vm_area_struct *vma,
+- struct ma_state *mas_detach)
+-{
+- mas_set_range(mas_detach, vma->vm_start, vma->vm_end - 1);
+- if (mas_store_gfp(mas_detach, vma, GFP_KERNEL))
+- return -ENOMEM;
+-
+- if (vma->vm_flags & VM_LOCKED)
+- vma->vm_mm->locked_vm -= vma_pages(vma);
+-
+- return 0;
+-}
+-
+ /*
+ * do_vmi_align_munmap() - munmap the aligned region from @start to @end.
+ * @vmi: The vma iterator
+@@ -2314,6 +2390,7 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
+ struct maple_tree mt_detach;
+ int count = 0;
+ int error = -ENOMEM;
++ unsigned long locked_vm = 0;
+ MA_STATE(mas_detach, &mt_detach, 0, 0);
+ mt_init_flags(&mt_detach, vmi->mas.tree->ma_flags & MT_FLAGS_LOCK_MASK);
+ mt_set_external_lock(&mt_detach, &mm->mmap_lock);
+@@ -2359,9 +2436,12 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
+ if (error)
+ goto end_split_failed;
+ }
+- error = munmap_sidetree(next, &mas_detach);
++ mas_set_range(&mas_detach, next->vm_start, next->vm_end - 1);
++ error = mas_store_gfp(&mas_detach, next, GFP_KERNEL);
+ if (error)
+- goto munmap_sidetree_failed;
++ goto munmap_gather_failed;
++ if (next->vm_flags & VM_LOCKED)
++ locked_vm += vma_pages(next);
+
+ count++;
+ #ifdef CONFIG_DEBUG_VM_MAPLE_TREE
+@@ -2406,11 +2486,13 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
+ BUG_ON(count != test_count);
+ }
+ #endif
+- /* Point of no return */
+ vma_iter_set(vmi, start);
+- if (vma_iter_clear_gfp(vmi, start, end, GFP_KERNEL))
+- return -ENOMEM;
++ error = vma_iter_clear_gfp(vmi, start, end, GFP_KERNEL);
++ if (error)
++ goto clear_tree_failed;
+
++ /* Point of no return */
++ mm->locked_vm -= locked_vm;
+ mm->map_count -= count;
+ /*
+ * Do not downgrade mmap_lock if we are next to VM_GROWSDOWN or
+@@ -2440,8 +2522,9 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
+ validate_mm(mm);
+ return downgrade ? 1 : 0;
+
++clear_tree_failed:
+ userfaultfd_error:
+-munmap_sidetree_failed:
++munmap_gather_failed:
+ end_split_failed:
+ __mt_destroy(&mt_detach);
+ start_split_failed:
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 57ba243c6a37f..07a3af6a94ea8 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -631,23 +631,31 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+ EXPORT_SYMBOL(find_vma);
+
+ /*
+- * find a VMA
+- * - we don't extend stack VMAs under NOMMU conditions
++ * At least xtensa ends up having protection faults even with no
++ * MMU.. No stack expansion, at least.
+ */
+-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
++struct vm_area_struct *lock_mm_and_find_vma(struct mm_struct *mm,
++ unsigned long addr, struct pt_regs *regs)
+ {
+- return find_vma(mm, addr);
++ mmap_read_lock(mm);
++ return vma_lookup(mm, addr);
+ }
+
+ /*
+ * expand a stack to a given address
+ * - not supported under NOMMU conditions
+ */
+-int expand_stack(struct vm_area_struct *vma, unsigned long address)
++int expand_stack_locked(struct vm_area_struct *vma, unsigned long addr)
+ {
+ return -ENOMEM;
+ }
+
++struct vm_area_struct *expand_stack(struct mm_struct *mm, unsigned long addr)
++{
++ mmap_read_unlock(mm);
++ return NULL;
++}
++
+ /*
+ * look up the first VMA exactly that exactly matches addr
+ * - should be called with mm->mmap_lock at least held readlocked
+diff --git a/net/can/isotp.c b/net/can/isotp.c
+index 1af623839bffa..b3c2a49b189cc 100644
+--- a/net/can/isotp.c
++++ b/net/can/isotp.c
+@@ -1079,8 +1079,9 @@ wait_free_buffer:
+ if (err)
+ goto err_event_drop;
+
+- if (sk->sk_err)
+- return -sk->sk_err;
++ err = sock_error(sk);
++ if (err)
++ return err;
+ }
+
+ return size;