.. | .. |
---|
882 | 882 | } |
---|
883 | 883 | |
---|
884 | 884 | static inline void __user * |
---|
885 | | -get_sigframe(struct ksignal *ksig, size_t frame_size) |
---|
| 885 | +get_sigframe(struct ksignal *ksig, struct pt_regs *tregs, size_t frame_size) |
---|
886 | 886 | { |
---|
887 | 887 | unsigned long usp = sigsp(rdusp(), ksig); |
---|
| 888 | + unsigned long gap = 0; |
---|
888 | 889 | |
---|
889 | | - return (void __user *)((usp - frame_size) & -8UL); |
---|
| 890 | + if (CPU_IS_020_OR_030 && tregs->format == 0xb) { |
---|
| 891 | + /* USP is unreliable so use worst-case value */ |
---|
| 892 | + gap = 256; |
---|
| 893 | + } |
---|
| 894 | + |
---|
| 895 | + return (void __user *)((usp - gap - frame_size) & -8UL); |
---|
890 | 896 | } |
---|
891 | 897 | |
---|
892 | 898 | static int setup_frame(struct ksignal *ksig, sigset_t *set, |
---|
.. | .. |
---|
904 | 910 | return -EFAULT; |
---|
905 | 911 | } |
---|
906 | 912 | |
---|
907 | | - frame = get_sigframe(ksig, sizeof(*frame) + fsize); |
---|
| 913 | + frame = get_sigframe(ksig, tregs, sizeof(*frame) + fsize); |
---|
908 | 914 | |
---|
909 | 915 | if (fsize) |
---|
910 | 916 | err |= copy_to_user (frame + 1, regs + 1, fsize); |
---|
.. | .. |
---|
976 | 982 | return -EFAULT; |
---|
977 | 983 | } |
---|
978 | 984 | |
---|
979 | | - frame = get_sigframe(ksig, sizeof(*frame)); |
---|
| 985 | + frame = get_sigframe(ksig, tregs, sizeof(*frame)); |
---|
980 | 986 | |
---|
981 | 987 | if (fsize) |
---|
982 | 988 | err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); |
---|