m68k fixes for v6.4

- Fix user-space crashes on 68020/68030.
 -----BEGIN PGP SIGNATURE-----
 
 iIsEABYIADMWIQQ9qaHoIs/1I4cXmEiKwlD9ZEnxcAUCZG8O3xUcZ2VlcnRAbGlu
 dXgtbTY4ay5vcmcACgkQisJQ/WRJ8XCvywD/TDu1jmuiKKZeIOdGjRQOIW8jL94Y
 FlZ/3Ot58VR0A60BAK6My+4pkBoeAO4/cIWQNNf7+vzymV8bVP36BxZVx/IH
 =1Qsv
 -----END PGP SIGNATURE-----

Merge tag 'm68k-for-v6.4-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k

Pull m68k fix from Geert Uytterhoeven:

 - Fix signal frame issue causing user-space crashes on 68020/68030

* tag 'm68k-for-v6.4-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k:
  m68k: Move signal frame following exception on 68020/030
This commit is contained in:
Linus Torvalds 2023-05-25 09:33:03 -07:00
commit 5566051fa6

View file

@ -858,11 +858,17 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *
} }
static inline void __user * static inline void __user *
get_sigframe(struct ksignal *ksig, size_t frame_size) get_sigframe(struct ksignal *ksig, struct pt_regs *tregs, size_t frame_size)
{ {
unsigned long usp = sigsp(rdusp(), ksig); unsigned long usp = sigsp(rdusp(), ksig);
unsigned long gap = 0;
return (void __user *)((usp - frame_size) & -8UL); if (CPU_IS_020_OR_030 && tregs->format == 0xb) {
/* USP is unreliable so use worst-case value */
gap = 256;
}
return (void __user *)((usp - gap - frame_size) & -8UL);
} }
static int setup_frame(struct ksignal *ksig, sigset_t *set, static int setup_frame(struct ksignal *ksig, sigset_t *set,
@ -880,7 +886,7 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set,
return -EFAULT; return -EFAULT;
} }
frame = get_sigframe(ksig, sizeof(*frame) + fsize); frame = get_sigframe(ksig, tregs, sizeof(*frame) + fsize);
if (fsize) if (fsize)
err |= copy_to_user (frame + 1, regs + 1, fsize); err |= copy_to_user (frame + 1, regs + 1, fsize);
@ -952,7 +958,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
return -EFAULT; return -EFAULT;
} }
frame = get_sigframe(ksig, sizeof(*frame)); frame = get_sigframe(ksig, tregs, sizeof(*frame));
if (fsize) if (fsize)
err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);