On Tue, 25 Apr 2023, Finn Thain wrote: > On Tue, 25 Apr 2023, Michael Schmitz wrote: > > > As to a cause for the corruption: all the calculations in setup_frame > > and sys_sigreturn use fsize, but get_sigframe() masks off the result > > of usp - sizeof(sigframe) - fsize to place the entire frame at a > > quadword boundary. > ... > > I wonder if we are seeing some fallout from the issue described in > do_page_fault() i.e. usp is unreliable. > > /* Accessing the stack below usp is always a bug. The > "+ 256" is there due to some instructions doing > pre-decrement on the stack and that doesn't show up > until later. */ > if (address + 256 < rdusp()) > goto map_err; > > Maybe we should try modifying get_sigframe() to increase the gap between > the signal and exception frames from 0-1 long words up to 64-65 long > words. >
It turns out that doing so (patch below) does make the problem go away. Was the exception frame getting clobbered? diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index b9f6908a31bc..94104699f5a8 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -862,7 +862,7 @@ get_sigframe(struct ksignal *ksig, size_t frame_size) { unsigned long usp = sigsp(rdusp(), ksig); - return (void __user *)((usp - frame_size) & -8UL); + return (void __user *)((usp - 256 - frame_size) & -8UL); } static int setup_frame(struct ksignal *ksig, sigset_t *set,