All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] sh: mm: fix double mmap_lock release on SIGBUS and SIGSEGV faults
@ 2026-09-28  0:19 Karl Mehltretter
  2026-10-16  9:46 ` Karl Mehltretter
  0 siblings, 1 reply; 3+ messages in thread
From: Karl Mehltretter @ 2026-09-28  0:19 UTC (permalink / raw)
  To: Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz
  Cc: Karl Mehltretter, Peter Xu, Andrew Morton, linux-sh, linux-kernel

Since commit fb027ada051a ("sh/mm: use helper fault_signal_pending()"),
mm_fault_error() releases mmap_lock itself for every fault result
without VM_FAULT_RETRY. Before that, the VM_FAULT_SIGBUS and
VM_FAULT_SIGSEGV branches relied on do_sigbus() and bad_area() to
release it, and both still do. So a fault that ends in SIGBUS or
SIGSEGV releases mmap_lock twice.

A process that survives the signal keeps an mm with a corrupted
mmap_lock. With CONFIG_DEBUG_RWSEMS and lockdep, stress-ng --msync
(which catches SIGBUS) reports within a minute:

  WARNING: bad unlock balance detected!
  stress-ng-msync/54 is trying to release lock (&mm->mmap_lock) at:
  mm_fault_error+0xd0/0x16c
  ...
  DEBUG_RWSEMS_WARN_ON(tmp < 0): count = 0xffffff00, ...

and without them, find_vma() warns that mmap_lock is not held right
after it was taken. Seen on a custom QEMU model of the SH7785LCR, in
both 29-bit and 32-bit mode.

Drop the release from do_sigbus(), whose only caller is
mm_fault_error(), and use bad_area_nosemaphore() for VM_FAULT_SIGSEGV.
bad_area() has no users left and goes away.

Fixes: fb027ada051a ("sh/mm: use helper fault_signal_pending()")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---

Notes:
    Tested in QEMU on a custom SH7785LCR model, not on hardware.
    Reproducer: Debian sh4 stress-ng 0.22.01 --msync

    Unpatched:
    - debug kernel: lockdep "bad unlock balance", DEBUG_RWSEMS count
      0xffffff00
    - 29-bit and 32-bit non-debug kernels: find_vma() mmap_lock warnings

    Patched (debug kernel):
    - stress-ng --msync passes, no lock reports
    - stress-ng run with 48 stressors: no kernel reports

    Testing on real hardware is welcome.

 arch/sh/mm/fault.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 06e6b49529245..138fc577a4c13 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -281,12 +281,6 @@ __bad_area(struct pt_regs *regs, unsigned long error_code,
 	__bad_area_nosemaphore(regs, error_code, address, si_code);
 }
 
-static noinline void
-bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address)
-{
-	__bad_area(regs, error_code, address, SEGV_MAPERR);
-}
-
 static noinline void
 bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
 		      unsigned long address)
@@ -297,11 +291,6 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
 static void
 do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address)
 {
-	struct task_struct *tsk = current;
-	struct mm_struct *mm = tsk->mm;
-
-	mmap_read_unlock(mm);
-
 	/* Kernel mode? Handle exceptions or die: */
 	if (!user_mode(regs))
 		no_context(regs, error_code, address);
@@ -347,7 +336,7 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
 		if (fault & VM_FAULT_SIGBUS)
 			do_sigbus(regs, error_code, address);
 		else if (fault & VM_FAULT_SIGSEGV)
-			bad_area(regs, error_code, address);
+			bad_area_nosemaphore(regs, error_code, address);
 		else
 			BUG();
 	}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] sh: mm: fix double mmap_lock release on SIGBUS and SIGSEGV faults
  2026-09-28  0:19 [PATCH] sh: mm: fix double mmap_lock release on SIGBUS and SIGSEGV faults Karl Mehltretter
@ 2026-10-16  9:46 ` Karl Mehltretter
  2026-10-16 13:50   ` John Paul Adrian Glaubitz
  0 siblings, 1 reply; 3+ messages in thread
From: Karl Mehltretter @ 2026-10-16  9:46 UTC (permalink / raw)
  To: Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz
  Cc: Peter Xu, Andrew Morton, linux-sh, linux-kernel

On Mon, Sep 28, 2026 at 02:19:37AM +0100, Karl Mehltretter wrote:
> A process that survives the signal keeps an mm with a corrupted
> mmap_lock. With CONFIG_DEBUG_RWSEMS and lockdep, stress-ng --msync
> (which catches SIGBUS) reports within a minute:
> 
>   WARNING: bad unlock balance detected!
>   stress-ng-msync/54 is trying to release lock (&mm->mmap_lock) at:
>   mm_fault_error+0xd0/0x16c
>   ...
>   DEBUG_RWSEMS_WARN_ON(tmp < 0): count = 0xffffff00, ...
> 
> and without them, find_vma() warns that mmap_lock is not held right
> after it was taken. Seen on a custom QEMU model of the SH7785LCR, in
> both 29-bit and 32-bit mode.
> 
> Drop the release from do_sigbus(), whose only caller is
> mm_fault_error(), and use bad_area_nosemaphore() for VM_FAULT_SIGSEGV.
> bad_area() has no users left and goes away.
> 
> Fixes: fb027ada051a ("sh/mm: use helper fault_signal_pending()")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
> ---
> 
> Notes:
>     Tested in QEMU on a custom SH7785LCR model, not on hardware.
>     Reproducer: Debian sh4 stress-ng 0.22.01 --msync
> 

A friendly ping on this fix.

I have now also reproduced it with stock QEMU 11.0.2 on the upstream
r2d machine (SH7751R): the unpatched kernel warns after a caught SIGBUS,
while the patched kernel does not.

Also, the stress-ng command in the review notes is incorrect. Use:

  stress-ng --msync 1 --timeout 60s

Thanks,
Karl

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] sh: mm: fix double mmap_lock release on SIGBUS and SIGSEGV faults
  2026-10-16  9:46 ` Karl Mehltretter
