| .. | .. |
|---|
| 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); |
|---|