@ 2026-10-16 13:50   ` John Paul Adrian Glaubitz
  0 siblings, 0 replies; 3+ messages in thread
From: John Paul Adrian Glaubitz @ 2026-10-16 13:50 UTC (permalink / raw)
  To: Karl Mehltretter, Yoshinori Sato, Rich Felker
  Cc: Peter Xu, Andrew Morton, linux-sh, linux-kernel

Hi Karl,

On Fri, 2026-10-16 at 11:46 +0200, Karl Mehltretter wrote:
> On Mon, Sep 28, 2026 at 02:19:37AM +0100, Karl Mehltretter wrote:
> > A process that survives the signal keeps an mm with a corrupted
> > mmap_lock. With CONFIG_DEBUG_RWSEMS and lockdep, stress-ng --msync
> > (which catches SIGBUS) reports within a minute:
> > 
> >   WARNING: bad unlock balance detected!
> >   stress-ng-msync/54 is trying to release lock (&mm->mmap_lock) at:
> >   mm_fault_error+0xd0/0x16c
> >   ...
> >   DEBUG_RWSEMS_WARN_ON(tmp < 0): count = 0xffffff00, ...
> > 
> > and without them, find_vma() warns that mmap_lock is not held right
> > after it was taken. Seen on a custom QEMU model of the SH7785LCR, in
> > both 29-bit and 32-bit mode.
> > 
> > Drop the release from do_sigbus(), whose only caller is
> > mm_fault_error(), and use bad_area_nosemaphore() for VM_FAULT_SIGSEGV.
> > bad_area() has no users left and goes away.
> > 
> > Fixes: fb027ada051a ("sh/mm: use helper fault_signal_pending()")
> > Cc: stable@vger.kernel.org
> > Assisted-by: LLM
> > Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
> > ---
> > 
> > Notes:
> >     Tested in QEMU on a custom SH7785LCR model, not on hardware.
> >     Reproducer: Debian sh4 stress-ng 0.22.01 --msync
> > 
> 
> A friendly ping on this fix.
> 
> I have now also reproduced it with stock QEMU 11.0.2 on the upstream
> r2d machine (SH7751R): the unpatched kernel warns after a caught SIGBUS,
> while the patched kernel does not.
> 
> Also, the stress-ng command in the review notes is incorrect. Use:
> 
>   stress-ng --msync 1 --timeout 60s

I'm trying to get this reviewed in the weekend. I'm not forgetting about
patches as I'll always check what's on patchwork and pick everything up
that I haven't taken yet [1].

Adrian

> [1] https://patchwork.kernel.org/project/linux-sh/list/

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-16 13:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-28  0:19 [PATCH] sh: mm: fix double mmap_lock release on SIGBUS and SIGSEGV faults Karl Mehltretter
2026-10-16  9:46 ` Karl Mehltretter
2026-10-16 13:50   ` John Paul Adrian Glaubitz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.