Commit d09042da7284a86ffbdd18695f517a71514ed598

Authored by Laurent MEYER
Committed by Linus Torvalds
1 parent 785d55708c

[PATCH] fix incorrect SA_ONSTACK behaviour for 64-bit processes

- When setting a sighandler using sigaction() call, if the flag
  SA_ONSTACK is set and no alternate stack is provided via sigaltstack(),
  the kernel still try to install the alternate stack.  This behavior is
  the opposite of the one which is documented in Single Unix Specifications
  V3.

- Also when setting an alternate stack using sigaltstack() with the flag
  SS_DISABLE, the kernel try to install the alternate stack on signal
  delivery.

These two use cases makes the process crash at signal delivery.

Signed-off-by: Laurent Meyer <meyerlau@fr.ibm.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: David Howells <dhowells@redhat.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
Cc: Chris Zankel <chris@zankel.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 9 changed files with 9 additions and 9 deletions Inline Diff

arch/alpha/kernel/signal.c
1 /* 1 /*
2 * linux/arch/alpha/kernel/signal.c 2 * linux/arch/alpha/kernel/signal.c
3 * 3 *
4 * Copyright (C) 1995 Linus Torvalds 4 * Copyright (C) 1995 Linus Torvalds
5 * 5 *
6 * 1997-11-02 Modified for POSIX.1b signals by Richard Henderson 6 * 1997-11-02 Modified for POSIX.1b signals by Richard Henderson
7 */ 7 */
8 8
9 #include <linux/sched.h> 9 #include <linux/sched.h>
10 #include <linux/kernel.h> 10 #include <linux/kernel.h>
11 #include <linux/signal.h> 11 #include <linux/signal.h>
12 #include <linux/errno.h> 12 #include <linux/errno.h>
13 #include <linux/wait.h> 13 #include <linux/wait.h>
14 #include <linux/ptrace.h> 14 #include <linux/ptrace.h>
15 #include <linux/unistd.h> 15 #include <linux/unistd.h>
16 #include <linux/mm.h> 16 #include <linux/mm.h>
17 #include <linux/smp.h> 17 #include <linux/smp.h>
18 #include <linux/smp_lock.h> 18 #include <linux/smp_lock.h>
19 #include <linux/stddef.h> 19 #include <linux/stddef.h>
20 #include <linux/tty.h> 20 #include <linux/tty.h>
21 #include <linux/binfmts.h> 21 #include <linux/binfmts.h>
22 #include <linux/bitops.h> 22 #include <linux/bitops.h>
23 23
24 #include <asm/uaccess.h> 24 #include <asm/uaccess.h>
25 #include <asm/sigcontext.h> 25 #include <asm/sigcontext.h>
26 #include <asm/ucontext.h> 26 #include <asm/ucontext.h>
27 27
28 #include "proto.h" 28 #include "proto.h"
29 29
30 30
31 #define DEBUG_SIG 0 31 #define DEBUG_SIG 0
32 32
33 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 33 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34 34
35 asmlinkage void ret_from_sys_call(void); 35 asmlinkage void ret_from_sys_call(void);
36 static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *, 36 static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *,
37 unsigned long, unsigned long); 37 unsigned long, unsigned long);
38 38
39 39
40 /* 40 /*
41 * The OSF/1 sigprocmask calling sequence is different from the 41 * The OSF/1 sigprocmask calling sequence is different from the
42 * C sigprocmask() sequence.. 42 * C sigprocmask() sequence..
43 * 43 *
44 * how: 44 * how:
45 * 1 - SIG_BLOCK 45 * 1 - SIG_BLOCK
46 * 2 - SIG_UNBLOCK 46 * 2 - SIG_UNBLOCK
47 * 3 - SIG_SETMASK 47 * 3 - SIG_SETMASK
48 * 48 *
49 * We change the range to -1 .. 1 in order to let gcc easily 49 * We change the range to -1 .. 1 in order to let gcc easily
50 * use the conditional move instructions. 50 * use the conditional move instructions.
51 * 51 *
52 * Note that we don't need to acquire the kernel lock for SMP 52 * Note that we don't need to acquire the kernel lock for SMP
53 * operation, as all of this is local to this thread. 53 * operation, as all of this is local to this thread.
54 */ 54 */
55 asmlinkage unsigned long 55 asmlinkage unsigned long
56 do_osf_sigprocmask(int how, unsigned long newmask, struct pt_regs *regs) 56 do_osf_sigprocmask(int how, unsigned long newmask, struct pt_regs *regs)
57 { 57 {
58 unsigned long oldmask = -EINVAL; 58 unsigned long oldmask = -EINVAL;
59 59
60 if ((unsigned long)how-1 <= 2) { 60 if ((unsigned long)how-1 <= 2) {
61 long sign = how-2; /* -1 .. 1 */ 61 long sign = how-2; /* -1 .. 1 */
62 unsigned long block, unblock; 62 unsigned long block, unblock;
63 63
64 newmask &= _BLOCKABLE; 64 newmask &= _BLOCKABLE;
65 spin_lock_irq(&current->sighand->siglock); 65 spin_lock_irq(&current->sighand->siglock);
66 oldmask = current->blocked.sig[0]; 66 oldmask = current->blocked.sig[0];
67 67
68 unblock = oldmask & ~newmask; 68 unblock = oldmask & ~newmask;
69 block = oldmask | newmask; 69 block = oldmask | newmask;
70 if (!sign) 70 if (!sign)
71 block = unblock; 71 block = unblock;
72 if (sign <= 0) 72 if (sign <= 0)
73 newmask = block; 73 newmask = block;
74 if (_NSIG_WORDS > 1 && sign > 0) 74 if (_NSIG_WORDS > 1 && sign > 0)
75 sigemptyset(&current->blocked); 75 sigemptyset(&current->blocked);
76 current->blocked.sig[0] = newmask; 76 current->blocked.sig[0] = newmask;
77 recalc_sigpending(); 77 recalc_sigpending();
78 spin_unlock_irq(&current->sighand->siglock); 78 spin_unlock_irq(&current->sighand->siglock);
79 79
80 regs->r0 = 0; /* special no error return */ 80 regs->r0 = 0; /* special no error return */
81 } 81 }
82 return oldmask; 82 return oldmask;
83 } 83 }
84 84
85 asmlinkage int 85 asmlinkage int
86 osf_sigaction(int sig, const struct osf_sigaction __user *act, 86 osf_sigaction(int sig, const struct osf_sigaction __user *act,
87 struct osf_sigaction __user *oact) 87 struct osf_sigaction __user *oact)
88 { 88 {
89 struct k_sigaction new_ka, old_ka; 89 struct k_sigaction new_ka, old_ka;
90 int ret; 90 int ret;
91 91
92 if (act) { 92 if (act) {
93 old_sigset_t mask; 93 old_sigset_t mask;
94 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 94 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
95 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 95 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
96 __get_user(new_ka.sa.sa_flags, &act->sa_flags)) 96 __get_user(new_ka.sa.sa_flags, &act->sa_flags))
97 return -EFAULT; 97 return -EFAULT;
98 __get_user(mask, &act->sa_mask); 98 __get_user(mask, &act->sa_mask);
99 siginitset(&new_ka.sa.sa_mask, mask); 99 siginitset(&new_ka.sa.sa_mask, mask);
100 new_ka.ka_restorer = NULL; 100 new_ka.ka_restorer = NULL;
101 } 101 }
102 102
103 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 103 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
104 104
105 if (!ret && oact) { 105 if (!ret && oact) {
106 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 106 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
107 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 107 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
108 __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) 108 __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
109 return -EFAULT; 109 return -EFAULT;
110 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 110 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
111 } 111 }
112 112
113 return ret; 113 return ret;
114 } 114 }
115 115
116 asmlinkage long 116 asmlinkage long
117 sys_rt_sigaction(int sig, const struct sigaction __user *act, 117 sys_rt_sigaction(int sig, const struct sigaction __user *act,
118 struct sigaction __user *oact, 118 struct sigaction __user *oact,
119 size_t sigsetsize, void __user *restorer) 119 size_t sigsetsize, void __user *restorer)
120 { 120 {
121 struct k_sigaction new_ka, old_ka; 121 struct k_sigaction new_ka, old_ka;
122 int ret; 122 int ret;
123 123
124 /* XXX: Don't preclude handling different sized sigset_t's. */ 124 /* XXX: Don't preclude handling different sized sigset_t's. */
125 if (sigsetsize != sizeof(sigset_t)) 125 if (sigsetsize != sizeof(sigset_t))
126 return -EINVAL; 126 return -EINVAL;
127 127
128 if (act) { 128 if (act) {
129 new_ka.ka_restorer = restorer; 129 new_ka.ka_restorer = restorer;
130 if (copy_from_user(&new_ka.sa, act, sizeof(*act))) 130 if (copy_from_user(&new_ka.sa, act, sizeof(*act)))
131 return -EFAULT; 131 return -EFAULT;
132 } 132 }
133 133
134 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 134 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
135 135
136 if (!ret && oact) { 136 if (!ret && oact) {
137 if (copy_to_user(oact, &old_ka.sa, sizeof(*oact))) 137 if (copy_to_user(oact, &old_ka.sa, sizeof(*oact)))
138 return -EFAULT; 138 return -EFAULT;
139 } 139 }
140 140
141 return ret; 141 return ret;
142 } 142 }
143 143
144 /* 144 /*
145 * Atomically swap in the new signal mask, and wait for a signal. 145 * Atomically swap in the new signal mask, and wait for a signal.
146 */ 146 */
147 asmlinkage int 147 asmlinkage int
148 do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) 148 do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
149 { 149 {
150 sigset_t oldset; 150 sigset_t oldset;
151 151
152 mask &= _BLOCKABLE; 152 mask &= _BLOCKABLE;
153 spin_lock_irq(&current->sighand->siglock); 153 spin_lock_irq(&current->sighand->siglock);
154 oldset = current->blocked; 154 oldset = current->blocked;
155 siginitset(&current->blocked, mask); 155 siginitset(&current->blocked, mask);
156 recalc_sigpending(); 156 recalc_sigpending();
157 spin_unlock_irq(&current->sighand->siglock); 157 spin_unlock_irq(&current->sighand->siglock);
158 158
159 /* Indicate EINTR on return from any possible signal handler, 159 /* Indicate EINTR on return from any possible signal handler,
160 which will not come back through here, but via sigreturn. */ 160 which will not come back through here, but via sigreturn. */
161 regs->r0 = EINTR; 161 regs->r0 = EINTR;
162 regs->r19 = 1; 162 regs->r19 = 1;
163 163
164 while (1) { 164 while (1) {
165 current->state = TASK_INTERRUPTIBLE; 165 current->state = TASK_INTERRUPTIBLE;
166 schedule(); 166 schedule();
167 if (do_signal(&oldset, regs, sw, 0, 0)) 167 if (do_signal(&oldset, regs, sw, 0, 0))
168 return -EINTR; 168 return -EINTR;
169 } 169 }
170 } 170 }
171 171
172 asmlinkage int 172 asmlinkage int
173 do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, 173 do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
174 struct pt_regs *regs, struct switch_stack *sw) 174 struct pt_regs *regs, struct switch_stack *sw)
175 { 175 {
176 sigset_t oldset, set; 176 sigset_t oldset, set;
177 177
178 /* XXX: Don't preclude handling different sized sigset_t's. */ 178 /* XXX: Don't preclude handling different sized sigset_t's. */
179 if (sigsetsize != sizeof(sigset_t)) 179 if (sigsetsize != sizeof(sigset_t))
180 return -EINVAL; 180 return -EINVAL;
181 if (copy_from_user(&set, uset, sizeof(set))) 181 if (copy_from_user(&set, uset, sizeof(set)))
182 return -EFAULT; 182 return -EFAULT;
183 183
184 sigdelsetmask(&set, ~_BLOCKABLE); 184 sigdelsetmask(&set, ~_BLOCKABLE);
185 spin_lock_irq(&current->sighand->siglock); 185 spin_lock_irq(&current->sighand->siglock);
186 oldset = current->blocked; 186 oldset = current->blocked;
187 current->blocked = set; 187 current->blocked = set;
188 recalc_sigpending(); 188 recalc_sigpending();
189 spin_unlock_irq(&current->sighand->siglock); 189 spin_unlock_irq(&current->sighand->siglock);
190 190
191 /* Indicate EINTR on return from any possible signal handler, 191 /* Indicate EINTR on return from any possible signal handler,
192 which will not come back through here, but via sigreturn. */ 192 which will not come back through here, but via sigreturn. */
193 regs->r0 = EINTR; 193 regs->r0 = EINTR;
194 regs->r19 = 1; 194 regs->r19 = 1;
195 195
196 while (1) { 196 while (1) {
197 current->state = TASK_INTERRUPTIBLE; 197 current->state = TASK_INTERRUPTIBLE;
198 schedule(); 198 schedule();
199 if (do_signal(&oldset, regs, sw, 0, 0)) 199 if (do_signal(&oldset, regs, sw, 0, 0))
200 return -EINTR; 200 return -EINTR;
201 } 201 }
202 } 202 }
203 203
204 asmlinkage int 204 asmlinkage int
205 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) 205 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
206 { 206 {
207 return do_sigaltstack(uss, uoss, rdusp()); 207 return do_sigaltstack(uss, uoss, rdusp());
208 } 208 }
209 209
210 /* 210 /*
211 * Do a signal return; undo the signal stack. 211 * Do a signal return; undo the signal stack.
212 */ 212 */
213 213
214 #if _NSIG_WORDS > 1 214 #if _NSIG_WORDS > 1
215 # error "Non SA_SIGINFO frame needs rearranging" 215 # error "Non SA_SIGINFO frame needs rearranging"
216 #endif 216 #endif
217 217
218 struct sigframe 218 struct sigframe
219 { 219 {
220 struct sigcontext sc; 220 struct sigcontext sc;
221 unsigned int retcode[3]; 221 unsigned int retcode[3];
222 }; 222 };
223 223
224 struct rt_sigframe 224 struct rt_sigframe
225 { 225 {
226 struct siginfo info; 226 struct siginfo info;
227 struct ucontext uc; 227 struct ucontext uc;
228 unsigned int retcode[3]; 228 unsigned int retcode[3];
229 }; 229 };
230 230
231 /* If this changes, userland unwinders that Know Things about our signal 231 /* If this changes, userland unwinders that Know Things about our signal
232 frame will break. Do not undertake lightly. It also implies an ABI 232 frame will break. Do not undertake lightly. It also implies an ABI
233 change wrt the size of siginfo_t, which may cause some pain. */ 233 change wrt the size of siginfo_t, which may cause some pain. */
234 extern char compile_time_assert 234 extern char compile_time_assert
235 [offsetof(struct rt_sigframe, uc.uc_mcontext) == 176 ? 1 : -1]; 235 [offsetof(struct rt_sigframe, uc.uc_mcontext) == 176 ? 1 : -1];
236 236
237 #define INSN_MOV_R30_R16 0x47fe0410 237 #define INSN_MOV_R30_R16 0x47fe0410
238 #define INSN_LDI_R0 0x201f0000 238 #define INSN_LDI_R0 0x201f0000
239 #define INSN_CALLSYS 0x00000083 239 #define INSN_CALLSYS 0x00000083
240 240
241 static long 241 static long
242 restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 242 restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
243 struct switch_stack *sw) 243 struct switch_stack *sw)
244 { 244 {
245 unsigned long usp; 245 unsigned long usp;
246 long i, err = __get_user(regs->pc, &sc->sc_pc); 246 long i, err = __get_user(regs->pc, &sc->sc_pc);
247 247
248 sw->r26 = (unsigned long) ret_from_sys_call; 248 sw->r26 = (unsigned long) ret_from_sys_call;
249 249
250 err |= __get_user(regs->r0, sc->sc_regs+0); 250 err |= __get_user(regs->r0, sc->sc_regs+0);
251 err |= __get_user(regs->r1, sc->sc_regs+1); 251 err |= __get_user(regs->r1, sc->sc_regs+1);
252 err |= __get_user(regs->r2, sc->sc_regs+2); 252 err |= __get_user(regs->r2, sc->sc_regs+2);
253 err |= __get_user(regs->r3, sc->sc_regs+3); 253 err |= __get_user(regs->r3, sc->sc_regs+3);
254 err |= __get_user(regs->r4, sc->sc_regs+4); 254 err |= __get_user(regs->r4, sc->sc_regs+4);
255 err |= __get_user(regs->r5, sc->sc_regs+5); 255 err |= __get_user(regs->r5, sc->sc_regs+5);
256 err |= __get_user(regs->r6, sc->sc_regs+6); 256 err |= __get_user(regs->r6, sc->sc_regs+6);
257 err |= __get_user(regs->r7, sc->sc_regs+7); 257 err |= __get_user(regs->r7, sc->sc_regs+7);
258 err |= __get_user(regs->r8, sc->sc_regs+8); 258 err |= __get_user(regs->r8, sc->sc_regs+8);
259 err |= __get_user(sw->r9, sc->sc_regs+9); 259 err |= __get_user(sw->r9, sc->sc_regs+9);
260 err |= __get_user(sw->r10, sc->sc_regs+10); 260 err |= __get_user(sw->r10, sc->sc_regs+10);
261 err |= __get_user(sw->r11, sc->sc_regs+11); 261 err |= __get_user(sw->r11, sc->sc_regs+11);
262 err |= __get_user(sw->r12, sc->sc_regs+12); 262 err |= __get_user(sw->r12, sc->sc_regs+12);
263 err |= __get_user(sw->r13, sc->sc_regs+13); 263 err |= __get_user(sw->r13, sc->sc_regs+13);
264 err |= __get_user(sw->r14, sc->sc_regs+14); 264 err |= __get_user(sw->r14, sc->sc_regs+14);
265 err |= __get_user(sw->r15, sc->sc_regs+15); 265 err |= __get_user(sw->r15, sc->sc_regs+15);
266 err |= __get_user(regs->r16, sc->sc_regs+16); 266 err |= __get_user(regs->r16, sc->sc_regs+16);
267 err |= __get_user(regs->r17, sc->sc_regs+17); 267 err |= __get_user(regs->r17, sc->sc_regs+17);
268 err |= __get_user(regs->r18, sc->sc_regs+18); 268 err |= __get_user(regs->r18, sc->sc_regs+18);
269 err |= __get_user(regs->r19, sc->sc_regs+19); 269 err |= __get_user(regs->r19, sc->sc_regs+19);
270 err |= __get_user(regs->r20, sc->sc_regs+20); 270 err |= __get_user(regs->r20, sc->sc_regs+20);
271 err |= __get_user(regs->r21, sc->sc_regs+21); 271 err |= __get_user(regs->r21, sc->sc_regs+21);
272 err |= __get_user(regs->r22, sc->sc_regs+22); 272 err |= __get_user(regs->r22, sc->sc_regs+22);
273 err |= __get_user(regs->r23, sc->sc_regs+23); 273 err |= __get_user(regs->r23, sc->sc_regs+23);
274 err |= __get_user(regs->r24, sc->sc_regs+24); 274 err |= __get_user(regs->r24, sc->sc_regs+24);
275 err |= __get_user(regs->r25, sc->sc_regs+25); 275 err |= __get_user(regs->r25, sc->sc_regs+25);
276 err |= __get_user(regs->r26, sc->sc_regs+26); 276 err |= __get_user(regs->r26, sc->sc_regs+26);
277 err |= __get_user(regs->r27, sc->sc_regs+27); 277 err |= __get_user(regs->r27, sc->sc_regs+27);
278 err |= __get_user(regs->r28, sc->sc_regs+28); 278 err |= __get_user(regs->r28, sc->sc_regs+28);
279 err |= __get_user(regs->gp, sc->sc_regs+29); 279 err |= __get_user(regs->gp, sc->sc_regs+29);
280 err |= __get_user(usp, sc->sc_regs+30); 280 err |= __get_user(usp, sc->sc_regs+30);
281 wrusp(usp); 281 wrusp(usp);
282 282
283 for (i = 0; i < 31; i++) 283 for (i = 0; i < 31; i++)
284 err |= __get_user(sw->fp[i], sc->sc_fpregs+i); 284 err |= __get_user(sw->fp[i], sc->sc_fpregs+i);
285 err |= __get_user(sw->fp[31], &sc->sc_fpcr); 285 err |= __get_user(sw->fp[31], &sc->sc_fpcr);
286 286
287 return err; 287 return err;
288 } 288 }
289 289
290 /* Note that this syscall is also used by setcontext(3) to install 290 /* Note that this syscall is also used by setcontext(3) to install
291 a given sigcontext. This because it's impossible to set *all* 291 a given sigcontext. This because it's impossible to set *all*
292 registers and transfer control from userland. */ 292 registers and transfer control from userland. */
293 293
294 asmlinkage void 294 asmlinkage void
295 do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs, 295 do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs,
296 struct switch_stack *sw) 296 struct switch_stack *sw)
297 { 297 {
298 sigset_t set; 298 sigset_t set;
299 299
300 /* Verify that it's a good sigcontext before using it */ 300 /* Verify that it's a good sigcontext before using it */
301 if (!access_ok(VERIFY_READ, sc, sizeof(*sc))) 301 if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
302 goto give_sigsegv; 302 goto give_sigsegv;
303 if (__get_user(set.sig[0], &sc->sc_mask)) 303 if (__get_user(set.sig[0], &sc->sc_mask))
304 goto give_sigsegv; 304 goto give_sigsegv;
305 305
306 sigdelsetmask(&set, ~_BLOCKABLE); 306 sigdelsetmask(&set, ~_BLOCKABLE);
307 spin_lock_irq(&current->sighand->siglock); 307 spin_lock_irq(&current->sighand->siglock);
308 current->blocked = set; 308 current->blocked = set;
309 recalc_sigpending(); 309 recalc_sigpending();
310 spin_unlock_irq(&current->sighand->siglock); 310 spin_unlock_irq(&current->sighand->siglock);
311 311
312 if (restore_sigcontext(sc, regs, sw)) 312 if (restore_sigcontext(sc, regs, sw))
313 goto give_sigsegv; 313 goto give_sigsegv;
314 314
315 /* Send SIGTRAP if we're single-stepping: */ 315 /* Send SIGTRAP if we're single-stepping: */
316 if (ptrace_cancel_bpt (current)) { 316 if (ptrace_cancel_bpt (current)) {
317 siginfo_t info; 317 siginfo_t info;
318 318
319 info.si_signo = SIGTRAP; 319 info.si_signo = SIGTRAP;
320 info.si_errno = 0; 320 info.si_errno = 0;
321 info.si_code = TRAP_BRKPT; 321 info.si_code = TRAP_BRKPT;
322 info.si_addr = (void __user *) regs->pc; 322 info.si_addr = (void __user *) regs->pc;
323 info.si_trapno = 0; 323 info.si_trapno = 0;
324 send_sig_info(SIGTRAP, &info, current); 324 send_sig_info(SIGTRAP, &info, current);
325 } 325 }
326 return; 326 return;
327 327
328 give_sigsegv: 328 give_sigsegv:
329 force_sig(SIGSEGV, current); 329 force_sig(SIGSEGV, current);
330 } 330 }
331 331
332 asmlinkage void 332 asmlinkage void
333 do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs, 333 do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs,
334 struct switch_stack *sw) 334 struct switch_stack *sw)
335 { 335 {
336 sigset_t set; 336 sigset_t set;
337 337
338 /* Verify that it's a good ucontext_t before using it */ 338 /* Verify that it's a good ucontext_t before using it */
339 if (!access_ok(VERIFY_READ, &frame->uc, sizeof(frame->uc))) 339 if (!access_ok(VERIFY_READ, &frame->uc, sizeof(frame->uc)))
340 goto give_sigsegv; 340 goto give_sigsegv;
341 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 341 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
342 goto give_sigsegv; 342 goto give_sigsegv;
343 343
344 sigdelsetmask(&set, ~_BLOCKABLE); 344 sigdelsetmask(&set, ~_BLOCKABLE);
345 spin_lock_irq(&current->sighand->siglock); 345 spin_lock_irq(&current->sighand->siglock);
346 current->blocked = set; 346 current->blocked = set;
347 recalc_sigpending(); 347 recalc_sigpending();
348 spin_unlock_irq(&current->sighand->siglock); 348 spin_unlock_irq(&current->sighand->siglock);
349 349
350 if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw)) 350 if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw))
351 goto give_sigsegv; 351 goto give_sigsegv;
352 352
353 /* Send SIGTRAP if we're single-stepping: */ 353 /* Send SIGTRAP if we're single-stepping: */
354 if (ptrace_cancel_bpt (current)) { 354 if (ptrace_cancel_bpt (current)) {
355 siginfo_t info; 355 siginfo_t info;
356 356
357 info.si_signo = SIGTRAP; 357 info.si_signo = SIGTRAP;
358 info.si_errno = 0; 358 info.si_errno = 0;
359 info.si_code = TRAP_BRKPT; 359 info.si_code = TRAP_BRKPT;
360 info.si_addr = (void __user *) regs->pc; 360 info.si_addr = (void __user *) regs->pc;
361 info.si_trapno = 0; 361 info.si_trapno = 0;
362 send_sig_info(SIGTRAP, &info, current); 362 send_sig_info(SIGTRAP, &info, current);
363 } 363 }
364 return; 364 return;
365 365
366 give_sigsegv: 366 give_sigsegv:
367 force_sig(SIGSEGV, current); 367 force_sig(SIGSEGV, current);
368 } 368 }
369 369
370 370
371 /* 371 /*
372 * Set up a signal frame. 372 * Set up a signal frame.
373 */ 373 */
374 374
375 static inline void __user * 375 static inline void __user *
376 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) 376 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
377 { 377 {
378 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) 378 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
379 sp = current->sas_ss_sp + current->sas_ss_size; 379 sp = current->sas_ss_sp + current->sas_ss_size;
380 380
381 return (void __user *)((sp - frame_size) & -32ul); 381 return (void __user *)((sp - frame_size) & -32ul);
382 } 382 }
383 383
384 static long 384 static long
385 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 385 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
386 struct switch_stack *sw, unsigned long mask, unsigned long sp) 386 struct switch_stack *sw, unsigned long mask, unsigned long sp)
387 { 387 {
388 long i, err = 0; 388 long i, err = 0;
389 389
390 err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack); 390 err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack);
391 err |= __put_user(mask, &sc->sc_mask); 391 err |= __put_user(mask, &sc->sc_mask);
392 err |= __put_user(regs->pc, &sc->sc_pc); 392 err |= __put_user(regs->pc, &sc->sc_pc);
393 err |= __put_user(8, &sc->sc_ps); 393 err |= __put_user(8, &sc->sc_ps);
394 394
395 err |= __put_user(regs->r0 , sc->sc_regs+0); 395 err |= __put_user(regs->r0 , sc->sc_regs+0);
396 err |= __put_user(regs->r1 , sc->sc_regs+1); 396 err |= __put_user(regs->r1 , sc->sc_regs+1);
397 err |= __put_user(regs->r2 , sc->sc_regs+2); 397 err |= __put_user(regs->r2 , sc->sc_regs+2);
398 err |= __put_user(regs->r3 , sc->sc_regs+3); 398 err |= __put_user(regs->r3 , sc->sc_regs+3);
399 err |= __put_user(regs->r4 , sc->sc_regs+4); 399 err |= __put_user(regs->r4 , sc->sc_regs+4);
400 err |= __put_user(regs->r5 , sc->sc_regs+5); 400 err |= __put_user(regs->r5 , sc->sc_regs+5);
401 err |= __put_user(regs->r6 , sc->sc_regs+6); 401 err |= __put_user(regs->r6 , sc->sc_regs+6);
402 err |= __put_user(regs->r7 , sc->sc_regs+7); 402 err |= __put_user(regs->r7 , sc->sc_regs+7);
403 err |= __put_user(regs->r8 , sc->sc_regs+8); 403 err |= __put_user(regs->r8 , sc->sc_regs+8);
404 err |= __put_user(sw->r9 , sc->sc_regs+9); 404 err |= __put_user(sw->r9 , sc->sc_regs+9);
405 err |= __put_user(sw->r10 , sc->sc_regs+10); 405 err |= __put_user(sw->r10 , sc->sc_regs+10);
406 err |= __put_user(sw->r11 , sc->sc_regs+11); 406 err |= __put_user(sw->r11 , sc->sc_regs+11);
407 err |= __put_user(sw->r12 , sc->sc_regs+12); 407 err |= __put_user(sw->r12 , sc->sc_regs+12);
408 err |= __put_user(sw->r13 , sc->sc_regs+13); 408 err |= __put_user(sw->r13 , sc->sc_regs+13);
409 err |= __put_user(sw->r14 , sc->sc_regs+14); 409 err |= __put_user(sw->r14 , sc->sc_regs+14);
410 err |= __put_user(sw->r15 , sc->sc_regs+15); 410 err |= __put_user(sw->r15 , sc->sc_regs+15);
411 err |= __put_user(regs->r16, sc->sc_regs+16); 411 err |= __put_user(regs->r16, sc->sc_regs+16);
412 err |= __put_user(regs->r17, sc->sc_regs+17); 412 err |= __put_user(regs->r17, sc->sc_regs+17);
413 err |= __put_user(regs->r18, sc->sc_regs+18); 413 err |= __put_user(regs->r18, sc->sc_regs+18);
414 err |= __put_user(regs->r19, sc->sc_regs+19); 414 err |= __put_user(regs->r19, sc->sc_regs+19);
415 err |= __put_user(regs->r20, sc->sc_regs+20); 415 err |= __put_user(regs->r20, sc->sc_regs+20);
416 err |= __put_user(regs->r21, sc->sc_regs+21); 416 err |= __put_user(regs->r21, sc->sc_regs+21);
417 err |= __put_user(regs->r22, sc->sc_regs+22); 417 err |= __put_user(regs->r22, sc->sc_regs+22);
418 err |= __put_user(regs->r23, sc->sc_regs+23); 418 err |= __put_user(regs->r23, sc->sc_regs+23);
419 err |= __put_user(regs->r24, sc->sc_regs+24); 419 err |= __put_user(regs->r24, sc->sc_regs+24);
420 err |= __put_user(regs->r25, sc->sc_regs+25); 420 err |= __put_user(regs->r25, sc->sc_regs+25);
421 err |= __put_user(regs->r26, sc->sc_regs+26); 421 err |= __put_user(regs->r26, sc->sc_regs+26);
422 err |= __put_user(regs->r27, sc->sc_regs+27); 422 err |= __put_user(regs->r27, sc->sc_regs+27);
423 err |= __put_user(regs->r28, sc->sc_regs+28); 423 err |= __put_user(regs->r28, sc->sc_regs+28);
424 err |= __put_user(regs->gp , sc->sc_regs+29); 424 err |= __put_user(regs->gp , sc->sc_regs+29);
425 err |= __put_user(sp, sc->sc_regs+30); 425 err |= __put_user(sp, sc->sc_regs+30);
426 err |= __put_user(0, sc->sc_regs+31); 426 err |= __put_user(0, sc->sc_regs+31);
427 427
428 for (i = 0; i < 31; i++) 428 for (i = 0; i < 31; i++)
429 err |= __put_user(sw->fp[i], sc->sc_fpregs+i); 429 err |= __put_user(sw->fp[i], sc->sc_fpregs+i);
430 err |= __put_user(0, sc->sc_fpregs+31); 430 err |= __put_user(0, sc->sc_fpregs+31);
431 err |= __put_user(sw->fp[31], &sc->sc_fpcr); 431 err |= __put_user(sw->fp[31], &sc->sc_fpcr);
432 432
433 err |= __put_user(regs->trap_a0, &sc->sc_traparg_a0); 433 err |= __put_user(regs->trap_a0, &sc->sc_traparg_a0);
434 err |= __put_user(regs->trap_a1, &sc->sc_traparg_a1); 434 err |= __put_user(regs->trap_a1, &sc->sc_traparg_a1);
435 err |= __put_user(regs->trap_a2, &sc->sc_traparg_a2); 435 err |= __put_user(regs->trap_a2, &sc->sc_traparg_a2);
436 436
437 return err; 437 return err;
438 } 438 }
439 439
440 static void 440 static void
441 setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 441 setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
442 struct pt_regs *regs, struct switch_stack * sw) 442 struct pt_regs *regs, struct switch_stack * sw)
443 { 443 {
444 unsigned long oldsp, r26, err = 0; 444 unsigned long oldsp, r26, err = 0;
445 struct sigframe __user *frame; 445 struct sigframe __user *frame;
446 446
447 oldsp = rdusp(); 447 oldsp = rdusp();
448 frame = get_sigframe(ka, oldsp, sizeof(*frame)); 448 frame = get_sigframe(ka, oldsp, sizeof(*frame));
449 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 449 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
450 goto give_sigsegv; 450 goto give_sigsegv;
451 451
452 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp); 452 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
453 if (err) 453 if (err)
454 goto give_sigsegv; 454 goto give_sigsegv;
455 455
456 /* Set up to return from userspace. If provided, use a stub 456 /* Set up to return from userspace. If provided, use a stub
457 already in userspace. */ 457 already in userspace. */
458 if (ka->ka_restorer) { 458 if (ka->ka_restorer) {
459 r26 = (unsigned long) ka->ka_restorer; 459 r26 = (unsigned long) ka->ka_restorer;
460 } else { 460 } else {
461 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0); 461 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
462 err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1); 462 err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1);
463 err |= __put_user(INSN_CALLSYS, frame->retcode+2); 463 err |= __put_user(INSN_CALLSYS, frame->retcode+2);
464 imb(); 464 imb();
465 r26 = (unsigned long) frame->retcode; 465 r26 = (unsigned long) frame->retcode;
466 } 466 }
467 467
468 /* Check that everything was written properly. */ 468 /* Check that everything was written properly. */
469 if (err) 469 if (err)
470 goto give_sigsegv; 470 goto give_sigsegv;
471 471
472 /* "Return" to the handler */ 472 /* "Return" to the handler */
473 regs->r26 = r26; 473 regs->r26 = r26;
474 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler; 474 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
475 regs->r16 = sig; /* a0: signal number */ 475 regs->r16 = sig; /* a0: signal number */
476 regs->r17 = 0; /* a1: exception code */ 476 regs->r17 = 0; /* a1: exception code */
477 regs->r18 = (unsigned long) &frame->sc; /* a2: sigcontext pointer */ 477 regs->r18 = (unsigned long) &frame->sc; /* a2: sigcontext pointer */
478 wrusp((unsigned long) frame); 478 wrusp((unsigned long) frame);
479 479
480 #if DEBUG_SIG 480 #if DEBUG_SIG
481 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 481 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
482 current->comm, current->pid, frame, regs->pc, regs->r26); 482 current->comm, current->pid, frame, regs->pc, regs->r26);
483 #endif 483 #endif
484 484
485 return; 485 return;
486 486
487 give_sigsegv: 487 give_sigsegv:
488 force_sigsegv(sig, current); 488 force_sigsegv(sig, current);
489 } 489 }
490 490
491 static void 491 static void
492 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 492 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
493 sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) 493 sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
494 { 494 {
495 unsigned long oldsp, r26, err = 0; 495 unsigned long oldsp, r26, err = 0;
496 struct rt_sigframe __user *frame; 496 struct rt_sigframe __user *frame;
497 497
498 oldsp = rdusp(); 498 oldsp = rdusp();
499 frame = get_sigframe(ka, oldsp, sizeof(*frame)); 499 frame = get_sigframe(ka, oldsp, sizeof(*frame));
500 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 500 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
501 goto give_sigsegv; 501 goto give_sigsegv;
502 502
503 err |= copy_siginfo_to_user(&frame->info, info); 503 err |= copy_siginfo_to_user(&frame->info, info);
504 504
505 /* Create the ucontext. */ 505 /* Create the ucontext. */
506 err |= __put_user(0, &frame->uc.uc_flags); 506 err |= __put_user(0, &frame->uc.uc_flags);
507 err |= __put_user(0, &frame->uc.uc_link); 507 err |= __put_user(0, &frame->uc.uc_link);
508 err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask); 508 err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask);
509 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 509 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
510 err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags); 510 err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags);
511 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 511 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
512 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw, 512 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw,
513 set->sig[0], oldsp); 513 set->sig[0], oldsp);
514 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 514 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
515 if (err) 515 if (err)
516 goto give_sigsegv; 516 goto give_sigsegv;
517 517
518 /* Set up to return from userspace. If provided, use a stub 518 /* Set up to return from userspace. If provided, use a stub
519 already in userspace. */ 519 already in userspace. */
520 if (ka->ka_restorer) { 520 if (ka->ka_restorer) {
521 r26 = (unsigned long) ka->ka_restorer; 521 r26 = (unsigned long) ka->ka_restorer;
522 } else { 522 } else {
523 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0); 523 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
524 err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn, 524 err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn,
525 frame->retcode+1); 525 frame->retcode+1);
526 err |= __put_user(INSN_CALLSYS, frame->retcode+2); 526 err |= __put_user(INSN_CALLSYS, frame->retcode+2);
527 imb(); 527 imb();
528 r26 = (unsigned long) frame->retcode; 528 r26 = (unsigned long) frame->retcode;
529 } 529 }
530 530
531 if (err) 531 if (err)
532 goto give_sigsegv; 532 goto give_sigsegv;
533 533
534 /* "Return" to the handler */ 534 /* "Return" to the handler */
535 regs->r26 = r26; 535 regs->r26 = r26;
536 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler; 536 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
537 regs->r16 = sig; /* a0: signal number */ 537 regs->r16 = sig; /* a0: signal number */
538 regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */ 538 regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */
539 regs->r18 = (unsigned long) &frame->uc; /* a2: ucontext pointer */ 539 regs->r18 = (unsigned long) &frame->uc; /* a2: ucontext pointer */
540 wrusp((unsigned long) frame); 540 wrusp((unsigned long) frame);
541 541
542 #if DEBUG_SIG 542 #if DEBUG_SIG
543 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 543 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
544 current->comm, current->pid, frame, regs->pc, regs->r26); 544 current->comm, current->pid, frame, regs->pc, regs->r26);
545 #endif 545 #endif
546 546
547 return; 547 return;
548 548
549 give_sigsegv: 549 give_sigsegv:
550 force_sigsegv(sig, current); 550 force_sigsegv(sig, current);
551 } 551 }
552 552
553 553
554 /* 554 /*
555 * OK, we're invoking a handler. 555 * OK, we're invoking a handler.
556 */ 556 */
557 static inline void 557 static inline void
558 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 558 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
559 sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) 559 sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
560 { 560 {
561 if (ka->sa.sa_flags & SA_SIGINFO) 561 if (ka->sa.sa_flags & SA_SIGINFO)
562 setup_rt_frame(sig, ka, info, oldset, regs, sw); 562 setup_rt_frame(sig, ka, info, oldset, regs, sw);
563 else 563 else
564 setup_frame(sig, ka, oldset, regs, sw); 564 setup_frame(sig, ka, oldset, regs, sw);
565 565
566 if (ka->sa.sa_flags & SA_RESETHAND) 566 if (ka->sa.sa_flags & SA_RESETHAND)
567 ka->sa.sa_handler = SIG_DFL; 567 ka->sa.sa_handler = SIG_DFL;
568 568
569 spin_lock_irq(&current->sighand->siglock); 569 spin_lock_irq(&current->sighand->siglock);
570 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 570 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
571 if (!(ka->sa.sa_flags & SA_NODEFER)) 571 if (!(ka->sa.sa_flags & SA_NODEFER))
572 sigaddset(&current->blocked,sig); 572 sigaddset(&current->blocked,sig);
573 recalc_sigpending(); 573 recalc_sigpending();
574 spin_unlock_irq(&current->sighand->siglock); 574 spin_unlock_irq(&current->sighand->siglock);
575 } 575 }
576 576
577 static inline void 577 static inline void
578 syscall_restart(unsigned long r0, unsigned long r19, 578 syscall_restart(unsigned long r0, unsigned long r19,
579 struct pt_regs *regs, struct k_sigaction *ka) 579 struct pt_regs *regs, struct k_sigaction *ka)
580 { 580 {
581 switch (regs->r0) { 581 switch (regs->r0) {
582 case ERESTARTSYS: 582 case ERESTARTSYS:
583 if (!(ka->sa.sa_flags & SA_RESTART)) { 583 if (!(ka->sa.sa_flags & SA_RESTART)) {
584 case ERESTARTNOHAND: 584 case ERESTARTNOHAND:
585 regs->r0 = EINTR; 585 regs->r0 = EINTR;
586 break; 586 break;
587 } 587 }
588 /* fallthrough */ 588 /* fallthrough */
589 case ERESTARTNOINTR: 589 case ERESTARTNOINTR:
590 regs->r0 = r0; /* reset v0 and a3 and replay syscall */ 590 regs->r0 = r0; /* reset v0 and a3 and replay syscall */
591 regs->r19 = r19; 591 regs->r19 = r19;
592 regs->pc -= 4; 592 regs->pc -= 4;
593 break; 593 break;
594 case ERESTART_RESTARTBLOCK: 594 case ERESTART_RESTARTBLOCK:
595 current_thread_info()->restart_block.fn = do_no_restart_syscall; 595 current_thread_info()->restart_block.fn = do_no_restart_syscall;
596 regs->r0 = EINTR; 596 regs->r0 = EINTR;
597 break; 597 break;
598 } 598 }
599 } 599 }
600 600
601 601
602 /* 602 /*
603 * Note that 'init' is a special process: it doesn't get signals it doesn't 603 * Note that 'init' is a special process: it doesn't get signals it doesn't
604 * want to handle. Thus you cannot kill init even with a SIGKILL even by 604 * want to handle. Thus you cannot kill init even with a SIGKILL even by
605 * mistake. 605 * mistake.
606 * 606 *
607 * Note that we go through the signals twice: once to check the signals that 607 * Note that we go through the signals twice: once to check the signals that
608 * the kernel can handle, and then we build all the user-level signal handling 608 * the kernel can handle, and then we build all the user-level signal handling
609 * stack-frames in one go after that. 609 * stack-frames in one go after that.
610 * 610 *
611 * "r0" and "r19" are the registers we need to restore for system call 611 * "r0" and "r19" are the registers we need to restore for system call
612 * restart. "r0" is also used as an indicator whether we can restart at 612 * restart. "r0" is also used as an indicator whether we can restart at
613 * all (if we get here from anything but a syscall return, it will be 0) 613 * all (if we get here from anything but a syscall return, it will be 0)
614 */ 614 */
615 static int 615 static int
616 do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, 616 do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
617 unsigned long r0, unsigned long r19) 617 unsigned long r0, unsigned long r19)
618 { 618 {
619 siginfo_t info; 619 siginfo_t info;
620 int signr; 620 int signr;
621 unsigned long single_stepping = ptrace_cancel_bpt(current); 621 unsigned long single_stepping = ptrace_cancel_bpt(current);
622 struct k_sigaction ka; 622 struct k_sigaction ka;
623 623
624 if (!oldset) 624 if (!oldset)
625 oldset = &current->blocked; 625 oldset = &current->blocked;
626 626
627 /* This lets the debugger run, ... */ 627 /* This lets the debugger run, ... */
628 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 628 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
629 /* ... so re-check the single stepping. */ 629 /* ... so re-check the single stepping. */
630 single_stepping |= ptrace_cancel_bpt(current); 630 single_stepping |= ptrace_cancel_bpt(current);
631 631
632 if (signr > 0) { 632 if (signr > 0) {
633 /* Whee! Actually deliver the signal. */ 633 /* Whee! Actually deliver the signal. */
634 if (r0) syscall_restart(r0, r19, regs, &ka); 634 if (r0) syscall_restart(r0, r19, regs, &ka);
635 handle_signal(signr, &ka, &info, oldset, regs, sw); 635 handle_signal(signr, &ka, &info, oldset, regs, sw);
636 if (single_stepping) 636 if (single_stepping)
637 ptrace_set_bpt(current); /* re-set bpt */ 637 ptrace_set_bpt(current); /* re-set bpt */
638 return 1; 638 return 1;
639 } 639 }
640 640
641 if (r0) { 641 if (r0) {
642 switch (regs->r0) { 642 switch (regs->r0) {
643 case ERESTARTNOHAND: 643 case ERESTARTNOHAND:
644 case ERESTARTSYS: 644 case ERESTARTSYS:
645 case ERESTARTNOINTR: 645 case ERESTARTNOINTR:
646 /* Reset v0 and a3 and replay syscall. */ 646 /* Reset v0 and a3 and replay syscall. */
647 regs->r0 = r0; 647 regs->r0 = r0;
648 regs->r19 = r19; 648 regs->r19 = r19;
649 regs->pc -= 4; 649 regs->pc -= 4;
650 break; 650 break;
651 case ERESTART_RESTARTBLOCK: 651 case ERESTART_RESTARTBLOCK:
652 /* Force v0 to the restart syscall and reply. */ 652 /* Force v0 to the restart syscall and reply. */
653 regs->r0 = __NR_restart_syscall; 653 regs->r0 = __NR_restart_syscall;
654 regs->pc -= 4; 654 regs->pc -= 4;
655 break; 655 break;
656 } 656 }
657 } 657 }
658 if (single_stepping) 658 if (single_stepping)
659 ptrace_set_bpt(current); /* re-set breakpoint */ 659 ptrace_set_bpt(current); /* re-set breakpoint */
660 660
661 return 0; 661 return 0;
662 } 662 }
663 663
664 void 664 void
665 do_notify_resume(sigset_t *oldset, struct pt_regs *regs, 665 do_notify_resume(sigset_t *oldset, struct pt_regs *regs,
666 struct switch_stack *sw, unsigned long r0, 666 struct switch_stack *sw, unsigned long r0,
667 unsigned long r19, unsigned long thread_info_flags) 667 unsigned long r19, unsigned long thread_info_flags)
668 { 668 {
669 if (thread_info_flags & _TIF_SIGPENDING) 669 if (thread_info_flags & _TIF_SIGPENDING)
670 do_signal(oldset, regs, sw, r0, r19); 670 do_signal(oldset, regs, sw, r0, r19);
671 } 671 }
672 672
arch/frv/kernel/signal.c
1 /* signal.c: FRV specific bits of signal handling 1 /* signal.c: FRV specific bits of signal handling
2 * 2 *
3 * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * - Derived from arch/m68k/kernel/signal.c 5 * - Derived from arch/m68k/kernel/signal.c
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 12
13 #include <linux/sched.h> 13 #include <linux/sched.h>
14 #include <linux/mm.h> 14 #include <linux/mm.h>
15 #include <linux/smp.h> 15 #include <linux/smp.h>
16 #include <linux/smp_lock.h> 16 #include <linux/smp_lock.h>
17 #include <linux/kernel.h> 17 #include <linux/kernel.h>
18 #include <linux/signal.h> 18 #include <linux/signal.h>
19 #include <linux/errno.h> 19 #include <linux/errno.h>
20 #include <linux/wait.h> 20 #include <linux/wait.h>
21 #include <linux/ptrace.h> 21 #include <linux/ptrace.h>
22 #include <linux/unistd.h> 22 #include <linux/unistd.h>
23 #include <linux/personality.h> 23 #include <linux/personality.h>
24 #include <linux/suspend.h> 24 #include <linux/suspend.h>
25 #include <asm/ucontext.h> 25 #include <asm/ucontext.h>
26 #include <asm/uaccess.h> 26 #include <asm/uaccess.h>
27 #include <asm/cacheflush.h> 27 #include <asm/cacheflush.h>
28 28
29 #define DEBUG_SIG 0 29 #define DEBUG_SIG 0
30 30
31 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 31 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
32 32
33 struct fdpic_func_descriptor { 33 struct fdpic_func_descriptor {
34 unsigned long text; 34 unsigned long text;
35 unsigned long GOT; 35 unsigned long GOT;
36 }; 36 };
37 37
38 /* 38 /*
39 * Atomically swap in the new signal mask, and wait for a signal. 39 * Atomically swap in the new signal mask, and wait for a signal.
40 */ 40 */
41 asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask) 41 asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
42 { 42 {
43 mask &= _BLOCKABLE; 43 mask &= _BLOCKABLE;
44 spin_lock_irq(&current->sighand->siglock); 44 spin_lock_irq(&current->sighand->siglock);
45 current->saved_sigmask = current->blocked; 45 current->saved_sigmask = current->blocked;
46 siginitset(&current->blocked, mask); 46 siginitset(&current->blocked, mask);
47 recalc_sigpending(); 47 recalc_sigpending();
48 spin_unlock_irq(&current->sighand->siglock); 48 spin_unlock_irq(&current->sighand->siglock);
49 49
50 current->state = TASK_INTERRUPTIBLE; 50 current->state = TASK_INTERRUPTIBLE;
51 schedule(); 51 schedule();
52 set_thread_flag(TIF_RESTORE_SIGMASK); 52 set_thread_flag(TIF_RESTORE_SIGMASK);
53 return -ERESTARTNOHAND; 53 return -ERESTARTNOHAND;
54 } 54 }
55 55
56 asmlinkage int sys_sigaction(int sig, 56 asmlinkage int sys_sigaction(int sig,
57 const struct old_sigaction __user *act, 57 const struct old_sigaction __user *act,
58 struct old_sigaction __user *oact) 58 struct old_sigaction __user *oact)
59 { 59 {
60 struct k_sigaction new_ka, old_ka; 60 struct k_sigaction new_ka, old_ka;
61 int ret; 61 int ret;
62 62
63 if (act) { 63 if (act) {
64 old_sigset_t mask; 64 old_sigset_t mask;
65 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 65 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
66 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 66 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
67 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 67 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
68 return -EFAULT; 68 return -EFAULT;
69 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 69 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
70 __get_user(mask, &act->sa_mask); 70 __get_user(mask, &act->sa_mask);
71 siginitset(&new_ka.sa.sa_mask, mask); 71 siginitset(&new_ka.sa.sa_mask, mask);
72 } 72 }
73 73
74 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 74 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
75 75
76 if (!ret && oact) { 76 if (!ret && oact) {
77 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 77 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
78 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 78 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
79 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 79 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
80 return -EFAULT; 80 return -EFAULT;
81 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 81 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
82 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 82 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
83 } 83 }
84 84
85 return ret; 85 return ret;
86 } 86 }
87 87
88 asmlinkage 88 asmlinkage
89 int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) 89 int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
90 { 90 {
91 return do_sigaltstack(uss, uoss, __frame->sp); 91 return do_sigaltstack(uss, uoss, __frame->sp);
92 } 92 }
93 93
94 94
95 /* 95 /*
96 * Do a signal return; undo the signal stack. 96 * Do a signal return; undo the signal stack.
97 */ 97 */
98 98
99 struct sigframe 99 struct sigframe
100 { 100 {
101 __sigrestore_t pretcode; 101 __sigrestore_t pretcode;
102 int sig; 102 int sig;
103 struct sigcontext sc; 103 struct sigcontext sc;
104 unsigned long extramask[_NSIG_WORDS-1]; 104 unsigned long extramask[_NSIG_WORDS-1];
105 uint32_t retcode[2]; 105 uint32_t retcode[2];
106 }; 106 };
107 107
108 struct rt_sigframe 108 struct rt_sigframe
109 { 109 {
110 __sigrestore_t pretcode; 110 __sigrestore_t pretcode;
111 int sig; 111 int sig;
112 struct siginfo __user *pinfo; 112 struct siginfo __user *pinfo;
113 void __user *puc; 113 void __user *puc;
114 struct siginfo info; 114 struct siginfo info;
115 struct ucontext uc; 115 struct ucontext uc;
116 uint32_t retcode[2]; 116 uint32_t retcode[2];
117 }; 117 };
118 118
119 static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8) 119 static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8)
120 { 120 {
121 struct user_context *user = current->thread.user; 121 struct user_context *user = current->thread.user;
122 unsigned long tbr, psr; 122 unsigned long tbr, psr;
123 123
124 tbr = user->i.tbr; 124 tbr = user->i.tbr;
125 psr = user->i.psr; 125 psr = user->i.psr;
126 if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context))) 126 if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context)))
127 goto badframe; 127 goto badframe;
128 user->i.tbr = tbr; 128 user->i.tbr = tbr;
129 user->i.psr = psr; 129 user->i.psr = psr;
130 130
131 restore_user_regs(user); 131 restore_user_regs(user);
132 132
133 user->i.syscallno = -1; /* disable syscall checks */ 133 user->i.syscallno = -1; /* disable syscall checks */
134 134
135 *_gr8 = user->i.gr[8]; 135 *_gr8 = user->i.gr[8];
136 return 0; 136 return 0;
137 137
138 badframe: 138 badframe:
139 return 1; 139 return 1;
140 } 140 }
141 141
142 asmlinkage int sys_sigreturn(void) 142 asmlinkage int sys_sigreturn(void)
143 { 143 {
144 struct sigframe __user *frame = (struct sigframe __user *) __frame->sp; 144 struct sigframe __user *frame = (struct sigframe __user *) __frame->sp;
145 sigset_t set; 145 sigset_t set;
146 int gr8; 146 int gr8;
147 147
148 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 148 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
149 goto badframe; 149 goto badframe;
150 if (__get_user(set.sig[0], &frame->sc.sc_oldmask)) 150 if (__get_user(set.sig[0], &frame->sc.sc_oldmask))
151 goto badframe; 151 goto badframe;
152 152
153 if (_NSIG_WORDS > 1 && 153 if (_NSIG_WORDS > 1 &&
154 __copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask))) 154 __copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask)))
155 goto badframe; 155 goto badframe;
156 156
157 sigdelsetmask(&set, ~_BLOCKABLE); 157 sigdelsetmask(&set, ~_BLOCKABLE);
158 spin_lock_irq(&current->sighand->siglock); 158 spin_lock_irq(&current->sighand->siglock);
159 current->blocked = set; 159 current->blocked = set;
160 recalc_sigpending(); 160 recalc_sigpending();
161 spin_unlock_irq(&current->sighand->siglock); 161 spin_unlock_irq(&current->sighand->siglock);
162 162
163 if (restore_sigcontext(&frame->sc, &gr8)) 163 if (restore_sigcontext(&frame->sc, &gr8))
164 goto badframe; 164 goto badframe;
165 return gr8; 165 return gr8;
166 166
167 badframe: 167 badframe:
168 force_sig(SIGSEGV, current); 168 force_sig(SIGSEGV, current);
169 return 0; 169 return 0;
170 } 170 }
171 171
172 asmlinkage int sys_rt_sigreturn(void) 172 asmlinkage int sys_rt_sigreturn(void)
173 { 173 {
174 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) __frame->sp; 174 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) __frame->sp;
175 sigset_t set; 175 sigset_t set;
176 int gr8; 176 int gr8;
177 177
178 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 178 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
179 goto badframe; 179 goto badframe;
180 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 180 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
181 goto badframe; 181 goto badframe;
182 182
183 sigdelsetmask(&set, ~_BLOCKABLE); 183 sigdelsetmask(&set, ~_BLOCKABLE);
184 spin_lock_irq(&current->sighand->siglock); 184 spin_lock_irq(&current->sighand->siglock);
185 current->blocked = set; 185 current->blocked = set;
186 recalc_sigpending(); 186 recalc_sigpending();
187 spin_unlock_irq(&current->sighand->siglock); 187 spin_unlock_irq(&current->sighand->siglock);
188 188
189 if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8)) 189 if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8))
190 goto badframe; 190 goto badframe;
191 191
192 if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT) 192 if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT)
193 goto badframe; 193 goto badframe;
194 194
195 return gr8; 195 return gr8;
196 196
197 badframe: 197 badframe:
198 force_sig(SIGSEGV, current); 198 force_sig(SIGSEGV, current);
199 return 0; 199 return 0;
200 } 200 }
201 201
202 /* 202 /*
203 * Set up a signal frame 203 * Set up a signal frame
204 */ 204 */
205 static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask) 205 static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
206 { 206 {
207 save_user_regs(current->thread.user); 207 save_user_regs(current->thread.user);
208 208
209 if (copy_to_user(&sc->sc_context, current->thread.user, sizeof(sc->sc_context)) != 0) 209 if (copy_to_user(&sc->sc_context, current->thread.user, sizeof(sc->sc_context)) != 0)
210 goto badframe; 210 goto badframe;
211 211
212 /* non-iBCS2 extensions.. */ 212 /* non-iBCS2 extensions.. */
213 if (__put_user(mask, &sc->sc_oldmask) < 0) 213 if (__put_user(mask, &sc->sc_oldmask) < 0)
214 goto badframe; 214 goto badframe;
215 215
216 return 0; 216 return 0;
217 217
218 badframe: 218 badframe:
219 return 1; 219 return 1;
220 } 220 }
221 221
222 /*****************************************************************************/ 222 /*****************************************************************************/
223 /* 223 /*
224 * Determine which stack to use.. 224 * Determine which stack to use..
225 */ 225 */
226 static inline void __user *get_sigframe(struct k_sigaction *ka, 226 static inline void __user *get_sigframe(struct k_sigaction *ka,
227 size_t frame_size) 227 size_t frame_size)
228 { 228 {
229 unsigned long sp; 229 unsigned long sp;
230 230
231 /* Default to using normal stack */ 231 /* Default to using normal stack */
232 sp = __frame->sp; 232 sp = __frame->sp;
233 233
234 /* This is the X/Open sanctioned signal stack switching. */ 234 /* This is the X/Open sanctioned signal stack switching. */
235 if (ka->sa.sa_flags & SA_ONSTACK) { 235 if (ka->sa.sa_flags & SA_ONSTACK) {
236 if (! on_sig_stack(sp)) 236 if (! sas_ss_flags(sp))
237 sp = current->sas_ss_sp + current->sas_ss_size; 237 sp = current->sas_ss_sp + current->sas_ss_size;
238 } 238 }
239 239
240 return (void __user *) ((sp - frame_size) & ~7UL); 240 return (void __user *) ((sp - frame_size) & ~7UL);
241 241
242 } /* end get_sigframe() */ 242 } /* end get_sigframe() */
243 243
244 /*****************************************************************************/ 244 /*****************************************************************************/
245 /* 245 /*
246 * 246 *
247 */ 247 */
248 static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) 248 static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
249 { 249 {
250 struct sigframe __user *frame; 250 struct sigframe __user *frame;
251 int rsig; 251 int rsig;
252 252
253 frame = get_sigframe(ka, sizeof(*frame)); 253 frame = get_sigframe(ka, sizeof(*frame));
254 254
255 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 255 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
256 goto give_sigsegv; 256 goto give_sigsegv;
257 257
258 rsig = sig; 258 rsig = sig;
259 if (sig < 32 && 259 if (sig < 32 &&
260 __current_thread_info->exec_domain && 260 __current_thread_info->exec_domain &&
261 __current_thread_info->exec_domain->signal_invmap) 261 __current_thread_info->exec_domain->signal_invmap)
262 rsig = __current_thread_info->exec_domain->signal_invmap[sig]; 262 rsig = __current_thread_info->exec_domain->signal_invmap[sig];
263 263
264 if (__put_user(rsig, &frame->sig) < 0) 264 if (__put_user(rsig, &frame->sig) < 0)
265 goto give_sigsegv; 265 goto give_sigsegv;
266 266
267 if (setup_sigcontext(&frame->sc, set->sig[0])) 267 if (setup_sigcontext(&frame->sc, set->sig[0]))
268 goto give_sigsegv; 268 goto give_sigsegv;
269 269
270 if (_NSIG_WORDS > 1) { 270 if (_NSIG_WORDS > 1) {
271 if (__copy_to_user(frame->extramask, &set->sig[1], 271 if (__copy_to_user(frame->extramask, &set->sig[1],
272 sizeof(frame->extramask))) 272 sizeof(frame->extramask)))
273 goto give_sigsegv; 273 goto give_sigsegv;
274 } 274 }
275 275
276 /* Set up to return from userspace. If provided, use a stub 276 /* Set up to return from userspace. If provided, use a stub
277 * already in userspace. */ 277 * already in userspace. */
278 if (ka->sa.sa_flags & SA_RESTORER) { 278 if (ka->sa.sa_flags & SA_RESTORER) {
279 if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0) 279 if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0)
280 goto give_sigsegv; 280 goto give_sigsegv;
281 } 281 }
282 else { 282 else {
283 /* Set up the following code on the stack: 283 /* Set up the following code on the stack:
284 * setlos #__NR_sigreturn,gr7 284 * setlos #__NR_sigreturn,gr7
285 * tira gr0,0 285 * tira gr0,0
286 */ 286 */
287 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || 287 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
288 __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) || 288 __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
289 __put_user(0xc0700000, &frame->retcode[1])) 289 __put_user(0xc0700000, &frame->retcode[1]))
290 goto give_sigsegv; 290 goto give_sigsegv;
291 291
292 flush_icache_range((unsigned long) frame->retcode, 292 flush_icache_range((unsigned long) frame->retcode,
293 (unsigned long) (frame->retcode + 2)); 293 (unsigned long) (frame->retcode + 2));
294 } 294 }
295 295
296 /* set up registers for signal handler */ 296 /* set up registers for signal handler */
297 __frame->sp = (unsigned long) frame; 297 __frame->sp = (unsigned long) frame;
298 __frame->lr = (unsigned long) &frame->retcode; 298 __frame->lr = (unsigned long) &frame->retcode;
299 __frame->gr8 = sig; 299 __frame->gr8 = sig;
300 300
301 if (get_personality & FDPIC_FUNCPTRS) { 301 if (get_personality & FDPIC_FUNCPTRS) {
302 struct fdpic_func_descriptor __user *funcptr = 302 struct fdpic_func_descriptor __user *funcptr =
303 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 303 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
304 __get_user(__frame->pc, &funcptr->text); 304 __get_user(__frame->pc, &funcptr->text);
305 __get_user(__frame->gr15, &funcptr->GOT); 305 __get_user(__frame->gr15, &funcptr->GOT);
306 } else { 306 } else {
307 __frame->pc = (unsigned long) ka->sa.sa_handler; 307 __frame->pc = (unsigned long) ka->sa.sa_handler;
308 __frame->gr15 = 0; 308 __frame->gr15 = 0;
309 } 309 }
310 310
311 set_fs(USER_DS); 311 set_fs(USER_DS);
312 312
313 /* the tracer may want to single-step inside the handler */ 313 /* the tracer may want to single-step inside the handler */
314 if (test_thread_flag(TIF_SINGLESTEP)) 314 if (test_thread_flag(TIF_SINGLESTEP))
315 ptrace_notify(SIGTRAP); 315 ptrace_notify(SIGTRAP);
316 316
317 #if DEBUG_SIG 317 #if DEBUG_SIG
318 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 318 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
319 sig, current->comm, current->pid, frame, __frame->pc, 319 sig, current->comm, current->pid, frame, __frame->pc,
320 frame->pretcode); 320 frame->pretcode);
321 #endif 321 #endif
322 322
323 return 0; 323 return 0;
324 324
325 give_sigsegv: 325 give_sigsegv:
326 force_sig(SIGSEGV, current); 326 force_sig(SIGSEGV, current);
327 return -EFAULT; 327 return -EFAULT;
328 328
329 } /* end setup_frame() */ 329 } /* end setup_frame() */
330 330
331 /*****************************************************************************/ 331 /*****************************************************************************/
332 /* 332 /*
333 * 333 *
334 */ 334 */
335 static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 335 static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
336 sigset_t *set) 336 sigset_t *set)
337 { 337 {
338 struct rt_sigframe __user *frame; 338 struct rt_sigframe __user *frame;
339 int rsig; 339 int rsig;
340 340
341 frame = get_sigframe(ka, sizeof(*frame)); 341 frame = get_sigframe(ka, sizeof(*frame));
342 342
343 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 343 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
344 goto give_sigsegv; 344 goto give_sigsegv;
345 345
346 rsig = sig; 346 rsig = sig;
347 if (sig < 32 && 347 if (sig < 32 &&
348 __current_thread_info->exec_domain && 348 __current_thread_info->exec_domain &&
349 __current_thread_info->exec_domain->signal_invmap) 349 __current_thread_info->exec_domain->signal_invmap)
350 rsig = __current_thread_info->exec_domain->signal_invmap[sig]; 350 rsig = __current_thread_info->exec_domain->signal_invmap[sig];
351 351
352 if (__put_user(rsig, &frame->sig) || 352 if (__put_user(rsig, &frame->sig) ||
353 __put_user(&frame->info, &frame->pinfo) || 353 __put_user(&frame->info, &frame->pinfo) ||
354 __put_user(&frame->uc, &frame->puc)) 354 __put_user(&frame->uc, &frame->puc))
355 goto give_sigsegv; 355 goto give_sigsegv;
356 356
357 if (copy_siginfo_to_user(&frame->info, info)) 357 if (copy_siginfo_to_user(&frame->info, info))
358 goto give_sigsegv; 358 goto give_sigsegv;
359 359
360 /* Create the ucontext. */ 360 /* Create the ucontext. */
361 if (__put_user(0, &frame->uc.uc_flags) || 361 if (__put_user(0, &frame->uc.uc_flags) ||
362 __put_user(NULL, &frame->uc.uc_link) || 362 __put_user(NULL, &frame->uc.uc_link) ||
363 __put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || 363 __put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
364 __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) || 364 __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
365 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size)) 365 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
366 goto give_sigsegv; 366 goto give_sigsegv;
367 367
368 if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0])) 368 if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
369 goto give_sigsegv; 369 goto give_sigsegv;
370 370
371 if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) 371 if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
372 goto give_sigsegv; 372 goto give_sigsegv;
373 373
374 /* Set up to return from userspace. If provided, use a stub 374 /* Set up to return from userspace. If provided, use a stub
375 * already in userspace. */ 375 * already in userspace. */
376 if (ka->sa.sa_flags & SA_RESTORER) { 376 if (ka->sa.sa_flags & SA_RESTORER) {
377 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 377 if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
378 goto give_sigsegv; 378 goto give_sigsegv;
379 } 379 }
380 else { 380 else {
381 /* Set up the following code on the stack: 381 /* Set up the following code on the stack:
382 * setlos #__NR_sigreturn,gr7 382 * setlos #__NR_sigreturn,gr7
383 * tira gr0,0 383 * tira gr0,0
384 */ 384 */
385 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || 385 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
386 __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) || 386 __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
387 __put_user(0xc0700000, &frame->retcode[1])) 387 __put_user(0xc0700000, &frame->retcode[1]))
388 goto give_sigsegv; 388 goto give_sigsegv;
389 389
390 flush_icache_range((unsigned long) frame->retcode, 390 flush_icache_range((unsigned long) frame->retcode,
391 (unsigned long) (frame->retcode + 2)); 391 (unsigned long) (frame->retcode + 2));
392 } 392 }
393 393
394 /* Set up registers for signal handler */ 394 /* Set up registers for signal handler */
395 __frame->sp = (unsigned long) frame; 395 __frame->sp = (unsigned long) frame;
396 __frame->lr = (unsigned long) &frame->retcode; 396 __frame->lr = (unsigned long) &frame->retcode;
397 __frame->gr8 = sig; 397 __frame->gr8 = sig;
398 __frame->gr9 = (unsigned long) &frame->info; 398 __frame->gr9 = (unsigned long) &frame->info;
399 399
400 if (get_personality & FDPIC_FUNCPTRS) { 400 if (get_personality & FDPIC_FUNCPTRS) {
401 struct fdpic_func_descriptor __user *funcptr = 401 struct fdpic_func_descriptor __user *funcptr =
402 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 402 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
403 __get_user(__frame->pc, &funcptr->text); 403 __get_user(__frame->pc, &funcptr->text);
404 __get_user(__frame->gr15, &funcptr->GOT); 404 __get_user(__frame->gr15, &funcptr->GOT);
405 } else { 405 } else {
406 __frame->pc = (unsigned long) ka->sa.sa_handler; 406 __frame->pc = (unsigned long) ka->sa.sa_handler;
407 __frame->gr15 = 0; 407 __frame->gr15 = 0;
408 } 408 }
409 409
410 set_fs(USER_DS); 410 set_fs(USER_DS);
411 411
412 /* the tracer may want to single-step inside the handler */ 412 /* the tracer may want to single-step inside the handler */
413 if (test_thread_flag(TIF_SINGLESTEP)) 413 if (test_thread_flag(TIF_SINGLESTEP))
414 ptrace_notify(SIGTRAP); 414 ptrace_notify(SIGTRAP);
415 415
416 #if DEBUG_SIG 416 #if DEBUG_SIG
417 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 417 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
418 sig, current->comm, current->pid, frame, __frame->pc, 418 sig, current->comm, current->pid, frame, __frame->pc,
419 frame->pretcode); 419 frame->pretcode);
420 #endif 420 #endif
421 421
422 return 0; 422 return 0;
423 423
424 give_sigsegv: 424 give_sigsegv:
425 force_sig(SIGSEGV, current); 425 force_sig(SIGSEGV, current);
426 return -EFAULT; 426 return -EFAULT;
427 427
428 } /* end setup_rt_frame() */ 428 } /* end setup_rt_frame() */
429 429
430 /*****************************************************************************/ 430 /*****************************************************************************/
431 /* 431 /*
432 * OK, we're invoking a handler 432 * OK, we're invoking a handler
433 */ 433 */
434 static int handle_signal(unsigned long sig, siginfo_t *info, 434 static int handle_signal(unsigned long sig, siginfo_t *info,
435 struct k_sigaction *ka, sigset_t *oldset) 435 struct k_sigaction *ka, sigset_t *oldset)
436 { 436 {
437 int ret; 437 int ret;
438 438
439 /* Are we from a system call? */ 439 /* Are we from a system call? */
440 if (in_syscall(__frame)) { 440 if (in_syscall(__frame)) {
441 /* If so, check system call restarting.. */ 441 /* If so, check system call restarting.. */
442 switch (__frame->gr8) { 442 switch (__frame->gr8) {
443 case -ERESTART_RESTARTBLOCK: 443 case -ERESTART_RESTARTBLOCK:
444 case -ERESTARTNOHAND: 444 case -ERESTARTNOHAND:
445 __frame->gr8 = -EINTR; 445 __frame->gr8 = -EINTR;
446 break; 446 break;
447 447
448 case -ERESTARTSYS: 448 case -ERESTARTSYS:
449 if (!(ka->sa.sa_flags & SA_RESTART)) { 449 if (!(ka->sa.sa_flags & SA_RESTART)) {
450 __frame->gr8 = -EINTR; 450 __frame->gr8 = -EINTR;
451 break; 451 break;
452 } 452 }
453 453
454 /* fallthrough */ 454 /* fallthrough */
455 case -ERESTARTNOINTR: 455 case -ERESTARTNOINTR:
456 __frame->gr8 = __frame->orig_gr8; 456 __frame->gr8 = __frame->orig_gr8;
457 __frame->pc -= 4; 457 __frame->pc -= 4;
458 } 458 }
459 } 459 }
460 460
461 /* Set up the stack frame */ 461 /* Set up the stack frame */
462 if (ka->sa.sa_flags & SA_SIGINFO) 462 if (ka->sa.sa_flags & SA_SIGINFO)
463 ret = setup_rt_frame(sig, ka, info, oldset); 463 ret = setup_rt_frame(sig, ka, info, oldset);
464 else 464 else
465 ret = setup_frame(sig, ka, oldset); 465 ret = setup_frame(sig, ka, oldset);
466 466
467 if (ret == 0) { 467 if (ret == 0) {
468 spin_lock_irq(&current->sighand->siglock); 468 spin_lock_irq(&current->sighand->siglock);
469 sigorsets(&current->blocked, &current->blocked, 469 sigorsets(&current->blocked, &current->blocked,
470 &ka->sa.sa_mask); 470 &ka->sa.sa_mask);
471 if (!(ka->sa.sa_flags & SA_NODEFER)) 471 if (!(ka->sa.sa_flags & SA_NODEFER))
472 sigaddset(&current->blocked, sig); 472 sigaddset(&current->blocked, sig);
473 recalc_sigpending(); 473 recalc_sigpending();
474 spin_unlock_irq(&current->sighand->siglock); 474 spin_unlock_irq(&current->sighand->siglock);
475 } 475 }
476 476
477 return ret; 477 return ret;
478 478
479 } /* end handle_signal() */ 479 } /* end handle_signal() */
480 480
481 /*****************************************************************************/ 481 /*****************************************************************************/
482 /* 482 /*
483 * Note that 'init' is a special process: it doesn't get signals it doesn't 483 * Note that 'init' is a special process: it doesn't get signals it doesn't
484 * want to handle. Thus you cannot kill init even with a SIGKILL even by 484 * want to handle. Thus you cannot kill init even with a SIGKILL even by
485 * mistake. 485 * mistake.
486 */ 486 */
487 static void do_signal(void) 487 static void do_signal(void)
488 { 488 {
489 struct k_sigaction ka; 489 struct k_sigaction ka;
490 siginfo_t info; 490 siginfo_t info;
491 sigset_t *oldset; 491 sigset_t *oldset;
492 int signr; 492 int signr;
493 493
494 /* 494 /*
495 * We want the common case to go fast, which 495 * We want the common case to go fast, which
496 * is why we may in certain cases get here from 496 * is why we may in certain cases get here from
497 * kernel mode. Just return without doing anything 497 * kernel mode. Just return without doing anything
498 * if so. 498 * if so.
499 */ 499 */
500 if (!user_mode(__frame)) 500 if (!user_mode(__frame))
501 return; 501 return;
502 502
503 if (try_to_freeze()) 503 if (try_to_freeze())
504 goto no_signal; 504 goto no_signal;
505 505
506 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 506 if (test_thread_flag(TIF_RESTORE_SIGMASK))
507 oldset = &current->saved_sigmask; 507 oldset = &current->saved_sigmask;
508 else 508 else
509 oldset = &current->blocked; 509 oldset = &current->blocked;
510 510
511 signr = get_signal_to_deliver(&info, &ka, __frame, NULL); 511 signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
512 if (signr > 0) { 512 if (signr > 0) {
513 if (handle_signal(signr, &info, &ka, oldset) == 0) { 513 if (handle_signal(signr, &info, &ka, oldset) == 0) {
514 /* a signal was successfully delivered; the saved 514 /* a signal was successfully delivered; the saved
515 * sigmask will have been stored in the signal frame, 515 * sigmask will have been stored in the signal frame,
516 * and will be restored by sigreturn, so we can simply 516 * and will be restored by sigreturn, so we can simply
517 * clear the TIF_RESTORE_SIGMASK flag */ 517 * clear the TIF_RESTORE_SIGMASK flag */
518 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 518 if (test_thread_flag(TIF_RESTORE_SIGMASK))
519 clear_thread_flag(TIF_RESTORE_SIGMASK); 519 clear_thread_flag(TIF_RESTORE_SIGMASK);
520 } 520 }
521 521
522 return; 522 return;
523 } 523 }
524 524
525 no_signal: 525 no_signal:
526 /* Did we come from a system call? */ 526 /* Did we come from a system call? */
527 if (__frame->syscallno >= 0) { 527 if (__frame->syscallno >= 0) {
528 /* Restart the system call - no handlers present */ 528 /* Restart the system call - no handlers present */
529 switch (__frame->gr8) { 529 switch (__frame->gr8) {
530 case -ERESTARTNOHAND: 530 case -ERESTARTNOHAND:
531 case -ERESTARTSYS: 531 case -ERESTARTSYS:
532 case -ERESTARTNOINTR: 532 case -ERESTARTNOINTR:
533 __frame->gr8 = __frame->orig_gr8; 533 __frame->gr8 = __frame->orig_gr8;
534 __frame->pc -= 4; 534 __frame->pc -= 4;
535 break; 535 break;
536 536
537 case -ERESTART_RESTARTBLOCK: 537 case -ERESTART_RESTARTBLOCK:
538 __frame->gr8 = __NR_restart_syscall; 538 __frame->gr8 = __NR_restart_syscall;
539 __frame->pc -= 4; 539 __frame->pc -= 4;
540 break; 540 break;
541 } 541 }
542 } 542 }
543 543
544 /* if there's no signal to deliver, we just put the saved sigmask 544 /* if there's no signal to deliver, we just put the saved sigmask
545 * back */ 545 * back */
546 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 546 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
547 clear_thread_flag(TIF_RESTORE_SIGMASK); 547 clear_thread_flag(TIF_RESTORE_SIGMASK);
548 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 548 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
549 } 549 }
550 550
551 } /* end do_signal() */ 551 } /* end do_signal() */
552 552
553 /*****************************************************************************/ 553 /*****************************************************************************/
554 /* 554 /*
555 * notification of userspace execution resumption 555 * notification of userspace execution resumption
556 * - triggered by the TIF_WORK_MASK flags 556 * - triggered by the TIF_WORK_MASK flags
557 */ 557 */
558 asmlinkage void do_notify_resume(__u32 thread_info_flags) 558 asmlinkage void do_notify_resume(__u32 thread_info_flags)
559 { 559 {
560 /* pending single-step? */ 560 /* pending single-step? */
561 if (thread_info_flags & _TIF_SINGLESTEP) 561 if (thread_info_flags & _TIF_SINGLESTEP)
562 clear_thread_flag(TIF_SINGLESTEP); 562 clear_thread_flag(TIF_SINGLESTEP);
563 563
564 /* deal with pending signal delivery */ 564 /* deal with pending signal delivery */
565 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 565 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
566 do_signal(); 566 do_signal();
567 567
568 } /* end do_notify_resume() */ 568 } /* end do_notify_resume() */
569 569
arch/h8300/kernel/signal.c
1 /* 1 /*
2 * linux/arch/h8300/kernel/signal.c 2 * linux/arch/h8300/kernel/signal.c
3 * 3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * 5 *
6 * This file is subject to the terms and conditions of the GNU General Public 6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive 7 * License. See the file COPYING in the main directory of this archive
8 * for more details. 8 * for more details.
9 */ 9 */
10 10
11 /* 11 /*
12 * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp> 12 * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp>
13 * and David McCullough <davidm@snapgear.com> 13 * and David McCullough <davidm@snapgear.com>
14 * 14 *
15 * Based on 15 * Based on
16 * Linux/m68k by Hamish Macdonald 16 * Linux/m68k by Hamish Macdonald
17 */ 17 */
18 18
19 /* 19 /*
20 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 20 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
21 * Atari :-) Current limitation: Only one sigstack can be active at one time. 21 * Atari :-) Current limitation: Only one sigstack can be active at one time.
22 * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 22 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
23 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 23 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
24 * signal handlers! 24 * signal handlers!
25 */ 25 */
26 26
27 #include <linux/sched.h> 27 #include <linux/sched.h>
28 #include <linux/mm.h> 28 #include <linux/mm.h>
29 #include <linux/kernel.h> 29 #include <linux/kernel.h>
30 #include <linux/signal.h> 30 #include <linux/signal.h>
31 #include <linux/syscalls.h> 31 #include <linux/syscalls.h>
32 #include <linux/errno.h> 32 #include <linux/errno.h>
33 #include <linux/wait.h> 33 #include <linux/wait.h>
34 #include <linux/ptrace.h> 34 #include <linux/ptrace.h>
35 #include <linux/unistd.h> 35 #include <linux/unistd.h>
36 #include <linux/stddef.h> 36 #include <linux/stddef.h>
37 #include <linux/highuid.h> 37 #include <linux/highuid.h>
38 #include <linux/personality.h> 38 #include <linux/personality.h>
39 #include <linux/tty.h> 39 #include <linux/tty.h>
40 #include <linux/binfmts.h> 40 #include <linux/binfmts.h>
41 #include <linux/suspend.h> 41 #include <linux/suspend.h>
42 42
43 #include <asm/setup.h> 43 #include <asm/setup.h>
44 #include <asm/uaccess.h> 44 #include <asm/uaccess.h>
45 #include <asm/pgtable.h> 45 #include <asm/pgtable.h>
46 #include <asm/traps.h> 46 #include <asm/traps.h>
47 #include <asm/ucontext.h> 47 #include <asm/ucontext.h>
48 48
49 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 49 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
50 50
51 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 51 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
52 52
53 /* 53 /*
54 * Atomically swap in the new signal mask, and wait for a signal. 54 * Atomically swap in the new signal mask, and wait for a signal.
55 */ 55 */
56 asmlinkage int do_sigsuspend(struct pt_regs *regs) 56 asmlinkage int do_sigsuspend(struct pt_regs *regs)
57 { 57 {
58 old_sigset_t mask = regs->er3; 58 old_sigset_t mask = regs->er3;
59 sigset_t saveset; 59 sigset_t saveset;
60 60
61 mask &= _BLOCKABLE; 61 mask &= _BLOCKABLE;
62 spin_lock_irq(&current->sighand->siglock); 62 spin_lock_irq(&current->sighand->siglock);
63 saveset = current->blocked; 63 saveset = current->blocked;
64 siginitset(&current->blocked, mask); 64 siginitset(&current->blocked, mask);
65 recalc_sigpending(); 65 recalc_sigpending();
66 spin_unlock_irq(&current->sighand->siglock); 66 spin_unlock_irq(&current->sighand->siglock);
67 67
68 regs->er0 = -EINTR; 68 regs->er0 = -EINTR;
69 while (1) { 69 while (1) {
70 current->state = TASK_INTERRUPTIBLE; 70 current->state = TASK_INTERRUPTIBLE;
71 schedule(); 71 schedule();
72 if (do_signal(regs, &saveset)) 72 if (do_signal(regs, &saveset))
73 return -EINTR; 73 return -EINTR;
74 } 74 }
75 } 75 }
76 76
77 asmlinkage int 77 asmlinkage int
78 do_rt_sigsuspend(struct pt_regs *regs) 78 do_rt_sigsuspend(struct pt_regs *regs)
79 { 79 {
80 sigset_t *unewset = (sigset_t *)regs->er1; 80 sigset_t *unewset = (sigset_t *)regs->er1;
81 size_t sigsetsize = (size_t)regs->er2; 81 size_t sigsetsize = (size_t)regs->er2;
82 sigset_t saveset, newset; 82 sigset_t saveset, newset;
83 83
84 /* XXX: Don't preclude handling different sized sigset_t's. */ 84 /* XXX: Don't preclude handling different sized sigset_t's. */
85 if (sigsetsize != sizeof(sigset_t)) 85 if (sigsetsize != sizeof(sigset_t))
86 return -EINVAL; 86 return -EINVAL;
87 87
88 if (copy_from_user(&newset, unewset, sizeof(newset))) 88 if (copy_from_user(&newset, unewset, sizeof(newset)))
89 return -EFAULT; 89 return -EFAULT;
90 sigdelsetmask(&newset, ~_BLOCKABLE); 90 sigdelsetmask(&newset, ~_BLOCKABLE);
91 91
92 spin_lock_irq(&current->sighand->siglock); 92 spin_lock_irq(&current->sighand->siglock);
93 saveset = current->blocked; 93 saveset = current->blocked;
94 current->blocked = newset; 94 current->blocked = newset;
95 recalc_sigpending(); 95 recalc_sigpending();
96 spin_unlock_irq(&current->sighand->siglock); 96 spin_unlock_irq(&current->sighand->siglock);
97 97
98 regs->er0 = -EINTR; 98 regs->er0 = -EINTR;
99 while (1) { 99 while (1) {
100 current->state = TASK_INTERRUPTIBLE; 100 current->state = TASK_INTERRUPTIBLE;
101 schedule(); 101 schedule();
102 if (do_signal(regs, &saveset)) 102 if (do_signal(regs, &saveset))
103 return -EINTR; 103 return -EINTR;
104 } 104 }
105 } 105 }
106 106
107 asmlinkage int 107 asmlinkage int
108 sys_sigaction(int sig, const struct old_sigaction *act, 108 sys_sigaction(int sig, const struct old_sigaction *act,
109 struct old_sigaction *oact) 109 struct old_sigaction *oact)
110 { 110 {
111 struct k_sigaction new_ka, old_ka; 111 struct k_sigaction new_ka, old_ka;
112 int ret; 112 int ret;
113 113
114 if (act) { 114 if (act) {
115 old_sigset_t mask; 115 old_sigset_t mask;
116 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 116 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
117 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 117 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
118 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 118 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
119 return -EFAULT; 119 return -EFAULT;
120 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 120 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
121 __get_user(mask, &act->sa_mask); 121 __get_user(mask, &act->sa_mask);
122 siginitset(&new_ka.sa.sa_mask, mask); 122 siginitset(&new_ka.sa.sa_mask, mask);
123 } 123 }
124 124
125 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 125 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
126 126
127 if (!ret && oact) { 127 if (!ret && oact) {
128 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 128 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
129 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 129 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
130 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 130 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
131 return -EFAULT; 131 return -EFAULT;
132 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 132 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
133 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 133 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
134 } 134 }
135 135
136 return ret; 136 return ret;
137 } 137 }
138 138
139 asmlinkage int 139 asmlinkage int
140 sys_sigaltstack(const stack_t *uss, stack_t *uoss) 140 sys_sigaltstack(const stack_t *uss, stack_t *uoss)
141 { 141 {
142 return do_sigaltstack(uss, uoss, rdusp()); 142 return do_sigaltstack(uss, uoss, rdusp());
143 } 143 }
144 144
145 145
146 /* 146 /*
147 * Do a signal return; undo the signal stack. 147 * Do a signal return; undo the signal stack.
148 * 148 *
149 * Keep the return code on the stack quadword aligned! 149 * Keep the return code on the stack quadword aligned!
150 * That makes the cache flush below easier. 150 * That makes the cache flush below easier.
151 */ 151 */
152 152
153 struct sigframe 153 struct sigframe
154 { 154 {
155 long dummy_er0; 155 long dummy_er0;
156 long dummy_vector; 156 long dummy_vector;
157 #if defined(CONFIG_CPU_H8S) 157 #if defined(CONFIG_CPU_H8S)
158 short dummy_exr; 158 short dummy_exr;
159 #endif 159 #endif
160 long dummy_pc; 160 long dummy_pc;
161 char *pretcode; 161 char *pretcode;
162 unsigned char retcode[8]; 162 unsigned char retcode[8];
163 unsigned long extramask[_NSIG_WORDS-1]; 163 unsigned long extramask[_NSIG_WORDS-1];
164 struct sigcontext sc; 164 struct sigcontext sc;
165 int sig; 165 int sig;
166 } __attribute__((aligned(2),packed)); 166 } __attribute__((aligned(2),packed));
167 167
168 struct rt_sigframe 168 struct rt_sigframe
169 { 169 {
170 long dummy_er0; 170 long dummy_er0;
171 long dummy_vector; 171 long dummy_vector;
172 #if defined(CONFIG_CPU_H8S) 172 #if defined(CONFIG_CPU_H8S)
173 short dummy_exr; 173 short dummy_exr;
174 #endif 174 #endif
175 long dummy_pc; 175 long dummy_pc;
176 char *pretcode; 176 char *pretcode;
177 struct siginfo *pinfo; 177 struct siginfo *pinfo;
178 void *puc; 178 void *puc;
179 unsigned char retcode[8]; 179 unsigned char retcode[8];
180 struct siginfo info; 180 struct siginfo info;
181 struct ucontext uc; 181 struct ucontext uc;
182 int sig; 182 int sig;
183 } __attribute__((aligned(2),packed)); 183 } __attribute__((aligned(2),packed));
184 184
185 static inline int 185 static inline int
186 restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, 186 restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc,
187 int *pd0) 187 int *pd0)
188 { 188 {
189 int err = 0; 189 int err = 0;
190 unsigned int ccr; 190 unsigned int ccr;
191 unsigned int usp; 191 unsigned int usp;
192 unsigned int er0; 192 unsigned int er0;
193 193
194 /* Always make any pending restarted system calls return -EINTR */ 194 /* Always make any pending restarted system calls return -EINTR */
195 current_thread_info()->restart_block.fn = do_no_restart_syscall; 195 current_thread_info()->restart_block.fn = do_no_restart_syscall;
196 196
197 #define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */ 197 #define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */
198 COPY(er1); 198 COPY(er1);
199 COPY(er2); 199 COPY(er2);
200 COPY(er3); 200 COPY(er3);
201 COPY(er5); 201 COPY(er5);
202 COPY(pc); 202 COPY(pc);
203 ccr = regs->ccr & 0x10; 203 ccr = regs->ccr & 0x10;
204 COPY(ccr); 204 COPY(ccr);
205 #undef COPY 205 #undef COPY
206 regs->ccr &= 0xef; 206 regs->ccr &= 0xef;
207 regs->ccr |= ccr; 207 regs->ccr |= ccr;
208 regs->orig_er0 = -1; /* disable syscall checks */ 208 regs->orig_er0 = -1; /* disable syscall checks */
209 err |= __get_user(usp, &usc->sc_usp); 209 err |= __get_user(usp, &usc->sc_usp);
210 wrusp(usp); 210 wrusp(usp);
211 211
212 err |= __get_user(er0, &usc->sc_er0); 212 err |= __get_user(er0, &usc->sc_er0);
213 *pd0 = er0; 213 *pd0 = er0;
214 return err; 214 return err;
215 } 215 }
216 216
217 asmlinkage int do_sigreturn(unsigned long __unused,...) 217 asmlinkage int do_sigreturn(unsigned long __unused,...)
218 { 218 {
219 struct pt_regs *regs = (struct pt_regs *) (&__unused - 1); 219 struct pt_regs *regs = (struct pt_regs *) (&__unused - 1);
220 unsigned long usp = rdusp(); 220 unsigned long usp = rdusp();
221 struct sigframe *frame = (struct sigframe *)(usp - 4); 221 struct sigframe *frame = (struct sigframe *)(usp - 4);
222 sigset_t set; 222 sigset_t set;
223 int er0; 223 int er0;
224 224
225 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 225 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
226 goto badframe; 226 goto badframe;
227 if (__get_user(set.sig[0], &frame->sc.sc_mask) || 227 if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
228 (_NSIG_WORDS > 1 && 228 (_NSIG_WORDS > 1 &&
229 __copy_from_user(&set.sig[1], &frame->extramask, 229 __copy_from_user(&set.sig[1], &frame->extramask,
230 sizeof(frame->extramask)))) 230 sizeof(frame->extramask))))
231 goto badframe; 231 goto badframe;
232 232
233 sigdelsetmask(&set, ~_BLOCKABLE); 233 sigdelsetmask(&set, ~_BLOCKABLE);
234 spin_lock_irq(&current->sighand->siglock); 234 spin_lock_irq(&current->sighand->siglock);
235 current->blocked = set; 235 current->blocked = set;
236 recalc_sigpending(); 236 recalc_sigpending();
237 spin_unlock_irq(&current->sighand->siglock); 237 spin_unlock_irq(&current->sighand->siglock);
238 238
239 if (restore_sigcontext(regs, &frame->sc, &er0)) 239 if (restore_sigcontext(regs, &frame->sc, &er0))
240 goto badframe; 240 goto badframe;
241 return er0; 241 return er0;
242 242
243 badframe: 243 badframe:
244 force_sig(SIGSEGV, current); 244 force_sig(SIGSEGV, current);
245 return 0; 245 return 0;
246 } 246 }
247 247
248 asmlinkage int do_rt_sigreturn(unsigned long __unused,...) 248 asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
249 { 249 {
250 struct pt_regs *regs = (struct pt_regs *) &__unused; 250 struct pt_regs *regs = (struct pt_regs *) &__unused;
251 unsigned long usp = rdusp(); 251 unsigned long usp = rdusp();
252 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); 252 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
253 sigset_t set; 253 sigset_t set;
254 int er0; 254 int er0;
255 255
256 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 256 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
257 goto badframe; 257 goto badframe;
258 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 258 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
259 goto badframe; 259 goto badframe;
260 260
261 sigdelsetmask(&set, ~_BLOCKABLE); 261 sigdelsetmask(&set, ~_BLOCKABLE);
262 spin_unlock_irq(&current->sighand->siglock); 262 spin_unlock_irq(&current->sighand->siglock);
263 current->blocked = set; 263 current->blocked = set;
264 recalc_sigpending(); 264 recalc_sigpending();
265 spin_lock_irq(&current->sighand->siglock); 265 spin_lock_irq(&current->sighand->siglock);
266 266
267 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0)) 267 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0))
268 goto badframe; 268 goto badframe;
269 269
270 if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT) 270 if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
271 goto badframe; 271 goto badframe;
272 272
273 return er0; 273 return er0;
274 274
275 badframe: 275 badframe:
276 force_sig(SIGSEGV, current); 276 force_sig(SIGSEGV, current);
277 return 0; 277 return 0;
278 } 278 }
279 279
280 static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 280 static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
281 unsigned long mask) 281 unsigned long mask)
282 { 282 {
283 int err = 0; 283 int err = 0;
284 284
285 err |= __put_user(regs->er0, &sc->sc_er0); 285 err |= __put_user(regs->er0, &sc->sc_er0);
286 err |= __put_user(regs->er1, &sc->sc_er1); 286 err |= __put_user(regs->er1, &sc->sc_er1);
287 err |= __put_user(regs->er2, &sc->sc_er2); 287 err |= __put_user(regs->er2, &sc->sc_er2);
288 err |= __put_user(regs->er3, &sc->sc_er3); 288 err |= __put_user(regs->er3, &sc->sc_er3);
289 err |= __put_user(regs->er4, &sc->sc_er4); 289 err |= __put_user(regs->er4, &sc->sc_er4);
290 err |= __put_user(regs->er5, &sc->sc_er5); 290 err |= __put_user(regs->er5, &sc->sc_er5);
291 err |= __put_user(regs->er6, &sc->sc_er6); 291 err |= __put_user(regs->er6, &sc->sc_er6);
292 err |= __put_user(rdusp(), &sc->sc_usp); 292 err |= __put_user(rdusp(), &sc->sc_usp);
293 err |= __put_user(regs->pc, &sc->sc_pc); 293 err |= __put_user(regs->pc, &sc->sc_pc);
294 err |= __put_user(regs->ccr, &sc->sc_ccr); 294 err |= __put_user(regs->ccr, &sc->sc_ccr);
295 err |= __put_user(mask, &sc->sc_mask); 295 err |= __put_user(mask, &sc->sc_mask);
296 296
297 return err; 297 return err;
298 } 298 }
299 299
300 static inline void * 300 static inline void *
301 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 301 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
302 { 302 {
303 unsigned long usp; 303 unsigned long usp;
304 304
305 /* Default to using normal stack. */ 305 /* Default to using normal stack. */
306 usp = rdusp(); 306 usp = rdusp();
307 307
308 /* This is the X/Open sanctioned signal stack switching. */ 308 /* This is the X/Open sanctioned signal stack switching. */
309 if (ka->sa.sa_flags & SA_ONSTACK) { 309 if (ka->sa.sa_flags & SA_ONSTACK) {
310 if (!on_sig_stack(usp)) 310 if (!sas_ss_flags(usp))
311 usp = current->sas_ss_sp + current->sas_ss_size; 311 usp = current->sas_ss_sp + current->sas_ss_size;
312 } 312 }
313 return (void *)((usp - frame_size) & -8UL); 313 return (void *)((usp - frame_size) & -8UL);
314 } 314 }
315 315
316 static void setup_frame (int sig, struct k_sigaction *ka, 316 static void setup_frame (int sig, struct k_sigaction *ka,
317 sigset_t *set, struct pt_regs *regs) 317 sigset_t *set, struct pt_regs *regs)
318 { 318 {
319 struct sigframe *frame; 319 struct sigframe *frame;
320 int err = 0; 320 int err = 0;
321 int usig; 321 int usig;
322 unsigned char *ret; 322 unsigned char *ret;
323 323
324 frame = get_sigframe(ka, regs, sizeof(*frame)); 324 frame = get_sigframe(ka, regs, sizeof(*frame));
325 325
326 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 326 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
327 goto give_sigsegv; 327 goto give_sigsegv;
328 328
329 usig = current_thread_info()->exec_domain 329 usig = current_thread_info()->exec_domain
330 && current_thread_info()->exec_domain->signal_invmap 330 && current_thread_info()->exec_domain->signal_invmap
331 && sig < 32 331 && sig < 32
332 ? current_thread_info()->exec_domain->signal_invmap[sig] 332 ? current_thread_info()->exec_domain->signal_invmap[sig]
333 : sig; 333 : sig;
334 334
335 err |= __put_user(usig, &frame->sig); 335 err |= __put_user(usig, &frame->sig);
336 if (err) 336 if (err)
337 goto give_sigsegv; 337 goto give_sigsegv;
338 338
339 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); 339 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
340 if (err) 340 if (err)
341 goto give_sigsegv; 341 goto give_sigsegv;
342 342
343 if (_NSIG_WORDS > 1) { 343 if (_NSIG_WORDS > 1) {
344 err |= copy_to_user(frame->extramask, &set->sig[1], 344 err |= copy_to_user(frame->extramask, &set->sig[1],
345 sizeof(frame->extramask)); 345 sizeof(frame->extramask));
346 if (err) 346 if (err)
347 goto give_sigsegv; 347 goto give_sigsegv;
348 } 348 }
349 349
350 ret = frame->retcode; 350 ret = frame->retcode;
351 if (ka->sa.sa_flags & SA_RESTORER) 351 if (ka->sa.sa_flags & SA_RESTORER)
352 ret = (unsigned char *)(ka->sa.sa_restorer); 352 ret = (unsigned char *)(ka->sa.sa_restorer);
353 else { 353 else {
354 /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ 354 /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
355 err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), 355 err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
356 (unsigned long *)(frame->retcode + 0)); 356 (unsigned long *)(frame->retcode + 0));
357 err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); 357 err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
358 } 358 }
359 359
360 /* Set up to return from userspace. */ 360 /* Set up to return from userspace. */
361 err |= __put_user(ret, &frame->pretcode); 361 err |= __put_user(ret, &frame->pretcode);
362 362
363 if (err) 363 if (err)
364 goto give_sigsegv; 364 goto give_sigsegv;
365 365
366 /* Set up registers for signal handler */ 366 /* Set up registers for signal handler */
367 wrusp ((unsigned long) frame); 367 wrusp ((unsigned long) frame);
368 regs->pc = (unsigned long) ka->sa.sa_handler; 368 regs->pc = (unsigned long) ka->sa.sa_handler;
369 regs->er0 = (current_thread_info()->exec_domain 369 regs->er0 = (current_thread_info()->exec_domain
370 && current_thread_info()->exec_domain->signal_invmap 370 && current_thread_info()->exec_domain->signal_invmap
371 && sig < 32 371 && sig < 32
372 ? current_thread_info()->exec_domain->signal_invmap[sig] 372 ? current_thread_info()->exec_domain->signal_invmap[sig]
373 : sig); 373 : sig);
374 regs->er1 = (unsigned long)&(frame->sc); 374 regs->er1 = (unsigned long)&(frame->sc);
375 regs->er5 = current->mm->start_data; /* GOT base */ 375 regs->er5 = current->mm->start_data; /* GOT base */
376 376
377 return; 377 return;
378 378
379 give_sigsegv: 379 give_sigsegv:
380 force_sigsegv(sig, current); 380 force_sigsegv(sig, current);
381 } 381 }
382 382
383 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 383 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
384 sigset_t *set, struct pt_regs *regs) 384 sigset_t *set, struct pt_regs *regs)
385 { 385 {
386 struct rt_sigframe *frame; 386 struct rt_sigframe *frame;
387 int err = 0; 387 int err = 0;
388 int usig; 388 int usig;
389 unsigned char *ret; 389 unsigned char *ret;
390 390
391 frame = get_sigframe(ka, regs, sizeof(*frame)); 391 frame = get_sigframe(ka, regs, sizeof(*frame));
392 392
393 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 393 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
394 goto give_sigsegv; 394 goto give_sigsegv;
395 395
396 usig = current_thread_info()->exec_domain 396 usig = current_thread_info()->exec_domain
397 && current_thread_info()->exec_domain->signal_invmap 397 && current_thread_info()->exec_domain->signal_invmap
398 && sig < 32 398 && sig < 32
399 ? current_thread_info()->exec_domain->signal_invmap[sig] 399 ? current_thread_info()->exec_domain->signal_invmap[sig]
400 : sig; 400 : sig;
401 401
402 err |= __put_user(usig, &frame->sig); 402 err |= __put_user(usig, &frame->sig);
403 if (err) 403 if (err)
404 goto give_sigsegv; 404 goto give_sigsegv;
405 405
406 err |= __put_user(&frame->info, &frame->pinfo); 406 err |= __put_user(&frame->info, &frame->pinfo);
407 err |= __put_user(&frame->uc, &frame->puc); 407 err |= __put_user(&frame->uc, &frame->puc);
408 err |= copy_siginfo_to_user(&frame->info, info); 408 err |= copy_siginfo_to_user(&frame->info, info);
409 if (err) 409 if (err)
410 goto give_sigsegv; 410 goto give_sigsegv;
411 411
412 /* Create the ucontext. */ 412 /* Create the ucontext. */
413 err |= __put_user(0, &frame->uc.uc_flags); 413 err |= __put_user(0, &frame->uc.uc_flags);
414 err |= __put_user(0, &frame->uc.uc_link); 414 err |= __put_user(0, &frame->uc.uc_link);
415 err |= __put_user((void *)current->sas_ss_sp, 415 err |= __put_user((void *)current->sas_ss_sp,
416 &frame->uc.uc_stack.ss_sp); 416 &frame->uc.uc_stack.ss_sp);
417 err |= __put_user(sas_ss_flags(rdusp()), 417 err |= __put_user(sas_ss_flags(rdusp()),
418 &frame->uc.uc_stack.ss_flags); 418 &frame->uc.uc_stack.ss_flags);
419 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 419 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
420 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); 420 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
421 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 421 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
422 if (err) 422 if (err)
423 goto give_sigsegv; 423 goto give_sigsegv;
424 424
425 /* Set up to return from userspace. */ 425 /* Set up to return from userspace. */
426 ret = frame->retcode; 426 ret = frame->retcode;
427 if (ka->sa.sa_flags & SA_RESTORER) 427 if (ka->sa.sa_flags & SA_RESTORER)
428 ret = (unsigned char *)(ka->sa.sa_restorer); 428 ret = (unsigned char *)(ka->sa.sa_restorer);
429 else { 429 else {
430 /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ 430 /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
431 err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), 431 err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
432 (unsigned long *)(frame->retcode + 0)); 432 (unsigned long *)(frame->retcode + 0));
433 err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); 433 err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
434 } 434 }
435 err |= __put_user(ret, &frame->pretcode); 435 err |= __put_user(ret, &frame->pretcode);
436 436
437 if (err) 437 if (err)
438 goto give_sigsegv; 438 goto give_sigsegv;
439 439
440 /* Set up registers for signal handler */ 440 /* Set up registers for signal handler */
441 wrusp ((unsigned long) frame); 441 wrusp ((unsigned long) frame);
442 regs->pc = (unsigned long) ka->sa.sa_handler; 442 regs->pc = (unsigned long) ka->sa.sa_handler;
443 regs->er0 = (current_thread_info()->exec_domain 443 regs->er0 = (current_thread_info()->exec_domain
444 && current_thread_info()->exec_domain->signal_invmap 444 && current_thread_info()->exec_domain->signal_invmap
445 && sig < 32 445 && sig < 32
446 ? current_thread_info()->exec_domain->signal_invmap[sig] 446 ? current_thread_info()->exec_domain->signal_invmap[sig]
447 : sig); 447 : sig);
448 regs->er1 = (unsigned long)&(frame->info); 448 regs->er1 = (unsigned long)&(frame->info);
449 regs->er2 = (unsigned long)&frame->uc; 449 regs->er2 = (unsigned long)&frame->uc;
450 regs->er5 = current->mm->start_data; /* GOT base */ 450 regs->er5 = current->mm->start_data; /* GOT base */
451 451
452 return; 452 return;
453 453
454 give_sigsegv: 454 give_sigsegv:
455 force_sigsegv(sig, current); 455 force_sigsegv(sig, current);
456 } 456 }
457 457
458 /* 458 /*
459 * OK, we're invoking a handler 459 * OK, we're invoking a handler
460 */ 460 */
461 static void 461 static void
462 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 462 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
463 sigset_t *oldset, struct pt_regs * regs) 463 sigset_t *oldset, struct pt_regs * regs)
464 { 464 {
465 /* are we from a system call? */ 465 /* are we from a system call? */
466 if (regs->orig_er0 >= 0) { 466 if (regs->orig_er0 >= 0) {
467 switch (regs->er0) { 467 switch (regs->er0) {
468 case -ERESTART_RESTARTBLOCK: 468 case -ERESTART_RESTARTBLOCK:
469 case -ERESTARTNOHAND: 469 case -ERESTARTNOHAND:
470 regs->er0 = -EINTR; 470 regs->er0 = -EINTR;
471 break; 471 break;
472 472
473 case -ERESTARTSYS: 473 case -ERESTARTSYS:
474 if (!(ka->sa.sa_flags & SA_RESTART)) { 474 if (!(ka->sa.sa_flags & SA_RESTART)) {
475 regs->er0 = -EINTR; 475 regs->er0 = -EINTR;
476 break; 476 break;
477 } 477 }
478 /* fallthrough */ 478 /* fallthrough */
479 case -ERESTARTNOINTR: 479 case -ERESTARTNOINTR:
480 regs->er0 = regs->orig_er0; 480 regs->er0 = regs->orig_er0;
481 regs->pc -= 2; 481 regs->pc -= 2;
482 } 482 }
483 } 483 }
484 484
485 /* set up the stack frame */ 485 /* set up the stack frame */
486 if (ka->sa.sa_flags & SA_SIGINFO) 486 if (ka->sa.sa_flags & SA_SIGINFO)
487 setup_rt_frame(sig, ka, info, oldset, regs); 487 setup_rt_frame(sig, ka, info, oldset, regs);
488 else 488 else
489 setup_frame(sig, ka, oldset, regs); 489 setup_frame(sig, ka, oldset, regs);
490 490
491 spin_lock_irq(&current->sighand->siglock); 491 spin_lock_irq(&current->sighand->siglock);
492 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 492 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
493 if (!(ka->sa.sa_flags & SA_NODEFER)) 493 if (!(ka->sa.sa_flags & SA_NODEFER))
494 sigaddset(&current->blocked,sig); 494 sigaddset(&current->blocked,sig);
495 recalc_sigpending(); 495 recalc_sigpending();
496 spin_unlock_irq(&current->sighand->siglock); 496 spin_unlock_irq(&current->sighand->siglock);
497 } 497 }
498 498
499 /* 499 /*
500 * Note that 'init' is a special process: it doesn't get signals it doesn't 500 * Note that 'init' is a special process: it doesn't get signals it doesn't
501 * want to handle. Thus you cannot kill init even with a SIGKILL even by 501 * want to handle. Thus you cannot kill init even with a SIGKILL even by
502 * mistake. 502 * mistake.
503 */ 503 */
504 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset) 504 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
505 { 505 {
506 siginfo_t info; 506 siginfo_t info;
507 int signr; 507 int signr;
508 struct k_sigaction ka; 508 struct k_sigaction ka;
509 509
510 /* 510 /*
511 * We want the common case to go fast, which 511 * We want the common case to go fast, which
512 * is why we may in certain cases get here from 512 * is why we may in certain cases get here from
513 * kernel mode. Just return without doing anything 513 * kernel mode. Just return without doing anything
514 * if so. 514 * if so.
515 */ 515 */
516 if ((regs->ccr & 0x10)) 516 if ((regs->ccr & 0x10))
517 return 1; 517 return 1;
518 518
519 if (try_to_freeze()) 519 if (try_to_freeze())
520 goto no_signal; 520 goto no_signal;
521 521
522 current->thread.esp0 = (unsigned long) regs; 522 current->thread.esp0 = (unsigned long) regs;
523 523
524 if (!oldset) 524 if (!oldset)
525 oldset = &current->blocked; 525 oldset = &current->blocked;
526 526
527 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 527 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
528 if (signr > 0) { 528 if (signr > 0) {
529 /* Whee! Actually deliver the signal. */ 529 /* Whee! Actually deliver the signal. */
530 handle_signal(signr, &info, &ka, oldset, regs); 530 handle_signal(signr, &info, &ka, oldset, regs);
531 return 1; 531 return 1;
532 } 532 }
533 no_signal: 533 no_signal:
534 /* Did we come from a system call? */ 534 /* Did we come from a system call? */
535 if (regs->orig_er0 >= 0) { 535 if (regs->orig_er0 >= 0) {
536 /* Restart the system call - no handlers present */ 536 /* Restart the system call - no handlers present */
537 if (regs->er0 == -ERESTARTNOHAND || 537 if (regs->er0 == -ERESTARTNOHAND ||
538 regs->er0 == -ERESTARTSYS || 538 regs->er0 == -ERESTARTSYS ||
539 regs->er0 == -ERESTARTNOINTR) { 539 regs->er0 == -ERESTARTNOINTR) {
540 regs->er0 = regs->orig_er0; 540 regs->er0 = regs->orig_er0;
541 regs->pc -= 2; 541 regs->pc -= 2;
542 } 542 }
543 if (regs->er0 == -ERESTART_RESTARTBLOCK){ 543 if (regs->er0 == -ERESTART_RESTARTBLOCK){
544 regs->er0 = __NR_restart_syscall; 544 regs->er0 = __NR_restart_syscall;
545 regs->pc -= 2; 545 regs->pc -= 2;
546 } 546 }
547 } 547 }
548 return 0; 548 return 0;
549 } 549 }
550 550
arch/m68k/kernel/signal.c
1 /* 1 /*
2 * linux/arch/m68k/kernel/signal.c 2 * linux/arch/m68k/kernel/signal.c
3 * 3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * 5 *
6 * This file is subject to the terms and conditions of the GNU General Public 6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive 7 * License. See the file COPYING in the main directory of this archive
8 * for more details. 8 * for more details.
9 */ 9 */
10 10
11 /* 11 /*
12 * Linux/m68k support by Hamish Macdonald 12 * Linux/m68k support by Hamish Macdonald
13 * 13 *
14 * 68060 fixes by Jesper Skov 14 * 68060 fixes by Jesper Skov
15 * 15 *
16 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab 16 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab
17 * 17 *
18 * mathemu support by Roman Zippel 18 * mathemu support by Roman Zippel
19 * (Note: fpstate in the signal context is completely ignored for the emulator 19 * (Note: fpstate in the signal context is completely ignored for the emulator
20 * and the internal floating point format is put on stack) 20 * and the internal floating point format is put on stack)
21 */ 21 */
22 22
23 /* 23 /*
24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
25 * Atari :-) Current limitation: Only one sigstack can be active at one time. 25 * Atari :-) Current limitation: Only one sigstack can be active at one time.
26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
28 * signal handlers! 28 * signal handlers!
29 */ 29 */
30 30
31 #include <linux/sched.h> 31 #include <linux/sched.h>
32 #include <linux/mm.h> 32 #include <linux/mm.h>
33 #include <linux/kernel.h> 33 #include <linux/kernel.h>
34 #include <linux/signal.h> 34 #include <linux/signal.h>
35 #include <linux/syscalls.h> 35 #include <linux/syscalls.h>
36 #include <linux/errno.h> 36 #include <linux/errno.h>
37 #include <linux/wait.h> 37 #include <linux/wait.h>
38 #include <linux/ptrace.h> 38 #include <linux/ptrace.h>
39 #include <linux/unistd.h> 39 #include <linux/unistd.h>
40 #include <linux/stddef.h> 40 #include <linux/stddef.h>
41 #include <linux/highuid.h> 41 #include <linux/highuid.h>
42 #include <linux/personality.h> 42 #include <linux/personality.h>
43 #include <linux/tty.h> 43 #include <linux/tty.h>
44 #include <linux/binfmts.h> 44 #include <linux/binfmts.h>
45 45
46 #include <asm/setup.h> 46 #include <asm/setup.h>
47 #include <asm/uaccess.h> 47 #include <asm/uaccess.h>
48 #include <asm/pgtable.h> 48 #include <asm/pgtable.h>
49 #include <asm/traps.h> 49 #include <asm/traps.h>
50 #include <asm/ucontext.h> 50 #include <asm/ucontext.h>
51 51
52 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 52 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
53 53
54 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); 54 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
55 55
56 const int frame_extra_sizes[16] = { 56 const int frame_extra_sizes[16] = {
57 [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ 57 [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
58 [2] = sizeof(((struct frame *)0)->un.fmt2), 58 [2] = sizeof(((struct frame *)0)->un.fmt2),
59 [3] = sizeof(((struct frame *)0)->un.fmt3), 59 [3] = sizeof(((struct frame *)0)->un.fmt3),
60 [4] = sizeof(((struct frame *)0)->un.fmt4), 60 [4] = sizeof(((struct frame *)0)->un.fmt4),
61 [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ 61 [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */
62 [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ 62 [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */
63 [7] = sizeof(((struct frame *)0)->un.fmt7), 63 [7] = sizeof(((struct frame *)0)->un.fmt7),
64 [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */ 64 [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */
65 [9] = sizeof(((struct frame *)0)->un.fmt9), 65 [9] = sizeof(((struct frame *)0)->un.fmt9),
66 [10] = sizeof(((struct frame *)0)->un.fmta), 66 [10] = sizeof(((struct frame *)0)->un.fmta),
67 [11] = sizeof(((struct frame *)0)->un.fmtb), 67 [11] = sizeof(((struct frame *)0)->un.fmtb),
68 [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */ 68 [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */
69 [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */ 69 [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */
70 [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */ 70 [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */
71 [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */ 71 [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */
72 }; 72 };
73 73
74 /* 74 /*
75 * Atomically swap in the new signal mask, and wait for a signal. 75 * Atomically swap in the new signal mask, and wait for a signal.
76 */ 76 */
77 asmlinkage int do_sigsuspend(struct pt_regs *regs) 77 asmlinkage int do_sigsuspend(struct pt_regs *regs)
78 { 78 {
79 old_sigset_t mask = regs->d3; 79 old_sigset_t mask = regs->d3;
80 sigset_t saveset; 80 sigset_t saveset;
81 81
82 mask &= _BLOCKABLE; 82 mask &= _BLOCKABLE;
83 saveset = current->blocked; 83 saveset = current->blocked;
84 siginitset(&current->blocked, mask); 84 siginitset(&current->blocked, mask);
85 recalc_sigpending(); 85 recalc_sigpending();
86 86
87 regs->d0 = -EINTR; 87 regs->d0 = -EINTR;
88 while (1) { 88 while (1) {
89 current->state = TASK_INTERRUPTIBLE; 89 current->state = TASK_INTERRUPTIBLE;
90 schedule(); 90 schedule();
91 if (do_signal(&saveset, regs)) 91 if (do_signal(&saveset, regs))
92 return -EINTR; 92 return -EINTR;
93 } 93 }
94 } 94 }
95 95
96 asmlinkage int 96 asmlinkage int
97 do_rt_sigsuspend(struct pt_regs *regs) 97 do_rt_sigsuspend(struct pt_regs *regs)
98 { 98 {
99 sigset_t __user *unewset = (sigset_t __user *)regs->d1; 99 sigset_t __user *unewset = (sigset_t __user *)regs->d1;
100 size_t sigsetsize = (size_t)regs->d2; 100 size_t sigsetsize = (size_t)regs->d2;
101 sigset_t saveset, newset; 101 sigset_t saveset, newset;
102 102
103 /* XXX: Don't preclude handling different sized sigset_t's. */ 103 /* XXX: Don't preclude handling different sized sigset_t's. */
104 if (sigsetsize != sizeof(sigset_t)) 104 if (sigsetsize != sizeof(sigset_t))
105 return -EINVAL; 105 return -EINVAL;
106 106
107 if (copy_from_user(&newset, unewset, sizeof(newset))) 107 if (copy_from_user(&newset, unewset, sizeof(newset)))
108 return -EFAULT; 108 return -EFAULT;
109 sigdelsetmask(&newset, ~_BLOCKABLE); 109 sigdelsetmask(&newset, ~_BLOCKABLE);
110 110
111 saveset = current->blocked; 111 saveset = current->blocked;
112 current->blocked = newset; 112 current->blocked = newset;
113 recalc_sigpending(); 113 recalc_sigpending();
114 114
115 regs->d0 = -EINTR; 115 regs->d0 = -EINTR;
116 while (1) { 116 while (1) {
117 current->state = TASK_INTERRUPTIBLE; 117 current->state = TASK_INTERRUPTIBLE;
118 schedule(); 118 schedule();
119 if (do_signal(&saveset, regs)) 119 if (do_signal(&saveset, regs))
120 return -EINTR; 120 return -EINTR;
121 } 121 }
122 } 122 }
123 123
124 asmlinkage int 124 asmlinkage int
125 sys_sigaction(int sig, const struct old_sigaction __user *act, 125 sys_sigaction(int sig, const struct old_sigaction __user *act,
126 struct old_sigaction __user *oact) 126 struct old_sigaction __user *oact)
127 { 127 {
128 struct k_sigaction new_ka, old_ka; 128 struct k_sigaction new_ka, old_ka;
129 int ret; 129 int ret;
130 130
131 if (act) { 131 if (act) {
132 old_sigset_t mask; 132 old_sigset_t mask;
133 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 133 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
134 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 134 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
135 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 135 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
136 return -EFAULT; 136 return -EFAULT;
137 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 137 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
138 __get_user(mask, &act->sa_mask); 138 __get_user(mask, &act->sa_mask);
139 siginitset(&new_ka.sa.sa_mask, mask); 139 siginitset(&new_ka.sa.sa_mask, mask);
140 } 140 }
141 141
142 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 142 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
143 143
144 if (!ret && oact) { 144 if (!ret && oact) {
145 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 145 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
146 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 146 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
147 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 147 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
148 return -EFAULT; 148 return -EFAULT;
149 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 149 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
150 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 150 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
151 } 151 }
152 152
153 return ret; 153 return ret;
154 } 154 }
155 155
156 asmlinkage int 156 asmlinkage int
157 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) 157 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
158 { 158 {
159 return do_sigaltstack(uss, uoss, rdusp()); 159 return do_sigaltstack(uss, uoss, rdusp());
160 } 160 }
161 161
162 162
163 /* 163 /*
164 * Do a signal return; undo the signal stack. 164 * Do a signal return; undo the signal stack.
165 * 165 *
166 * Keep the return code on the stack quadword aligned! 166 * Keep the return code on the stack quadword aligned!
167 * That makes the cache flush below easier. 167 * That makes the cache flush below easier.
168 */ 168 */
169 169
170 struct sigframe 170 struct sigframe
171 { 171 {
172 char __user *pretcode; 172 char __user *pretcode;
173 int sig; 173 int sig;
174 int code; 174 int code;
175 struct sigcontext __user *psc; 175 struct sigcontext __user *psc;
176 char retcode[8]; 176 char retcode[8];
177 unsigned long extramask[_NSIG_WORDS-1]; 177 unsigned long extramask[_NSIG_WORDS-1];
178 struct sigcontext sc; 178 struct sigcontext sc;
179 }; 179 };
180 180
181 struct rt_sigframe 181 struct rt_sigframe
182 { 182 {
183 char __user *pretcode; 183 char __user *pretcode;
184 int sig; 184 int sig;
185 struct siginfo __user *pinfo; 185 struct siginfo __user *pinfo;
186 void __user *puc; 186 void __user *puc;
187 char retcode[8]; 187 char retcode[8];
188 struct siginfo info; 188 struct siginfo info;
189 struct ucontext uc; 189 struct ucontext uc;
190 }; 190 };
191 191
192 192
193 static unsigned char fpu_version; /* version number of fpu, set by setup_frame */ 193 static unsigned char fpu_version; /* version number of fpu, set by setup_frame */
194 194
195 static inline int restore_fpu_state(struct sigcontext *sc) 195 static inline int restore_fpu_state(struct sigcontext *sc)
196 { 196 {
197 int err = 1; 197 int err = 1;
198 198
199 if (FPU_IS_EMU) { 199 if (FPU_IS_EMU) {
200 /* restore registers */ 200 /* restore registers */
201 memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); 201 memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
202 memcpy(current->thread.fp, sc->sc_fpregs, 24); 202 memcpy(current->thread.fp, sc->sc_fpregs, 24);
203 return 0; 203 return 0;
204 } 204 }
205 205
206 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { 206 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
207 /* Verify the frame format. */ 207 /* Verify the frame format. */
208 if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version)) 208 if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))
209 goto out; 209 goto out;
210 if (CPU_IS_020_OR_030) { 210 if (CPU_IS_020_OR_030) {
211 if (m68k_fputype & FPU_68881 && 211 if (m68k_fputype & FPU_68881 &&
212 !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4)) 212 !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
213 goto out; 213 goto out;
214 if (m68k_fputype & FPU_68882 && 214 if (m68k_fputype & FPU_68882 &&
215 !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4)) 215 !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
216 goto out; 216 goto out;
217 } else if (CPU_IS_040) { 217 } else if (CPU_IS_040) {
218 if (!(sc->sc_fpstate[1] == 0x00 || 218 if (!(sc->sc_fpstate[1] == 0x00 ||
219 sc->sc_fpstate[1] == 0x28 || 219 sc->sc_fpstate[1] == 0x28 ||
220 sc->sc_fpstate[1] == 0x60)) 220 sc->sc_fpstate[1] == 0x60))
221 goto out; 221 goto out;
222 } else if (CPU_IS_060) { 222 } else if (CPU_IS_060) {
223 if (!(sc->sc_fpstate[3] == 0x00 || 223 if (!(sc->sc_fpstate[3] == 0x00 ||
224 sc->sc_fpstate[3] == 0x60 || 224 sc->sc_fpstate[3] == 0x60 ||
225 sc->sc_fpstate[3] == 0xe0)) 225 sc->sc_fpstate[3] == 0xe0))
226 goto out; 226 goto out;
227 } else 227 } else
228 goto out; 228 goto out;
229 229
230 __asm__ volatile (".chip 68k/68881\n\t" 230 __asm__ volatile (".chip 68k/68881\n\t"
231 "fmovemx %0,%%fp0-%%fp1\n\t" 231 "fmovemx %0,%%fp0-%%fp1\n\t"
232 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" 232 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
233 ".chip 68k" 233 ".chip 68k"
234 : /* no outputs */ 234 : /* no outputs */
235 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); 235 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
236 } 236 }
237 __asm__ volatile (".chip 68k/68881\n\t" 237 __asm__ volatile (".chip 68k/68881\n\t"
238 "frestore %0\n\t" 238 "frestore %0\n\t"
239 ".chip 68k" : : "m" (*sc->sc_fpstate)); 239 ".chip 68k" : : "m" (*sc->sc_fpstate));
240 err = 0; 240 err = 0;
241 241
242 out: 242 out:
243 return err; 243 return err;
244 } 244 }
245 245
246 #define FPCONTEXT_SIZE 216 246 #define FPCONTEXT_SIZE 216
247 #define uc_fpstate uc_filler[0] 247 #define uc_fpstate uc_filler[0]
248 #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] 248 #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
249 #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] 249 #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
250 250
251 static inline int rt_restore_fpu_state(struct ucontext __user *uc) 251 static inline int rt_restore_fpu_state(struct ucontext __user *uc)
252 { 252 {
253 unsigned char fpstate[FPCONTEXT_SIZE]; 253 unsigned char fpstate[FPCONTEXT_SIZE];
254 int context_size = CPU_IS_060 ? 8 : 0; 254 int context_size = CPU_IS_060 ? 8 : 0;
255 fpregset_t fpregs; 255 fpregset_t fpregs;
256 int err = 1; 256 int err = 1;
257 257
258 if (FPU_IS_EMU) { 258 if (FPU_IS_EMU) {
259 /* restore fpu control register */ 259 /* restore fpu control register */
260 if (__copy_from_user(current->thread.fpcntl, 260 if (__copy_from_user(current->thread.fpcntl,
261 uc->uc_mcontext.fpregs.f_fpcntl, 12)) 261 uc->uc_mcontext.fpregs.f_fpcntl, 12))
262 goto out; 262 goto out;
263 /* restore all other fpu register */ 263 /* restore all other fpu register */
264 if (__copy_from_user(current->thread.fp, 264 if (__copy_from_user(current->thread.fp,
265 uc->uc_mcontext.fpregs.f_fpregs, 96)) 265 uc->uc_mcontext.fpregs.f_fpregs, 96))
266 goto out; 266 goto out;
267 return 0; 267 return 0;
268 } 268 }
269 269
270 if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) 270 if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
271 goto out; 271 goto out;
272 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { 272 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
273 if (!CPU_IS_060) 273 if (!CPU_IS_060)
274 context_size = fpstate[1]; 274 context_size = fpstate[1];
275 /* Verify the frame format. */ 275 /* Verify the frame format. */
276 if (!CPU_IS_060 && (fpstate[0] != fpu_version)) 276 if (!CPU_IS_060 && (fpstate[0] != fpu_version))
277 goto out; 277 goto out;
278 if (CPU_IS_020_OR_030) { 278 if (CPU_IS_020_OR_030) {
279 if (m68k_fputype & FPU_68881 && 279 if (m68k_fputype & FPU_68881 &&
280 !(context_size == 0x18 || context_size == 0xb4)) 280 !(context_size == 0x18 || context_size == 0xb4))
281 goto out; 281 goto out;
282 if (m68k_fputype & FPU_68882 && 282 if (m68k_fputype & FPU_68882 &&
283 !(context_size == 0x38 || context_size == 0xd4)) 283 !(context_size == 0x38 || context_size == 0xd4))
284 goto out; 284 goto out;
285 } else if (CPU_IS_040) { 285 } else if (CPU_IS_040) {
286 if (!(context_size == 0x00 || 286 if (!(context_size == 0x00 ||
287 context_size == 0x28 || 287 context_size == 0x28 ||
288 context_size == 0x60)) 288 context_size == 0x60))
289 goto out; 289 goto out;
290 } else if (CPU_IS_060) { 290 } else if (CPU_IS_060) {
291 if (!(fpstate[3] == 0x00 || 291 if (!(fpstate[3] == 0x00 ||
292 fpstate[3] == 0x60 || 292 fpstate[3] == 0x60 ||
293 fpstate[3] == 0xe0)) 293 fpstate[3] == 0xe0))
294 goto out; 294 goto out;
295 } else 295 } else
296 goto out; 296 goto out;
297 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, 297 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
298 sizeof(fpregs))) 298 sizeof(fpregs)))
299 goto out; 299 goto out;
300 __asm__ volatile (".chip 68k/68881\n\t" 300 __asm__ volatile (".chip 68k/68881\n\t"
301 "fmovemx %0,%%fp0-%%fp7\n\t" 301 "fmovemx %0,%%fp0-%%fp7\n\t"
302 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" 302 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
303 ".chip 68k" 303 ".chip 68k"
304 : /* no outputs */ 304 : /* no outputs */
305 : "m" (*fpregs.f_fpregs), 305 : "m" (*fpregs.f_fpregs),
306 "m" (*fpregs.f_fpcntl)); 306 "m" (*fpregs.f_fpcntl));
307 } 307 }
308 if (context_size && 308 if (context_size &&
309 __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, 309 __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
310 context_size)) 310 context_size))
311 goto out; 311 goto out;
312 __asm__ volatile (".chip 68k/68881\n\t" 312 __asm__ volatile (".chip 68k/68881\n\t"
313 "frestore %0\n\t" 313 "frestore %0\n\t"
314 ".chip 68k" : : "m" (*fpstate)); 314 ".chip 68k" : : "m" (*fpstate));
315 err = 0; 315 err = 0;
316 316
317 out: 317 out:
318 return err; 318 return err;
319 } 319 }
320 320
321 static inline int 321 static inline int
322 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp, 322 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp,
323 int *pd0) 323 int *pd0)
324 { 324 {
325 int fsize, formatvec; 325 int fsize, formatvec;
326 struct sigcontext context; 326 struct sigcontext context;
327 int err; 327 int err;
328 328
329 /* get previous context */ 329 /* get previous context */
330 if (copy_from_user(&context, usc, sizeof(context))) 330 if (copy_from_user(&context, usc, sizeof(context)))
331 goto badframe; 331 goto badframe;
332 332
333 /* restore passed registers */ 333 /* restore passed registers */
334 regs->d1 = context.sc_d1; 334 regs->d1 = context.sc_d1;
335 regs->a0 = context.sc_a0; 335 regs->a0 = context.sc_a0;
336 regs->a1 = context.sc_a1; 336 regs->a1 = context.sc_a1;
337 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); 337 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
338 regs->pc = context.sc_pc; 338 regs->pc = context.sc_pc;
339 regs->orig_d0 = -1; /* disable syscall checks */ 339 regs->orig_d0 = -1; /* disable syscall checks */
340 wrusp(context.sc_usp); 340 wrusp(context.sc_usp);
341 formatvec = context.sc_formatvec; 341 formatvec = context.sc_formatvec;
342 regs->format = formatvec >> 12; 342 regs->format = formatvec >> 12;
343 regs->vector = formatvec & 0xfff; 343 regs->vector = formatvec & 0xfff;
344 344
345 err = restore_fpu_state(&context); 345 err = restore_fpu_state(&context);
346 346
347 fsize = frame_extra_sizes[regs->format]; 347 fsize = frame_extra_sizes[regs->format];
348 if (fsize < 0) { 348 if (fsize < 0) {
349 /* 349 /*
350 * user process trying to return with weird frame format 350 * user process trying to return with weird frame format
351 */ 351 */
352 #ifdef DEBUG 352 #ifdef DEBUG
353 printk("user process returning with weird frame format\n"); 353 printk("user process returning with weird frame format\n");
354 #endif 354 #endif
355 goto badframe; 355 goto badframe;
356 } 356 }
357 357
358 /* OK. Make room on the supervisor stack for the extra junk, 358 /* OK. Make room on the supervisor stack for the extra junk,
359 * if necessary. 359 * if necessary.
360 */ 360 */
361 361
362 if (fsize) { 362 if (fsize) {
363 struct switch_stack *sw = (struct switch_stack *)regs - 1; 363 struct switch_stack *sw = (struct switch_stack *)regs - 1;
364 regs->d0 = context.sc_d0; 364 regs->d0 = context.sc_d0;
365 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) 365 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
366 __asm__ __volatile__ 366 __asm__ __volatile__
367 (" movel %0,%/a0\n\t" 367 (" movel %0,%/a0\n\t"
368 " subl %1,%/a0\n\t" /* make room on stack */ 368 " subl %1,%/a0\n\t" /* make room on stack */
369 " movel %/a0,%/sp\n\t" /* set stack pointer */ 369 " movel %/a0,%/sp\n\t" /* set stack pointer */
370 /* move switch_stack and pt_regs */ 370 /* move switch_stack and pt_regs */
371 "1: movel %0@+,%/a0@+\n\t" 371 "1: movel %0@+,%/a0@+\n\t"
372 " dbra %2,1b\n\t" 372 " dbra %2,1b\n\t"
373 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ 373 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
374 " lsrl #2,%1\n\t" 374 " lsrl #2,%1\n\t"
375 " subql #1,%1\n\t" 375 " subql #1,%1\n\t"
376 "2: movesl %4@+,%2\n\t" 376 "2: movesl %4@+,%2\n\t"
377 "3: movel %2,%/a0@+\n\t" 377 "3: movel %2,%/a0@+\n\t"
378 " dbra %1,2b\n\t" 378 " dbra %1,2b\n\t"
379 " bral ret_from_signal\n" 379 " bral ret_from_signal\n"
380 "4:\n" 380 "4:\n"
381 ".section __ex_table,\"a\"\n" 381 ".section __ex_table,\"a\"\n"
382 " .align 4\n" 382 " .align 4\n"
383 " .long 2b,4b\n" 383 " .long 2b,4b\n"
384 " .long 3b,4b\n" 384 " .long 3b,4b\n"
385 ".previous" 385 ".previous"
386 : /* no outputs, it doesn't ever return */ 386 : /* no outputs, it doesn't ever return */
387 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), 387 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
388 "n" (frame_offset), "a" (fp) 388 "n" (frame_offset), "a" (fp)
389 : "a0"); 389 : "a0");
390 #undef frame_offset 390 #undef frame_offset
391 /* 391 /*
392 * If we ever get here an exception occurred while 392 * If we ever get here an exception occurred while
393 * building the above stack-frame. 393 * building the above stack-frame.
394 */ 394 */
395 goto badframe; 395 goto badframe;
396 } 396 }
397 397
398 *pd0 = context.sc_d0; 398 *pd0 = context.sc_d0;
399 return err; 399 return err;
400 400
401 badframe: 401 badframe:
402 return 1; 402 return 1;
403 } 403 }
404 404
405 static inline int 405 static inline int
406 rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, 406 rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
407 struct ucontext __user *uc, int *pd0) 407 struct ucontext __user *uc, int *pd0)
408 { 408 {
409 int fsize, temp; 409 int fsize, temp;
410 greg_t __user *gregs = uc->uc_mcontext.gregs; 410 greg_t __user *gregs = uc->uc_mcontext.gregs;
411 unsigned long usp; 411 unsigned long usp;
412 int err; 412 int err;
413 413
414 err = __get_user(temp, &uc->uc_mcontext.version); 414 err = __get_user(temp, &uc->uc_mcontext.version);
415 if (temp != MCONTEXT_VERSION) 415 if (temp != MCONTEXT_VERSION)
416 goto badframe; 416 goto badframe;
417 /* restore passed registers */ 417 /* restore passed registers */
418 err |= __get_user(regs->d0, &gregs[0]); 418 err |= __get_user(regs->d0, &gregs[0]);
419 err |= __get_user(regs->d1, &gregs[1]); 419 err |= __get_user(regs->d1, &gregs[1]);
420 err |= __get_user(regs->d2, &gregs[2]); 420 err |= __get_user(regs->d2, &gregs[2]);
421 err |= __get_user(regs->d3, &gregs[3]); 421 err |= __get_user(regs->d3, &gregs[3]);
422 err |= __get_user(regs->d4, &gregs[4]); 422 err |= __get_user(regs->d4, &gregs[4]);
423 err |= __get_user(regs->d5, &gregs[5]); 423 err |= __get_user(regs->d5, &gregs[5]);
424 err |= __get_user(sw->d6, &gregs[6]); 424 err |= __get_user(sw->d6, &gregs[6]);
425 err |= __get_user(sw->d7, &gregs[7]); 425 err |= __get_user(sw->d7, &gregs[7]);
426 err |= __get_user(regs->a0, &gregs[8]); 426 err |= __get_user(regs->a0, &gregs[8]);
427 err |= __get_user(regs->a1, &gregs[9]); 427 err |= __get_user(regs->a1, &gregs[9]);
428 err |= __get_user(regs->a2, &gregs[10]); 428 err |= __get_user(regs->a2, &gregs[10]);
429 err |= __get_user(sw->a3, &gregs[11]); 429 err |= __get_user(sw->a3, &gregs[11]);
430 err |= __get_user(sw->a4, &gregs[12]); 430 err |= __get_user(sw->a4, &gregs[12]);
431 err |= __get_user(sw->a5, &gregs[13]); 431 err |= __get_user(sw->a5, &gregs[13]);
432 err |= __get_user(sw->a6, &gregs[14]); 432 err |= __get_user(sw->a6, &gregs[14]);
433 err |= __get_user(usp, &gregs[15]); 433 err |= __get_user(usp, &gregs[15]);
434 wrusp(usp); 434 wrusp(usp);
435 err |= __get_user(regs->pc, &gregs[16]); 435 err |= __get_user(regs->pc, &gregs[16]);
436 err |= __get_user(temp, &gregs[17]); 436 err |= __get_user(temp, &gregs[17]);
437 regs->sr = (regs->sr & 0xff00) | (temp & 0xff); 437 regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
438 regs->orig_d0 = -1; /* disable syscall checks */ 438 regs->orig_d0 = -1; /* disable syscall checks */
439 err |= __get_user(temp, &uc->uc_formatvec); 439 err |= __get_user(temp, &uc->uc_formatvec);
440 regs->format = temp >> 12; 440 regs->format = temp >> 12;
441 regs->vector = temp & 0xfff; 441 regs->vector = temp & 0xfff;
442 442
443 err |= rt_restore_fpu_state(uc); 443 err |= rt_restore_fpu_state(uc);
444 444
445 if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) 445 if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
446 goto badframe; 446 goto badframe;
447 447
448 fsize = frame_extra_sizes[regs->format]; 448 fsize = frame_extra_sizes[regs->format];
449 if (fsize < 0) { 449 if (fsize < 0) {
450 /* 450 /*
451 * user process trying to return with weird frame format 451 * user process trying to return with weird frame format
452 */ 452 */
453 #ifdef DEBUG 453 #ifdef DEBUG
454 printk("user process returning with weird frame format\n"); 454 printk("user process returning with weird frame format\n");
455 #endif 455 #endif
456 goto badframe; 456 goto badframe;
457 } 457 }
458 458
459 /* OK. Make room on the supervisor stack for the extra junk, 459 /* OK. Make room on the supervisor stack for the extra junk,
460 * if necessary. 460 * if necessary.
461 */ 461 */
462 462
463 if (fsize) { 463 if (fsize) {
464 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) 464 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
465 __asm__ __volatile__ 465 __asm__ __volatile__
466 (" movel %0,%/a0\n\t" 466 (" movel %0,%/a0\n\t"
467 " subl %1,%/a0\n\t" /* make room on stack */ 467 " subl %1,%/a0\n\t" /* make room on stack */
468 " movel %/a0,%/sp\n\t" /* set stack pointer */ 468 " movel %/a0,%/sp\n\t" /* set stack pointer */
469 /* move switch_stack and pt_regs */ 469 /* move switch_stack and pt_regs */
470 "1: movel %0@+,%/a0@+\n\t" 470 "1: movel %0@+,%/a0@+\n\t"
471 " dbra %2,1b\n\t" 471 " dbra %2,1b\n\t"
472 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ 472 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
473 " lsrl #2,%1\n\t" 473 " lsrl #2,%1\n\t"
474 " subql #1,%1\n\t" 474 " subql #1,%1\n\t"
475 "2: movesl %4@+,%2\n\t" 475 "2: movesl %4@+,%2\n\t"
476 "3: movel %2,%/a0@+\n\t" 476 "3: movel %2,%/a0@+\n\t"
477 " dbra %1,2b\n\t" 477 " dbra %1,2b\n\t"
478 " bral ret_from_signal\n" 478 " bral ret_from_signal\n"
479 "4:\n" 479 "4:\n"
480 ".section __ex_table,\"a\"\n" 480 ".section __ex_table,\"a\"\n"
481 " .align 4\n" 481 " .align 4\n"
482 " .long 2b,4b\n" 482 " .long 2b,4b\n"
483 " .long 3b,4b\n" 483 " .long 3b,4b\n"
484 ".previous" 484 ".previous"
485 : /* no outputs, it doesn't ever return */ 485 : /* no outputs, it doesn't ever return */
486 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), 486 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
487 "n" (frame_offset), "a" (&uc->uc_extra) 487 "n" (frame_offset), "a" (&uc->uc_extra)
488 : "a0"); 488 : "a0");
489 #undef frame_offset 489 #undef frame_offset
490 /* 490 /*
491 * If we ever get here an exception occurred while 491 * If we ever get here an exception occurred while
492 * building the above stack-frame. 492 * building the above stack-frame.
493 */ 493 */
494 goto badframe; 494 goto badframe;
495 } 495 }
496 496
497 *pd0 = regs->d0; 497 *pd0 = regs->d0;
498 return err; 498 return err;
499 499
500 badframe: 500 badframe:
501 return 1; 501 return 1;
502 } 502 }
503 503
504 asmlinkage int do_sigreturn(unsigned long __unused) 504 asmlinkage int do_sigreturn(unsigned long __unused)
505 { 505 {
506 struct switch_stack *sw = (struct switch_stack *) &__unused; 506 struct switch_stack *sw = (struct switch_stack *) &__unused;
507 struct pt_regs *regs = (struct pt_regs *) (sw + 1); 507 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
508 unsigned long usp = rdusp(); 508 unsigned long usp = rdusp();
509 struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); 509 struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
510 sigset_t set; 510 sigset_t set;
511 int d0; 511 int d0;
512 512
513 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 513 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
514 goto badframe; 514 goto badframe;
515 if (__get_user(set.sig[0], &frame->sc.sc_mask) || 515 if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
516 (_NSIG_WORDS > 1 && 516 (_NSIG_WORDS > 1 &&
517 __copy_from_user(&set.sig[1], &frame->extramask, 517 __copy_from_user(&set.sig[1], &frame->extramask,
518 sizeof(frame->extramask)))) 518 sizeof(frame->extramask))))
519 goto badframe; 519 goto badframe;
520 520
521 sigdelsetmask(&set, ~_BLOCKABLE); 521 sigdelsetmask(&set, ~_BLOCKABLE);
522 current->blocked = set; 522 current->blocked = set;
523 recalc_sigpending(); 523 recalc_sigpending();
524 524
525 if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0)) 525 if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
526 goto badframe; 526 goto badframe;
527 return d0; 527 return d0;
528 528
529 badframe: 529 badframe:
530 force_sig(SIGSEGV, current); 530 force_sig(SIGSEGV, current);
531 return 0; 531 return 0;
532 } 532 }
533 533
534 asmlinkage int do_rt_sigreturn(unsigned long __unused) 534 asmlinkage int do_rt_sigreturn(unsigned long __unused)
535 { 535 {
536 struct switch_stack *sw = (struct switch_stack *) &__unused; 536 struct switch_stack *sw = (struct switch_stack *) &__unused;
537 struct pt_regs *regs = (struct pt_regs *) (sw + 1); 537 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
538 unsigned long usp = rdusp(); 538 unsigned long usp = rdusp();
539 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); 539 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
540 sigset_t set; 540 sigset_t set;
541 int d0; 541 int d0;
542 542
543 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 543 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
544 goto badframe; 544 goto badframe;
545 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 545 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
546 goto badframe; 546 goto badframe;
547 547
548 sigdelsetmask(&set, ~_BLOCKABLE); 548 sigdelsetmask(&set, ~_BLOCKABLE);
549 current->blocked = set; 549 current->blocked = set;
550 recalc_sigpending(); 550 recalc_sigpending();
551 551
552 if (rt_restore_ucontext(regs, sw, &frame->uc, &d0)) 552 if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
553 goto badframe; 553 goto badframe;
554 return d0; 554 return d0;
555 555
556 badframe: 556 badframe:
557 force_sig(SIGSEGV, current); 557 force_sig(SIGSEGV, current);
558 return 0; 558 return 0;
559 } 559 }
560 560
561 /* 561 /*
562 * Set up a signal frame. 562 * Set up a signal frame.
563 */ 563 */
564 564
565 static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) 565 static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
566 { 566 {
567 if (FPU_IS_EMU) { 567 if (FPU_IS_EMU) {
568 /* save registers */ 568 /* save registers */
569 memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); 569 memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
570 memcpy(sc->sc_fpregs, current->thread.fp, 24); 570 memcpy(sc->sc_fpregs, current->thread.fp, 24);
571 return; 571 return;
572 } 572 }
573 573
574 __asm__ volatile (".chip 68k/68881\n\t" 574 __asm__ volatile (".chip 68k/68881\n\t"
575 "fsave %0\n\t" 575 "fsave %0\n\t"
576 ".chip 68k" 576 ".chip 68k"
577 : : "m" (*sc->sc_fpstate) : "memory"); 577 : : "m" (*sc->sc_fpstate) : "memory");
578 578
579 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { 579 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
580 fpu_version = sc->sc_fpstate[0]; 580 fpu_version = sc->sc_fpstate[0];
581 if (CPU_IS_020_OR_030 && 581 if (CPU_IS_020_OR_030 &&
582 regs->vector >= (VEC_FPBRUC * 4) && 582 regs->vector >= (VEC_FPBRUC * 4) &&
583 regs->vector <= (VEC_FPNAN * 4)) { 583 regs->vector <= (VEC_FPNAN * 4)) {
584 /* Clear pending exception in 68882 idle frame */ 584 /* Clear pending exception in 68882 idle frame */
585 if (*(unsigned short *) sc->sc_fpstate == 0x1f38) 585 if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
586 sc->sc_fpstate[0x38] |= 1 << 3; 586 sc->sc_fpstate[0x38] |= 1 << 3;
587 } 587 }
588 __asm__ volatile (".chip 68k/68881\n\t" 588 __asm__ volatile (".chip 68k/68881\n\t"
589 "fmovemx %%fp0-%%fp1,%0\n\t" 589 "fmovemx %%fp0-%%fp1,%0\n\t"
590 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" 590 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
591 ".chip 68k" 591 ".chip 68k"
592 : "=m" (*sc->sc_fpregs), 592 : "=m" (*sc->sc_fpregs),
593 "=m" (*sc->sc_fpcntl) 593 "=m" (*sc->sc_fpcntl)
594 : /* no inputs */ 594 : /* no inputs */
595 : "memory"); 595 : "memory");
596 } 596 }
597 } 597 }
598 598
599 static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) 599 static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
600 { 600 {
601 unsigned char fpstate[FPCONTEXT_SIZE]; 601 unsigned char fpstate[FPCONTEXT_SIZE];
602 int context_size = CPU_IS_060 ? 8 : 0; 602 int context_size = CPU_IS_060 ? 8 : 0;
603 int err = 0; 603 int err = 0;
604 604
605 if (FPU_IS_EMU) { 605 if (FPU_IS_EMU) {
606 /* save fpu control register */ 606 /* save fpu control register */
607 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, 607 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,
608 current->thread.fpcntl, 12); 608 current->thread.fpcntl, 12);
609 /* save all other fpu register */ 609 /* save all other fpu register */
610 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, 610 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
611 current->thread.fp, 96); 611 current->thread.fp, 96);
612 return err; 612 return err;
613 } 613 }
614 614
615 __asm__ volatile (".chip 68k/68881\n\t" 615 __asm__ volatile (".chip 68k/68881\n\t"
616 "fsave %0\n\t" 616 "fsave %0\n\t"
617 ".chip 68k" 617 ".chip 68k"
618 : : "m" (*fpstate) : "memory"); 618 : : "m" (*fpstate) : "memory");
619 619
620 err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); 620 err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
621 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { 621 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
622 fpregset_t fpregs; 622 fpregset_t fpregs;
623 if (!CPU_IS_060) 623 if (!CPU_IS_060)
624 context_size = fpstate[1]; 624 context_size = fpstate[1];
625 fpu_version = fpstate[0]; 625 fpu_version = fpstate[0];
626 if (CPU_IS_020_OR_030 && 626 if (CPU_IS_020_OR_030 &&
627 regs->vector >= (VEC_FPBRUC * 4) && 627 regs->vector >= (VEC_FPBRUC * 4) &&
628 regs->vector <= (VEC_FPNAN * 4)) { 628 regs->vector <= (VEC_FPNAN * 4)) {
629 /* Clear pending exception in 68882 idle frame */ 629 /* Clear pending exception in 68882 idle frame */
630 if (*(unsigned short *) fpstate == 0x1f38) 630 if (*(unsigned short *) fpstate == 0x1f38)
631 fpstate[0x38] |= 1 << 3; 631 fpstate[0x38] |= 1 << 3;
632 } 632 }
633 __asm__ volatile (".chip 68k/68881\n\t" 633 __asm__ volatile (".chip 68k/68881\n\t"
634 "fmovemx %%fp0-%%fp7,%0\n\t" 634 "fmovemx %%fp0-%%fp7,%0\n\t"
635 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" 635 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
636 ".chip 68k" 636 ".chip 68k"
637 : "=m" (*fpregs.f_fpregs), 637 : "=m" (*fpregs.f_fpregs),
638 "=m" (*fpregs.f_fpcntl) 638 "=m" (*fpregs.f_fpcntl)
639 : /* no inputs */ 639 : /* no inputs */
640 : "memory"); 640 : "memory");
641 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, 641 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
642 sizeof(fpregs)); 642 sizeof(fpregs));
643 } 643 }
644 if (context_size) 644 if (context_size)
645 err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, 645 err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,
646 context_size); 646 context_size);
647 return err; 647 return err;
648 } 648 }
649 649
650 static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, 650 static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
651 unsigned long mask) 651 unsigned long mask)
652 { 652 {
653 sc->sc_mask = mask; 653 sc->sc_mask = mask;
654 sc->sc_usp = rdusp(); 654 sc->sc_usp = rdusp();
655 sc->sc_d0 = regs->d0; 655 sc->sc_d0 = regs->d0;
656 sc->sc_d1 = regs->d1; 656 sc->sc_d1 = regs->d1;
657 sc->sc_a0 = regs->a0; 657 sc->sc_a0 = regs->a0;
658 sc->sc_a1 = regs->a1; 658 sc->sc_a1 = regs->a1;
659 sc->sc_sr = regs->sr; 659 sc->sc_sr = regs->sr;
660 sc->sc_pc = regs->pc; 660 sc->sc_pc = regs->pc;
661 sc->sc_formatvec = regs->format << 12 | regs->vector; 661 sc->sc_formatvec = regs->format << 12 | regs->vector;
662 save_fpu_state(sc, regs); 662 save_fpu_state(sc, regs);
663 } 663 }
664 664
665 static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) 665 static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
666 { 666 {
667 struct switch_stack *sw = (struct switch_stack *)regs - 1; 667 struct switch_stack *sw = (struct switch_stack *)regs - 1;
668 greg_t __user *gregs = uc->uc_mcontext.gregs; 668 greg_t __user *gregs = uc->uc_mcontext.gregs;
669 int err = 0; 669 int err = 0;
670 670
671 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); 671 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
672 err |= __put_user(regs->d0, &gregs[0]); 672 err |= __put_user(regs->d0, &gregs[0]);
673 err |= __put_user(regs->d1, &gregs[1]); 673 err |= __put_user(regs->d1, &gregs[1]);
674 err |= __put_user(regs->d2, &gregs[2]); 674 err |= __put_user(regs->d2, &gregs[2]);
675 err |= __put_user(regs->d3, &gregs[3]); 675 err |= __put_user(regs->d3, &gregs[3]);
676 err |= __put_user(regs->d4, &gregs[4]); 676 err |= __put_user(regs->d4, &gregs[4]);
677 err |= __put_user(regs->d5, &gregs[5]); 677 err |= __put_user(regs->d5, &gregs[5]);
678 err |= __put_user(sw->d6, &gregs[6]); 678 err |= __put_user(sw->d6, &gregs[6]);
679 err |= __put_user(sw->d7, &gregs[7]); 679 err |= __put_user(sw->d7, &gregs[7]);
680 err |= __put_user(regs->a0, &gregs[8]); 680 err |= __put_user(regs->a0, &gregs[8]);
681 err |= __put_user(regs->a1, &gregs[9]); 681 err |= __put_user(regs->a1, &gregs[9]);
682 err |= __put_user(regs->a2, &gregs[10]); 682 err |= __put_user(regs->a2, &gregs[10]);
683 err |= __put_user(sw->a3, &gregs[11]); 683 err |= __put_user(sw->a3, &gregs[11]);
684 err |= __put_user(sw->a4, &gregs[12]); 684 err |= __put_user(sw->a4, &gregs[12]);
685 err |= __put_user(sw->a5, &gregs[13]); 685 err |= __put_user(sw->a5, &gregs[13]);
686 err |= __put_user(sw->a6, &gregs[14]); 686 err |= __put_user(sw->a6, &gregs[14]);
687 err |= __put_user(rdusp(), &gregs[15]); 687 err |= __put_user(rdusp(), &gregs[15]);
688 err |= __put_user(regs->pc, &gregs[16]); 688 err |= __put_user(regs->pc, &gregs[16]);
689 err |= __put_user(regs->sr, &gregs[17]); 689 err |= __put_user(regs->sr, &gregs[17]);
690 err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec); 690 err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);
691 err |= rt_save_fpu_state(uc, regs); 691 err |= rt_save_fpu_state(uc, regs);
692 return err; 692 return err;
693 } 693 }
694 694
695 static inline void push_cache (unsigned long vaddr) 695 static inline void push_cache (unsigned long vaddr)
696 { 696 {
697 /* 697 /*
698 * Using the old cache_push_v() was really a big waste. 698 * Using the old cache_push_v() was really a big waste.
699 * 699 *
700 * What we are trying to do is to flush 8 bytes to ram. 700 * What we are trying to do is to flush 8 bytes to ram.
701 * Flushing 2 cache lines of 16 bytes is much cheaper than 701 * Flushing 2 cache lines of 16 bytes is much cheaper than
702 * flushing 1 or 2 pages, as previously done in 702 * flushing 1 or 2 pages, as previously done in
703 * cache_push_v(). 703 * cache_push_v().
704 * Jes 704 * Jes
705 */ 705 */
706 if (CPU_IS_040) { 706 if (CPU_IS_040) {
707 unsigned long temp; 707 unsigned long temp;
708 708
709 __asm__ __volatile__ (".chip 68040\n\t" 709 __asm__ __volatile__ (".chip 68040\n\t"
710 "nop\n\t" 710 "nop\n\t"
711 "ptestr (%1)\n\t" 711 "ptestr (%1)\n\t"
712 "movec %%mmusr,%0\n\t" 712 "movec %%mmusr,%0\n\t"
713 ".chip 68k" 713 ".chip 68k"
714 : "=r" (temp) 714 : "=r" (temp)
715 : "a" (vaddr)); 715 : "a" (vaddr));
716 716
717 temp &= PAGE_MASK; 717 temp &= PAGE_MASK;
718 temp |= vaddr & ~PAGE_MASK; 718 temp |= vaddr & ~PAGE_MASK;
719 719
720 __asm__ __volatile__ (".chip 68040\n\t" 720 __asm__ __volatile__ (".chip 68040\n\t"
721 "nop\n\t" 721 "nop\n\t"
722 "cpushl %%bc,(%0)\n\t" 722 "cpushl %%bc,(%0)\n\t"
723 ".chip 68k" 723 ".chip 68k"
724 : : "a" (temp)); 724 : : "a" (temp));
725 } 725 }
726 else if (CPU_IS_060) { 726 else if (CPU_IS_060) {
727 unsigned long temp; 727 unsigned long temp;
728 __asm__ __volatile__ (".chip 68060\n\t" 728 __asm__ __volatile__ (".chip 68060\n\t"
729 "plpar (%0)\n\t" 729 "plpar (%0)\n\t"
730 ".chip 68k" 730 ".chip 68k"
731 : "=a" (temp) 731 : "=a" (temp)
732 : "0" (vaddr)); 732 : "0" (vaddr));
733 __asm__ __volatile__ (".chip 68060\n\t" 733 __asm__ __volatile__ (".chip 68060\n\t"
734 "cpushl %%bc,(%0)\n\t" 734 "cpushl %%bc,(%0)\n\t"
735 ".chip 68k" 735 ".chip 68k"
736 : : "a" (temp)); 736 : : "a" (temp));
737 } 737 }
738 else { 738 else {
739 /* 739 /*
740 * 68030/68020 have no writeback cache; 740 * 68030/68020 have no writeback cache;
741 * still need to clear icache. 741 * still need to clear icache.
742 * Note that vaddr is guaranteed to be long word aligned. 742 * Note that vaddr is guaranteed to be long word aligned.
743 */ 743 */
744 unsigned long temp; 744 unsigned long temp;
745 asm volatile ("movec %%cacr,%0" : "=r" (temp)); 745 asm volatile ("movec %%cacr,%0" : "=r" (temp));
746 temp += 4; 746 temp += 4;
747 asm volatile ("movec %0,%%caar\n\t" 747 asm volatile ("movec %0,%%caar\n\t"
748 "movec %1,%%cacr" 748 "movec %1,%%cacr"
749 : : "r" (vaddr), "r" (temp)); 749 : : "r" (vaddr), "r" (temp));
750 asm volatile ("movec %0,%%caar\n\t" 750 asm volatile ("movec %0,%%caar\n\t"
751 "movec %1,%%cacr" 751 "movec %1,%%cacr"
752 : : "r" (vaddr + 4), "r" (temp)); 752 : : "r" (vaddr + 4), "r" (temp));
753 } 753 }
754 } 754 }
755 755
756 static inline void __user * 756 static inline void __user *
757 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 757 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
758 { 758 {
759 unsigned long usp; 759 unsigned long usp;
760 760
761 /* Default to using normal stack. */ 761 /* Default to using normal stack. */
762 usp = rdusp(); 762 usp = rdusp();
763 763
764 /* This is the X/Open sanctioned signal stack switching. */ 764 /* This is the X/Open sanctioned signal stack switching. */
765 if (ka->sa.sa_flags & SA_ONSTACK) { 765 if (ka->sa.sa_flags & SA_ONSTACK) {
766 if (!on_sig_stack(usp)) 766 if (!sas_ss_flags(usp))
767 usp = current->sas_ss_sp + current->sas_ss_size; 767 usp = current->sas_ss_sp + current->sas_ss_size;
768 } 768 }
769 return (void __user *)((usp - frame_size) & -8UL); 769 return (void __user *)((usp - frame_size) & -8UL);
770 } 770 }
771 771
772 static void setup_frame (int sig, struct k_sigaction *ka, 772 static void setup_frame (int sig, struct k_sigaction *ka,
773 sigset_t *set, struct pt_regs *regs) 773 sigset_t *set, struct pt_regs *regs)
774 { 774 {
775 struct sigframe __user *frame; 775 struct sigframe __user *frame;
776 int fsize = frame_extra_sizes[regs->format]; 776 int fsize = frame_extra_sizes[regs->format];
777 struct sigcontext context; 777 struct sigcontext context;
778 int err = 0; 778 int err = 0;
779 779
780 if (fsize < 0) { 780 if (fsize < 0) {
781 #ifdef DEBUG 781 #ifdef DEBUG
782 printk ("setup_frame: Unknown frame format %#x\n", 782 printk ("setup_frame: Unknown frame format %#x\n",
783 regs->format); 783 regs->format);
784 #endif 784 #endif
785 goto give_sigsegv; 785 goto give_sigsegv;
786 } 786 }
787 787
788 frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); 788 frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
789 789
790 if (fsize) { 790 if (fsize) {
791 err |= copy_to_user (frame + 1, regs + 1, fsize); 791 err |= copy_to_user (frame + 1, regs + 1, fsize);
792 regs->stkadj = fsize; 792 regs->stkadj = fsize;
793 } 793 }
794 794
795 err |= __put_user((current_thread_info()->exec_domain 795 err |= __put_user((current_thread_info()->exec_domain
796 && current_thread_info()->exec_domain->signal_invmap 796 && current_thread_info()->exec_domain->signal_invmap
797 && sig < 32 797 && sig < 32
798 ? current_thread_info()->exec_domain->signal_invmap[sig] 798 ? current_thread_info()->exec_domain->signal_invmap[sig]
799 : sig), 799 : sig),
800 &frame->sig); 800 &frame->sig);
801 801
802 err |= __put_user(regs->vector, &frame->code); 802 err |= __put_user(regs->vector, &frame->code);
803 err |= __put_user(&frame->sc, &frame->psc); 803 err |= __put_user(&frame->sc, &frame->psc);
804 804
805 if (_NSIG_WORDS > 1) 805 if (_NSIG_WORDS > 1)
806 err |= copy_to_user(frame->extramask, &set->sig[1], 806 err |= copy_to_user(frame->extramask, &set->sig[1],
807 sizeof(frame->extramask)); 807 sizeof(frame->extramask));
808 808
809 setup_sigcontext(&context, regs, set->sig[0]); 809 setup_sigcontext(&context, regs, set->sig[0]);
810 err |= copy_to_user (&frame->sc, &context, sizeof(context)); 810 err |= copy_to_user (&frame->sc, &context, sizeof(context));
811 811
812 /* Set up to return from userspace. */ 812 /* Set up to return from userspace. */
813 err |= __put_user(frame->retcode, &frame->pretcode); 813 err |= __put_user(frame->retcode, &frame->pretcode);
814 /* moveq #,d0; trap #0 */ 814 /* moveq #,d0; trap #0 */
815 err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), 815 err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
816 (long __user *)(frame->retcode)); 816 (long __user *)(frame->retcode));
817 817
818 if (err) 818 if (err)
819 goto give_sigsegv; 819 goto give_sigsegv;
820 820
821 push_cache ((unsigned long) &frame->retcode); 821 push_cache ((unsigned long) &frame->retcode);
822 822
823 /* Set up registers for signal handler */ 823 /* Set up registers for signal handler */
824 wrusp ((unsigned long) frame); 824 wrusp ((unsigned long) frame);
825 regs->pc = (unsigned long) ka->sa.sa_handler; 825 regs->pc = (unsigned long) ka->sa.sa_handler;
826 826
827 adjust_stack: 827 adjust_stack:
828 /* Prepare to skip over the extra stuff in the exception frame. */ 828 /* Prepare to skip over the extra stuff in the exception frame. */
829 if (regs->stkadj) { 829 if (regs->stkadj) {
830 struct pt_regs *tregs = 830 struct pt_regs *tregs =
831 (struct pt_regs *)((ulong)regs + regs->stkadj); 831 (struct pt_regs *)((ulong)regs + regs->stkadj);
832 #ifdef DEBUG 832 #ifdef DEBUG
833 printk("Performing stackadjust=%04x\n", regs->stkadj); 833 printk("Performing stackadjust=%04x\n", regs->stkadj);
834 #endif 834 #endif
835 /* This must be copied with decreasing addresses to 835 /* This must be copied with decreasing addresses to
836 handle overlaps. */ 836 handle overlaps. */
837 tregs->vector = 0; 837 tregs->vector = 0;
838 tregs->format = 0; 838 tregs->format = 0;
839 tregs->pc = regs->pc; 839 tregs->pc = regs->pc;
840 tregs->sr = regs->sr; 840 tregs->sr = regs->sr;
841 } 841 }
842 return; 842 return;
843 843
844 give_sigsegv: 844 give_sigsegv:
845 force_sigsegv(sig, current); 845 force_sigsegv(sig, current);
846 goto adjust_stack; 846 goto adjust_stack;
847 } 847 }
848 848
849 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 849 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
850 sigset_t *set, struct pt_regs *regs) 850 sigset_t *set, struct pt_regs *regs)
851 { 851 {
852 struct rt_sigframe __user *frame; 852 struct rt_sigframe __user *frame;
853 int fsize = frame_extra_sizes[regs->format]; 853 int fsize = frame_extra_sizes[regs->format];
854 int err = 0; 854 int err = 0;
855 855
856 if (fsize < 0) { 856 if (fsize < 0) {
857 #ifdef DEBUG 857 #ifdef DEBUG
858 printk ("setup_frame: Unknown frame format %#x\n", 858 printk ("setup_frame: Unknown frame format %#x\n",
859 regs->format); 859 regs->format);
860 #endif 860 #endif
861 goto give_sigsegv; 861 goto give_sigsegv;
862 } 862 }
863 863
864 frame = get_sigframe(ka, regs, sizeof(*frame)); 864 frame = get_sigframe(ka, regs, sizeof(*frame));
865 865
866 if (fsize) { 866 if (fsize) {
867 err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); 867 err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
868 regs->stkadj = fsize; 868 regs->stkadj = fsize;
869 } 869 }
870 870
871 err |= __put_user((current_thread_info()->exec_domain 871 err |= __put_user((current_thread_info()->exec_domain
872 && current_thread_info()->exec_domain->signal_invmap 872 && current_thread_info()->exec_domain->signal_invmap
873 && sig < 32 873 && sig < 32
874 ? current_thread_info()->exec_domain->signal_invmap[sig] 874 ? current_thread_info()->exec_domain->signal_invmap[sig]
875 : sig), 875 : sig),
876 &frame->sig); 876 &frame->sig);
877 err |= __put_user(&frame->info, &frame->pinfo); 877 err |= __put_user(&frame->info, &frame->pinfo);
878 err |= __put_user(&frame->uc, &frame->puc); 878 err |= __put_user(&frame->uc, &frame->puc);
879 err |= copy_siginfo_to_user(&frame->info, info); 879 err |= copy_siginfo_to_user(&frame->info, info);
880 880
881 /* Create the ucontext. */ 881 /* Create the ucontext. */
882 err |= __put_user(0, &frame->uc.uc_flags); 882 err |= __put_user(0, &frame->uc.uc_flags);
883 err |= __put_user(NULL, &frame->uc.uc_link); 883 err |= __put_user(NULL, &frame->uc.uc_link);
884 err |= __put_user((void __user *)current->sas_ss_sp, 884 err |= __put_user((void __user *)current->sas_ss_sp,
885 &frame->uc.uc_stack.ss_sp); 885 &frame->uc.uc_stack.ss_sp);
886 err |= __put_user(sas_ss_flags(rdusp()), 886 err |= __put_user(sas_ss_flags(rdusp()),
887 &frame->uc.uc_stack.ss_flags); 887 &frame->uc.uc_stack.ss_flags);
888 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 888 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
889 err |= rt_setup_ucontext(&frame->uc, regs); 889 err |= rt_setup_ucontext(&frame->uc, regs);
890 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 890 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
891 891
892 /* Set up to return from userspace. */ 892 /* Set up to return from userspace. */
893 err |= __put_user(frame->retcode, &frame->pretcode); 893 err |= __put_user(frame->retcode, &frame->pretcode);
894 /* moveq #,d0; notb d0; trap #0 */ 894 /* moveq #,d0; notb d0; trap #0 */
895 err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), 895 err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
896 (long __user *)(frame->retcode + 0)); 896 (long __user *)(frame->retcode + 0));
897 err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); 897 err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4));
898 898
899 if (err) 899 if (err)
900 goto give_sigsegv; 900 goto give_sigsegv;
901 901
902 push_cache ((unsigned long) &frame->retcode); 902 push_cache ((unsigned long) &frame->retcode);
903 903
904 /* Set up registers for signal handler */ 904 /* Set up registers for signal handler */
905 wrusp ((unsigned long) frame); 905 wrusp ((unsigned long) frame);
906 regs->pc = (unsigned long) ka->sa.sa_handler; 906 regs->pc = (unsigned long) ka->sa.sa_handler;
907 907
908 adjust_stack: 908 adjust_stack:
909 /* Prepare to skip over the extra stuff in the exception frame. */ 909 /* Prepare to skip over the extra stuff in the exception frame. */
910 if (regs->stkadj) { 910 if (regs->stkadj) {
911 struct pt_regs *tregs = 911 struct pt_regs *tregs =
912 (struct pt_regs *)((ulong)regs + regs->stkadj); 912 (struct pt_regs *)((ulong)regs + regs->stkadj);
913 #ifdef DEBUG 913 #ifdef DEBUG
914 printk("Performing stackadjust=%04x\n", regs->stkadj); 914 printk("Performing stackadjust=%04x\n", regs->stkadj);
915 #endif 915 #endif
916 /* This must be copied with decreasing addresses to 916 /* This must be copied with decreasing addresses to
917 handle overlaps. */ 917 handle overlaps. */
918 tregs->vector = 0; 918 tregs->vector = 0;
919 tregs->format = 0; 919 tregs->format = 0;
920 tregs->pc = regs->pc; 920 tregs->pc = regs->pc;
921 tregs->sr = regs->sr; 921 tregs->sr = regs->sr;
922 } 922 }
923 return; 923 return;
924 924
925 give_sigsegv: 925 give_sigsegv:
926 force_sigsegv(sig, current); 926 force_sigsegv(sig, current);
927 goto adjust_stack; 927 goto adjust_stack;
928 } 928 }
929 929
930 static inline void 930 static inline void
931 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) 931 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
932 { 932 {
933 switch (regs->d0) { 933 switch (regs->d0) {
934 case -ERESTARTNOHAND: 934 case -ERESTARTNOHAND:
935 if (!has_handler) 935 if (!has_handler)
936 goto do_restart; 936 goto do_restart;
937 regs->d0 = -EINTR; 937 regs->d0 = -EINTR;
938 break; 938 break;
939 939
940 case -ERESTARTSYS: 940 case -ERESTARTSYS:
941 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { 941 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
942 regs->d0 = -EINTR; 942 regs->d0 = -EINTR;
943 break; 943 break;
944 } 944 }
945 /* fallthrough */ 945 /* fallthrough */
946 case -ERESTARTNOINTR: 946 case -ERESTARTNOINTR:
947 do_restart: 947 do_restart:
948 regs->d0 = regs->orig_d0; 948 regs->d0 = regs->orig_d0;
949 regs->pc -= 2; 949 regs->pc -= 2;
950 break; 950 break;
951 } 951 }
952 } 952 }
953 953
954 void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) 954 void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
955 { 955 {
956 if (regs->orig_d0 < 0) 956 if (regs->orig_d0 < 0)
957 return; 957 return;
958 switch (regs->d0) { 958 switch (regs->d0) {
959 case -ERESTARTNOHAND: 959 case -ERESTARTNOHAND:
960 case -ERESTARTSYS: 960 case -ERESTARTSYS:
961 case -ERESTARTNOINTR: 961 case -ERESTARTNOINTR:
962 regs->d0 = regs->orig_d0; 962 regs->d0 = regs->orig_d0;
963 regs->orig_d0 = -1; 963 regs->orig_d0 = -1;
964 regs->pc -= 2; 964 regs->pc -= 2;
965 break; 965 break;
966 } 966 }
967 } 967 }
968 968
969 /* 969 /*
970 * OK, we're invoking a handler 970 * OK, we're invoking a handler
971 */ 971 */
972 static void 972 static void
973 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 973 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
974 sigset_t *oldset, struct pt_regs *regs) 974 sigset_t *oldset, struct pt_regs *regs)
975 { 975 {
976 /* are we from a system call? */ 976 /* are we from a system call? */
977 if (regs->orig_d0 >= 0) 977 if (regs->orig_d0 >= 0)
978 /* If so, check system call restarting.. */ 978 /* If so, check system call restarting.. */
979 handle_restart(regs, ka, 1); 979 handle_restart(regs, ka, 1);
980 980
981 /* set up the stack frame */ 981 /* set up the stack frame */
982 if (ka->sa.sa_flags & SA_SIGINFO) 982 if (ka->sa.sa_flags & SA_SIGINFO)
983 setup_rt_frame(sig, ka, info, oldset, regs); 983 setup_rt_frame(sig, ka, info, oldset, regs);
984 else 984 else
985 setup_frame(sig, ka, oldset, regs); 985 setup_frame(sig, ka, oldset, regs);
986 986
987 if (ka->sa.sa_flags & SA_ONESHOT) 987 if (ka->sa.sa_flags & SA_ONESHOT)
988 ka->sa.sa_handler = SIG_DFL; 988 ka->sa.sa_handler = SIG_DFL;
989 989
990 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 990 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
991 if (!(ka->sa.sa_flags & SA_NODEFER)) 991 if (!(ka->sa.sa_flags & SA_NODEFER))
992 sigaddset(&current->blocked,sig); 992 sigaddset(&current->blocked,sig);
993 recalc_sigpending(); 993 recalc_sigpending();
994 } 994 }
995 995
996 /* 996 /*
997 * Note that 'init' is a special process: it doesn't get signals it doesn't 997 * Note that 'init' is a special process: it doesn't get signals it doesn't
998 * want to handle. Thus you cannot kill init even with a SIGKILL even by 998 * want to handle. Thus you cannot kill init even with a SIGKILL even by
999 * mistake. 999 * mistake.
1000 */ 1000 */
1001 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) 1001 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
1002 { 1002 {
1003 siginfo_t info; 1003 siginfo_t info;
1004 struct k_sigaction ka; 1004 struct k_sigaction ka;
1005 int signr; 1005 int signr;
1006 1006
1007 current->thread.esp0 = (unsigned long) regs; 1007 current->thread.esp0 = (unsigned long) regs;
1008 1008
1009 if (!oldset) 1009 if (!oldset)
1010 oldset = &current->blocked; 1010 oldset = &current->blocked;
1011 1011
1012 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 1012 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
1013 if (signr > 0) { 1013 if (signr > 0) {
1014 /* Whee! Actually deliver the signal. */ 1014 /* Whee! Actually deliver the signal. */
1015 handle_signal(signr, &ka, &info, oldset, regs); 1015 handle_signal(signr, &ka, &info, oldset, regs);
1016 return 1; 1016 return 1;
1017 } 1017 }
1018 1018
1019 /* Did we come from a system call? */ 1019 /* Did we come from a system call? */
1020 if (regs->orig_d0 >= 0) 1020 if (regs->orig_d0 >= 0)
1021 /* Restart the system call - no handlers present */ 1021 /* Restart the system call - no handlers present */
1022 handle_restart(regs, NULL, 0); 1022 handle_restart(regs, NULL, 0);
1023 1023
1024 return 0; 1024 return 0;
1025 } 1025 }
1026 1026
arch/m68knommu/kernel/signal.c
1 /* 1 /*
2 * linux/arch/m68knommu/kernel/signal.c 2 * linux/arch/m68knommu/kernel/signal.c
3 * 3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * 5 *
6 * This file is subject to the terms and conditions of the GNU General Public 6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive 7 * License. See the file COPYING in the main directory of this archive
8 * for more details. 8 * for more details.
9 */ 9 */
10 10
11 /* 11 /*
12 * Linux/m68k support by Hamish Macdonald 12 * Linux/m68k support by Hamish Macdonald
13 * 13 *
14 * 68060 fixes by Jesper Skov 14 * 68060 fixes by Jesper Skov
15 * 15 *
16 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab 16 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab
17 * 17 *
18 * mathemu support by Roman Zippel 18 * mathemu support by Roman Zippel
19 * (Note: fpstate in the signal context is completely ignored for the emulator 19 * (Note: fpstate in the signal context is completely ignored for the emulator
20 * and the internal floating point format is put on stack) 20 * and the internal floating point format is put on stack)
21 */ 21 */
22 22
23 /* 23 /*
24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
25 * Atari :-) Current limitation: Only one sigstack can be active at one time. 25 * Atari :-) Current limitation: Only one sigstack can be active at one time.
26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
28 * signal handlers! 28 * signal handlers!
29 */ 29 */
30 30
31 #include <linux/sched.h> 31 #include <linux/sched.h>
32 #include <linux/mm.h> 32 #include <linux/mm.h>
33 #include <linux/kernel.h> 33 #include <linux/kernel.h>
34 #include <linux/signal.h> 34 #include <linux/signal.h>
35 #include <linux/syscalls.h> 35 #include <linux/syscalls.h>
36 #include <linux/errno.h> 36 #include <linux/errno.h>
37 #include <linux/wait.h> 37 #include <linux/wait.h>
38 #include <linux/ptrace.h> 38 #include <linux/ptrace.h>
39 #include <linux/unistd.h> 39 #include <linux/unistd.h>
40 #include <linux/stddef.h> 40 #include <linux/stddef.h>
41 #include <linux/highuid.h> 41 #include <linux/highuid.h>
42 #include <linux/tty.h> 42 #include <linux/tty.h>
43 #include <linux/personality.h> 43 #include <linux/personality.h>
44 #include <linux/binfmts.h> 44 #include <linux/binfmts.h>
45 45
46 #include <asm/setup.h> 46 #include <asm/setup.h>
47 #include <asm/uaccess.h> 47 #include <asm/uaccess.h>
48 #include <asm/pgtable.h> 48 #include <asm/pgtable.h>
49 #include <asm/traps.h> 49 #include <asm/traps.h>
50 #include <asm/ucontext.h> 50 #include <asm/ucontext.h>
51 51
52 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 52 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
53 53
54 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); 54 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
55 55
56 /* 56 /*
57 * Atomically swap in the new signal mask, and wait for a signal. 57 * Atomically swap in the new signal mask, and wait for a signal.
58 */ 58 */
59 asmlinkage int do_sigsuspend(struct pt_regs *regs) 59 asmlinkage int do_sigsuspend(struct pt_regs *regs)
60 { 60 {
61 old_sigset_t mask = regs->d3; 61 old_sigset_t mask = regs->d3;
62 sigset_t saveset; 62 sigset_t saveset;
63 63
64 mask &= _BLOCKABLE; 64 mask &= _BLOCKABLE;
65 spin_lock_irq(&current->sighand->siglock); 65 spin_lock_irq(&current->sighand->siglock);
66 saveset = current->blocked; 66 saveset = current->blocked;
67 siginitset(&current->blocked, mask); 67 siginitset(&current->blocked, mask);
68 recalc_sigpending(); 68 recalc_sigpending();
69 spin_unlock_irq(&current->sighand->siglock); 69 spin_unlock_irq(&current->sighand->siglock);
70 70
71 regs->d0 = -EINTR; 71 regs->d0 = -EINTR;
72 while (1) { 72 while (1) {
73 current->state = TASK_INTERRUPTIBLE; 73 current->state = TASK_INTERRUPTIBLE;
74 schedule(); 74 schedule();
75 if (do_signal(&saveset, regs)) 75 if (do_signal(&saveset, regs))
76 return -EINTR; 76 return -EINTR;
77 } 77 }
78 } 78 }
79 79
80 asmlinkage int 80 asmlinkage int
81 do_rt_sigsuspend(struct pt_regs *regs) 81 do_rt_sigsuspend(struct pt_regs *regs)
82 { 82 {
83 sigset_t *unewset = (sigset_t *)regs->d1; 83 sigset_t *unewset = (sigset_t *)regs->d1;
84 size_t sigsetsize = (size_t)regs->d2; 84 size_t sigsetsize = (size_t)regs->d2;
85 sigset_t saveset, newset; 85 sigset_t saveset, newset;
86 86
87 /* XXX: Don't preclude handling different sized sigset_t's. */ 87 /* XXX: Don't preclude handling different sized sigset_t's. */
88 if (sigsetsize != sizeof(sigset_t)) 88 if (sigsetsize != sizeof(sigset_t))
89 return -EINVAL; 89 return -EINVAL;
90 90
91 if (copy_from_user(&newset, unewset, sizeof(newset))) 91 if (copy_from_user(&newset, unewset, sizeof(newset)))
92 return -EFAULT; 92 return -EFAULT;
93 sigdelsetmask(&newset, ~_BLOCKABLE); 93 sigdelsetmask(&newset, ~_BLOCKABLE);
94 94
95 spin_lock_irq(&current->sighand->siglock); 95 spin_lock_irq(&current->sighand->siglock);
96 saveset = current->blocked; 96 saveset = current->blocked;
97 current->blocked = newset; 97 current->blocked = newset;
98 recalc_sigpending(); 98 recalc_sigpending();
99 spin_unlock_irq(&current->sighand->siglock); 99 spin_unlock_irq(&current->sighand->siglock);
100 100
101 regs->d0 = -EINTR; 101 regs->d0 = -EINTR;
102 while (1) { 102 while (1) {
103 current->state = TASK_INTERRUPTIBLE; 103 current->state = TASK_INTERRUPTIBLE;
104 schedule(); 104 schedule();
105 if (do_signal(&saveset, regs)) 105 if (do_signal(&saveset, regs))
106 return -EINTR; 106 return -EINTR;
107 } 107 }
108 } 108 }
109 109
110 asmlinkage int 110 asmlinkage int
111 sys_sigaction(int sig, const struct old_sigaction *act, 111 sys_sigaction(int sig, const struct old_sigaction *act,
112 struct old_sigaction *oact) 112 struct old_sigaction *oact)
113 { 113 {
114 struct k_sigaction new_ka, old_ka; 114 struct k_sigaction new_ka, old_ka;
115 int ret; 115 int ret;
116 116
117 if (act) { 117 if (act) {
118 old_sigset_t mask; 118 old_sigset_t mask;
119 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 119 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
120 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 120 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
121 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 121 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
122 return -EFAULT; 122 return -EFAULT;
123 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 123 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
124 __get_user(mask, &act->sa_mask); 124 __get_user(mask, &act->sa_mask);
125 siginitset(&new_ka.sa.sa_mask, mask); 125 siginitset(&new_ka.sa.sa_mask, mask);
126 } 126 }
127 127
128 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 128 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
129 129
130 if (!ret && oact) { 130 if (!ret && oact) {
131 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 131 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
132 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 132 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
133 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 133 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
134 return -EFAULT; 134 return -EFAULT;
135 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 135 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
136 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 136 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
137 } 137 }
138 138
139 return ret; 139 return ret;
140 } 140 }
141 141
142 asmlinkage int 142 asmlinkage int
143 sys_sigaltstack(const stack_t *uss, stack_t *uoss) 143 sys_sigaltstack(const stack_t *uss, stack_t *uoss)
144 { 144 {
145 return do_sigaltstack(uss, uoss, rdusp()); 145 return do_sigaltstack(uss, uoss, rdusp());
146 } 146 }
147 147
148 148
149 /* 149 /*
150 * Do a signal return; undo the signal stack. 150 * Do a signal return; undo the signal stack.
151 * 151 *
152 * Keep the return code on the stack quadword aligned! 152 * Keep the return code on the stack quadword aligned!
153 * That makes the cache flush below easier. 153 * That makes the cache flush below easier.
154 */ 154 */
155 155
156 struct sigframe 156 struct sigframe
157 { 157 {
158 char *pretcode; 158 char *pretcode;
159 int sig; 159 int sig;
160 int code; 160 int code;
161 struct sigcontext *psc; 161 struct sigcontext *psc;
162 char retcode[8]; 162 char retcode[8];
163 unsigned long extramask[_NSIG_WORDS-1]; 163 unsigned long extramask[_NSIG_WORDS-1];
164 struct sigcontext sc; 164 struct sigcontext sc;
165 }; 165 };
166 166
167 struct rt_sigframe 167 struct rt_sigframe
168 { 168 {
169 char *pretcode; 169 char *pretcode;
170 int sig; 170 int sig;
171 struct siginfo *pinfo; 171 struct siginfo *pinfo;
172 void *puc; 172 void *puc;
173 char retcode[8]; 173 char retcode[8];
174 struct siginfo info; 174 struct siginfo info;
175 struct ucontext uc; 175 struct ucontext uc;
176 }; 176 };
177 177
178 #ifdef CONFIG_FPU 178 #ifdef CONFIG_FPU
179 179
180 static unsigned char fpu_version = 0; /* version number of fpu, set by setup_frame */ 180 static unsigned char fpu_version = 0; /* version number of fpu, set by setup_frame */
181 181
182 static inline int restore_fpu_state(struct sigcontext *sc) 182 static inline int restore_fpu_state(struct sigcontext *sc)
183 { 183 {
184 int err = 1; 184 int err = 1;
185 185
186 if (FPU_IS_EMU) { 186 if (FPU_IS_EMU) {
187 /* restore registers */ 187 /* restore registers */
188 memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); 188 memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
189 memcpy(current->thread.fp, sc->sc_fpregs, 24); 189 memcpy(current->thread.fp, sc->sc_fpregs, 24);
190 return 0; 190 return 0;
191 } 191 }
192 192
193 if (sc->sc_fpstate[0]) { 193 if (sc->sc_fpstate[0]) {
194 /* Verify the frame format. */ 194 /* Verify the frame format. */
195 if (sc->sc_fpstate[0] != fpu_version) 195 if (sc->sc_fpstate[0] != fpu_version)
196 goto out; 196 goto out;
197 197
198 __asm__ volatile (".chip 68k/68881\n\t" 198 __asm__ volatile (".chip 68k/68881\n\t"
199 "fmovemx %0,%/fp0-%/fp1\n\t" 199 "fmovemx %0,%/fp0-%/fp1\n\t"
200 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t" 200 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
201 ".chip 68k" 201 ".chip 68k"
202 : /* no outputs */ 202 : /* no outputs */
203 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); 203 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
204 } 204 }
205 __asm__ volatile (".chip 68k/68881\n\t" 205 __asm__ volatile (".chip 68k/68881\n\t"
206 "frestore %0\n\t" 206 "frestore %0\n\t"
207 ".chip 68k" : : "m" (*sc->sc_fpstate)); 207 ".chip 68k" : : "m" (*sc->sc_fpstate));
208 err = 0; 208 err = 0;
209 209
210 out: 210 out:
211 return err; 211 return err;
212 } 212 }
213 213
214 #define FPCONTEXT_SIZE 216 214 #define FPCONTEXT_SIZE 216
215 #define uc_fpstate uc_filler[0] 215 #define uc_fpstate uc_filler[0]
216 #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] 216 #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
217 #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] 217 #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
218 218
219 static inline int rt_restore_fpu_state(struct ucontext *uc) 219 static inline int rt_restore_fpu_state(struct ucontext *uc)
220 { 220 {
221 unsigned char fpstate[FPCONTEXT_SIZE]; 221 unsigned char fpstate[FPCONTEXT_SIZE];
222 int context_size = 0; 222 int context_size = 0;
223 fpregset_t fpregs; 223 fpregset_t fpregs;
224 int err = 1; 224 int err = 1;
225 225
226 if (FPU_IS_EMU) { 226 if (FPU_IS_EMU) {
227 /* restore fpu control register */ 227 /* restore fpu control register */
228 if (__copy_from_user(current->thread.fpcntl, 228 if (__copy_from_user(current->thread.fpcntl,
229 &uc->uc_mcontext.fpregs.f_pcr, 12)) 229 &uc->uc_mcontext.fpregs.f_pcr, 12))
230 goto out; 230 goto out;
231 /* restore all other fpu register */ 231 /* restore all other fpu register */
232 if (__copy_from_user(current->thread.fp, 232 if (__copy_from_user(current->thread.fp,
233 uc->uc_mcontext.fpregs.f_fpregs, 96)) 233 uc->uc_mcontext.fpregs.f_fpregs, 96))
234 goto out; 234 goto out;
235 return 0; 235 return 0;
236 } 236 }
237 237
238 if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate)) 238 if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate))
239 goto out; 239 goto out;
240 if (fpstate[0]) { 240 if (fpstate[0]) {
241 context_size = fpstate[1]; 241 context_size = fpstate[1];
242 242
243 /* Verify the frame format. */ 243 /* Verify the frame format. */
244 if (fpstate[0] != fpu_version) 244 if (fpstate[0] != fpu_version)
245 goto out; 245 goto out;
246 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, 246 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
247 sizeof(fpregs))) 247 sizeof(fpregs)))
248 goto out; 248 goto out;
249 __asm__ volatile (".chip 68k/68881\n\t" 249 __asm__ volatile (".chip 68k/68881\n\t"
250 "fmovemx %0,%/fp0-%/fp7\n\t" 250 "fmovemx %0,%/fp0-%/fp7\n\t"
251 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t" 251 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
252 ".chip 68k" 252 ".chip 68k"
253 : /* no outputs */ 253 : /* no outputs */
254 : "m" (*fpregs.f_fpregs), 254 : "m" (*fpregs.f_fpregs),
255 "m" (fpregs.f_pcr)); 255 "m" (fpregs.f_pcr));
256 } 256 }
257 if (context_size && 257 if (context_size &&
258 __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1, 258 __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1,
259 context_size)) 259 context_size))
260 goto out; 260 goto out;
261 __asm__ volatile (".chip 68k/68881\n\t" 261 __asm__ volatile (".chip 68k/68881\n\t"
262 "frestore %0\n\t" 262 "frestore %0\n\t"
263 ".chip 68k" : : "m" (*fpstate)); 263 ".chip 68k" : : "m" (*fpstate));
264 err = 0; 264 err = 0;
265 265
266 out: 266 out:
267 return err; 267 return err;
268 } 268 }
269 269
270 #endif 270 #endif
271 271
272 static inline int 272 static inline int
273 restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, 273 restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
274 int *pd0) 274 int *pd0)
275 { 275 {
276 int formatvec; 276 int formatvec;
277 struct sigcontext context; 277 struct sigcontext context;
278 int err = 0; 278 int err = 0;
279 279
280 /* get previous context */ 280 /* get previous context */
281 if (copy_from_user(&context, usc, sizeof(context))) 281 if (copy_from_user(&context, usc, sizeof(context)))
282 goto badframe; 282 goto badframe;
283 283
284 /* restore passed registers */ 284 /* restore passed registers */
285 regs->d1 = context.sc_d1; 285 regs->d1 = context.sc_d1;
286 regs->a0 = context.sc_a0; 286 regs->a0 = context.sc_a0;
287 regs->a1 = context.sc_a1; 287 regs->a1 = context.sc_a1;
288 ((struct switch_stack *)regs - 1)->a5 = context.sc_a5; 288 ((struct switch_stack *)regs - 1)->a5 = context.sc_a5;
289 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); 289 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
290 regs->pc = context.sc_pc; 290 regs->pc = context.sc_pc;
291 regs->orig_d0 = -1; /* disable syscall checks */ 291 regs->orig_d0 = -1; /* disable syscall checks */
292 wrusp(context.sc_usp); 292 wrusp(context.sc_usp);
293 formatvec = context.sc_formatvec; 293 formatvec = context.sc_formatvec;
294 regs->format = formatvec >> 12; 294 regs->format = formatvec >> 12;
295 regs->vector = formatvec & 0xfff; 295 regs->vector = formatvec & 0xfff;
296 296
297 #ifdef CONFIG_FPU 297 #ifdef CONFIG_FPU
298 err = restore_fpu_state(&context); 298 err = restore_fpu_state(&context);
299 #endif 299 #endif
300 300
301 *pd0 = context.sc_d0; 301 *pd0 = context.sc_d0;
302 return err; 302 return err;
303 303
304 badframe: 304 badframe:
305 return 1; 305 return 1;
306 } 306 }
307 307
308 static inline int 308 static inline int
309 rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, 309 rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
310 struct ucontext *uc, int *pd0) 310 struct ucontext *uc, int *pd0)
311 { 311 {
312 int temp; 312 int temp;
313 greg_t *gregs = uc->uc_mcontext.gregs; 313 greg_t *gregs = uc->uc_mcontext.gregs;
314 unsigned long usp; 314 unsigned long usp;
315 int err; 315 int err;
316 316
317 err = __get_user(temp, &uc->uc_mcontext.version); 317 err = __get_user(temp, &uc->uc_mcontext.version);
318 if (temp != MCONTEXT_VERSION) 318 if (temp != MCONTEXT_VERSION)
319 goto badframe; 319 goto badframe;
320 /* restore passed registers */ 320 /* restore passed registers */
321 err |= __get_user(regs->d0, &gregs[0]); 321 err |= __get_user(regs->d0, &gregs[0]);
322 err |= __get_user(regs->d1, &gregs[1]); 322 err |= __get_user(regs->d1, &gregs[1]);
323 err |= __get_user(regs->d2, &gregs[2]); 323 err |= __get_user(regs->d2, &gregs[2]);
324 err |= __get_user(regs->d3, &gregs[3]); 324 err |= __get_user(regs->d3, &gregs[3]);
325 err |= __get_user(regs->d4, &gregs[4]); 325 err |= __get_user(regs->d4, &gregs[4]);
326 err |= __get_user(regs->d5, &gregs[5]); 326 err |= __get_user(regs->d5, &gregs[5]);
327 err |= __get_user(sw->d6, &gregs[6]); 327 err |= __get_user(sw->d6, &gregs[6]);
328 err |= __get_user(sw->d7, &gregs[7]); 328 err |= __get_user(sw->d7, &gregs[7]);
329 err |= __get_user(regs->a0, &gregs[8]); 329 err |= __get_user(regs->a0, &gregs[8]);
330 err |= __get_user(regs->a1, &gregs[9]); 330 err |= __get_user(regs->a1, &gregs[9]);
331 err |= __get_user(regs->a2, &gregs[10]); 331 err |= __get_user(regs->a2, &gregs[10]);
332 err |= __get_user(sw->a3, &gregs[11]); 332 err |= __get_user(sw->a3, &gregs[11]);
333 err |= __get_user(sw->a4, &gregs[12]); 333 err |= __get_user(sw->a4, &gregs[12]);
334 err |= __get_user(sw->a5, &gregs[13]); 334 err |= __get_user(sw->a5, &gregs[13]);
335 err |= __get_user(sw->a6, &gregs[14]); 335 err |= __get_user(sw->a6, &gregs[14]);
336 err |= __get_user(usp, &gregs[15]); 336 err |= __get_user(usp, &gregs[15]);
337 wrusp(usp); 337 wrusp(usp);
338 err |= __get_user(regs->pc, &gregs[16]); 338 err |= __get_user(regs->pc, &gregs[16]);
339 err |= __get_user(temp, &gregs[17]); 339 err |= __get_user(temp, &gregs[17]);
340 regs->sr = (regs->sr & 0xff00) | (temp & 0xff); 340 regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
341 regs->orig_d0 = -1; /* disable syscall checks */ 341 regs->orig_d0 = -1; /* disable syscall checks */
342 regs->format = temp >> 12; 342 regs->format = temp >> 12;
343 regs->vector = temp & 0xfff; 343 regs->vector = temp & 0xfff;
344 344
345 if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) 345 if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
346 goto badframe; 346 goto badframe;
347 347
348 *pd0 = regs->d0; 348 *pd0 = regs->d0;
349 return err; 349 return err;
350 350
351 badframe: 351 badframe:
352 return 1; 352 return 1;
353 } 353 }
354 354
355 asmlinkage int do_sigreturn(unsigned long __unused) 355 asmlinkage int do_sigreturn(unsigned long __unused)
356 { 356 {
357 struct switch_stack *sw = (struct switch_stack *) &__unused; 357 struct switch_stack *sw = (struct switch_stack *) &__unused;
358 struct pt_regs *regs = (struct pt_regs *) (sw + 1); 358 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
359 unsigned long usp = rdusp(); 359 unsigned long usp = rdusp();
360 struct sigframe *frame = (struct sigframe *)(usp - 4); 360 struct sigframe *frame = (struct sigframe *)(usp - 4);
361 sigset_t set; 361 sigset_t set;
362 int d0; 362 int d0;
363 363
364 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 364 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
365 goto badframe; 365 goto badframe;
366 if (__get_user(set.sig[0], &frame->sc.sc_mask) || 366 if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
367 (_NSIG_WORDS > 1 && 367 (_NSIG_WORDS > 1 &&
368 __copy_from_user(&set.sig[1], &frame->extramask, 368 __copy_from_user(&set.sig[1], &frame->extramask,
369 sizeof(frame->extramask)))) 369 sizeof(frame->extramask))))
370 goto badframe; 370 goto badframe;
371 371
372 sigdelsetmask(&set, ~_BLOCKABLE); 372 sigdelsetmask(&set, ~_BLOCKABLE);
373 spin_lock_irq(&current->sighand->siglock); 373 spin_lock_irq(&current->sighand->siglock);
374 current->blocked = set; 374 current->blocked = set;
375 recalc_sigpending(); 375 recalc_sigpending();
376 spin_unlock_irq(&current->sighand->siglock); 376 spin_unlock_irq(&current->sighand->siglock);
377 377
378 if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0)) 378 if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
379 goto badframe; 379 goto badframe;
380 return d0; 380 return d0;
381 381
382 badframe: 382 badframe:
383 force_sig(SIGSEGV, current); 383 force_sig(SIGSEGV, current);
384 return 0; 384 return 0;
385 } 385 }
386 386
387 asmlinkage int do_rt_sigreturn(unsigned long __unused) 387 asmlinkage int do_rt_sigreturn(unsigned long __unused)
388 { 388 {
389 struct switch_stack *sw = (struct switch_stack *) &__unused; 389 struct switch_stack *sw = (struct switch_stack *) &__unused;
390 struct pt_regs *regs = (struct pt_regs *) (sw + 1); 390 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
391 unsigned long usp = rdusp(); 391 unsigned long usp = rdusp();
392 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); 392 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
393 sigset_t set; 393 sigset_t set;
394 int d0; 394 int d0;
395 395
396 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 396 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
397 goto badframe; 397 goto badframe;
398 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 398 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
399 goto badframe; 399 goto badframe;
400 400
401 sigdelsetmask(&set, ~_BLOCKABLE); 401 sigdelsetmask(&set, ~_BLOCKABLE);
402 spin_lock_irq(&current->sighand->siglock); 402 spin_lock_irq(&current->sighand->siglock);
403 current->blocked = set; 403 current->blocked = set;
404 recalc_sigpending(); 404 recalc_sigpending();
405 spin_unlock_irq(&current->sighand->siglock); 405 spin_unlock_irq(&current->sighand->siglock);
406 406
407 if (rt_restore_ucontext(regs, sw, &frame->uc, &d0)) 407 if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
408 goto badframe; 408 goto badframe;
409 return d0; 409 return d0;
410 410
411 badframe: 411 badframe:
412 force_sig(SIGSEGV, current); 412 force_sig(SIGSEGV, current);
413 return 0; 413 return 0;
414 } 414 }
415 415
416 #ifdef CONFIG_FPU 416 #ifdef CONFIG_FPU
417 /* 417 /*
418 * Set up a signal frame. 418 * Set up a signal frame.
419 */ 419 */
420 420
421 static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) 421 static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
422 { 422 {
423 if (FPU_IS_EMU) { 423 if (FPU_IS_EMU) {
424 /* save registers */ 424 /* save registers */
425 memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); 425 memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
426 memcpy(sc->sc_fpregs, current->thread.fp, 24); 426 memcpy(sc->sc_fpregs, current->thread.fp, 24);
427 return; 427 return;
428 } 428 }
429 429
430 __asm__ volatile (".chip 68k/68881\n\t" 430 __asm__ volatile (".chip 68k/68881\n\t"
431 "fsave %0\n\t" 431 "fsave %0\n\t"
432 ".chip 68k" 432 ".chip 68k"
433 : : "m" (*sc->sc_fpstate) : "memory"); 433 : : "m" (*sc->sc_fpstate) : "memory");
434 434
435 if (sc->sc_fpstate[0]) { 435 if (sc->sc_fpstate[0]) {
436 fpu_version = sc->sc_fpstate[0]; 436 fpu_version = sc->sc_fpstate[0];
437 __asm__ volatile (".chip 68k/68881\n\t" 437 __asm__ volatile (".chip 68k/68881\n\t"
438 "fmovemx %/fp0-%/fp1,%0\n\t" 438 "fmovemx %/fp0-%/fp1,%0\n\t"
439 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t" 439 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
440 ".chip 68k" 440 ".chip 68k"
441 : /* no outputs */ 441 : /* no outputs */
442 : "m" (*sc->sc_fpregs), 442 : "m" (*sc->sc_fpregs),
443 "m" (*sc->sc_fpcntl) 443 "m" (*sc->sc_fpcntl)
444 : "memory"); 444 : "memory");
445 } 445 }
446 } 446 }
447 447
448 static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs) 448 static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
449 { 449 {
450 unsigned char fpstate[FPCONTEXT_SIZE]; 450 unsigned char fpstate[FPCONTEXT_SIZE];
451 int context_size = 0; 451 int context_size = 0;
452 int err = 0; 452 int err = 0;
453 453
454 if (FPU_IS_EMU) { 454 if (FPU_IS_EMU) {
455 /* save fpu control register */ 455 /* save fpu control register */
456 err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr, 456 err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr,
457 current->thread.fpcntl, 12); 457 current->thread.fpcntl, 12);
458 /* save all other fpu register */ 458 /* save all other fpu register */
459 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, 459 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
460 current->thread.fp, 96); 460 current->thread.fp, 96);
461 return err; 461 return err;
462 } 462 }
463 463
464 __asm__ volatile (".chip 68k/68881\n\t" 464 __asm__ volatile (".chip 68k/68881\n\t"
465 "fsave %0\n\t" 465 "fsave %0\n\t"
466 ".chip 68k" 466 ".chip 68k"
467 : : "m" (*fpstate) : "memory"); 467 : : "m" (*fpstate) : "memory");
468 468
469 err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate); 469 err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
470 if (fpstate[0]) { 470 if (fpstate[0]) {
471 fpregset_t fpregs; 471 fpregset_t fpregs;
472 context_size = fpstate[1]; 472 context_size = fpstate[1];
473 fpu_version = fpstate[0]; 473 fpu_version = fpstate[0];
474 __asm__ volatile (".chip 68k/68881\n\t" 474 __asm__ volatile (".chip 68k/68881\n\t"
475 "fmovemx %/fp0-%/fp7,%0\n\t" 475 "fmovemx %/fp0-%/fp7,%0\n\t"
476 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t" 476 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
477 ".chip 68k" 477 ".chip 68k"
478 : /* no outputs */ 478 : /* no outputs */
479 : "m" (*fpregs.f_fpregs), 479 : "m" (*fpregs.f_fpregs),
480 "m" (fpregs.f_pcr) 480 "m" (fpregs.f_pcr)
481 : "memory"); 481 : "memory");
482 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, 482 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
483 sizeof(fpregs)); 483 sizeof(fpregs));
484 } 484 }
485 if (context_size) 485 if (context_size)
486 err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4, 486 err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
487 context_size); 487 context_size);
488 return err; 488 return err;
489 } 489 }
490 490
491 #endif 491 #endif
492 492
493 static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, 493 static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
494 unsigned long mask) 494 unsigned long mask)
495 { 495 {
496 sc->sc_mask = mask; 496 sc->sc_mask = mask;
497 sc->sc_usp = rdusp(); 497 sc->sc_usp = rdusp();
498 sc->sc_d0 = regs->d0; 498 sc->sc_d0 = regs->d0;
499 sc->sc_d1 = regs->d1; 499 sc->sc_d1 = regs->d1;
500 sc->sc_a0 = regs->a0; 500 sc->sc_a0 = regs->a0;
501 sc->sc_a1 = regs->a1; 501 sc->sc_a1 = regs->a1;
502 sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5; 502 sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5;
503 sc->sc_sr = regs->sr; 503 sc->sc_sr = regs->sr;
504 sc->sc_pc = regs->pc; 504 sc->sc_pc = regs->pc;
505 sc->sc_formatvec = regs->format << 12 | regs->vector; 505 sc->sc_formatvec = regs->format << 12 | regs->vector;
506 #ifdef CONFIG_FPU 506 #ifdef CONFIG_FPU
507 save_fpu_state(sc, regs); 507 save_fpu_state(sc, regs);
508 #endif 508 #endif
509 } 509 }
510 510
511 static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) 511 static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
512 { 512 {
513 struct switch_stack *sw = (struct switch_stack *)regs - 1; 513 struct switch_stack *sw = (struct switch_stack *)regs - 1;
514 greg_t *gregs = uc->uc_mcontext.gregs; 514 greg_t *gregs = uc->uc_mcontext.gregs;
515 int err = 0; 515 int err = 0;
516 516
517 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); 517 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
518 err |= __put_user(regs->d0, &gregs[0]); 518 err |= __put_user(regs->d0, &gregs[0]);
519 err |= __put_user(regs->d1, &gregs[1]); 519 err |= __put_user(regs->d1, &gregs[1]);
520 err |= __put_user(regs->d2, &gregs[2]); 520 err |= __put_user(regs->d2, &gregs[2]);
521 err |= __put_user(regs->d3, &gregs[3]); 521 err |= __put_user(regs->d3, &gregs[3]);
522 err |= __put_user(regs->d4, &gregs[4]); 522 err |= __put_user(regs->d4, &gregs[4]);
523 err |= __put_user(regs->d5, &gregs[5]); 523 err |= __put_user(regs->d5, &gregs[5]);
524 err |= __put_user(sw->d6, &gregs[6]); 524 err |= __put_user(sw->d6, &gregs[6]);
525 err |= __put_user(sw->d7, &gregs[7]); 525 err |= __put_user(sw->d7, &gregs[7]);
526 err |= __put_user(regs->a0, &gregs[8]); 526 err |= __put_user(regs->a0, &gregs[8]);
527 err |= __put_user(regs->a1, &gregs[9]); 527 err |= __put_user(regs->a1, &gregs[9]);
528 err |= __put_user(regs->a2, &gregs[10]); 528 err |= __put_user(regs->a2, &gregs[10]);
529 err |= __put_user(sw->a3, &gregs[11]); 529 err |= __put_user(sw->a3, &gregs[11]);
530 err |= __put_user(sw->a4, &gregs[12]); 530 err |= __put_user(sw->a4, &gregs[12]);
531 err |= __put_user(sw->a5, &gregs[13]); 531 err |= __put_user(sw->a5, &gregs[13]);
532 err |= __put_user(sw->a6, &gregs[14]); 532 err |= __put_user(sw->a6, &gregs[14]);
533 err |= __put_user(rdusp(), &gregs[15]); 533 err |= __put_user(rdusp(), &gregs[15]);
534 err |= __put_user(regs->pc, &gregs[16]); 534 err |= __put_user(regs->pc, &gregs[16]);
535 err |= __put_user(regs->sr, &gregs[17]); 535 err |= __put_user(regs->sr, &gregs[17]);
536 #ifdef CONFIG_FPU 536 #ifdef CONFIG_FPU
537 err |= rt_save_fpu_state(uc, regs); 537 err |= rt_save_fpu_state(uc, regs);
538 #endif 538 #endif
539 return err; 539 return err;
540 } 540 }
541 541
542 static inline void push_cache (unsigned long vaddr) 542 static inline void push_cache (unsigned long vaddr)
543 { 543 {
544 } 544 }
545 545
546 static inline void * 546 static inline void *
547 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 547 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
548 { 548 {
549 unsigned long usp; 549 unsigned long usp;
550 550
551 /* Default to using normal stack. */ 551 /* Default to using normal stack. */
552 usp = rdusp(); 552 usp = rdusp();
553 553
554 /* This is the X/Open sanctioned signal stack switching. */ 554 /* This is the X/Open sanctioned signal stack switching. */
555 if (ka->sa.sa_flags & SA_ONSTACK) { 555 if (ka->sa.sa_flags & SA_ONSTACK) {
556 if (!on_sig_stack(usp)) 556 if (!sas_ss_flags(usp))
557 usp = current->sas_ss_sp + current->sas_ss_size; 557 usp = current->sas_ss_sp + current->sas_ss_size;
558 } 558 }
559 return (void *)((usp - frame_size) & -8UL); 559 return (void *)((usp - frame_size) & -8UL);
560 } 560 }
561 561
562 static void setup_frame (int sig, struct k_sigaction *ka, 562 static void setup_frame (int sig, struct k_sigaction *ka,
563 sigset_t *set, struct pt_regs *regs) 563 sigset_t *set, struct pt_regs *regs)
564 { 564 {
565 struct sigframe *frame; 565 struct sigframe *frame;
566 struct sigcontext context; 566 struct sigcontext context;
567 int err = 0; 567 int err = 0;
568 568
569 frame = get_sigframe(ka, regs, sizeof(*frame)); 569 frame = get_sigframe(ka, regs, sizeof(*frame));
570 570
571 err |= __put_user((current_thread_info()->exec_domain 571 err |= __put_user((current_thread_info()->exec_domain
572 && current_thread_info()->exec_domain->signal_invmap 572 && current_thread_info()->exec_domain->signal_invmap
573 && sig < 32 573 && sig < 32
574 ? current_thread_info()->exec_domain->signal_invmap[sig] 574 ? current_thread_info()->exec_domain->signal_invmap[sig]
575 : sig), 575 : sig),
576 &frame->sig); 576 &frame->sig);
577 577
578 err |= __put_user(regs->vector, &frame->code); 578 err |= __put_user(regs->vector, &frame->code);
579 err |= __put_user(&frame->sc, &frame->psc); 579 err |= __put_user(&frame->sc, &frame->psc);
580 580
581 if (_NSIG_WORDS > 1) 581 if (_NSIG_WORDS > 1)
582 err |= copy_to_user(frame->extramask, &set->sig[1], 582 err |= copy_to_user(frame->extramask, &set->sig[1],
583 sizeof(frame->extramask)); 583 sizeof(frame->extramask));
584 584
585 setup_sigcontext(&context, regs, set->sig[0]); 585 setup_sigcontext(&context, regs, set->sig[0]);
586 err |= copy_to_user (&frame->sc, &context, sizeof(context)); 586 err |= copy_to_user (&frame->sc, &context, sizeof(context));
587 587
588 /* Set up to return from userspace. */ 588 /* Set up to return from userspace. */
589 err |= __put_user(frame->retcode, &frame->pretcode); 589 err |= __put_user(frame->retcode, &frame->pretcode);
590 /* moveq #,d0; trap #0 */ 590 /* moveq #,d0; trap #0 */
591 err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), 591 err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
592 (long *)(frame->retcode)); 592 (long *)(frame->retcode));
593 593
594 if (err) 594 if (err)
595 goto give_sigsegv; 595 goto give_sigsegv;
596 596
597 push_cache ((unsigned long) &frame->retcode); 597 push_cache ((unsigned long) &frame->retcode);
598 598
599 /* Set up registers for signal handler */ 599 /* Set up registers for signal handler */
600 wrusp ((unsigned long) frame); 600 wrusp ((unsigned long) frame);
601 regs->pc = (unsigned long) ka->sa.sa_handler; 601 regs->pc = (unsigned long) ka->sa.sa_handler;
602 ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data; 602 ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
603 regs->format = 0x4; /*set format byte to make stack appear modulo 4 603 regs->format = 0x4; /*set format byte to make stack appear modulo 4
604 which it will be when doing the rte */ 604 which it will be when doing the rte */
605 605
606 adjust_stack: 606 adjust_stack:
607 /* Prepare to skip over the extra stuff in the exception frame. */ 607 /* Prepare to skip over the extra stuff in the exception frame. */
608 if (regs->stkadj) { 608 if (regs->stkadj) {
609 struct pt_regs *tregs = 609 struct pt_regs *tregs =
610 (struct pt_regs *)((ulong)regs + regs->stkadj); 610 (struct pt_regs *)((ulong)regs + regs->stkadj);
611 #if DEBUG 611 #if DEBUG
612 printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); 612 printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj);
613 #endif 613 #endif
614 /* This must be copied with decreasing addresses to 614 /* This must be copied with decreasing addresses to
615 handle overlaps. */ 615 handle overlaps. */
616 tregs->vector = 0; 616 tregs->vector = 0;
617 tregs->format = 0; 617 tregs->format = 0;
618 tregs->pc = regs->pc; 618 tregs->pc = regs->pc;
619 tregs->sr = regs->sr; 619 tregs->sr = regs->sr;
620 } 620 }
621 return; 621 return;
622 622
623 give_sigsegv: 623 give_sigsegv:
624 force_sigsegv(sig, current); 624 force_sigsegv(sig, current);
625 goto adjust_stack; 625 goto adjust_stack;
626 } 626 }
627 627
628 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 628 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
629 sigset_t *set, struct pt_regs *regs) 629 sigset_t *set, struct pt_regs *regs)
630 { 630 {
631 struct rt_sigframe *frame; 631 struct rt_sigframe *frame;
632 int err = 0; 632 int err = 0;
633 633
634 frame = get_sigframe(ka, regs, sizeof(*frame)); 634 frame = get_sigframe(ka, regs, sizeof(*frame));
635 635
636 err |= __put_user((current_thread_info()->exec_domain 636 err |= __put_user((current_thread_info()->exec_domain
637 && current_thread_info()->exec_domain->signal_invmap 637 && current_thread_info()->exec_domain->signal_invmap
638 && sig < 32 638 && sig < 32
639 ? current_thread_info()->exec_domain->signal_invmap[sig] 639 ? current_thread_info()->exec_domain->signal_invmap[sig]
640 : sig), 640 : sig),
641 &frame->sig); 641 &frame->sig);
642 err |= __put_user(&frame->info, &frame->pinfo); 642 err |= __put_user(&frame->info, &frame->pinfo);
643 err |= __put_user(&frame->uc, &frame->puc); 643 err |= __put_user(&frame->uc, &frame->puc);
644 err |= copy_siginfo_to_user(&frame->info, info); 644 err |= copy_siginfo_to_user(&frame->info, info);
645 645
646 /* Create the ucontext. */ 646 /* Create the ucontext. */
647 err |= __put_user(0, &frame->uc.uc_flags); 647 err |= __put_user(0, &frame->uc.uc_flags);
648 err |= __put_user(0, &frame->uc.uc_link); 648 err |= __put_user(0, &frame->uc.uc_link);
649 err |= __put_user((void *)current->sas_ss_sp, 649 err |= __put_user((void *)current->sas_ss_sp,
650 &frame->uc.uc_stack.ss_sp); 650 &frame->uc.uc_stack.ss_sp);
651 err |= __put_user(sas_ss_flags(rdusp()), 651 err |= __put_user(sas_ss_flags(rdusp()),
652 &frame->uc.uc_stack.ss_flags); 652 &frame->uc.uc_stack.ss_flags);
653 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 653 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
654 err |= rt_setup_ucontext(&frame->uc, regs); 654 err |= rt_setup_ucontext(&frame->uc, regs);
655 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 655 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
656 656
657 /* Set up to return from userspace. */ 657 /* Set up to return from userspace. */
658 err |= __put_user(frame->retcode, &frame->pretcode); 658 err |= __put_user(frame->retcode, &frame->pretcode);
659 /* moveq #,d0; notb d0; trap #0 */ 659 /* moveq #,d0; notb d0; trap #0 */
660 err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), 660 err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
661 (long *)(frame->retcode + 0)); 661 (long *)(frame->retcode + 0));
662 err |= __put_user(0x4e40, (short *)(frame->retcode + 4)); 662 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
663 663
664 if (err) 664 if (err)
665 goto give_sigsegv; 665 goto give_sigsegv;
666 666
667 push_cache ((unsigned long) &frame->retcode); 667 push_cache ((unsigned long) &frame->retcode);
668 668
669 /* Set up registers for signal handler */ 669 /* Set up registers for signal handler */
670 wrusp ((unsigned long) frame); 670 wrusp ((unsigned long) frame);
671 regs->pc = (unsigned long) ka->sa.sa_handler; 671 regs->pc = (unsigned long) ka->sa.sa_handler;
672 ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data; 672 ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
673 regs->format = 0x4; /*set format byte to make stack appear modulo 4 673 regs->format = 0x4; /*set format byte to make stack appear modulo 4
674 which it will be when doing the rte */ 674 which it will be when doing the rte */
675 675
676 adjust_stack: 676 adjust_stack:
677 /* Prepare to skip over the extra stuff in the exception frame. */ 677 /* Prepare to skip over the extra stuff in the exception frame. */
678 if (regs->stkadj) { 678 if (regs->stkadj) {
679 struct pt_regs *tregs = 679 struct pt_regs *tregs =
680 (struct pt_regs *)((ulong)regs + regs->stkadj); 680 (struct pt_regs *)((ulong)regs + regs->stkadj);
681 #if DEBUG 681 #if DEBUG
682 printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); 682 printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj);
683 #endif 683 #endif
684 /* This must be copied with decreasing addresses to 684 /* This must be copied with decreasing addresses to
685 handle overlaps. */ 685 handle overlaps. */
686 tregs->vector = 0; 686 tregs->vector = 0;
687 tregs->format = 0; 687 tregs->format = 0;
688 tregs->pc = regs->pc; 688 tregs->pc = regs->pc;
689 tregs->sr = regs->sr; 689 tregs->sr = regs->sr;
690 } 690 }
691 return; 691 return;
692 692
693 give_sigsegv: 693 give_sigsegv:
694 force_sigsegv(sig, current); 694 force_sigsegv(sig, current);
695 goto adjust_stack; 695 goto adjust_stack;
696 } 696 }
697 697
698 static inline void 698 static inline void
699 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) 699 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
700 { 700 {
701 switch (regs->d0) { 701 switch (regs->d0) {
702 case -ERESTARTNOHAND: 702 case -ERESTARTNOHAND:
703 if (!has_handler) 703 if (!has_handler)
704 goto do_restart; 704 goto do_restart;
705 regs->d0 = -EINTR; 705 regs->d0 = -EINTR;
706 break; 706 break;
707 707
708 case -ERESTARTSYS: 708 case -ERESTARTSYS:
709 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { 709 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
710 regs->d0 = -EINTR; 710 regs->d0 = -EINTR;
711 break; 711 break;
712 } 712 }
713 /* fallthrough */ 713 /* fallthrough */
714 case -ERESTARTNOINTR: 714 case -ERESTARTNOINTR:
715 do_restart: 715 do_restart:
716 regs->d0 = regs->orig_d0; 716 regs->d0 = regs->orig_d0;
717 regs->pc -= 2; 717 regs->pc -= 2;
718 break; 718 break;
719 } 719 }
720 } 720 }
721 721
722 /* 722 /*
723 * OK, we're invoking a handler 723 * OK, we're invoking a handler
724 */ 724 */
725 static void 725 static void
726 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 726 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
727 sigset_t *oldset, struct pt_regs *regs) 727 sigset_t *oldset, struct pt_regs *regs)
728 { 728 {
729 /* are we from a system call? */ 729 /* are we from a system call? */
730 if (regs->orig_d0 >= 0) 730 if (regs->orig_d0 >= 0)
731 /* If so, check system call restarting.. */ 731 /* If so, check system call restarting.. */
732 handle_restart(regs, ka, 1); 732 handle_restart(regs, ka, 1);
733 733
734 /* set up the stack frame */ 734 /* set up the stack frame */
735 if (ka->sa.sa_flags & SA_SIGINFO) 735 if (ka->sa.sa_flags & SA_SIGINFO)
736 setup_rt_frame(sig, ka, info, oldset, regs); 736 setup_rt_frame(sig, ka, info, oldset, regs);
737 else 737 else
738 setup_frame(sig, ka, oldset, regs); 738 setup_frame(sig, ka, oldset, regs);
739 739
740 if (ka->sa.sa_flags & SA_ONESHOT) 740 if (ka->sa.sa_flags & SA_ONESHOT)
741 ka->sa.sa_handler = SIG_DFL; 741 ka->sa.sa_handler = SIG_DFL;
742 742
743 spin_lock_irq(&current->sighand->siglock); 743 spin_lock_irq(&current->sighand->siglock);
744 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 744 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
745 if (!(ka->sa.sa_flags & SA_NODEFER)) 745 if (!(ka->sa.sa_flags & SA_NODEFER))
746 sigaddset(&current->blocked,sig); 746 sigaddset(&current->blocked,sig);
747 recalc_sigpending(); 747 recalc_sigpending();
748 spin_unlock_irq(&current->sighand->siglock); 748 spin_unlock_irq(&current->sighand->siglock);
749 } 749 }
750 750
751 /* 751 /*
752 * Note that 'init' is a special process: it doesn't get signals it doesn't 752 * Note that 'init' is a special process: it doesn't get signals it doesn't
753 * want to handle. Thus you cannot kill init even with a SIGKILL even by 753 * want to handle. Thus you cannot kill init even with a SIGKILL even by
754 * mistake. 754 * mistake.
755 */ 755 */
756 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) 756 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
757 { 757 {
758 struct k_sigaction ka; 758 struct k_sigaction ka;
759 siginfo_t info; 759 siginfo_t info;
760 int signr; 760 int signr;
761 761
762 /* 762 /*
763 * We want the common case to go fast, which 763 * We want the common case to go fast, which
764 * is why we may in certain cases get here from 764 * is why we may in certain cases get here from
765 * kernel mode. Just return without doing anything 765 * kernel mode. Just return without doing anything
766 * if so. 766 * if so.
767 */ 767 */
768 if (!user_mode(regs)) 768 if (!user_mode(regs))
769 return 1; 769 return 1;
770 770
771 if (!oldset) 771 if (!oldset)
772 oldset = &current->blocked; 772 oldset = &current->blocked;
773 773
774 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 774 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
775 if (signr > 0) { 775 if (signr > 0) {
776 /* Whee! Actually deliver the signal. */ 776 /* Whee! Actually deliver the signal. */
777 handle_signal(signr, &ka, &info, oldset, regs); 777 handle_signal(signr, &ka, &info, oldset, regs);
778 return 1; 778 return 1;
779 } 779 }
780 780
781 /* Did we come from a system call? */ 781 /* Did we come from a system call? */
782 if (regs->orig_d0 >= 0) { 782 if (regs->orig_d0 >= 0) {
783 /* Restart the system call - no handlers present */ 783 /* Restart the system call - no handlers present */
784 if (regs->d0 == -ERESTARTNOHAND 784 if (regs->d0 == -ERESTARTNOHAND
785 || regs->d0 == -ERESTARTSYS 785 || regs->d0 == -ERESTARTSYS
786 || regs->d0 == -ERESTARTNOINTR) { 786 || regs->d0 == -ERESTARTNOINTR) {
787 regs->d0 = regs->orig_d0; 787 regs->d0 = regs->orig_d0;
788 regs->pc -= 2; 788 regs->pc -= 2;
789 } else if (regs->d0 == -ERESTART_RESTARTBLOCK) { 789 } else if (regs->d0 == -ERESTART_RESTARTBLOCK) {
790 regs->d0 = __NR_restart_syscall; 790 regs->d0 = __NR_restart_syscall;
791 regs->pc -= 2; 791 regs->pc -= 2;
792 } 792 }
793 } 793 }
794 return 0; 794 return 0;
795 } 795 }
796 796
arch/parisc/kernel/signal.c
1 /* 1 /*
2 * linux/arch/parisc/kernel/signal.c: Architecture-specific signal 2 * linux/arch/parisc/kernel/signal.c: Architecture-specific signal
3 * handling support. 3 * handling support.
4 * 4 *
5 * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org> 5 * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
6 * Copyright (C) 2000 Linuxcare, Inc. 6 * Copyright (C) 2000 Linuxcare, Inc.
7 * 7 *
8 * Based on the ia64, i386, and alpha versions. 8 * Based on the ia64, i386, and alpha versions.
9 * 9 *
10 * Like the IA-64, we are a recent enough port (we are *starting* 10 * Like the IA-64, we are a recent enough port (we are *starting*
11 * with glibc2.2) that we do not need to support the old non-realtime 11 * with glibc2.2) that we do not need to support the old non-realtime
12 * Linux signals. Therefore we don't. HP/UX signals will go in 12 * Linux signals. Therefore we don't. HP/UX signals will go in
13 * arch/parisc/hpux/signal.c when we figure out how to do them. 13 * arch/parisc/hpux/signal.c when we figure out how to do them.
14 */ 14 */
15 15
16 #include <linux/sched.h> 16 #include <linux/sched.h>
17 #include <linux/mm.h> 17 #include <linux/mm.h>
18 #include <linux/smp.h> 18 #include <linux/smp.h>
19 #include <linux/smp_lock.h> 19 #include <linux/smp_lock.h>
20 #include <linux/kernel.h> 20 #include <linux/kernel.h>
21 #include <linux/signal.h> 21 #include <linux/signal.h>
22 #include <linux/errno.h> 22 #include <linux/errno.h>
23 #include <linux/wait.h> 23 #include <linux/wait.h>
24 #include <linux/ptrace.h> 24 #include <linux/ptrace.h>
25 #include <linux/unistd.h> 25 #include <linux/unistd.h>
26 #include <linux/stddef.h> 26 #include <linux/stddef.h>
27 #include <linux/compat.h> 27 #include <linux/compat.h>
28 #include <linux/elf.h> 28 #include <linux/elf.h>
29 #include <linux/personality.h> 29 #include <linux/personality.h>
30 #include <asm/ucontext.h> 30 #include <asm/ucontext.h>
31 #include <asm/rt_sigframe.h> 31 #include <asm/rt_sigframe.h>
32 #include <asm/uaccess.h> 32 #include <asm/uaccess.h>
33 #include <asm/pgalloc.h> 33 #include <asm/pgalloc.h>
34 #include <asm/cacheflush.h> 34 #include <asm/cacheflush.h>
35 #include <asm/asm-offsets.h> 35 #include <asm/asm-offsets.h>
36 36
37 #ifdef CONFIG_COMPAT 37 #ifdef CONFIG_COMPAT
38 #include <linux/compat.h> 38 #include <linux/compat.h>
39 #include "signal32.h" 39 #include "signal32.h"
40 #endif 40 #endif
41 41
42 #define DEBUG_SIG 0 42 #define DEBUG_SIG 0
43 #define DEBUG_SIG_LEVEL 2 43 #define DEBUG_SIG_LEVEL 2
44 44
45 #if DEBUG_SIG 45 #if DEBUG_SIG
46 #define DBG(LEVEL, ...) \ 46 #define DBG(LEVEL, ...) \
47 ((DEBUG_SIG_LEVEL >= LEVEL) \ 47 ((DEBUG_SIG_LEVEL >= LEVEL) \
48 ? printk(__VA_ARGS__) : (void) 0) 48 ? printk(__VA_ARGS__) : (void) 0)
49 #else 49 #else
50 #define DBG(LEVEL, ...) 50 #define DBG(LEVEL, ...)
51 #endif 51 #endif
52 52
53 53
54 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 54 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
55 55
56 /* gcc will complain if a pointer is cast to an integer of different 56 /* gcc will complain if a pointer is cast to an integer of different
57 * size. If you really need to do this (and we do for an ELF32 user 57 * size. If you really need to do this (and we do for an ELF32 user
58 * application in an ELF64 kernel) then you have to do a cast to an 58 * application in an ELF64 kernel) then you have to do a cast to an
59 * integer of the same size first. The A() macro accomplishes 59 * integer of the same size first. The A() macro accomplishes
60 * this. */ 60 * this. */
61 #define A(__x) ((unsigned long)(__x)) 61 #define A(__x) ((unsigned long)(__x))
62 62
63 int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall); 63 int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall);
64 64
65 /* 65 /*
66 * Atomically swap in the new signal mask, and wait for a signal. 66 * Atomically swap in the new signal mask, and wait for a signal.
67 */ 67 */
68 #ifdef __LP64__ 68 #ifdef __LP64__
69 #include "sys32.h" 69 #include "sys32.h"
70 #endif 70 #endif
71 71
72 asmlinkage int 72 asmlinkage int
73 sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) 73 sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
74 { 74 {
75 sigset_t saveset, newset; 75 sigset_t saveset, newset;
76 #ifdef __LP64__ 76 #ifdef __LP64__
77 compat_sigset_t newset32; 77 compat_sigset_t newset32;
78 78
79 if(personality(current->personality) == PER_LINUX32){ 79 if(personality(current->personality) == PER_LINUX32){
80 /* XXX: Don't preclude handling different sized sigset_t's. */ 80 /* XXX: Don't preclude handling different sized sigset_t's. */
81 if (sigsetsize != sizeof(compat_sigset_t)) 81 if (sigsetsize != sizeof(compat_sigset_t))
82 return -EINVAL; 82 return -EINVAL;
83 if (copy_from_user(&newset32, (compat_sigset_t __user *)unewset, sizeof(newset32))) 83 if (copy_from_user(&newset32, (compat_sigset_t __user *)unewset, sizeof(newset32)))
84 return -EFAULT; 84 return -EFAULT;
85 sigset_32to64(&newset,&newset32); 85 sigset_32to64(&newset,&newset32);
86 86
87 } else 87 } else
88 #endif 88 #endif
89 { 89 {
90 /* XXX: Don't preclude handling different sized sigset_t's. */ 90 /* XXX: Don't preclude handling different sized sigset_t's. */
91 if (sigsetsize != sizeof(sigset_t)) 91 if (sigsetsize != sizeof(sigset_t))
92 return -EINVAL; 92 return -EINVAL;
93 93
94 if (copy_from_user(&newset, unewset, sizeof(newset))) 94 if (copy_from_user(&newset, unewset, sizeof(newset)))
95 return -EFAULT; 95 return -EFAULT;
96 } 96 }
97 97
98 sigdelsetmask(&newset, ~_BLOCKABLE); 98 sigdelsetmask(&newset, ~_BLOCKABLE);
99 99
100 spin_lock_irq(&current->sighand->siglock); 100 spin_lock_irq(&current->sighand->siglock);
101 saveset = current->blocked; 101 saveset = current->blocked;
102 current->blocked = newset; 102 current->blocked = newset;
103 recalc_sigpending(); 103 recalc_sigpending();
104 spin_unlock_irq(&current->sighand->siglock); 104 spin_unlock_irq(&current->sighand->siglock);
105 105
106 regs->gr[28] = -EINTR; 106 regs->gr[28] = -EINTR;
107 while (1) { 107 while (1) {
108 current->state = TASK_INTERRUPTIBLE; 108 current->state = TASK_INTERRUPTIBLE;
109 schedule(); 109 schedule();
110 if (do_signal(&saveset, regs, 1)) 110 if (do_signal(&saveset, regs, 1))
111 return -EINTR; 111 return -EINTR;
112 } 112 }
113 } 113 }
114 114
115 /* 115 /*
116 * Do a signal return - restore sigcontext. 116 * Do a signal return - restore sigcontext.
117 */ 117 */
118 118
119 /* Trampoline for calling rt_sigreturn() */ 119 /* Trampoline for calling rt_sigreturn() */
120 #define INSN_LDI_R25_0 0x34190000 /* ldi 0,%r25 (in_syscall=0) */ 120 #define INSN_LDI_R25_0 0x34190000 /* ldi 0,%r25 (in_syscall=0) */
121 #define INSN_LDI_R25_1 0x34190002 /* ldi 1,%r25 (in_syscall=1) */ 121 #define INSN_LDI_R25_1 0x34190002 /* ldi 1,%r25 (in_syscall=1) */
122 #define INSN_LDI_R20 0x3414015a /* ldi __NR_rt_sigreturn,%r20 */ 122 #define INSN_LDI_R20 0x3414015a /* ldi __NR_rt_sigreturn,%r20 */
123 #define INSN_BLE_SR2_R0 0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */ 123 #define INSN_BLE_SR2_R0 0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
124 #define INSN_NOP 0x08000240 /* nop */ 124 #define INSN_NOP 0x08000240 /* nop */
125 /* For debugging */ 125 /* For debugging */
126 #define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */ 126 #define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
127 127
128 static long 128 static long
129 restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) 129 restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
130 { 130 {
131 long err = 0; 131 long err = 0;
132 132
133 err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr)); 133 err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr));
134 err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr)); 134 err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
135 err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq)); 135 err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq));
136 err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq)); 136 err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq));
137 err |= __get_user(regs->sar, &sc->sc_sar); 137 err |= __get_user(regs->sar, &sc->sc_sar);
138 DBG(2,"restore_sigcontext: iaoq is 0x%#lx / 0x%#lx\n", 138 DBG(2,"restore_sigcontext: iaoq is 0x%#lx / 0x%#lx\n",
139 regs->iaoq[0],regs->iaoq[1]); 139 regs->iaoq[0],regs->iaoq[1]);
140 DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]); 140 DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]);
141 return err; 141 return err;
142 } 142 }
143 143
144 void 144 void
145 sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) 145 sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
146 { 146 {
147 struct rt_sigframe __user *frame; 147 struct rt_sigframe __user *frame;
148 struct siginfo si; 148 struct siginfo si;
149 sigset_t set; 149 sigset_t set;
150 unsigned long usp = (regs->gr[30] & ~(0x01UL)); 150 unsigned long usp = (regs->gr[30] & ~(0x01UL));
151 unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE; 151 unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
152 #ifdef __LP64__ 152 #ifdef __LP64__
153 compat_sigset_t compat_set; 153 compat_sigset_t compat_set;
154 struct compat_rt_sigframe __user * compat_frame; 154 struct compat_rt_sigframe __user * compat_frame;
155 155
156 if(personality(current->personality) == PER_LINUX32) 156 if(personality(current->personality) == PER_LINUX32)
157 sigframe_size = PARISC_RT_SIGFRAME_SIZE32; 157 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
158 #endif 158 #endif
159 159
160 160
161 /* Unwind the user stack to get the rt_sigframe structure. */ 161 /* Unwind the user stack to get the rt_sigframe structure. */
162 frame = (struct rt_sigframe __user *) 162 frame = (struct rt_sigframe __user *)
163 (usp - sigframe_size); 163 (usp - sigframe_size);
164 DBG(2,"sys_rt_sigreturn: frame is %p\n", frame); 164 DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
165 165
166 #ifdef __LP64__ 166 #ifdef __LP64__
167 compat_frame = (struct compat_rt_sigframe __user *)frame; 167 compat_frame = (struct compat_rt_sigframe __user *)frame;
168 168
169 if(personality(current->personality) == PER_LINUX32){ 169 if(personality(current->personality) == PER_LINUX32){
170 DBG(2,"sys_rt_sigreturn: ELF32 process.\n"); 170 DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
171 if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set))) 171 if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
172 goto give_sigsegv; 172 goto give_sigsegv;
173 sigset_32to64(&set,&compat_set); 173 sigset_32to64(&set,&compat_set);
174 } else 174 } else
175 #endif 175 #endif
176 { 176 {
177 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 177 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
178 goto give_sigsegv; 178 goto give_sigsegv;
179 } 179 }
180 180
181 sigdelsetmask(&set, ~_BLOCKABLE); 181 sigdelsetmask(&set, ~_BLOCKABLE);
182 spin_lock_irq(&current->sighand->siglock); 182 spin_lock_irq(&current->sighand->siglock);
183 current->blocked = set; 183 current->blocked = set;
184 recalc_sigpending(); 184 recalc_sigpending();
185 spin_unlock_irq(&current->sighand->siglock); 185 spin_unlock_irq(&current->sighand->siglock);
186 186
187 /* Good thing we saved the old gr[30], eh? */ 187 /* Good thing we saved the old gr[30], eh? */
188 #ifdef __LP64__ 188 #ifdef __LP64__
189 if(personality(current->personality) == PER_LINUX32){ 189 if(personality(current->personality) == PER_LINUX32){
190 DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n", 190 DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
191 &compat_frame->uc.uc_mcontext); 191 &compat_frame->uc.uc_mcontext);
192 // FIXME: Load upper half from register file 192 // FIXME: Load upper half from register file
193 if (restore_sigcontext32(&compat_frame->uc.uc_mcontext, 193 if (restore_sigcontext32(&compat_frame->uc.uc_mcontext,
194 &compat_frame->regs, regs)) 194 &compat_frame->regs, regs))
195 goto give_sigsegv; 195 goto give_sigsegv;
196 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 196 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n",
197 usp, &compat_frame->uc.uc_stack); 197 usp, &compat_frame->uc.uc_stack);
198 if (do_sigaltstack32(&compat_frame->uc.uc_stack, NULL, usp) == -EFAULT) 198 if (do_sigaltstack32(&compat_frame->uc.uc_stack, NULL, usp) == -EFAULT)
199 goto give_sigsegv; 199 goto give_sigsegv;
200 } else 200 } else
201 #endif 201 #endif
202 { 202 {
203 DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n", 203 DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n",
204 &frame->uc.uc_mcontext); 204 &frame->uc.uc_mcontext);
205 if (restore_sigcontext(&frame->uc.uc_mcontext, regs)) 205 if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
206 goto give_sigsegv; 206 goto give_sigsegv;
207 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 207 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n",
208 usp, &frame->uc.uc_stack); 208 usp, &frame->uc.uc_stack);
209 if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT) 209 if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
210 goto give_sigsegv; 210 goto give_sigsegv;
211 } 211 }
212 212
213 213
214 214
215 /* If we are on the syscall path IAOQ will not be restored, and 215 /* If we are on the syscall path IAOQ will not be restored, and
216 * if we are on the interrupt path we must not corrupt gr31. 216 * if we are on the interrupt path we must not corrupt gr31.
217 */ 217 */
218 if (in_syscall) 218 if (in_syscall)
219 regs->gr[31] = regs->iaoq[0]; 219 regs->gr[31] = regs->iaoq[0];
220 #if DEBUG_SIG 220 #if DEBUG_SIG
221 DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]); 221 DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]);
222 show_regs(regs); 222 show_regs(regs);
223 #endif 223 #endif
224 return; 224 return;
225 225
226 give_sigsegv: 226 give_sigsegv:
227 DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n"); 227 DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
228 si.si_signo = SIGSEGV; 228 si.si_signo = SIGSEGV;
229 si.si_errno = 0; 229 si.si_errno = 0;
230 si.si_code = SI_KERNEL; 230 si.si_code = SI_KERNEL;
231 si.si_pid = current->pid; 231 si.si_pid = current->pid;
232 si.si_uid = current->uid; 232 si.si_uid = current->uid;
233 si.si_addr = &frame->uc; 233 si.si_addr = &frame->uc;
234 force_sig_info(SIGSEGV, &si, current); 234 force_sig_info(SIGSEGV, &si, current);
235 return; 235 return;
236 } 236 }
237 237
238 /* 238 /*
239 * Set up a signal frame. 239 * Set up a signal frame.
240 */ 240 */
241 241
242 static inline void __user * 242 static inline void __user *
243 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) 243 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
244 { 244 {
245 /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we 245 /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
246 don't use the parameter it doesn't matter */ 246 don't use the parameter it doesn't matter */
247 247
248 DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n", 248 DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
249 (unsigned long)ka, sp, frame_size); 249 (unsigned long)ka, sp, frame_size);
250 250
251 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) 251 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
252 sp = current->sas_ss_sp; /* Stacks grow up! */ 252 sp = current->sas_ss_sp; /* Stacks grow up! */
253 253
254 DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp); 254 DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
255 return (void __user *) sp; /* Stacks grow up. Fun. */ 255 return (void __user *) sp; /* Stacks grow up. Fun. */
256 } 256 }
257 257
258 static long 258 static long
259 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall) 259 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall)
260 260
261 { 261 {
262 unsigned long flags = 0; 262 unsigned long flags = 0;
263 long err = 0; 263 long err = 0;
264 264
265 if (on_sig_stack((unsigned long) sc)) 265 if (on_sig_stack((unsigned long) sc))
266 flags |= PARISC_SC_FLAG_ONSTACK; 266 flags |= PARISC_SC_FLAG_ONSTACK;
267 if (in_syscall) { 267 if (in_syscall) {
268 flags |= PARISC_SC_FLAG_IN_SYSCALL; 268 flags |= PARISC_SC_FLAG_IN_SYSCALL;
269 /* regs->iaoq is undefined in the syscall return path */ 269 /* regs->iaoq is undefined in the syscall return path */
270 err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]); 270 err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]);
271 err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]); 271 err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]);
272 err |= __put_user(regs->sr[3], &sc->sc_iasq[0]); 272 err |= __put_user(regs->sr[3], &sc->sc_iasq[0]);
273 err |= __put_user(regs->sr[3], &sc->sc_iasq[1]); 273 err |= __put_user(regs->sr[3], &sc->sc_iasq[1]);
274 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n", 274 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n",
275 regs->gr[31], regs->gr[31]+4); 275 regs->gr[31], regs->gr[31]+4);
276 } else { 276 } else {
277 err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq)); 277 err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq));
278 err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq)); 278 err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq));
279 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n", 279 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n",
280 regs->iaoq[0], regs->iaoq[1]); 280 regs->iaoq[0], regs->iaoq[1]);
281 } 281 }
282 282
283 err |= __put_user(flags, &sc->sc_flags); 283 err |= __put_user(flags, &sc->sc_flags);
284 err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr)); 284 err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr));
285 err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr)); 285 err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
286 err |= __put_user(regs->sar, &sc->sc_sar); 286 err |= __put_user(regs->sar, &sc->sc_sar);
287 DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]); 287 DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]);
288 288
289 return err; 289 return err;
290 } 290 }
291 291
292 static long 292 static long
293 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 293 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
294 sigset_t *set, struct pt_regs *regs, int in_syscall) 294 sigset_t *set, struct pt_regs *regs, int in_syscall)
295 { 295 {
296 struct rt_sigframe __user *frame; 296 struct rt_sigframe __user *frame;
297 unsigned long rp, usp; 297 unsigned long rp, usp;
298 unsigned long haddr, sigframe_size; 298 unsigned long haddr, sigframe_size;
299 int err = 0; 299 int err = 0;
300 #ifdef __LP64__ 300 #ifdef __LP64__
301 compat_int_t compat_val; 301 compat_int_t compat_val;
302 struct compat_rt_sigframe __user * compat_frame; 302 struct compat_rt_sigframe __user * compat_frame;
303 compat_sigset_t compat_set; 303 compat_sigset_t compat_set;
304 #endif 304 #endif
305 305
306 usp = (regs->gr[30] & ~(0x01UL)); 306 usp = (regs->gr[30] & ~(0x01UL));
307 /*FIXME: frame_size parameter is unused, remove it. */ 307 /*FIXME: frame_size parameter is unused, remove it. */
308 frame = get_sigframe(ka, usp, sizeof(*frame)); 308 frame = get_sigframe(ka, usp, sizeof(*frame));
309 309
310 DBG(1,"SETUP_RT_FRAME: START\n"); 310 DBG(1,"SETUP_RT_FRAME: START\n");
311 DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info); 311 DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info);
312 312
313 313
314 #ifdef __LP64__ 314 #ifdef __LP64__
315 315
316 compat_frame = (struct compat_rt_sigframe __user *)frame; 316 compat_frame = (struct compat_rt_sigframe __user *)frame;
317 317
318 if(personality(current->personality) == PER_LINUX32) { 318 if(personality(current->personality) == PER_LINUX32) {
319 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); 319 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
320 err |= copy_siginfo_to_user32(&compat_frame->info, info); 320 err |= copy_siginfo_to_user32(&compat_frame->info, info);
321 DBG(1,"SETUP_RT_FRAME: 1\n"); 321 DBG(1,"SETUP_RT_FRAME: 1\n");
322 compat_val = (compat_int_t)current->sas_ss_sp; 322 compat_val = (compat_int_t)current->sas_ss_sp;
323 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp); 323 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp);
324 DBG(1,"SETUP_RT_FRAME: 2\n"); 324 DBG(1,"SETUP_RT_FRAME: 2\n");
325 compat_val = (compat_int_t)current->sas_ss_size; 325 compat_val = (compat_int_t)current->sas_ss_size;
326 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_size); 326 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_size);
327 DBG(1,"SETUP_RT_FRAME: 3\n"); 327 DBG(1,"SETUP_RT_FRAME: 3\n");
328 compat_val = sas_ss_flags(regs->gr[30]); 328 compat_val = sas_ss_flags(regs->gr[30]);
329 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_flags); 329 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_flags);
330 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc); 330 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
331 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext); 331 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
332 err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 332 err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext,
333 &compat_frame->regs, regs, in_syscall); 333 &compat_frame->regs, regs, in_syscall);
334 sigset_64to32(&compat_set,set); 334 sigset_64to32(&compat_set,set);
335 err |= __copy_to_user(&compat_frame->uc.uc_sigmask, &compat_set, sizeof(compat_set)); 335 err |= __copy_to_user(&compat_frame->uc.uc_sigmask, &compat_set, sizeof(compat_set));
336 } else 336 } else
337 #endif 337 #endif
338 { 338 {
339 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info); 339 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
340 err |= copy_siginfo_to_user(&frame->info, info); 340 err |= copy_siginfo_to_user(&frame->info, info);
341 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 341 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
342 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 342 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
343 err |= __put_user(sas_ss_flags(regs->gr[30]), 343 err |= __put_user(sas_ss_flags(regs->gr[30]),
344 &frame->uc.uc_stack.ss_flags); 344 &frame->uc.uc_stack.ss_flags);
345 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc); 345 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
346 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext); 346 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
347 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall); 347 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
348 /* FIXME: Should probably be converted aswell for the compat case */ 348 /* FIXME: Should probably be converted aswell for the compat case */
349 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 349 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
350 } 350 }
351 351
352 if (err) 352 if (err)
353 goto give_sigsegv; 353 goto give_sigsegv;
354 354
355 /* Set up to return from userspace. If provided, use a stub 355 /* Set up to return from userspace. If provided, use a stub
356 already in userspace. The first words of tramp are used to 356 already in userspace. The first words of tramp are used to
357 save the previous sigrestartblock trampoline that might be 357 save the previous sigrestartblock trampoline that might be
358 on the stack. We start the sigreturn trampoline at 358 on the stack. We start the sigreturn trampoline at
359 SIGRESTARTBLOCK_TRAMP+X. */ 359 SIGRESTARTBLOCK_TRAMP+X. */
360 err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0, 360 err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
361 &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]); 361 &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
362 err |= __put_user(INSN_LDI_R20, 362 err |= __put_user(INSN_LDI_R20,
363 &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]); 363 &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
364 err |= __put_user(INSN_BLE_SR2_R0, 364 err |= __put_user(INSN_BLE_SR2_R0,
365 &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]); 365 &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
366 err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]); 366 err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
367 367
368 #if DEBUG_SIG 368 #if DEBUG_SIG
369 /* Assert that we're flushing in the correct space... */ 369 /* Assert that we're flushing in the correct space... */
370 { 370 {
371 int sid; 371 int sid;
372 asm ("mfsp %%sr3,%0" : "=r" (sid)); 372 asm ("mfsp %%sr3,%0" : "=r" (sid));
373 DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n", 373 DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
374 sid, frame->tramp); 374 sid, frame->tramp);
375 } 375 }
376 #endif 376 #endif
377 377
378 flush_user_dcache_range((unsigned long) &frame->tramp[0], 378 flush_user_dcache_range((unsigned long) &frame->tramp[0],
379 (unsigned long) &frame->tramp[TRAMP_SIZE]); 379 (unsigned long) &frame->tramp[TRAMP_SIZE]);
380 flush_user_icache_range((unsigned long) &frame->tramp[0], 380 flush_user_icache_range((unsigned long) &frame->tramp[0],
381 (unsigned long) &frame->tramp[TRAMP_SIZE]); 381 (unsigned long) &frame->tramp[TRAMP_SIZE]);
382 382
383 /* TRAMP Words 0-4, Lenght 5 = SIGRESTARTBLOCK_TRAMP 383 /* TRAMP Words 0-4, Lenght 5 = SIGRESTARTBLOCK_TRAMP
384 * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP 384 * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
385 * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP 385 * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
386 */ 386 */
387 rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP]; 387 rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
388 388
389 if (err) 389 if (err)
390 goto give_sigsegv; 390 goto give_sigsegv;
391 391
392 haddr = A(ka->sa.sa_handler); 392 haddr = A(ka->sa.sa_handler);
393 /* The sa_handler may be a pointer to a function descriptor */ 393 /* The sa_handler may be a pointer to a function descriptor */
394 #ifdef __LP64__ 394 #ifdef __LP64__
395 if(personality(current->personality) == PER_LINUX32) { 395 if(personality(current->personality) == PER_LINUX32) {
396 #endif 396 #endif
397 if (haddr & PA_PLABEL_FDESC) { 397 if (haddr & PA_PLABEL_FDESC) {
398 Elf32_Fdesc fdesc; 398 Elf32_Fdesc fdesc;
399 Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3); 399 Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3);
400 400
401 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc)); 401 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
402 402
403 if (err) 403 if (err)
404 goto give_sigsegv; 404 goto give_sigsegv;
405 405
406 haddr = fdesc.addr; 406 haddr = fdesc.addr;
407 regs->gr[19] = fdesc.gp; 407 regs->gr[19] = fdesc.gp;
408 } 408 }
409 #ifdef __LP64__ 409 #ifdef __LP64__
410 } else { 410 } else {
411 Elf64_Fdesc fdesc; 411 Elf64_Fdesc fdesc;
412 Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3); 412 Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
413 413
414 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc)); 414 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
415 415
416 if (err) 416 if (err)
417 goto give_sigsegv; 417 goto give_sigsegv;
418 418
419 haddr = fdesc.addr; 419 haddr = fdesc.addr;
420 regs->gr[19] = fdesc.gp; 420 regs->gr[19] = fdesc.gp;
421 DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n", 421 DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
422 haddr, regs->gr[19], in_syscall); 422 haddr, regs->gr[19], in_syscall);
423 } 423 }
424 #endif 424 #endif
425 425
426 /* The syscall return path will create IAOQ values from r31. 426 /* The syscall return path will create IAOQ values from r31.
427 */ 427 */
428 sigframe_size = PARISC_RT_SIGFRAME_SIZE; 428 sigframe_size = PARISC_RT_SIGFRAME_SIZE;
429 #ifdef __LP64__ 429 #ifdef __LP64__
430 if(personality(current->personality) == PER_LINUX32) 430 if(personality(current->personality) == PER_LINUX32)
431 sigframe_size = PARISC_RT_SIGFRAME_SIZE32; 431 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
432 #endif 432 #endif
433 if (in_syscall) { 433 if (in_syscall) {
434 regs->gr[31] = haddr; 434 regs->gr[31] = haddr;
435 #ifdef __LP64__ 435 #ifdef __LP64__
436 if(personality(current->personality) == PER_LINUX) 436 if(personality(current->personality) == PER_LINUX)
437 sigframe_size |= 1; 437 sigframe_size |= 1;
438 #endif 438 #endif
439 } else { 439 } else {
440 unsigned long psw = USER_PSW; 440 unsigned long psw = USER_PSW;
441 #ifdef __LP64__ 441 #ifdef __LP64__
442 if(personality(current->personality) == PER_LINUX) 442 if(personality(current->personality) == PER_LINUX)
443 psw |= PSW_W; 443 psw |= PSW_W;
444 #endif 444 #endif
445 445
446 /* If we are singlestepping, arrange a trap to be delivered 446 /* If we are singlestepping, arrange a trap to be delivered
447 when we return to userspace. Note the semantics -- we 447 when we return to userspace. Note the semantics -- we
448 should trap before the first insn in the handler is 448 should trap before the first insn in the handler is
449 executed. Ref: 449 executed. Ref:
450 http://sources.redhat.com/ml/gdb/2004-11/msg00245.html 450 http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
451 */ 451 */
452 if (pa_psw(current)->r) { 452 if (pa_psw(current)->r) {
453 pa_psw(current)->r = 0; 453 pa_psw(current)->r = 0;
454 psw |= PSW_R; 454 psw |= PSW_R;
455 mtctl(-1, 0); 455 mtctl(-1, 0);
456 } 456 }
457 457
458 regs->gr[0] = psw; 458 regs->gr[0] = psw;
459 regs->iaoq[0] = haddr | 3; 459 regs->iaoq[0] = haddr | 3;
460 regs->iaoq[1] = regs->iaoq[0] + 4; 460 regs->iaoq[1] = regs->iaoq[0] + 4;
461 } 461 }
462 462
463 regs->gr[2] = rp; /* userland return pointer */ 463 regs->gr[2] = rp; /* userland return pointer */
464 regs->gr[26] = sig; /* signal number */ 464 regs->gr[26] = sig; /* signal number */
465 465
466 #ifdef __LP64__ 466 #ifdef __LP64__
467 if(personality(current->personality) == PER_LINUX32){ 467 if(personality(current->personality) == PER_LINUX32){
468 regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ 468 regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
469 regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ 469 regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */
470 } else 470 } else
471 #endif 471 #endif
472 { 472 {
473 regs->gr[25] = A(&frame->info); /* siginfo pointer */ 473 regs->gr[25] = A(&frame->info); /* siginfo pointer */
474 regs->gr[24] = A(&frame->uc); /* ucontext pointer */ 474 regs->gr[24] = A(&frame->uc); /* ucontext pointer */
475 } 475 }
476 476
477 DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n", 477 DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
478 regs->gr[30], sigframe_size, 478 regs->gr[30], sigframe_size,
479 regs->gr[30] + sigframe_size); 479 regs->gr[30] + sigframe_size);
480 /* Raise the user stack pointer to make a proper call frame. */ 480 /* Raise the user stack pointer to make a proper call frame. */
481 regs->gr[30] = (A(frame) + sigframe_size); 481 regs->gr[30] = (A(frame) + sigframe_size);
482 482
483 483
484 DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n", 484 DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
485 current->comm, current->pid, frame, regs->gr[30], 485 current->comm, current->pid, frame, regs->gr[30],
486 regs->iaoq[0], regs->iaoq[1], rp); 486 regs->iaoq[0], regs->iaoq[1], rp);
487 487
488 return 1; 488 return 1;
489 489
490 give_sigsegv: 490 give_sigsegv:
491 DBG(1,"setup_rt_frame: sending SIGSEGV\n"); 491 DBG(1,"setup_rt_frame: sending SIGSEGV\n");
492 force_sigsegv(sig, current); 492 force_sigsegv(sig, current);
493 return 0; 493 return 0;
494 } 494 }
495 495
496 /* 496 /*
497 * OK, we're invoking a handler. 497 * OK, we're invoking a handler.
498 */ 498 */
499 499
500 static long 500 static long
501 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 501 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
502 sigset_t *oldset, struct pt_regs *regs, int in_syscall) 502 sigset_t *oldset, struct pt_regs *regs, int in_syscall)
503 { 503 {
504 DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n", 504 DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
505 sig, ka, info, oldset, regs); 505 sig, ka, info, oldset, regs);
506 506
507 /* Set up the stack frame */ 507 /* Set up the stack frame */
508 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) 508 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
509 return 0; 509 return 0;
510 510
511 spin_lock_irq(&current->sighand->siglock); 511 spin_lock_irq(&current->sighand->siglock);
512 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 512 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
513 if (!(ka->sa.sa_flags & SA_NODEFER)) 513 if (!(ka->sa.sa_flags & SA_NODEFER))
514 sigaddset(&current->blocked,sig); 514 sigaddset(&current->blocked,sig);
515 recalc_sigpending(); 515 recalc_sigpending();
516 spin_unlock_irq(&current->sighand->siglock); 516 spin_unlock_irq(&current->sighand->siglock);
517 return 1; 517 return 1;
518 } 518 }
519 519
520 /* 520 /*
521 * Note that 'init' is a special process: it doesn't get signals it doesn't 521 * Note that 'init' is a special process: it doesn't get signals it doesn't
522 * want to handle. Thus you cannot kill init even with a SIGKILL even by 522 * want to handle. Thus you cannot kill init even with a SIGKILL even by
523 * mistake. 523 * mistake.
524 * 524 *
525 * We need to be able to restore the syscall arguments (r21-r26) to 525 * We need to be able to restore the syscall arguments (r21-r26) to
526 * restart syscalls. Thus, the syscall path should save them in the 526 * restart syscalls. Thus, the syscall path should save them in the
527 * pt_regs structure (it's okay to do so since they are caller-save 527 * pt_regs structure (it's okay to do so since they are caller-save
528 * registers). As noted below, the syscall number gets restored for 528 * registers). As noted below, the syscall number gets restored for
529 * us due to the magic of delayed branching. 529 * us due to the magic of delayed branching.
530 */ 530 */
531 531
532 asmlinkage int 532 asmlinkage int
533 do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall) 533 do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
534 { 534 {
535 siginfo_t info; 535 siginfo_t info;
536 struct k_sigaction ka; 536 struct k_sigaction ka;
537 int signr; 537 int signr;
538 538
539 DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n", 539 DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n",
540 oldset, regs, regs->sr[7], in_syscall); 540 oldset, regs, regs->sr[7], in_syscall);
541 541
542 /* Everyone else checks to see if they are in kernel mode at 542 /* Everyone else checks to see if they are in kernel mode at
543 this point and exits if that's the case. I'm not sure why 543 this point and exits if that's the case. I'm not sure why
544 we would be called in that case, but for some reason we 544 we would be called in that case, but for some reason we
545 are. */ 545 are. */
546 546
547 if (!oldset) 547 if (!oldset)
548 oldset = &current->blocked; 548 oldset = &current->blocked;
549 549
550 DBG(1,"do_signal: oldset %08lx / %08lx\n", 550 DBG(1,"do_signal: oldset %08lx / %08lx\n",
551 oldset->sig[0], oldset->sig[1]); 551 oldset->sig[0], oldset->sig[1]);
552 552
553 553
554 /* May need to force signal if handle_signal failed to deliver */ 554 /* May need to force signal if handle_signal failed to deliver */
555 while (1) { 555 while (1) {
556 556
557 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 557 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
558 DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 558 DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
559 559
560 if (signr <= 0) 560 if (signr <= 0)
561 break; 561 break;
562 562
563 /* Restart a system call if necessary. */ 563 /* Restart a system call if necessary. */
564 if (in_syscall) { 564 if (in_syscall) {
565 /* Check the return code */ 565 /* Check the return code */
566 switch (regs->gr[28]) { 566 switch (regs->gr[28]) {
567 case -ERESTART_RESTARTBLOCK: 567 case -ERESTART_RESTARTBLOCK:
568 current_thread_info()->restart_block.fn = do_no_restart_syscall; 568 current_thread_info()->restart_block.fn = do_no_restart_syscall;
569 case -ERESTARTNOHAND: 569 case -ERESTARTNOHAND:
570 DBG(1,"ERESTARTNOHAND: returning -EINTR\n"); 570 DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
571 regs->gr[28] = -EINTR; 571 regs->gr[28] = -EINTR;
572 break; 572 break;
573 573
574 case -ERESTARTSYS: 574 case -ERESTARTSYS:
575 if (!(ka.sa.sa_flags & SA_RESTART)) { 575 if (!(ka.sa.sa_flags & SA_RESTART)) {
576 DBG(1,"ERESTARTSYS: putting -EINTR\n"); 576 DBG(1,"ERESTARTSYS: putting -EINTR\n");
577 regs->gr[28] = -EINTR; 577 regs->gr[28] = -EINTR;
578 break; 578 break;
579 } 579 }
580 /* fallthrough */ 580 /* fallthrough */
581 case -ERESTARTNOINTR: 581 case -ERESTARTNOINTR:
582 /* A syscall is just a branch, so all 582 /* A syscall is just a branch, so all
583 we have to do is fiddle the return pointer. */ 583 we have to do is fiddle the return pointer. */
584 regs->gr[31] -= 8; /* delayed branching */ 584 regs->gr[31] -= 8; /* delayed branching */
585 /* Preserve original r28. */ 585 /* Preserve original r28. */
586 regs->gr[28] = regs->orig_r28; 586 regs->gr[28] = regs->orig_r28;
587 break; 587 break;
588 } 588 }
589 } 589 }
590 /* Whee! Actually deliver the signal. If the 590 /* Whee! Actually deliver the signal. If the
591 delivery failed, we need to continue to iterate in 591 delivery failed, we need to continue to iterate in
592 this loop so we can deliver the SIGSEGV... */ 592 this loop so we can deliver the SIGSEGV... */
593 if (handle_signal(signr, &info, &ka, oldset, regs, in_syscall)) { 593 if (handle_signal(signr, &info, &ka, oldset, regs, in_syscall)) {
594 DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n", 594 DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
595 regs->gr[28]); 595 regs->gr[28]);
596 return 1; 596 return 1;
597 } 597 }
598 } 598 }
599 /* end of while(1) looping forever if we can't force a signal */ 599 /* end of while(1) looping forever if we can't force a signal */
600 600
601 /* Did we come from a system call? */ 601 /* Did we come from a system call? */
602 if (in_syscall) { 602 if (in_syscall) {
603 /* Restart the system call - no handlers present */ 603 /* Restart the system call - no handlers present */
604 if (regs->gr[28] == -ERESTART_RESTARTBLOCK) { 604 if (regs->gr[28] == -ERESTART_RESTARTBLOCK) {
605 unsigned int *usp = (unsigned int *)regs->gr[30]; 605 unsigned int *usp = (unsigned int *)regs->gr[30];
606 606
607 /* Setup a trampoline to restart the syscall 607 /* Setup a trampoline to restart the syscall
608 * with __NR_restart_syscall 608 * with __NR_restart_syscall
609 * 609 *
610 * 0: <return address (orig r31)> 610 * 0: <return address (orig r31)>
611 * 4: <2nd half for 64-bit> 611 * 4: <2nd half for 64-bit>
612 * 8: ldw 0(%sp), %r31 612 * 8: ldw 0(%sp), %r31
613 * 12: be 0x100(%sr2, %r0) 613 * 12: be 0x100(%sr2, %r0)
614 * 16: ldi __NR_restart_syscall, %r20 614 * 16: ldi __NR_restart_syscall, %r20
615 */ 615 */
616 #ifndef __LP64__ 616 #ifndef __LP64__
617 put_user(regs->gr[31], &usp[0]); 617 put_user(regs->gr[31], &usp[0]);
618 put_user(0x0fc0109f, &usp[2]); 618 put_user(0x0fc0109f, &usp[2]);
619 #else 619 #else
620 put_user(regs->gr[31] >> 32, &usp[0]); 620 put_user(regs->gr[31] >> 32, &usp[0]);
621 put_user(regs->gr[31] & 0xffffffff, &usp[1]); 621 put_user(regs->gr[31] & 0xffffffff, &usp[1]);
622 put_user(0x0fc010df, &usp[2]); 622 put_user(0x0fc010df, &usp[2]);
623 #endif 623 #endif
624 put_user(0xe0008200, &usp[3]); 624 put_user(0xe0008200, &usp[3]);
625 put_user(0x34140000, &usp[4]); 625 put_user(0x34140000, &usp[4]);
626 626
627 /* Stack is 64-byte aligned, and we only need 627 /* Stack is 64-byte aligned, and we only need
628 * to flush 1 cache line. 628 * to flush 1 cache line.
629 * Flushing one cacheline is cheap. 629 * Flushing one cacheline is cheap.
630 * "sync" on bigger (> 4 way) boxes is not. 630 * "sync" on bigger (> 4 way) boxes is not.
631 */ 631 */
632 asm("fdc %%r0(%%sr3, %0)\n" 632 asm("fdc %%r0(%%sr3, %0)\n"
633 "sync\n" 633 "sync\n"
634 "fic %%r0(%%sr3, %0)\n" 634 "fic %%r0(%%sr3, %0)\n"
635 "sync\n" 635 "sync\n"
636 : : "r"(regs->gr[30])); 636 : : "r"(regs->gr[30]));
637 637
638 regs->gr[31] = regs->gr[30] + 8; 638 regs->gr[31] = regs->gr[30] + 8;
639 /* Preserve original r28. */ 639 /* Preserve original r28. */
640 regs->gr[28] = regs->orig_r28; 640 regs->gr[28] = regs->orig_r28;
641 } else if (regs->gr[28] == -ERESTARTNOHAND || 641 } else if (regs->gr[28] == -ERESTARTNOHAND ||
642 regs->gr[28] == -ERESTARTSYS || 642 regs->gr[28] == -ERESTARTSYS ||
643 regs->gr[28] == -ERESTARTNOINTR) { 643 regs->gr[28] == -ERESTARTNOINTR) {
644 /* Hooray for delayed branching. We don't 644 /* Hooray for delayed branching. We don't
645 have to restore %r20 (the system call 645 have to restore %r20 (the system call
646 number) because it gets loaded in the delay 646 number) because it gets loaded in the delay
647 slot of the branch external instruction. */ 647 slot of the branch external instruction. */
648 regs->gr[31] -= 8; 648 regs->gr[31] -= 8;
649 /* Preserve original r28. */ 649 /* Preserve original r28. */
650 regs->gr[28] = regs->orig_r28; 650 regs->gr[28] = regs->orig_r28;
651 } 651 }
652 } 652 }
653 653
654 DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 654 DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n",
655 regs->gr[28]); 655 regs->gr[28]);
656 656
657 return 0; 657 return 0;
658 } 658 }
659 659
arch/sh64/kernel/signal.c
1 /* 1 /*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * arch/sh64/kernel/signal.c 6 * arch/sh64/kernel/signal.c
7 * 7 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli 8 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 Paul Mundt 9 * Copyright (C) 2003 Paul Mundt
10 * Copyright (C) 2004 Richard Curnow 10 * Copyright (C) 2004 Richard Curnow
11 * 11 *
12 * Started from sh version. 12 * Started from sh version.
13 * 13 *
14 */ 14 */
15 #include <linux/rwsem.h> 15 #include <linux/rwsem.h>
16 #include <linux/sched.h> 16 #include <linux/sched.h>
17 #include <linux/mm.h> 17 #include <linux/mm.h>
18 #include <linux/smp.h> 18 #include <linux/smp.h>
19 #include <linux/smp_lock.h> 19 #include <linux/smp_lock.h>
20 #include <linux/kernel.h> 20 #include <linux/kernel.h>
21 #include <linux/signal.h> 21 #include <linux/signal.h>
22 #include <linux/errno.h> 22 #include <linux/errno.h>
23 #include <linux/wait.h> 23 #include <linux/wait.h>
24 #include <linux/personality.h> 24 #include <linux/personality.h>
25 #include <linux/suspend.h> 25 #include <linux/suspend.h>
26 #include <linux/ptrace.h> 26 #include <linux/ptrace.h>
27 #include <linux/unistd.h> 27 #include <linux/unistd.h>
28 #include <linux/stddef.h> 28 #include <linux/stddef.h>
29 #include <linux/personality.h> 29 #include <linux/personality.h>
30 #include <asm/ucontext.h> 30 #include <asm/ucontext.h>
31 #include <asm/uaccess.h> 31 #include <asm/uaccess.h>
32 #include <asm/pgtable.h> 32 #include <asm/pgtable.h>
33 33
34 34
35 #define REG_RET 9 35 #define REG_RET 9
36 #define REG_ARG1 2 36 #define REG_ARG1 2
37 #define REG_ARG2 3 37 #define REG_ARG2 3
38 #define REG_ARG3 4 38 #define REG_ARG3 4
39 #define REG_SP 15 39 #define REG_SP 15
40 #define REG_PR 18 40 #define REG_PR 18
41 #define REF_REG_RET regs->regs[REG_RET] 41 #define REF_REG_RET regs->regs[REG_RET]
42 #define REF_REG_SP regs->regs[REG_SP] 42 #define REF_REG_SP regs->regs[REG_SP]
43 #define DEREF_REG_PR regs->regs[REG_PR] 43 #define DEREF_REG_PR regs->regs[REG_PR]
44 44
45 #define DEBUG_SIG 0 45 #define DEBUG_SIG 0
46 46
47 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 47 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
48 48
49 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 49 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
50 50
51 /* 51 /*
52 * Atomically swap in the new signal mask, and wait for a signal. 52 * Atomically swap in the new signal mask, and wait for a signal.
53 */ 53 */
54 54
55 asmlinkage int 55 asmlinkage int
56 sys_sigsuspend(old_sigset_t mask, 56 sys_sigsuspend(old_sigset_t mask,
57 unsigned long r3, unsigned long r4, unsigned long r5, 57 unsigned long r3, unsigned long r4, unsigned long r5,
58 unsigned long r6, unsigned long r7, 58 unsigned long r6, unsigned long r7,
59 struct pt_regs * regs) 59 struct pt_regs * regs)
60 { 60 {
61 sigset_t saveset; 61 sigset_t saveset;
62 62
63 mask &= _BLOCKABLE; 63 mask &= _BLOCKABLE;
64 spin_lock_irq(&current->sighand->siglock); 64 spin_lock_irq(&current->sighand->siglock);
65 saveset = current->blocked; 65 saveset = current->blocked;
66 siginitset(&current->blocked, mask); 66 siginitset(&current->blocked, mask);
67 recalc_sigpending(); 67 recalc_sigpending();
68 spin_unlock_irq(&current->sighand->siglock); 68 spin_unlock_irq(&current->sighand->siglock);
69 69
70 REF_REG_RET = -EINTR; 70 REF_REG_RET = -EINTR;
71 while (1) { 71 while (1) {
72 current->state = TASK_INTERRUPTIBLE; 72 current->state = TASK_INTERRUPTIBLE;
73 schedule(); 73 schedule();
74 regs->pc += 4; /* because sys_sigreturn decrements the pc */ 74 regs->pc += 4; /* because sys_sigreturn decrements the pc */
75 if (do_signal(regs, &saveset)) { 75 if (do_signal(regs, &saveset)) {
76 /* pc now points at signal handler. Need to decrement 76 /* pc now points at signal handler. Need to decrement
77 it because entry.S will increment it. */ 77 it because entry.S will increment it. */
78 regs->pc -= 4; 78 regs->pc -= 4;
79 return -EINTR; 79 return -EINTR;
80 } 80 }
81 } 81 }
82 } 82 }
83 83
84 asmlinkage int 84 asmlinkage int
85 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, 85 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
86 unsigned long r4, unsigned long r5, unsigned long r6, 86 unsigned long r4, unsigned long r5, unsigned long r6,
87 unsigned long r7, 87 unsigned long r7,
88 struct pt_regs * regs) 88 struct pt_regs * regs)
89 { 89 {
90 sigset_t saveset, newset; 90 sigset_t saveset, newset;
91 91
92 /* XXX: Don't preclude handling different sized sigset_t's. */ 92 /* XXX: Don't preclude handling different sized sigset_t's. */
93 if (sigsetsize != sizeof(sigset_t)) 93 if (sigsetsize != sizeof(sigset_t))
94 return -EINVAL; 94 return -EINVAL;
95 95
96 if (copy_from_user(&newset, unewset, sizeof(newset))) 96 if (copy_from_user(&newset, unewset, sizeof(newset)))
97 return -EFAULT; 97 return -EFAULT;
98 sigdelsetmask(&newset, ~_BLOCKABLE); 98 sigdelsetmask(&newset, ~_BLOCKABLE);
99 spin_lock_irq(&current->sighand->siglock); 99 spin_lock_irq(&current->sighand->siglock);
100 saveset = current->blocked; 100 saveset = current->blocked;
101 current->blocked = newset; 101 current->blocked = newset;
102 recalc_sigpending(); 102 recalc_sigpending();
103 spin_unlock_irq(&current->sighand->siglock); 103 spin_unlock_irq(&current->sighand->siglock);
104 104
105 REF_REG_RET = -EINTR; 105 REF_REG_RET = -EINTR;
106 while (1) { 106 while (1) {
107 current->state = TASK_INTERRUPTIBLE; 107 current->state = TASK_INTERRUPTIBLE;
108 schedule(); 108 schedule();
109 regs->pc += 4; /* because sys_sigreturn decrements the pc */ 109 regs->pc += 4; /* because sys_sigreturn decrements the pc */
110 if (do_signal(regs, &saveset)) { 110 if (do_signal(regs, &saveset)) {
111 /* pc now points at signal handler. Need to decrement 111 /* pc now points at signal handler. Need to decrement
112 it because entry.S will increment it. */ 112 it because entry.S will increment it. */
113 regs->pc -= 4; 113 regs->pc -= 4;
114 return -EINTR; 114 return -EINTR;
115 } 115 }
116 } 116 }
117 } 117 }
118 118
119 asmlinkage int 119 asmlinkage int
120 sys_sigaction(int sig, const struct old_sigaction __user *act, 120 sys_sigaction(int sig, const struct old_sigaction __user *act,
121 struct old_sigaction __user *oact) 121 struct old_sigaction __user *oact)
122 { 122 {
123 struct k_sigaction new_ka, old_ka; 123 struct k_sigaction new_ka, old_ka;
124 int ret; 124 int ret;
125 125
126 if (act) { 126 if (act) {
127 old_sigset_t mask; 127 old_sigset_t mask;
128 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 128 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
129 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 129 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
130 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 130 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
131 return -EFAULT; 131 return -EFAULT;
132 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 132 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
133 __get_user(mask, &act->sa_mask); 133 __get_user(mask, &act->sa_mask);
134 siginitset(&new_ka.sa.sa_mask, mask); 134 siginitset(&new_ka.sa.sa_mask, mask);
135 } 135 }
136 136
137 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 137 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
138 138
139 if (!ret && oact) { 139 if (!ret && oact) {
140 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 140 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
141 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 141 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
142 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 142 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
143 return -EFAULT; 143 return -EFAULT;
144 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 144 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
145 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 145 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
146 } 146 }
147 147
148 return ret; 148 return ret;
149 } 149 }
150 150
151 asmlinkage int 151 asmlinkage int
152 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 152 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
153 unsigned long r4, unsigned long r5, unsigned long r6, 153 unsigned long r4, unsigned long r5, unsigned long r6,
154 unsigned long r7, 154 unsigned long r7,
155 struct pt_regs * regs) 155 struct pt_regs * regs)
156 { 156 {
157 return do_sigaltstack(uss, uoss, REF_REG_SP); 157 return do_sigaltstack(uss, uoss, REF_REG_SP);
158 } 158 }
159 159
160 160
161 /* 161 /*
162 * Do a signal return; undo the signal stack. 162 * Do a signal return; undo the signal stack.
163 */ 163 */
164 164
165 struct sigframe 165 struct sigframe
166 { 166 {
167 struct sigcontext sc; 167 struct sigcontext sc;
168 unsigned long extramask[_NSIG_WORDS-1]; 168 unsigned long extramask[_NSIG_WORDS-1];
169 long long retcode[2]; 169 long long retcode[2];
170 }; 170 };
171 171
172 struct rt_sigframe 172 struct rt_sigframe
173 { 173 {
174 struct siginfo __user *pinfo; 174 struct siginfo __user *pinfo;
175 void *puc; 175 void *puc;
176 struct siginfo info; 176 struct siginfo info;
177 struct ucontext uc; 177 struct ucontext uc;
178 long long retcode[2]; 178 long long retcode[2];
179 }; 179 };
180 180
181 #ifdef CONFIG_SH_FPU 181 #ifdef CONFIG_SH_FPU
182 static inline int 182 static inline int
183 restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) 183 restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
184 { 184 {
185 int err = 0; 185 int err = 0;
186 int fpvalid; 186 int fpvalid;
187 187
188 err |= __get_user (fpvalid, &sc->sc_fpvalid); 188 err |= __get_user (fpvalid, &sc->sc_fpvalid);
189 conditional_used_math(fpvalid); 189 conditional_used_math(fpvalid);
190 if (! fpvalid) 190 if (! fpvalid)
191 return err; 191 return err;
192 192
193 if (current == last_task_used_math) { 193 if (current == last_task_used_math) {
194 last_task_used_math = NULL; 194 last_task_used_math = NULL;
195 regs->sr |= SR_FD; 195 regs->sr |= SR_FD;
196 } 196 }
197 197
198 err |= __copy_from_user(&current->thread.fpu.hard, &sc->sc_fpregs[0], 198 err |= __copy_from_user(&current->thread.fpu.hard, &sc->sc_fpregs[0],
199 (sizeof(long long) * 32) + (sizeof(int) * 1)); 199 (sizeof(long long) * 32) + (sizeof(int) * 1));
200 200
201 return err; 201 return err;
202 } 202 }
203 203
204 static inline int 204 static inline int
205 setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) 205 setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
206 { 206 {
207 int err = 0; 207 int err = 0;
208 int fpvalid; 208 int fpvalid;
209 209
210 fpvalid = !!used_math(); 210 fpvalid = !!used_math();
211 err |= __put_user(fpvalid, &sc->sc_fpvalid); 211 err |= __put_user(fpvalid, &sc->sc_fpvalid);
212 if (! fpvalid) 212 if (! fpvalid)
213 return err; 213 return err;
214 214
215 if (current == last_task_used_math) { 215 if (current == last_task_used_math) {
216 grab_fpu(); 216 grab_fpu();
217 fpsave(&current->thread.fpu.hard); 217 fpsave(&current->thread.fpu.hard);
218 release_fpu(); 218 release_fpu();
219 last_task_used_math = NULL; 219 last_task_used_math = NULL;
220 regs->sr |= SR_FD; 220 regs->sr |= SR_FD;
221 } 221 }
222 222
223 err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard, 223 err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard,
224 (sizeof(long long) * 32) + (sizeof(int) * 1)); 224 (sizeof(long long) * 32) + (sizeof(int) * 1));
225 clear_used_math(); 225 clear_used_math();
226 226
227 return err; 227 return err;
228 } 228 }
229 #else 229 #else
230 static inline int 230 static inline int
231 restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) 231 restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
232 {} 232 {}
233 static inline int 233 static inline int
234 setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) 234 setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
235 {} 235 {}
236 #endif 236 #endif
237 237
238 static int 238 static int
239 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, long long *r2_p) 239 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, long long *r2_p)
240 { 240 {
241 unsigned int err = 0; 241 unsigned int err = 0;
242 unsigned long long current_sr, new_sr; 242 unsigned long long current_sr, new_sr;
243 #define SR_MASK 0xffff8cfd 243 #define SR_MASK 0xffff8cfd
244 244
245 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) 245 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
246 246
247 COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]); 247 COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]);
248 COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]); 248 COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]);
249 COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); 249 COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]);
250 COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]); 250 COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
251 COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]); 251 COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
252 COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]); 252 COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
253 COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]); 253 COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
254 COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]); 254 COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
255 COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]); 255 COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
256 COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]); 256 COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
257 COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]); 257 COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
258 COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]); 258 COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
259 COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]); 259 COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
260 COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]); 260 COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
261 COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]); 261 COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
262 COPY(regs[60]); COPY(regs[61]); COPY(regs[62]); 262 COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
263 COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]); 263 COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
264 COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]); 264 COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
265 265
266 /* Prevent the signal handler manipulating SR in a way that can 266 /* Prevent the signal handler manipulating SR in a way that can
267 crash the kernel. i.e. only allow S, Q, M, PR, SZ, FR to be 267 crash the kernel. i.e. only allow S, Q, M, PR, SZ, FR to be
268 modified */ 268 modified */
269 current_sr = regs->sr; 269 current_sr = regs->sr;
270 err |= __get_user(new_sr, &sc->sc_sr); 270 err |= __get_user(new_sr, &sc->sc_sr);
271 regs->sr &= SR_MASK; 271 regs->sr &= SR_MASK;
272 regs->sr |= (new_sr & ~SR_MASK); 272 regs->sr |= (new_sr & ~SR_MASK);
273 273
274 COPY(pc); 274 COPY(pc);
275 275
276 #undef COPY 276 #undef COPY
277 277
278 /* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr 278 /* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr
279 * has been restored above.) */ 279 * has been restored above.) */
280 err |= restore_sigcontext_fpu(regs, sc); 280 err |= restore_sigcontext_fpu(regs, sc);
281 281
282 regs->syscall_nr = -1; /* disable syscall checks */ 282 regs->syscall_nr = -1; /* disable syscall checks */
283 err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]); 283 err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]);
284 return err; 284 return err;
285 } 285 }
286 286
287 asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3, 287 asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
288 unsigned long r4, unsigned long r5, 288 unsigned long r4, unsigned long r5,
289 unsigned long r6, unsigned long r7, 289 unsigned long r6, unsigned long r7,
290 struct pt_regs * regs) 290 struct pt_regs * regs)
291 { 291 {
292 struct sigframe __user *frame = (struct sigframe __user *) (long) REF_REG_SP; 292 struct sigframe __user *frame = (struct sigframe __user *) (long) REF_REG_SP;
293 sigset_t set; 293 sigset_t set;
294 long long ret; 294 long long ret;
295 295
296 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 296 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
297 goto badframe; 297 goto badframe;
298 298
299 if (__get_user(set.sig[0], &frame->sc.oldmask) 299 if (__get_user(set.sig[0], &frame->sc.oldmask)
300 || (_NSIG_WORDS > 1 300 || (_NSIG_WORDS > 1
301 && __copy_from_user(&set.sig[1], &frame->extramask, 301 && __copy_from_user(&set.sig[1], &frame->extramask,
302 sizeof(frame->extramask)))) 302 sizeof(frame->extramask))))
303 goto badframe; 303 goto badframe;
304 304
305 sigdelsetmask(&set, ~_BLOCKABLE); 305 sigdelsetmask(&set, ~_BLOCKABLE);
306 306
307 spin_lock_irq(&current->sighand->siglock); 307 spin_lock_irq(&current->sighand->siglock);
308 current->blocked = set; 308 current->blocked = set;
309 recalc_sigpending(); 309 recalc_sigpending();
310 spin_unlock_irq(&current->sighand->siglock); 310 spin_unlock_irq(&current->sighand->siglock);
311 311
312 if (restore_sigcontext(regs, &frame->sc, &ret)) 312 if (restore_sigcontext(regs, &frame->sc, &ret))
313 goto badframe; 313 goto badframe;
314 regs->pc -= 4; 314 regs->pc -= 4;
315 315
316 return (int) ret; 316 return (int) ret;
317 317
318 badframe: 318 badframe:
319 force_sig(SIGSEGV, current); 319 force_sig(SIGSEGV, current);
320 return 0; 320 return 0;
321 } 321 }
322 322
323 asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, 323 asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
324 unsigned long r4, unsigned long r5, 324 unsigned long r4, unsigned long r5,
325 unsigned long r6, unsigned long r7, 325 unsigned long r6, unsigned long r7,
326 struct pt_regs * regs) 326 struct pt_regs * regs)
327 { 327 {
328 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP; 328 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP;
329 sigset_t set; 329 sigset_t set;
330 stack_t __user st; 330 stack_t __user st;
331 long long ret; 331 long long ret;
332 332
333 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 333 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
334 goto badframe; 334 goto badframe;
335 335
336 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 336 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
337 goto badframe; 337 goto badframe;
338 338
339 sigdelsetmask(&set, ~_BLOCKABLE); 339 sigdelsetmask(&set, ~_BLOCKABLE);
340 spin_lock_irq(&current->sighand->siglock); 340 spin_lock_irq(&current->sighand->siglock);
341 current->blocked = set; 341 current->blocked = set;
342 recalc_sigpending(); 342 recalc_sigpending();
343 spin_unlock_irq(&current->sighand->siglock); 343 spin_unlock_irq(&current->sighand->siglock);
344 344
345 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret)) 345 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
346 goto badframe; 346 goto badframe;
347 regs->pc -= 4; 347 regs->pc -= 4;
348 348
349 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) 349 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
350 goto badframe; 350 goto badframe;
351 /* It is more difficult to avoid calling this function than to 351 /* It is more difficult to avoid calling this function than to
352 call it and ignore errors. */ 352 call it and ignore errors. */
353 do_sigaltstack(&st, NULL, REF_REG_SP); 353 do_sigaltstack(&st, NULL, REF_REG_SP);
354 354
355 return (int) ret; 355 return (int) ret;
356 356
357 badframe: 357 badframe:
358 force_sig(SIGSEGV, current); 358 force_sig(SIGSEGV, current);
359 return 0; 359 return 0;
360 } 360 }
361 361
362 /* 362 /*
363 * Set up a signal frame. 363 * Set up a signal frame.
364 */ 364 */
365 365
366 static int 366 static int
367 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 367 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
368 unsigned long mask) 368 unsigned long mask)
369 { 369 {
370 int err = 0; 370 int err = 0;
371 371
372 /* Do this first, otherwise is this sets sr->fd, that value isn't preserved. */ 372 /* Do this first, otherwise is this sets sr->fd, that value isn't preserved. */
373 err |= setup_sigcontext_fpu(regs, sc); 373 err |= setup_sigcontext_fpu(regs, sc);
374 374
375 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) 375 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
376 376
377 COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]); 377 COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]);
378 COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]); 378 COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]);
379 COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]); 379 COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]);
380 COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]); 380 COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
381 COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]); 381 COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
382 COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]); 382 COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
383 COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]); 383 COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
384 COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]); 384 COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
385 COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]); 385 COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
386 COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]); 386 COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
387 COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]); 387 COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
388 COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]); 388 COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
389 COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]); 389 COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
390 COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]); 390 COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
391 COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]); 391 COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
392 COPY(regs[60]); COPY(regs[61]); COPY(regs[62]); 392 COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
393 COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]); 393 COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
394 COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]); 394 COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
395 COPY(sr); COPY(pc); 395 COPY(sr); COPY(pc);
396 396
397 #undef COPY 397 #undef COPY
398 398
399 err |= __put_user(mask, &sc->oldmask); 399 err |= __put_user(mask, &sc->oldmask);
400 400
401 return err; 401 return err;
402 } 402 }
403 403
404 /* 404 /*
405 * Determine which stack to use.. 405 * Determine which stack to use..
406 */ 406 */
407 static inline void __user * 407 static inline void __user *
408 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) 408 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
409 { 409 {
410 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) 410 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
411 sp = current->sas_ss_sp + current->sas_ss_size; 411 sp = current->sas_ss_sp + current->sas_ss_size;
412 412
413 return (void __user *)((sp - frame_size) & -8ul); 413 return (void __user *)((sp - frame_size) & -8ul);
414 } 414 }
415 415
416 void sa_default_restorer(void); /* See comments below */ 416 void sa_default_restorer(void); /* See comments below */
417 void sa_default_rt_restorer(void); /* See comments below */ 417 void sa_default_rt_restorer(void); /* See comments below */
418 418
419 static void setup_frame(int sig, struct k_sigaction *ka, 419 static void setup_frame(int sig, struct k_sigaction *ka,
420 sigset_t *set, struct pt_regs *regs) 420 sigset_t *set, struct pt_regs *regs)
421 { 421 {
422 struct sigframe __user *frame; 422 struct sigframe __user *frame;
423 int err = 0; 423 int err = 0;
424 int signal; 424 int signal;
425 425
426 frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame)); 426 frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
427 427
428 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 428 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
429 goto give_sigsegv; 429 goto give_sigsegv;
430 430
431 signal = current_thread_info()->exec_domain 431 signal = current_thread_info()->exec_domain
432 && current_thread_info()->exec_domain->signal_invmap 432 && current_thread_info()->exec_domain->signal_invmap
433 && sig < 32 433 && sig < 32
434 ? current_thread_info()->exec_domain->signal_invmap[sig] 434 ? current_thread_info()->exec_domain->signal_invmap[sig]
435 : sig; 435 : sig;
436 436
437 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); 437 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
438 438
439 /* Give up earlier as i386, in case */ 439 /* Give up earlier as i386, in case */
440 if (err) 440 if (err)
441 goto give_sigsegv; 441 goto give_sigsegv;
442 442
443 if (_NSIG_WORDS > 1) { 443 if (_NSIG_WORDS > 1) {
444 err |= __copy_to_user(frame->extramask, &set->sig[1], 444 err |= __copy_to_user(frame->extramask, &set->sig[1],
445 sizeof(frame->extramask)); } 445 sizeof(frame->extramask)); }
446 446
447 /* Give up earlier as i386, in case */ 447 /* Give up earlier as i386, in case */
448 if (err) 448 if (err)
449 goto give_sigsegv; 449 goto give_sigsegv;
450 450
451 /* Set up to return from userspace. If provided, use a stub 451 /* Set up to return from userspace. If provided, use a stub
452 already in userspace. */ 452 already in userspace. */
453 if (ka->sa.sa_flags & SA_RESTORER) { 453 if (ka->sa.sa_flags & SA_RESTORER) {
454 DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1; 454 DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
455 455
456 /* 456 /*
457 * On SH5 all edited pointers are subject to NEFF 457 * On SH5 all edited pointers are subject to NEFF
458 */ 458 */
459 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? 459 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
460 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; 460 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
461 } else { 461 } else {
462 /* 462 /*
463 * Different approach on SH5. 463 * Different approach on SH5.
464 * . Endianness independent asm code gets placed in entry.S . 464 * . Endianness independent asm code gets placed in entry.S .
465 * This is limited to four ASM instructions corresponding 465 * This is limited to four ASM instructions corresponding
466 * to two long longs in size. 466 * to two long longs in size.
467 * . err checking is done on the else branch only 467 * . err checking is done on the else branch only
468 * . flush_icache_range() is called upon __put_user() only 468 * . flush_icache_range() is called upon __put_user() only
469 * . all edited pointers are subject to NEFF 469 * . all edited pointers are subject to NEFF
470 * . being code, linker turns ShMedia bit on, always 470 * . being code, linker turns ShMedia bit on, always
471 * dereference index -1. 471 * dereference index -1.
472 */ 472 */
473 DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; 473 DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
474 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? 474 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
475 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; 475 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
476 476
477 if (__copy_to_user(frame->retcode, 477 if (__copy_to_user(frame->retcode,
478 (unsigned long long)sa_default_restorer & (~1), 16) != 0) 478 (unsigned long long)sa_default_restorer & (~1), 16) != 0)
479 goto give_sigsegv; 479 goto give_sigsegv;
480 480
481 /* Cohere the trampoline with the I-cache. */ 481 /* Cohere the trampoline with the I-cache. */
482 flush_cache_sigtramp(DEREF_REG_PR-1, DEREF_REG_PR-1+16); 482 flush_cache_sigtramp(DEREF_REG_PR-1, DEREF_REG_PR-1+16);
483 } 483 }
484 484
485 /* 485 /*
486 * Set up registers for signal handler. 486 * Set up registers for signal handler.
487 * All edited pointers are subject to NEFF. 487 * All edited pointers are subject to NEFF.
488 */ 488 */
489 regs->regs[REG_SP] = (unsigned long) frame; 489 regs->regs[REG_SP] = (unsigned long) frame;
490 regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? 490 regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
491 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; 491 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
492 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ 492 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
493 493
494 /* FIXME: 494 /* FIXME:
495 The glibc profiling support for SH-5 needs to be passed a sigcontext 495 The glibc profiling support for SH-5 needs to be passed a sigcontext
496 so it can retrieve the PC. At some point during 2003 the glibc 496 so it can retrieve the PC. At some point during 2003 the glibc
497 support was changed to receive the sigcontext through the 2nd 497 support was changed to receive the sigcontext through the 2nd
498 argument, but there are still versions of libc.so in use that use 498 argument, but there are still versions of libc.so in use that use
499 the 3rd argument. Until libc.so is stabilised, pass the sigcontext 499 the 3rd argument. Until libc.so is stabilised, pass the sigcontext
500 through both 2nd and 3rd arguments. 500 through both 2nd and 3rd arguments.
501 */ 501 */
502 502
503 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc; 503 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
504 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc; 504 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
505 505
506 regs->pc = (unsigned long) ka->sa.sa_handler; 506 regs->pc = (unsigned long) ka->sa.sa_handler;
507 regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; 507 regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
508 508
509 set_fs(USER_DS); 509 set_fs(USER_DS);
510 510
511 #if DEBUG_SIG 511 #if DEBUG_SIG
512 /* Broken %016Lx */ 512 /* Broken %016Lx */
513 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", 513 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
514 signal, 514 signal,
515 current->comm, current->pid, frame, 515 current->comm, current->pid, frame,
516 regs->pc >> 32, regs->pc & 0xffffffff, 516 regs->pc >> 32, regs->pc & 0xffffffff,
517 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff); 517 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
518 #endif 518 #endif
519 519
520 return; 520 return;
521 521
522 give_sigsegv: 522 give_sigsegv:
523 force_sigsegv(sig, current); 523 force_sigsegv(sig, current);
524 } 524 }
525 525
526 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 526 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
527 sigset_t *set, struct pt_regs *regs) 527 sigset_t *set, struct pt_regs *regs)
528 { 528 {
529 struct rt_sigframe __user *frame; 529 struct rt_sigframe __user *frame;
530 int err = 0; 530 int err = 0;
531 int signal; 531 int signal;
532 532
533 frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame)); 533 frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
534 534
535 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 535 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
536 goto give_sigsegv; 536 goto give_sigsegv;
537 537
538 signal = current_thread_info()->exec_domain 538 signal = current_thread_info()->exec_domain
539 && current_thread_info()->exec_domain->signal_invmap 539 && current_thread_info()->exec_domain->signal_invmap
540 && sig < 32 540 && sig < 32
541 ? current_thread_info()->exec_domain->signal_invmap[sig] 541 ? current_thread_info()->exec_domain->signal_invmap[sig]
542 : sig; 542 : sig;
543 543
544 err |= __put_user(&frame->info, &frame->pinfo); 544 err |= __put_user(&frame->info, &frame->pinfo);
545 err |= __put_user(&frame->uc, &frame->puc); 545 err |= __put_user(&frame->uc, &frame->puc);
546 err |= copy_siginfo_to_user(&frame->info, info); 546 err |= copy_siginfo_to_user(&frame->info, info);
547 547
548 /* Give up earlier as i386, in case */ 548 /* Give up earlier as i386, in case */
549 if (err) 549 if (err)
550 goto give_sigsegv; 550 goto give_sigsegv;
551 551
552 /* Create the ucontext. */ 552 /* Create the ucontext. */
553 err |= __put_user(0, &frame->uc.uc_flags); 553 err |= __put_user(0, &frame->uc.uc_flags);
554 err |= __put_user(0, &frame->uc.uc_link); 554 err |= __put_user(0, &frame->uc.uc_link);
555 err |= __put_user((void *)current->sas_ss_sp, 555 err |= __put_user((void *)current->sas_ss_sp,
556 &frame->uc.uc_stack.ss_sp); 556 &frame->uc.uc_stack.ss_sp);
557 err |= __put_user(sas_ss_flags(regs->regs[REG_SP]), 557 err |= __put_user(sas_ss_flags(regs->regs[REG_SP]),
558 &frame->uc.uc_stack.ss_flags); 558 &frame->uc.uc_stack.ss_flags);
559 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 559 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
560 err |= setup_sigcontext(&frame->uc.uc_mcontext, 560 err |= setup_sigcontext(&frame->uc.uc_mcontext,
561 regs, set->sig[0]); 561 regs, set->sig[0]);
562 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 562 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
563 563
564 /* Give up earlier as i386, in case */ 564 /* Give up earlier as i386, in case */
565 if (err) 565 if (err)
566 goto give_sigsegv; 566 goto give_sigsegv;
567 567
568 /* Set up to return from userspace. If provided, use a stub 568 /* Set up to return from userspace. If provided, use a stub
569 already in userspace. */ 569 already in userspace. */
570 if (ka->sa.sa_flags & SA_RESTORER) { 570 if (ka->sa.sa_flags & SA_RESTORER) {
571 DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1; 571 DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
572 572
573 /* 573 /*
574 * On SH5 all edited pointers are subject to NEFF 574 * On SH5 all edited pointers are subject to NEFF
575 */ 575 */
576 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? 576 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
577 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; 577 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
578 } else { 578 } else {
579 /* 579 /*
580 * Different approach on SH5. 580 * Different approach on SH5.
581 * . Endianness independent asm code gets placed in entry.S . 581 * . Endianness independent asm code gets placed in entry.S .
582 * This is limited to four ASM instructions corresponding 582 * This is limited to four ASM instructions corresponding
583 * to two long longs in size. 583 * to two long longs in size.
584 * . err checking is done on the else branch only 584 * . err checking is done on the else branch only
585 * . flush_icache_range() is called upon __put_user() only 585 * . flush_icache_range() is called upon __put_user() only
586 * . all edited pointers are subject to NEFF 586 * . all edited pointers are subject to NEFF
587 * . being code, linker turns ShMedia bit on, always 587 * . being code, linker turns ShMedia bit on, always
588 * dereference index -1. 588 * dereference index -1.
589 */ 589 */
590 590
591 DEREF_REG_PR = (unsigned long) frame->retcode | 0x01; 591 DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
592 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ? 592 DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
593 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR; 593 (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
594 594
595 if (__copy_to_user(frame->retcode, 595 if (__copy_to_user(frame->retcode,
596 (unsigned long long)sa_default_rt_restorer & (~1), 16) != 0) 596 (unsigned long long)sa_default_rt_restorer & (~1), 16) != 0)
597 goto give_sigsegv; 597 goto give_sigsegv;
598 598
599 flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15); 599 flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
600 } 600 }
601 601
602 /* 602 /*
603 * Set up registers for signal handler. 603 * Set up registers for signal handler.
604 * All edited pointers are subject to NEFF. 604 * All edited pointers are subject to NEFF.
605 */ 605 */
606 regs->regs[REG_SP] = (unsigned long) frame; 606 regs->regs[REG_SP] = (unsigned long) frame;
607 regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ? 607 regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
608 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP]; 608 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
609 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ 609 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
610 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info; 610 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
611 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext; 611 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
612 regs->pc = (unsigned long) ka->sa.sa_handler; 612 regs->pc = (unsigned long) ka->sa.sa_handler;
613 regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc; 613 regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
614 614
615 set_fs(USER_DS); 615 set_fs(USER_DS);
616 616
617 #if DEBUG_SIG 617 #if DEBUG_SIG
618 /* Broken %016Lx */ 618 /* Broken %016Lx */
619 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", 619 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
620 signal, 620 signal,
621 current->comm, current->pid, frame, 621 current->comm, current->pid, frame,
622 regs->pc >> 32, regs->pc & 0xffffffff, 622 regs->pc >> 32, regs->pc & 0xffffffff,
623 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff); 623 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
624 #endif 624 #endif
625 625
626 return; 626 return;
627 627
628 give_sigsegv: 628 give_sigsegv:
629 force_sigsegv(sig, current); 629 force_sigsegv(sig, current);
630 } 630 }
631 631
632 /* 632 /*
633 * OK, we're invoking a handler 633 * OK, we're invoking a handler
634 */ 634 */
635 635
636 static void 636 static void
637 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 637 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
638 sigset_t *oldset, struct pt_regs * regs) 638 sigset_t *oldset, struct pt_regs * regs)
639 { 639 {
640 /* Are we from a system call? */ 640 /* Are we from a system call? */
641 if (regs->syscall_nr >= 0) { 641 if (regs->syscall_nr >= 0) {
642 /* If so, check system call restarting.. */ 642 /* If so, check system call restarting.. */
643 switch (regs->regs[REG_RET]) { 643 switch (regs->regs[REG_RET]) {
644 case -ERESTARTNOHAND: 644 case -ERESTARTNOHAND:
645 regs->regs[REG_RET] = -EINTR; 645 regs->regs[REG_RET] = -EINTR;
646 break; 646 break;
647 647
648 case -ERESTARTSYS: 648 case -ERESTARTSYS:
649 if (!(ka->sa.sa_flags & SA_RESTART)) { 649 if (!(ka->sa.sa_flags & SA_RESTART)) {
650 regs->regs[REG_RET] = -EINTR; 650 regs->regs[REG_RET] = -EINTR;
651 break; 651 break;
652 } 652 }
653 /* fallthrough */ 653 /* fallthrough */
654 case -ERESTARTNOINTR: 654 case -ERESTARTNOINTR:
655 /* Decode syscall # */ 655 /* Decode syscall # */
656 regs->regs[REG_RET] = regs->syscall_nr; 656 regs->regs[REG_RET] = regs->syscall_nr;
657 regs->pc -= 4; 657 regs->pc -= 4;
658 } 658 }
659 } 659 }
660 660
661 /* Set up the stack frame */ 661 /* Set up the stack frame */
662 if (ka->sa.sa_flags & SA_SIGINFO) 662 if (ka->sa.sa_flags & SA_SIGINFO)
663 setup_rt_frame(sig, ka, info, oldset, regs); 663 setup_rt_frame(sig, ka, info, oldset, regs);
664 else 664 else
665 setup_frame(sig, ka, oldset, regs); 665 setup_frame(sig, ka, oldset, regs);
666 666
667 spin_lock_irq(&current->sighand->siglock); 667 spin_lock_irq(&current->sighand->siglock);
668 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 668 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
669 if (!(ka->sa.sa_flags & SA_NODEFER)) 669 if (!(ka->sa.sa_flags & SA_NODEFER))
670 sigaddset(&current->blocked,sig); 670 sigaddset(&current->blocked,sig);
671 recalc_sigpending(); 671 recalc_sigpending();
672 spin_unlock_irq(&current->sighand->siglock); 672 spin_unlock_irq(&current->sighand->siglock);
673 } 673 }
674 674
675 /* 675 /*
676 * Note that 'init' is a special process: it doesn't get signals it doesn't 676 * Note that 'init' is a special process: it doesn't get signals it doesn't
677 * want to handle. Thus you cannot kill init even with a SIGKILL even by 677 * want to handle. Thus you cannot kill init even with a SIGKILL even by
678 * mistake. 678 * mistake.
679 * 679 *
680 * Note that we go through the signals twice: once to check the signals that 680 * Note that we go through the signals twice: once to check the signals that
681 * the kernel can handle, and then we build all the user-level signal handling 681 * the kernel can handle, and then we build all the user-level signal handling
682 * stack-frames in one go after that. 682 * stack-frames in one go after that.
683 */ 683 */
684 int do_signal(struct pt_regs *regs, sigset_t *oldset) 684 int do_signal(struct pt_regs *regs, sigset_t *oldset)
685 { 685 {
686 siginfo_t info; 686 siginfo_t info;
687 int signr; 687 int signr;
688 struct k_sigaction ka; 688 struct k_sigaction ka;
689 689
690 /* 690 /*
691 * We want the common case to go fast, which 691 * We want the common case to go fast, which
692 * is why we may in certain cases get here from 692 * is why we may in certain cases get here from
693 * kernel mode. Just return without doing anything 693 * kernel mode. Just return without doing anything
694 * if so. 694 * if so.
695 */ 695 */
696 if (!user_mode(regs)) 696 if (!user_mode(regs))
697 return 1; 697 return 1;
698 698
699 if (try_to_freeze()) 699 if (try_to_freeze())
700 goto no_signal; 700 goto no_signal;
701 701
702 if (!oldset) 702 if (!oldset)
703 oldset = &current->blocked; 703 oldset = &current->blocked;
704 704
705 signr = get_signal_to_deliver(&info, &ka, regs, 0); 705 signr = get_signal_to_deliver(&info, &ka, regs, 0);
706 706
707 if (signr > 0) { 707 if (signr > 0) {
708 /* Whee! Actually deliver the signal. */ 708 /* Whee! Actually deliver the signal. */
709 handle_signal(signr, &info, &ka, oldset, regs); 709 handle_signal(signr, &info, &ka, oldset, regs);
710 return 1; 710 return 1;
711 } 711 }
712 712
713 no_signal: 713 no_signal:
714 /* Did we come from a system call? */ 714 /* Did we come from a system call? */
715 if (regs->syscall_nr >= 0) { 715 if (regs->syscall_nr >= 0) {
716 /* Restart the system call - no handlers present */ 716 /* Restart the system call - no handlers present */
717 if (regs->regs[REG_RET] == -ERESTARTNOHAND || 717 if (regs->regs[REG_RET] == -ERESTARTNOHAND ||
718 regs->regs[REG_RET] == -ERESTARTSYS || 718 regs->regs[REG_RET] == -ERESTARTSYS ||
719 regs->regs[REG_RET] == -ERESTARTNOINTR) { 719 regs->regs[REG_RET] == -ERESTARTNOINTR) {
720 /* Decode Syscall # */ 720 /* Decode Syscall # */
721 regs->regs[REG_RET] = regs->syscall_nr; 721 regs->regs[REG_RET] = regs->syscall_nr;
722 regs->pc -= 4; 722 regs->pc -= 4;
723 } 723 }
724 } 724 }
725 return 0; 725 return 0;
726 } 726 }
727 727
arch/v850/kernel/signal.c
1 /* 1 /*
2 * arch/v850/kernel/signal.c -- Signal handling 2 * arch/v850/kernel/signal.c -- Signal handling
3 * 3 *
4 * Copyright (C) 2001,02,03 NEC Electronics Corporation 4 * Copyright (C) 2001,02,03 NEC Electronics Corporation
5 * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org> 5 * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
6 * Copyright (C) 1999,2000,2002 Niibe Yutaka & Kaz Kojima 6 * Copyright (C) 1999,2000,2002 Niibe Yutaka & Kaz Kojima
7 * Copyright (C) 1991,1992 Linus Torvalds 7 * Copyright (C) 1991,1992 Linus Torvalds
8 * 8 *
9 * This file is subject to the terms and conditions of the GNU General 9 * This file is subject to the terms and conditions of the GNU General
10 * Public License. See the file COPYING in the main directory of this 10 * Public License. See the file COPYING in the main directory of this
11 * archive for more details. 11 * archive for more details.
12 * 12 *
13 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson 13 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
14 * 14 *
15 * This file was derived from the sh version, arch/sh/kernel/signal.c 15 * This file was derived from the sh version, arch/sh/kernel/signal.c
16 */ 16 */
17 17
18 #include <linux/mm.h> 18 #include <linux/mm.h>
19 #include <linux/smp.h> 19 #include <linux/smp.h>
20 #include <linux/smp_lock.h> 20 #include <linux/smp_lock.h>
21 #include <linux/kernel.h> 21 #include <linux/kernel.h>
22 #include <linux/signal.h> 22 #include <linux/signal.h>
23 #include <linux/errno.h> 23 #include <linux/errno.h>
24 #include <linux/wait.h> 24 #include <linux/wait.h>
25 #include <linux/ptrace.h> 25 #include <linux/ptrace.h>
26 #include <linux/unistd.h> 26 #include <linux/unistd.h>
27 #include <linux/stddef.h> 27 #include <linux/stddef.h>
28 #include <linux/personality.h> 28 #include <linux/personality.h>
29 #include <linux/tty.h> 29 #include <linux/tty.h>
30 30
31 #include <asm/ucontext.h> 31 #include <asm/ucontext.h>
32 #include <asm/uaccess.h> 32 #include <asm/uaccess.h>
33 #include <asm/pgtable.h> 33 #include <asm/pgtable.h>
34 #include <asm/pgalloc.h> 34 #include <asm/pgalloc.h>
35 #include <asm/thread_info.h> 35 #include <asm/thread_info.h>
36 #include <asm/cacheflush.h> 36 #include <asm/cacheflush.h>
37 37
38 #define DEBUG_SIG 0 38 #define DEBUG_SIG 0
39 39
40 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 40 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
41 41
42 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 42 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
43 43
44 /* 44 /*
45 * Atomically swap in the new signal mask, and wait for a signal. 45 * Atomically swap in the new signal mask, and wait for a signal.
46 */ 46 */
47 asmlinkage int 47 asmlinkage int
48 sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs) 48 sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
49 { 49 {
50 sigset_t saveset; 50 sigset_t saveset;
51 51
52 mask &= _BLOCKABLE; 52 mask &= _BLOCKABLE;
53 spin_lock_irq(&current->sighand->siglock); 53 spin_lock_irq(&current->sighand->siglock);
54 saveset = current->blocked; 54 saveset = current->blocked;
55 siginitset(&current->blocked, mask); 55 siginitset(&current->blocked, mask);
56 recalc_sigpending(); 56 recalc_sigpending();
57 spin_unlock_irq(&current->sighand->siglock); 57 spin_unlock_irq(&current->sighand->siglock);
58 58
59 regs->gpr[GPR_RVAL] = -EINTR; 59 regs->gpr[GPR_RVAL] = -EINTR;
60 while (1) { 60 while (1) {
61 current->state = TASK_INTERRUPTIBLE; 61 current->state = TASK_INTERRUPTIBLE;
62 schedule(); 62 schedule();
63 if (do_signal(regs, &saveset)) 63 if (do_signal(regs, &saveset))
64 return -EINTR; 64 return -EINTR;
65 } 65 }
66 } 66 }
67 67
68 asmlinkage int 68 asmlinkage int
69 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, 69 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
70 struct pt_regs *regs) 70 struct pt_regs *regs)
71 { 71 {
72 sigset_t saveset, newset; 72 sigset_t saveset, newset;
73 73
74 /* XXX: Don't preclude handling different sized sigset_t's. */ 74 /* XXX: Don't preclude handling different sized sigset_t's. */
75 if (sigsetsize != sizeof(sigset_t)) 75 if (sigsetsize != sizeof(sigset_t))
76 return -EINVAL; 76 return -EINVAL;
77 77
78 if (copy_from_user(&newset, unewset, sizeof(newset))) 78 if (copy_from_user(&newset, unewset, sizeof(newset)))
79 return -EFAULT; 79 return -EFAULT;
80 sigdelsetmask(&newset, ~_BLOCKABLE); 80 sigdelsetmask(&newset, ~_BLOCKABLE);
81 spin_lock_irq(&current->sighand->siglock); 81 spin_lock_irq(&current->sighand->siglock);
82 saveset = current->blocked; 82 saveset = current->blocked;
83 current->blocked = newset; 83 current->blocked = newset;
84 recalc_sigpending(); 84 recalc_sigpending();
85 spin_unlock_irq(&current->sighand->siglock); 85 spin_unlock_irq(&current->sighand->siglock);
86 86
87 regs->gpr[GPR_RVAL] = -EINTR; 87 regs->gpr[GPR_RVAL] = -EINTR;
88 while (1) { 88 while (1) {
89 current->state = TASK_INTERRUPTIBLE; 89 current->state = TASK_INTERRUPTIBLE;
90 schedule(); 90 schedule();
91 if (do_signal(regs, &saveset)) 91 if (do_signal(regs, &saveset))
92 return -EINTR; 92 return -EINTR;
93 } 93 }
94 } 94 }
95 95
96 asmlinkage int 96 asmlinkage int
97 sys_sigaction(int sig, const struct old_sigaction *act, 97 sys_sigaction(int sig, const struct old_sigaction *act,
98 struct old_sigaction *oact) 98 struct old_sigaction *oact)
99 { 99 {
100 struct k_sigaction new_ka, old_ka; 100 struct k_sigaction new_ka, old_ka;
101 int ret; 101 int ret;
102 102
103 if (act) { 103 if (act) {
104 old_sigset_t mask; 104 old_sigset_t mask;
105 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 105 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
106 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 106 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
107 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 107 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
108 return -EFAULT; 108 return -EFAULT;
109 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 109 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
110 __get_user(mask, &act->sa_mask); 110 __get_user(mask, &act->sa_mask);
111 siginitset(&new_ka.sa.sa_mask, mask); 111 siginitset(&new_ka.sa.sa_mask, mask);
112 } 112 }
113 113
114 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 114 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
115 115
116 if (!ret && oact) { 116 if (!ret && oact) {
117 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 117 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
118 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 118 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
119 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 119 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
120 return -EFAULT; 120 return -EFAULT;
121 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 121 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
122 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 122 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
123 } 123 }
124 124
125 return ret; 125 return ret;
126 } 126 }
127 127
128 asmlinkage int 128 asmlinkage int
129 sys_sigaltstack(const stack_t *uss, stack_t *uoss, 129 sys_sigaltstack(const stack_t *uss, stack_t *uoss,
130 struct pt_regs *regs) 130 struct pt_regs *regs)
131 { 131 {
132 return do_sigaltstack(uss, uoss, regs->gpr[GPR_SP]); 132 return do_sigaltstack(uss, uoss, regs->gpr[GPR_SP]);
133 } 133 }
134 134
135 135
136 /* 136 /*
137 * Do a signal return; undo the signal stack. 137 * Do a signal return; undo the signal stack.
138 */ 138 */
139 139
140 struct sigframe 140 struct sigframe
141 { 141 {
142 struct sigcontext sc; 142 struct sigcontext sc;
143 unsigned long extramask[_NSIG_WORDS-1]; 143 unsigned long extramask[_NSIG_WORDS-1];
144 unsigned long tramp[2]; /* signal trampoline */ 144 unsigned long tramp[2]; /* signal trampoline */
145 }; 145 };
146 146
147 struct rt_sigframe 147 struct rt_sigframe
148 { 148 {
149 struct siginfo info; 149 struct siginfo info;
150 struct ucontext uc; 150 struct ucontext uc;
151 unsigned long tramp[2]; /* signal trampoline */ 151 unsigned long tramp[2]; /* signal trampoline */
152 }; 152 };
153 153
154 static int 154 static int
155 restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p) 155 restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p)
156 { 156 {
157 unsigned int err = 0; 157 unsigned int err = 0;
158 158
159 #define COPY(x) err |= __get_user(regs->x, &sc->regs.x) 159 #define COPY(x) err |= __get_user(regs->x, &sc->regs.x)
160 COPY(gpr[0]); COPY(gpr[1]); COPY(gpr[2]); COPY(gpr[3]); 160 COPY(gpr[0]); COPY(gpr[1]); COPY(gpr[2]); COPY(gpr[3]);
161 COPY(gpr[4]); COPY(gpr[5]); COPY(gpr[6]); COPY(gpr[7]); 161 COPY(gpr[4]); COPY(gpr[5]); COPY(gpr[6]); COPY(gpr[7]);
162 COPY(gpr[8]); COPY(gpr[9]); COPY(gpr[10]); COPY(gpr[11]); 162 COPY(gpr[8]); COPY(gpr[9]); COPY(gpr[10]); COPY(gpr[11]);
163 COPY(gpr[12]); COPY(gpr[13]); COPY(gpr[14]); COPY(gpr[15]); 163 COPY(gpr[12]); COPY(gpr[13]); COPY(gpr[14]); COPY(gpr[15]);
164 COPY(gpr[16]); COPY(gpr[17]); COPY(gpr[18]); COPY(gpr[19]); 164 COPY(gpr[16]); COPY(gpr[17]); COPY(gpr[18]); COPY(gpr[19]);
165 COPY(gpr[20]); COPY(gpr[21]); COPY(gpr[22]); COPY(gpr[23]); 165 COPY(gpr[20]); COPY(gpr[21]); COPY(gpr[22]); COPY(gpr[23]);
166 COPY(gpr[24]); COPY(gpr[25]); COPY(gpr[26]); COPY(gpr[27]); 166 COPY(gpr[24]); COPY(gpr[25]); COPY(gpr[26]); COPY(gpr[27]);
167 COPY(gpr[28]); COPY(gpr[29]); COPY(gpr[30]); COPY(gpr[31]); 167 COPY(gpr[28]); COPY(gpr[29]); COPY(gpr[30]); COPY(gpr[31]);
168 COPY(pc); COPY(psw); 168 COPY(pc); COPY(psw);
169 COPY(ctpc); COPY(ctpsw); COPY(ctbp); 169 COPY(ctpc); COPY(ctpsw); COPY(ctbp);
170 #undef COPY 170 #undef COPY
171 171
172 return err; 172 return err;
173 } 173 }
174 174
175 asmlinkage int sys_sigreturn(struct pt_regs *regs) 175 asmlinkage int sys_sigreturn(struct pt_regs *regs)
176 { 176 {
177 struct sigframe *frame = (struct sigframe *)regs->gpr[GPR_SP]; 177 struct sigframe *frame = (struct sigframe *)regs->gpr[GPR_SP];
178 sigset_t set; 178 sigset_t set;
179 int rval; 179 int rval;
180 180
181 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 181 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
182 goto badframe; 182 goto badframe;
183 183
184 if (__get_user(set.sig[0], &frame->sc.oldmask) 184 if (__get_user(set.sig[0], &frame->sc.oldmask)
185 || (_NSIG_WORDS > 1 185 || (_NSIG_WORDS > 1
186 && __copy_from_user(&set.sig[1], &frame->extramask, 186 && __copy_from_user(&set.sig[1], &frame->extramask,
187 sizeof(frame->extramask)))) 187 sizeof(frame->extramask))))
188 goto badframe; 188 goto badframe;
189 189
190 sigdelsetmask(&set, ~_BLOCKABLE); 190 sigdelsetmask(&set, ~_BLOCKABLE);
191 spin_lock_irq(&current->sighand->siglock); 191 spin_lock_irq(&current->sighand->siglock);
192 current->blocked = set; 192 current->blocked = set;
193 recalc_sigpending(); 193 recalc_sigpending();
194 spin_unlock_irq(&current->sighand->siglock); 194 spin_unlock_irq(&current->sighand->siglock);
195 195
196 if (restore_sigcontext(regs, &frame->sc, &rval)) 196 if (restore_sigcontext(regs, &frame->sc, &rval))
197 goto badframe; 197 goto badframe;
198 return rval; 198 return rval;
199 199
200 badframe: 200 badframe:
201 force_sig(SIGSEGV, current); 201 force_sig(SIGSEGV, current);
202 return 0; 202 return 0;
203 } 203 }
204 204
205 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) 205 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
206 { 206 {
207 struct rt_sigframe *frame = (struct rt_sigframe *)regs->gpr[GPR_SP]; 207 struct rt_sigframe *frame = (struct rt_sigframe *)regs->gpr[GPR_SP];
208 sigset_t set; 208 sigset_t set;
209 stack_t st; 209 stack_t st;
210 int rval; 210 int rval;
211 211
212 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 212 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
213 goto badframe; 213 goto badframe;
214 214
215 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 215 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
216 goto badframe; 216 goto badframe;
217 217
218 sigdelsetmask(&set, ~_BLOCKABLE); 218 sigdelsetmask(&set, ~_BLOCKABLE);
219 spin_lock_irq(&current->sighand->siglock); 219 spin_lock_irq(&current->sighand->siglock);
220 current->blocked = set; 220 current->blocked = set;
221 recalc_sigpending(); 221 recalc_sigpending();
222 spin_unlock_irq(&current->sighand->siglock); 222 spin_unlock_irq(&current->sighand->siglock);
223 223
224 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval)) 224 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
225 goto badframe; 225 goto badframe;
226 226
227 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) 227 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
228 goto badframe; 228 goto badframe;
229 /* It is more difficult to avoid calling this function than to 229 /* It is more difficult to avoid calling this function than to
230 call it and ignore errors. */ 230 call it and ignore errors. */
231 do_sigaltstack(&st, NULL, regs->gpr[GPR_SP]); 231 do_sigaltstack(&st, NULL, regs->gpr[GPR_SP]);
232 232
233 return rval; 233 return rval;
234 234
235 badframe: 235 badframe:
236 force_sig(SIGSEGV, current); 236 force_sig(SIGSEGV, current);
237 return 0; 237 return 0;
238 } 238 }
239 239
240 /* 240 /*
241 * Set up a signal frame. 241 * Set up a signal frame.
242 */ 242 */
243 243
244 static int 244 static int
245 setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, 245 setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
246 unsigned long mask) 246 unsigned long mask)
247 { 247 {
248 int err = 0; 248 int err = 0;
249 249
250 #define COPY(x) err |= __put_user(regs->x, &sc->regs.x) 250 #define COPY(x) err |= __put_user(regs->x, &sc->regs.x)
251 COPY(gpr[0]); COPY(gpr[1]); COPY(gpr[2]); COPY(gpr[3]); 251 COPY(gpr[0]); COPY(gpr[1]); COPY(gpr[2]); COPY(gpr[3]);
252 COPY(gpr[4]); COPY(gpr[5]); COPY(gpr[6]); COPY(gpr[7]); 252 COPY(gpr[4]); COPY(gpr[5]); COPY(gpr[6]); COPY(gpr[7]);
253 COPY(gpr[8]); COPY(gpr[9]); COPY(gpr[10]); COPY(gpr[11]); 253 COPY(gpr[8]); COPY(gpr[9]); COPY(gpr[10]); COPY(gpr[11]);
254 COPY(gpr[12]); COPY(gpr[13]); COPY(gpr[14]); COPY(gpr[15]); 254 COPY(gpr[12]); COPY(gpr[13]); COPY(gpr[14]); COPY(gpr[15]);
255 COPY(gpr[16]); COPY(gpr[17]); COPY(gpr[18]); COPY(gpr[19]); 255 COPY(gpr[16]); COPY(gpr[17]); COPY(gpr[18]); COPY(gpr[19]);
256 COPY(gpr[20]); COPY(gpr[21]); COPY(gpr[22]); COPY(gpr[23]); 256 COPY(gpr[20]); COPY(gpr[21]); COPY(gpr[22]); COPY(gpr[23]);
257 COPY(gpr[24]); COPY(gpr[25]); COPY(gpr[26]); COPY(gpr[27]); 257 COPY(gpr[24]); COPY(gpr[25]); COPY(gpr[26]); COPY(gpr[27]);
258 COPY(gpr[28]); COPY(gpr[29]); COPY(gpr[30]); COPY(gpr[31]); 258 COPY(gpr[28]); COPY(gpr[29]); COPY(gpr[30]); COPY(gpr[31]);
259 COPY(pc); COPY(psw); 259 COPY(pc); COPY(psw);
260 COPY(ctpc); COPY(ctpsw); COPY(ctbp); 260 COPY(ctpc); COPY(ctpsw); COPY(ctbp);
261 #undef COPY 261 #undef COPY
262 262
263 err |= __put_user(mask, &sc->oldmask); 263 err |= __put_user(mask, &sc->oldmask);
264 264
265 return err; 265 return err;
266 } 266 }
267 267
268 /* 268 /*
269 * Determine which stack to use.. 269 * Determine which stack to use..
270 */ 270 */
271 static inline void * 271 static inline void *
272 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 272 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
273 { 273 {
274 /* Default to using normal stack */ 274 /* Default to using normal stack */
275 unsigned long sp = regs->gpr[GPR_SP]; 275 unsigned long sp = regs->gpr[GPR_SP];
276 276
277 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) 277 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
278 sp = current->sas_ss_sp + current->sas_ss_size; 278 sp = current->sas_ss_sp + current->sas_ss_size;
279 279
280 return (void *)((sp - frame_size) & -8UL); 280 return (void *)((sp - frame_size) & -8UL);
281 } 281 }
282 282
283 static void setup_frame(int sig, struct k_sigaction *ka, 283 static void setup_frame(int sig, struct k_sigaction *ka,
284 sigset_t *set, struct pt_regs *regs) 284 sigset_t *set, struct pt_regs *regs)
285 { 285 {
286 struct sigframe *frame; 286 struct sigframe *frame;
287 int err = 0; 287 int err = 0;
288 int signal; 288 int signal;
289 289
290 frame = get_sigframe(ka, regs, sizeof(*frame)); 290 frame = get_sigframe(ka, regs, sizeof(*frame));
291 291
292 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 292 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
293 goto give_sigsegv; 293 goto give_sigsegv;
294 294
295 signal = current_thread_info()->exec_domain 295 signal = current_thread_info()->exec_domain
296 && current_thread_info()->exec_domain->signal_invmap 296 && current_thread_info()->exec_domain->signal_invmap
297 && sig < 32 297 && sig < 32
298 ? current_thread_info()->exec_domain->signal_invmap[sig] 298 ? current_thread_info()->exec_domain->signal_invmap[sig]
299 : sig; 299 : sig;
300 300
301 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); 301 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
302 302
303 if (_NSIG_WORDS > 1) { 303 if (_NSIG_WORDS > 1) {
304 err |= __copy_to_user(frame->extramask, &set->sig[1], 304 err |= __copy_to_user(frame->extramask, &set->sig[1],
305 sizeof(frame->extramask)); 305 sizeof(frame->extramask));
306 } 306 }
307 307
308 /* Set up to return from userspace. If provided, use a stub 308 /* Set up to return from userspace. If provided, use a stub
309 already in userspace. */ 309 already in userspace. */
310 if (ka->sa.sa_flags & SA_RESTORER) { 310 if (ka->sa.sa_flags & SA_RESTORER) {
311 regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer; 311 regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer;
312 } else { 312 } else {
313 /* Note, these encodings are _little endian_! */ 313 /* Note, these encodings are _little endian_! */
314 314
315 /* addi __NR_sigreturn, r0, r12 */ 315 /* addi __NR_sigreturn, r0, r12 */
316 err |= __put_user(0x6600 | (__NR_sigreturn << 16), 316 err |= __put_user(0x6600 | (__NR_sigreturn << 16),
317 frame->tramp + 0); 317 frame->tramp + 0);
318 /* trap 0 */ 318 /* trap 0 */
319 err |= __put_user(0x010007e0, 319 err |= __put_user(0x010007e0,
320 frame->tramp + 1); 320 frame->tramp + 1);
321 321
322 regs->gpr[GPR_LP] = (unsigned long)frame->tramp; 322 regs->gpr[GPR_LP] = (unsigned long)frame->tramp;
323 323
324 flush_cache_sigtramp (regs->gpr[GPR_LP]); 324 flush_cache_sigtramp (regs->gpr[GPR_LP]);
325 } 325 }
326 326
327 if (err) 327 if (err)
328 goto give_sigsegv; 328 goto give_sigsegv;
329 329
330 /* Set up registers for signal handler. */ 330 /* Set up registers for signal handler. */
331 regs->pc = (v850_reg_t) ka->sa.sa_handler; 331 regs->pc = (v850_reg_t) ka->sa.sa_handler;
332 regs->gpr[GPR_SP] = (v850_reg_t)frame; 332 regs->gpr[GPR_SP] = (v850_reg_t)frame;
333 /* Signal handler args: */ 333 /* Signal handler args: */
334 regs->gpr[GPR_ARG0] = signal; /* arg 0: signum */ 334 regs->gpr[GPR_ARG0] = signal; /* arg 0: signum */
335 regs->gpr[GPR_ARG1] = (v850_reg_t)&frame->sc;/* arg 1: sigcontext */ 335 regs->gpr[GPR_ARG1] = (v850_reg_t)&frame->sc;/* arg 1: sigcontext */
336 336
337 set_fs(USER_DS); 337 set_fs(USER_DS);
338 338
339 #if DEBUG_SIG 339 #if DEBUG_SIG
340 printk("SIG deliver (%s:%d): sp=%p pc=%08lx ra=%08lx\n", 340 printk("SIG deliver (%s:%d): sp=%p pc=%08lx ra=%08lx\n",
341 current->comm, current->pid, frame, regs->pc, ); 341 current->comm, current->pid, frame, regs->pc, );
342 #endif 342 #endif
343 343
344 return; 344 return;
345 345
346 give_sigsegv: 346 give_sigsegv:
347 force_sigsegv(sig, current); 347 force_sigsegv(sig, current);
348 } 348 }
349 349
350 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 350 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
351 sigset_t *set, struct pt_regs *regs) 351 sigset_t *set, struct pt_regs *regs)
352 { 352 {
353 struct rt_sigframe *frame; 353 struct rt_sigframe *frame;
354 int err = 0; 354 int err = 0;
355 int signal; 355 int signal;
356 356
357 frame = get_sigframe(ka, regs, sizeof(*frame)); 357 frame = get_sigframe(ka, regs, sizeof(*frame));
358 358
359 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 359 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
360 goto give_sigsegv; 360 goto give_sigsegv;
361 361
362 signal = current_thread_info()->exec_domain 362 signal = current_thread_info()->exec_domain
363 && current_thread_info()->exec_domain->signal_invmap 363 && current_thread_info()->exec_domain->signal_invmap
364 && sig < 32 364 && sig < 32
365 ? current_thread_info()->exec_domain->signal_invmap[sig] 365 ? current_thread_info()->exec_domain->signal_invmap[sig]
366 : sig; 366 : sig;
367 367
368 err |= copy_siginfo_to_user(&frame->info, info); 368 err |= copy_siginfo_to_user(&frame->info, info);
369 369
370 /* Create the ucontext. */ 370 /* Create the ucontext. */
371 err |= __put_user(0, &frame->uc.uc_flags); 371 err |= __put_user(0, &frame->uc.uc_flags);
372 err |= __put_user(0, &frame->uc.uc_link); 372 err |= __put_user(0, &frame->uc.uc_link);
373 err |= __put_user((void *)current->sas_ss_sp, 373 err |= __put_user((void *)current->sas_ss_sp,
374 &frame->uc.uc_stack.ss_sp); 374 &frame->uc.uc_stack.ss_sp);
375 err |= __put_user(sas_ss_flags(regs->gpr[GPR_SP]), 375 err |= __put_user(sas_ss_flags(regs->gpr[GPR_SP]),
376 &frame->uc.uc_stack.ss_flags); 376 &frame->uc.uc_stack.ss_flags);
377 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 377 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
378 err |= setup_sigcontext(&frame->uc.uc_mcontext, 378 err |= setup_sigcontext(&frame->uc.uc_mcontext,
379 regs, set->sig[0]); 379 regs, set->sig[0]);
380 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 380 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
381 381
382 /* Set up to return from userspace. If provided, use a stub 382 /* Set up to return from userspace. If provided, use a stub
383 already in userspace. */ 383 already in userspace. */
384 if (ka->sa.sa_flags & SA_RESTORER) { 384 if (ka->sa.sa_flags & SA_RESTORER) {
385 regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer; 385 regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer;
386 } else { 386 } else {
387 /* Note, these encodings are _little endian_! */ 387 /* Note, these encodings are _little endian_! */
388 388
389 /* addi __NR_sigreturn, r0, r12 */ 389 /* addi __NR_sigreturn, r0, r12 */
390 err |= __put_user(0x6600 | (__NR_sigreturn << 16), 390 err |= __put_user(0x6600 | (__NR_sigreturn << 16),
391 frame->tramp + 0); 391 frame->tramp + 0);
392 /* trap 0 */ 392 /* trap 0 */
393 err |= __put_user(0x010007e0, 393 err |= __put_user(0x010007e0,
394 frame->tramp + 1); 394 frame->tramp + 1);
395 395
396 regs->gpr[GPR_LP] = (unsigned long)frame->tramp; 396 regs->gpr[GPR_LP] = (unsigned long)frame->tramp;
397 397
398 flush_cache_sigtramp (regs->gpr[GPR_LP]); 398 flush_cache_sigtramp (regs->gpr[GPR_LP]);
399 } 399 }
400 400
401 if (err) 401 if (err)
402 goto give_sigsegv; 402 goto give_sigsegv;
403 403
404 /* Set up registers for signal handler. */ 404 /* Set up registers for signal handler. */
405 regs->pc = (v850_reg_t) ka->sa.sa_handler; 405 regs->pc = (v850_reg_t) ka->sa.sa_handler;
406 regs->gpr[GPR_SP] = (v850_reg_t)frame; 406 regs->gpr[GPR_SP] = (v850_reg_t)frame;
407 /* Signal handler args: */ 407 /* Signal handler args: */
408 regs->gpr[GPR_ARG0] = signal; /* arg 0: signum */ 408 regs->gpr[GPR_ARG0] = signal; /* arg 0: signum */
409 regs->gpr[GPR_ARG1] = (v850_reg_t)&frame->info; /* arg 1: siginfo */ 409 regs->gpr[GPR_ARG1] = (v850_reg_t)&frame->info; /* arg 1: siginfo */
410 regs->gpr[GPR_ARG2] = (v850_reg_t)&frame->uc; /* arg 2: ucontext */ 410 regs->gpr[GPR_ARG2] = (v850_reg_t)&frame->uc; /* arg 2: ucontext */
411 411
412 set_fs(USER_DS); 412 set_fs(USER_DS);
413 413
414 #if DEBUG_SIG 414 #if DEBUG_SIG
415 printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", 415 printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
416 current->comm, current->pid, frame, regs->pc, regs->pr); 416 current->comm, current->pid, frame, regs->pc, regs->pr);
417 #endif 417 #endif
418 418
419 return; 419 return;
420 420
421 give_sigsegv: 421 give_sigsegv:
422 force_sigsegv(sig, current); 422 force_sigsegv(sig, current);
423 } 423 }
424 424
425 /* 425 /*
426 * OK, we're invoking a handler 426 * OK, we're invoking a handler
427 */ 427 */
428 428
429 static void 429 static void
430 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 430 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
431 sigset_t *oldset, struct pt_regs * regs) 431 sigset_t *oldset, struct pt_regs * regs)
432 { 432 {
433 /* Are we from a system call? */ 433 /* Are we from a system call? */
434 if (PT_REGS_SYSCALL (regs)) { 434 if (PT_REGS_SYSCALL (regs)) {
435 /* If so, check system call restarting.. */ 435 /* If so, check system call restarting.. */
436 switch (regs->gpr[GPR_RVAL]) { 436 switch (regs->gpr[GPR_RVAL]) {
437 case -ERESTART_RESTARTBLOCK: 437 case -ERESTART_RESTARTBLOCK:
438 current_thread_info()->restart_block.fn = 438 current_thread_info()->restart_block.fn =
439 do_no_restart_syscall; 439 do_no_restart_syscall;
440 /* fall through */ 440 /* fall through */
441 case -ERESTARTNOHAND: 441 case -ERESTARTNOHAND:
442 regs->gpr[GPR_RVAL] = -EINTR; 442 regs->gpr[GPR_RVAL] = -EINTR;
443 break; 443 break;
444 444
445 case -ERESTARTSYS: 445 case -ERESTARTSYS:
446 if (!(ka->sa.sa_flags & SA_RESTART)) { 446 if (!(ka->sa.sa_flags & SA_RESTART)) {
447 regs->gpr[GPR_RVAL] = -EINTR; 447 regs->gpr[GPR_RVAL] = -EINTR;
448 break; 448 break;
449 } 449 }
450 /* fallthrough */ 450 /* fallthrough */
451 case -ERESTARTNOINTR: 451 case -ERESTARTNOINTR:
452 regs->gpr[12] = PT_REGS_SYSCALL (regs); 452 regs->gpr[12] = PT_REGS_SYSCALL (regs);
453 regs->pc -= 4; /* Size of `trap 0' insn. */ 453 regs->pc -= 4; /* Size of `trap 0' insn. */
454 } 454 }
455 455
456 PT_REGS_SET_SYSCALL (regs, 0); 456 PT_REGS_SET_SYSCALL (regs, 0);
457 } 457 }
458 458
459 /* Set up the stack frame */ 459 /* Set up the stack frame */
460 if (ka->sa.sa_flags & SA_SIGINFO) 460 if (ka->sa.sa_flags & SA_SIGINFO)
461 setup_rt_frame(sig, ka, info, oldset, regs); 461 setup_rt_frame(sig, ka, info, oldset, regs);
462 else 462 else
463 setup_frame(sig, ka, oldset, regs); 463 setup_frame(sig, ka, oldset, regs);
464 464
465 spin_lock_irq(&current->sighand->siglock); 465 spin_lock_irq(&current->sighand->siglock);
466 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 466 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
467 if (!(ka->sa.sa_flags & SA_NODEFER)) 467 if (!(ka->sa.sa_flags & SA_NODEFER))
468 sigaddset(&current->blocked,sig); 468 sigaddset(&current->blocked,sig);
469 recalc_sigpending(); 469 recalc_sigpending();
470 spin_unlock_irq(&current->sighand->siglock); 470 spin_unlock_irq(&current->sighand->siglock);
471 } 471 }
472 472
473 /* 473 /*
474 * Note that 'init' is a special process: it doesn't get signals it doesn't 474 * Note that 'init' is a special process: it doesn't get signals it doesn't
475 * want to handle. Thus you cannot kill init even with a SIGKILL even by 475 * want to handle. Thus you cannot kill init even with a SIGKILL even by
476 * mistake. 476 * mistake.
477 * 477 *
478 * Note that we go through the signals twice: once to check the signals that 478 * Note that we go through the signals twice: once to check the signals that
479 * the kernel can handle, and then we build all the user-level signal handling 479 * the kernel can handle, and then we build all the user-level signal handling
480 * stack-frames in one go after that. 480 * stack-frames in one go after that.
481 */ 481 */
482 int do_signal(struct pt_regs *regs, sigset_t *oldset) 482 int do_signal(struct pt_regs *regs, sigset_t *oldset)
483 { 483 {
484 siginfo_t info; 484 siginfo_t info;
485 int signr; 485 int signr;
486 struct k_sigaction ka; 486 struct k_sigaction ka;
487 487
488 /* 488 /*
489 * We want the common case to go fast, which 489 * We want the common case to go fast, which
490 * is why we may in certain cases get here from 490 * is why we may in certain cases get here from
491 * kernel mode. Just return without doing anything 491 * kernel mode. Just return without doing anything
492 * if so. 492 * if so.
493 */ 493 */
494 if (!user_mode(regs)) 494 if (!user_mode(regs))
495 return 1; 495 return 1;
496 496
497 if (!oldset) 497 if (!oldset)
498 oldset = &current->blocked; 498 oldset = &current->blocked;
499 499
500 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 500 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
501 if (signr > 0) { 501 if (signr > 0) {
502 /* Whee! Actually deliver the signal. */ 502 /* Whee! Actually deliver the signal. */
503 handle_signal(signr, &info, &ka, oldset, regs); 503 handle_signal(signr, &info, &ka, oldset, regs);
504 return 1; 504 return 1;
505 } 505 }
506 506
507 /* Did we come from a system call? */ 507 /* Did we come from a system call? */
508 if (PT_REGS_SYSCALL (regs)) { 508 if (PT_REGS_SYSCALL (regs)) {
509 int rval = (int)regs->gpr[GPR_RVAL]; 509 int rval = (int)regs->gpr[GPR_RVAL];
510 /* Restart the system call - no handlers present */ 510 /* Restart the system call - no handlers present */
511 if (rval == -ERESTARTNOHAND 511 if (rval == -ERESTARTNOHAND
512 || rval == -ERESTARTSYS 512 || rval == -ERESTARTSYS
513 || rval == -ERESTARTNOINTR) 513 || rval == -ERESTARTNOINTR)
514 { 514 {
515 regs->gpr[12] = PT_REGS_SYSCALL (regs); 515 regs->gpr[12] = PT_REGS_SYSCALL (regs);
516 regs->pc -= 4; /* Size of `trap 0' insn. */ 516 regs->pc -= 4; /* Size of `trap 0' insn. */
517 } 517 }
518 else if (rval == -ERESTART_RESTARTBLOCK) { 518 else if (rval == -ERESTART_RESTARTBLOCK) {
519 regs->gpr[12] = __NR_restart_syscall; 519 regs->gpr[12] = __NR_restart_syscall;
520 regs->pc -= 4; /* Size of `trap 0' insn. */ 520 regs->pc -= 4; /* Size of `trap 0' insn. */
521 } 521 }
522 } 522 }
523 return 0; 523 return 0;
524 } 524 }
525 525
arch/xtensa/kernel/signal.c
1 // TODO coprocessor stuff 1 // TODO coprocessor stuff
2 /* 2 /*
3 * linux/arch/xtensa/kernel/signal.c 3 * linux/arch/xtensa/kernel/signal.c
4 * 4 *
5 * Copyright (C) 1991, 1992 Linus Torvalds 5 * Copyright (C) 1991, 1992 Linus Torvalds
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson 6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
7 * 7 *
8 * Joe Taylor <joe@tensilica.com> 8 * Joe Taylor <joe@tensilica.com>
9 * Chris Zankel <chris@zankel.net> 9 * Chris Zankel <chris@zankel.net>
10 * 10 *
11 * 11 *
12 * 12 *
13 */ 13 */
14 14
15 #include <xtensa/config/core.h> 15 #include <xtensa/config/core.h>
16 #include <xtensa/hal.h> 16 #include <xtensa/hal.h>
17 #include <linux/sched.h> 17 #include <linux/sched.h>
18 #include <linux/mm.h> 18 #include <linux/mm.h>
19 #include <linux/smp.h> 19 #include <linux/smp.h>
20 #include <linux/smp_lock.h> 20 #include <linux/smp_lock.h>
21 #include <linux/kernel.h> 21 #include <linux/kernel.h>
22 #include <linux/signal.h> 22 #include <linux/signal.h>
23 #include <linux/errno.h> 23 #include <linux/errno.h>
24 #include <linux/wait.h> 24 #include <linux/wait.h>
25 #include <linux/ptrace.h> 25 #include <linux/ptrace.h>
26 #include <linux/unistd.h> 26 #include <linux/unistd.h>
27 #include <linux/stddef.h> 27 #include <linux/stddef.h>
28 #include <linux/personality.h> 28 #include <linux/personality.h>
29 #include <asm/ucontext.h> 29 #include <asm/ucontext.h>
30 #include <asm/uaccess.h> 30 #include <asm/uaccess.h>
31 #include <asm/pgtable.h> 31 #include <asm/pgtable.h>
32 #include <asm/cacheflush.h> 32 #include <asm/cacheflush.h>
33 33
34 #define DEBUG_SIG 0 34 #define DEBUG_SIG 0
35 35
36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37 37
38 asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, 38 asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options,
39 struct rusage * ru); 39 struct rusage * ru);
40 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 40 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
41 41
42 extern struct task_struct *coproc_owners[]; 42 extern struct task_struct *coproc_owners[];
43 43
44 44
45 /* 45 /*
46 * Atomically swap in the new signal mask, and wait for a signal. 46 * Atomically swap in the new signal mask, and wait for a signal.
47 */ 47 */
48 48
49 int sys_sigsuspend(struct pt_regs *regs) 49 int sys_sigsuspend(struct pt_regs *regs)
50 { 50 {
51 old_sigset_t mask = (old_sigset_t) regs->areg[3]; 51 old_sigset_t mask = (old_sigset_t) regs->areg[3];
52 sigset_t saveset; 52 sigset_t saveset;
53 53
54 mask &= _BLOCKABLE; 54 mask &= _BLOCKABLE;
55 spin_lock_irq(&current->sighand->siglock); 55 spin_lock_irq(&current->sighand->siglock);
56 saveset = current->blocked; 56 saveset = current->blocked;
57 siginitset(&current->blocked, mask); 57 siginitset(&current->blocked, mask);
58 recalc_sigpending(); 58 recalc_sigpending();
59 spin_unlock_irq(&current->sighand->siglock); 59 spin_unlock_irq(&current->sighand->siglock);
60 60
61 regs->areg[2] = -EINTR; 61 regs->areg[2] = -EINTR;
62 while (1) { 62 while (1) {
63 current->state = TASK_INTERRUPTIBLE; 63 current->state = TASK_INTERRUPTIBLE;
64 schedule(); 64 schedule();
65 if (do_signal(regs, &saveset)) 65 if (do_signal(regs, &saveset))
66 return -EINTR; 66 return -EINTR;
67 } 67 }
68 } 68 }
69 69
70 asmlinkage int 70 asmlinkage int
71 sys_rt_sigsuspend(struct pt_regs *regs) 71 sys_rt_sigsuspend(struct pt_regs *regs)
72 { 72 {
73 sigset_t *unewset = (sigset_t *) regs->areg[4]; 73 sigset_t *unewset = (sigset_t *) regs->areg[4];
74 size_t sigsetsize = (size_t) regs->areg[3]; 74 size_t sigsetsize = (size_t) regs->areg[3];
75 sigset_t saveset, newset; 75 sigset_t saveset, newset;
76 /* XXX: Don't preclude handling different sized sigset_t's. */ 76 /* XXX: Don't preclude handling different sized sigset_t's. */
77 if (sigsetsize != sizeof(sigset_t)) 77 if (sigsetsize != sizeof(sigset_t))
78 return -EINVAL; 78 return -EINVAL;
79 79
80 if (copy_from_user(&newset, unewset, sizeof(newset))) 80 if (copy_from_user(&newset, unewset, sizeof(newset)))
81 return -EFAULT; 81 return -EFAULT;
82 sigdelsetmask(&newset, ~_BLOCKABLE); 82 sigdelsetmask(&newset, ~_BLOCKABLE);
83 spin_lock_irq(&current->sighand->siglock); 83 spin_lock_irq(&current->sighand->siglock);
84 saveset = current->blocked; 84 saveset = current->blocked;
85 current->blocked = newset; 85 current->blocked = newset;
86 recalc_sigpending(); 86 recalc_sigpending();
87 spin_unlock_irq(&current->sighand->siglock); 87 spin_unlock_irq(&current->sighand->siglock);
88 88
89 regs->areg[2] = -EINTR; 89 regs->areg[2] = -EINTR;
90 while (1) { 90 while (1) {
91 current->state = TASK_INTERRUPTIBLE; 91 current->state = TASK_INTERRUPTIBLE;
92 schedule(); 92 schedule();
93 if (do_signal(regs, &saveset)) 93 if (do_signal(regs, &saveset))
94 return -EINTR; 94 return -EINTR;
95 } 95 }
96 } 96 }
97 97
98 asmlinkage int 98 asmlinkage int
99 sys_sigaction(int sig, const struct old_sigaction *act, 99 sys_sigaction(int sig, const struct old_sigaction *act,
100 struct old_sigaction *oact) 100 struct old_sigaction *oact)
101 { 101 {
102 struct k_sigaction new_ka, old_ka; 102 struct k_sigaction new_ka, old_ka;
103 int ret; 103 int ret;
104 104
105 if (act) { 105 if (act) {
106 old_sigset_t mask; 106 old_sigset_t mask;
107 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 107 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
108 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 108 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
109 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 109 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
110 return -EFAULT; 110 return -EFAULT;
111 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 111 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
112 __get_user(mask, &act->sa_mask); 112 __get_user(mask, &act->sa_mask);
113 siginitset(&new_ka.sa.sa_mask, mask); 113 siginitset(&new_ka.sa.sa_mask, mask);
114 } 114 }
115 115
116 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 116 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
117 117
118 if (!ret && oact) { 118 if (!ret && oact) {
119 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 119 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
120 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 120 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
121 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 121 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
122 return -EFAULT; 122 return -EFAULT;
123 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 123 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
124 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 124 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
125 } 125 }
126 126
127 return ret; 127 return ret;
128 } 128 }
129 129
130 asmlinkage int 130 asmlinkage int
131 sys_sigaltstack(struct pt_regs *regs) 131 sys_sigaltstack(struct pt_regs *regs)
132 { 132 {
133 const stack_t *uss = (stack_t *) regs->areg[4]; 133 const stack_t *uss = (stack_t *) regs->areg[4];
134 stack_t *uoss = (stack_t *) regs->areg[3]; 134 stack_t *uoss = (stack_t *) regs->areg[3];
135 135
136 if (regs->depc > 64) 136 if (regs->depc > 64)
137 panic ("Double exception sys_sigreturn\n"); 137 panic ("Double exception sys_sigreturn\n");
138 138
139 139
140 return do_sigaltstack(uss, uoss, regs->areg[1]); 140 return do_sigaltstack(uss, uoss, regs->areg[1]);
141 } 141 }
142 142
143 143
144 /* 144 /*
145 * Do a signal return; undo the signal stack. 145 * Do a signal return; undo the signal stack.
146 */ 146 */
147 147
148 struct sigframe 148 struct sigframe
149 { 149 {
150 struct sigcontext sc; 150 struct sigcontext sc;
151 struct _cpstate cpstate; 151 struct _cpstate cpstate;
152 unsigned long extramask[_NSIG_WORDS-1]; 152 unsigned long extramask[_NSIG_WORDS-1];
153 unsigned char retcode[6]; 153 unsigned char retcode[6];
154 unsigned int reserved[4]; /* Reserved area for chaining */ 154 unsigned int reserved[4]; /* Reserved area for chaining */
155 unsigned int window[4]; /* Window of 4 registers for initial context */ 155 unsigned int window[4]; /* Window of 4 registers for initial context */
156 }; 156 };
157 157
158 struct rt_sigframe 158 struct rt_sigframe
159 { 159 {
160 struct siginfo info; 160 struct siginfo info;
161 struct ucontext uc; 161 struct ucontext uc;
162 struct _cpstate cpstate; 162 struct _cpstate cpstate;
163 unsigned char retcode[6]; 163 unsigned char retcode[6];
164 unsigned int reserved[4]; /* Reserved area for chaining */ 164 unsigned int reserved[4]; /* Reserved area for chaining */
165 unsigned int window[4]; /* Window of 4 registers for initial context */ 165 unsigned int window[4]; /* Window of 4 registers for initial context */
166 }; 166 };
167 167
168 extern void release_all_cp (struct task_struct *); 168 extern void release_all_cp (struct task_struct *);
169 169
170 170
171 // FIXME restore_cpextra 171 // FIXME restore_cpextra
172 static inline int 172 static inline int
173 restore_cpextra (struct _cpstate *buf) 173 restore_cpextra (struct _cpstate *buf)
174 { 174 {
175 #if 0 175 #if 0
176 /* The signal handler may have used coprocessors in which 176 /* The signal handler may have used coprocessors in which
177 * case they are still enabled. We disable them to force a 177 * case they are still enabled. We disable them to force a
178 * reloading of the original task's CP state by the lazy 178 * reloading of the original task's CP state by the lazy
179 * context-switching mechanisms of CP exception handling. 179 * context-switching mechanisms of CP exception handling.
180 * Also, we essentially discard any coprocessor state that the 180 * Also, we essentially discard any coprocessor state that the
181 * signal handler created. */ 181 * signal handler created. */
182 182
183 struct task_struct *tsk = current; 183 struct task_struct *tsk = current;
184 release_all_cp(tsk); 184 release_all_cp(tsk);
185 return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE); 185 return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE);
186 #endif 186 #endif
187 return 0; 187 return 0;
188 } 188 }
189 189
190 /* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately... 190 /* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately...
191 */ 191 */
192 192
193 193
194 static int 194 static int
195 restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) 195 restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
196 { 196 {
197 struct thread_struct *thread; 197 struct thread_struct *thread;
198 unsigned int err = 0; 198 unsigned int err = 0;
199 unsigned long ps; 199 unsigned long ps;
200 struct _cpstate *buf; 200 struct _cpstate *buf;
201 201
202 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) 202 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
203 COPY(pc); 203 COPY(pc);
204 COPY(depc); 204 COPY(depc);
205 COPY(wmask); 205 COPY(wmask);
206 COPY(lbeg); 206 COPY(lbeg);
207 COPY(lend); 207 COPY(lend);
208 COPY(lcount); 208 COPY(lcount);
209 COPY(sar); 209 COPY(sar);
210 COPY(windowbase); 210 COPY(windowbase);
211 COPY(windowstart); 211 COPY(windowstart);
212 #undef COPY 212 #undef COPY
213 213
214 /* For PS, restore only PS.CALLINC. 214 /* For PS, restore only PS.CALLINC.
215 * Assume that all other bits are either the same as for the signal 215 * Assume that all other bits are either the same as for the signal
216 * handler, or the user mode value doesn't matter (e.g. PS.OWB). 216 * handler, or the user mode value doesn't matter (e.g. PS.OWB).
217 */ 217 */
218 err |= __get_user(ps, &sc->sc_ps); 218 err |= __get_user(ps, &sc->sc_ps);
219 regs->ps = (regs->ps & ~XCHAL_PS_CALLINC_MASK) 219 regs->ps = (regs->ps & ~XCHAL_PS_CALLINC_MASK)
220 | (ps & XCHAL_PS_CALLINC_MASK); 220 | (ps & XCHAL_PS_CALLINC_MASK);
221 221
222 /* Additional corruption checks */ 222 /* Additional corruption checks */
223 223
224 if ((regs->windowbase >= (XCHAL_NUM_AREGS/4)) 224 if ((regs->windowbase >= (XCHAL_NUM_AREGS/4))
225 || ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) ) 225 || ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) )
226 err = 1; 226 err = 1;
227 if ((regs->lcount > 0) 227 if ((regs->lcount > 0)
228 && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) ) 228 && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
229 err = 1; 229 err = 1;
230 230
231 /* Restore extended register state. 231 /* Restore extended register state.
232 * See struct thread_struct in processor.h. 232 * See struct thread_struct in processor.h.
233 */ 233 */
234 thread = &current->thread; 234 thread = &current->thread;
235 235
236 err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4); 236 err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4);
237 err |= __get_user(buf, &sc->sc_cpstate); 237 err |= __get_user(buf, &sc->sc_cpstate);
238 if (buf) { 238 if (buf) {
239 if (!access_ok(VERIFY_READ, buf, sizeof(*buf))) 239 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
240 goto badframe; 240 goto badframe;
241 err |= restore_cpextra(buf); 241 err |= restore_cpextra(buf);
242 } 242 }
243 243
244 regs->syscall = -1; /* disable syscall checks */ 244 regs->syscall = -1; /* disable syscall checks */
245 return err; 245 return err;
246 246
247 badframe: 247 badframe:
248 return 1; 248 return 1;
249 } 249 }
250 250
251 static inline void 251 static inline void
252 flush_my_cpstate(struct task_struct *tsk) 252 flush_my_cpstate(struct task_struct *tsk)
253 { 253 {
254 unsigned long flags; 254 unsigned long flags;
255 local_irq_save(flags); 255 local_irq_save(flags);
256 256
257 #if 0 // FIXME 257 #if 0 // FIXME
258 for (i = 0; i < XCHAL_CP_NUM; i++) { 258 for (i = 0; i < XCHAL_CP_NUM; i++) {
259 if (tsk == coproc_owners[i]) { 259 if (tsk == coproc_owners[i]) {
260 xthal_validate_cp(i); 260 xthal_validate_cp(i);
261 xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i); 261 xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i);
262 262
263 /* Invalidate and "disown" the cp to allow 263 /* Invalidate and "disown" the cp to allow
264 * callers the chance to reset cp state in the 264 * callers the chance to reset cp state in the
265 * task_struct. */ 265 * task_struct. */
266 266
267 xthal_invalidate_cp(i); 267 xthal_invalidate_cp(i);
268 coproc_owners[i] = 0; 268 coproc_owners[i] = 0;
269 } 269 }
270 } 270 }
271 #endif 271 #endif
272 local_irq_restore(flags); 272 local_irq_restore(flags);
273 } 273 }
274 274
275 /* Return codes: 275 /* Return codes:
276 0: nothing saved 276 0: nothing saved
277 1: stuff to save, successful 277 1: stuff to save, successful
278 -1: stuff to save, error happened 278 -1: stuff to save, error happened
279 */ 279 */
280 static int 280 static int
281 save_cpextra (struct _cpstate *buf) 281 save_cpextra (struct _cpstate *buf)
282 { 282 {
283 #if (XCHAL_EXTRA_SA_SIZE == 0) && (XCHAL_CP_NUM == 0) 283 #if (XCHAL_EXTRA_SA_SIZE == 0) && (XCHAL_CP_NUM == 0)
284 return 0; 284 return 0;
285 #else 285 #else
286 286
287 /* FIXME: If a task has never used a coprocessor, there is 287 /* FIXME: If a task has never used a coprocessor, there is
288 * no need to save and restore anything. Tracking this 288 * no need to save and restore anything. Tracking this
289 * information would allow us to optimize this section. 289 * information would allow us to optimize this section.
290 * Perhaps we can use current->used_math or (current->flags & 290 * Perhaps we can use current->used_math or (current->flags &
291 * PF_USEDFPU) or define a new field in the thread 291 * PF_USEDFPU) or define a new field in the thread
292 * structure. */ 292 * structure. */
293 293
294 /* We flush any live, task-owned cp state to the task_struct, 294 /* We flush any live, task-owned cp state to the task_struct,
295 * then copy it all to the sigframe. Then we clear all 295 * then copy it all to the sigframe. Then we clear all
296 * cp/extra state in the task_struct, effectively 296 * cp/extra state in the task_struct, effectively
297 * clearing/resetting all cp/extra state for the signal 297 * clearing/resetting all cp/extra state for the signal
298 * handler (cp-exception handling will load these new values 298 * handler (cp-exception handling will load these new values
299 * into the cp/extra registers.) This step is important for 299 * into the cp/extra registers.) This step is important for
300 * things like a floating-point cp, where the OS must reset 300 * things like a floating-point cp, where the OS must reset
301 * the FCR to the default rounding mode. */ 301 * the FCR to the default rounding mode. */
302 302
303 int err = 0; 303 int err = 0;
304 struct task_struct *tsk = current; 304 struct task_struct *tsk = current;
305 305
306 flush_my_cpstate(tsk); 306 flush_my_cpstate(tsk);
307 /* Note that we just copy everything: 'extra' and 'cp' state together.*/ 307 /* Note that we just copy everything: 'extra' and 'cp' state together.*/
308 err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE); 308 err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
309 memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE); 309 memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE);
310 310
311 #if (XTENSA_CP_EXTRA_SIZE == 0) 311 #if (XTENSA_CP_EXTRA_SIZE == 0)
312 #error Sanity check on memset above, cpextra_size should not be zero. 312 #error Sanity check on memset above, cpextra_size should not be zero.
313 #endif 313 #endif
314 314
315 return err ? -1 : 1; 315 return err ? -1 : 1;
316 #endif 316 #endif
317 } 317 }
318 318
319 static int 319 static int
320 setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate, 320 setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate,
321 struct pt_regs *regs, unsigned long mask) 321 struct pt_regs *regs, unsigned long mask)
322 { 322 {
323 struct thread_struct *thread; 323 struct thread_struct *thread;
324 int err = 0; 324 int err = 0;
325 325
326 //printk("setup_sigcontext\n"); 326 //printk("setup_sigcontext\n");
327 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) 327 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
328 COPY(pc); 328 COPY(pc);
329 COPY(ps); 329 COPY(ps);
330 COPY(depc); 330 COPY(depc);
331 COPY(wmask); 331 COPY(wmask);
332 COPY(lbeg); 332 COPY(lbeg);
333 COPY(lend); 333 COPY(lend);
334 COPY(lcount); 334 COPY(lcount);
335 COPY(sar); 335 COPY(sar);
336 COPY(windowbase); 336 COPY(windowbase);
337 COPY(windowstart); 337 COPY(windowstart);
338 #undef COPY 338 #undef COPY
339 339
340 /* Save extended register state. 340 /* Save extended register state.
341 * See struct thread_struct in processor.h. 341 * See struct thread_struct in processor.h.
342 */ 342 */
343 thread = &current->thread; 343 thread = &current->thread;
344 err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4); 344 err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4);
345 err |= save_cpextra(cpstate); 345 err |= save_cpextra(cpstate);
346 err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate); 346 err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
347 /* non-iBCS2 extensions.. */ 347 /* non-iBCS2 extensions.. */
348 err |= __put_user(mask, &sc->oldmask); 348 err |= __put_user(mask, &sc->oldmask);
349 349
350 return err; 350 return err;
351 } 351 }
352 352
353 asmlinkage int sys_sigreturn(struct pt_regs *regs) 353 asmlinkage int sys_sigreturn(struct pt_regs *regs)
354 { 354 {
355 struct sigframe *frame = (struct sigframe *)regs->areg[1]; 355 struct sigframe *frame = (struct sigframe *)regs->areg[1];
356 sigset_t set; 356 sigset_t set;
357 if (regs->depc > 64) 357 if (regs->depc > 64)
358 panic ("Double exception sys_sigreturn\n"); 358 panic ("Double exception sys_sigreturn\n");
359 359
360 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 360 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
361 goto badframe; 361 goto badframe;
362 362
363 if (__get_user(set.sig[0], &frame->sc.oldmask) 363 if (__get_user(set.sig[0], &frame->sc.oldmask)
364 || (_NSIG_WORDS > 1 364 || (_NSIG_WORDS > 1
365 && __copy_from_user(&set.sig[1], &frame->extramask, 365 && __copy_from_user(&set.sig[1], &frame->extramask,
366 sizeof(frame->extramask)))) 366 sizeof(frame->extramask))))
367 goto badframe; 367 goto badframe;
368 368
369 sigdelsetmask(&set, ~_BLOCKABLE); 369 sigdelsetmask(&set, ~_BLOCKABLE);
370 370
371 spin_lock_irq(&current->sighand->siglock); 371 spin_lock_irq(&current->sighand->siglock);
372 current->blocked = set; 372 current->blocked = set;
373 recalc_sigpending(); 373 recalc_sigpending();
374 spin_unlock_irq(&current->sighand->siglock); 374 spin_unlock_irq(&current->sighand->siglock);
375 375
376 if (restore_sigcontext(regs, &frame->sc)) 376 if (restore_sigcontext(regs, &frame->sc))
377 goto badframe; 377 goto badframe;
378 return regs->areg[2]; 378 return regs->areg[2];
379 379
380 badframe: 380 badframe:
381 force_sig(SIGSEGV, current); 381 force_sig(SIGSEGV, current);
382 return 0; 382 return 0;
383 } 383 }
384 384
385 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) 385 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
386 { 386 {
387 struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1]; 387 struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1];
388 sigset_t set; 388 sigset_t set;
389 stack_t st; 389 stack_t st;
390 int ret; 390 int ret;
391 if (regs->depc > 64) 391 if (regs->depc > 64)
392 { 392 {
393 printk("!!!!!!! DEPC !!!!!!!\n"); 393 printk("!!!!!!! DEPC !!!!!!!\n");
394 return 0; 394 return 0;
395 } 395 }
396 396
397 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 397 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
398 goto badframe; 398 goto badframe;
399 399
400 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 400 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
401 goto badframe; 401 goto badframe;
402 402
403 sigdelsetmask(&set, ~_BLOCKABLE); 403 sigdelsetmask(&set, ~_BLOCKABLE);
404 spin_lock_irq(&current->sighand->siglock); 404 spin_lock_irq(&current->sighand->siglock);
405 current->blocked = set; 405 current->blocked = set;
406 recalc_sigpending(); 406 recalc_sigpending();
407 spin_unlock_irq(&current->sighand->siglock); 407 spin_unlock_irq(&current->sighand->siglock);
408 408
409 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 409 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
410 goto badframe; 410 goto badframe;
411 ret = regs->areg[2]; 411 ret = regs->areg[2];
412 412
413 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) 413 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
414 goto badframe; 414 goto badframe;
415 /* It is more difficult to avoid calling this function than to 415 /* It is more difficult to avoid calling this function than to
416 call it and ignore errors. */ 416 call it and ignore errors. */
417 do_sigaltstack(&st, NULL, regs->areg[1]); 417 do_sigaltstack(&st, NULL, regs->areg[1]);
418 418
419 return ret; 419 return ret;
420 420
421 badframe: 421 badframe:
422 force_sig(SIGSEGV, current); 422 force_sig(SIGSEGV, current);
423 return 0; 423 return 0;
424 } 424 }
425 425
426 /* 426 /*
427 * Set up a signal frame. 427 * Set up a signal frame.
428 */ 428 */
429 429
430 /* 430 /*
431 * Determine which stack to use.. 431 * Determine which stack to use..
432 */ 432 */
433 static inline void * 433 static inline void *
434 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) 434 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
435 { 435 {
436 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) 436 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
437 sp = current->sas_ss_sp + current->sas_ss_size; 437 sp = current->sas_ss_sp + current->sas_ss_size;
438 438
439 return (void *)((sp - frame_size) & -16ul); 439 return (void *)((sp - frame_size) & -16ul);
440 } 440 }
441 441
442 #define USE_SIGRETURN 0 442 #define USE_SIGRETURN 0
443 #define USE_RT_SIGRETURN 1 443 #define USE_RT_SIGRETURN 1
444 444
445 static int 445 static int
446 gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn) 446 gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn)
447 { 447 {
448 unsigned int retcall; 448 unsigned int retcall;
449 int err = 0; 449 int err = 0;
450 450
451 #if 0 451 #if 0
452 /* Ignoring SA_RESTORER for now; it's supposed to be obsolete, 452 /* Ignoring SA_RESTORER for now; it's supposed to be obsolete,
453 * and the xtensa glibc doesn't use it. 453 * and the xtensa glibc doesn't use it.
454 */ 454 */
455 if (ka->sa.sa_flags & SA_RESTORER) { 455 if (ka->sa.sa_flags & SA_RESTORER) {
456 regs->pr = (unsigned long) ka->sa.sa_restorer; 456 regs->pr = (unsigned long) ka->sa.sa_restorer;
457 } else 457 } else
458 #endif /* 0 */ 458 #endif /* 0 */
459 { 459 {
460 460
461 #if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255) 461 #if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255)
462 462
463 /* The 12-bit immediate is really split up within the 24-bit MOVI 463 /* The 12-bit immediate is really split up within the 24-bit MOVI
464 * instruction. As long as the above system call numbers fit within 464 * instruction. As long as the above system call numbers fit within
465 * 8-bits, the following code works fine. See the Xtensa ISA for 465 * 8-bits, the following code works fine. See the Xtensa ISA for
466 * details. 466 * details.
467 */ 467 */
468 468
469 #error Generating the MOVI instruction below breaks! 469 #error Generating the MOVI instruction below breaks!
470 #endif 470 #endif
471 471
472 retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn; 472 retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn;
473 473
474 #ifdef __XTENSA_EB__ /* Big Endian version */ 474 #ifdef __XTENSA_EB__ /* Big Endian version */
475 /* Generate instruction: MOVI a2, retcall */ 475 /* Generate instruction: MOVI a2, retcall */
476 err |= __put_user(0x22, &codemem[0]); 476 err |= __put_user(0x22, &codemem[0]);
477 err |= __put_user(0x0a, &codemem[1]); 477 err |= __put_user(0x0a, &codemem[1]);
478 err |= __put_user(retcall, &codemem[2]); 478 err |= __put_user(retcall, &codemem[2]);
479 /* Generate instruction: SYSCALL */ 479 /* Generate instruction: SYSCALL */
480 err |= __put_user(0x00, &codemem[3]); 480 err |= __put_user(0x00, &codemem[3]);
481 err |= __put_user(0x05, &codemem[4]); 481 err |= __put_user(0x05, &codemem[4]);
482 err |= __put_user(0x00, &codemem[5]); 482 err |= __put_user(0x00, &codemem[5]);
483 483
484 #elif defined __XTENSA_EL__ /* Little Endian version */ 484 #elif defined __XTENSA_EL__ /* Little Endian version */
485 /* Generate instruction: MOVI a2, retcall */ 485 /* Generate instruction: MOVI a2, retcall */
486 err |= __put_user(0x22, &codemem[0]); 486 err |= __put_user(0x22, &codemem[0]);
487 err |= __put_user(0xa0, &codemem[1]); 487 err |= __put_user(0xa0, &codemem[1]);
488 err |= __put_user(retcall, &codemem[2]); 488 err |= __put_user(retcall, &codemem[2]);
489 /* Generate instruction: SYSCALL */ 489 /* Generate instruction: SYSCALL */
490 err |= __put_user(0x00, &codemem[3]); 490 err |= __put_user(0x00, &codemem[3]);
491 err |= __put_user(0x50, &codemem[4]); 491 err |= __put_user(0x50, &codemem[4]);
492 err |= __put_user(0x00, &codemem[5]); 492 err |= __put_user(0x00, &codemem[5]);
493 #else 493 #else
494 #error Must use compiler for Xtensa processors. 494 #error Must use compiler for Xtensa processors.
495 #endif 495 #endif
496 } 496 }
497 497
498 /* Flush generated code out of the data cache */ 498 /* Flush generated code out of the data cache */
499 499
500 if (err == 0) 500 if (err == 0)
501 __flush_invalidate_cache_range((unsigned long)codemem, 6UL); 501 __flush_invalidate_cache_range((unsigned long)codemem, 6UL);
502 502
503 return err; 503 return err;
504 } 504 }
505 505
506 static void 506 static void
507 set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr, 507 set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr,
508 void *handler, unsigned long arg1, void *arg2, void *arg3) 508 void *handler, unsigned long arg1, void *arg2, void *arg3)
509 { 509 {
510 /* Set up registers for signal handler */ 510 /* Set up registers for signal handler */
511 start_thread(regs, (unsigned long) handler, (unsigned long) stack); 511 start_thread(regs, (unsigned long) handler, (unsigned long) stack);
512 512
513 /* Set up a stack frame for a call4 513 /* Set up a stack frame for a call4
514 * Note: PS.CALLINC is set to one by start_thread 514 * Note: PS.CALLINC is set to one by start_thread
515 */ 515 */
516 regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000; 516 regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000;
517 regs->areg[6] = arg1; 517 regs->areg[6] = arg1;
518 regs->areg[7] = (unsigned long) arg2; 518 regs->areg[7] = (unsigned long) arg2;
519 regs->areg[8] = (unsigned long) arg3; 519 regs->areg[8] = (unsigned long) arg3;
520 } 520 }
521 521
522 static void setup_frame(int sig, struct k_sigaction *ka, 522 static void setup_frame(int sig, struct k_sigaction *ka,
523 sigset_t *set, struct pt_regs *regs) 523 sigset_t *set, struct pt_regs *regs)
524 { 524 {
525 struct sigframe *frame; 525 struct sigframe *frame;
526 int err = 0; 526 int err = 0;
527 int signal; 527 int signal;
528 528
529 frame = get_sigframe(ka, regs->areg[1], sizeof(*frame)); 529 frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
530 if (regs->depc > 64) 530 if (regs->depc > 64)
531 { 531 {
532 printk("!!!!!!! DEPC !!!!!!!\n"); 532 printk("!!!!!!! DEPC !!!!!!!\n");
533 return; 533 return;
534 } 534 }
535 535
536 536
537 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 537 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
538 goto give_sigsegv; 538 goto give_sigsegv;
539 539
540 signal = current_thread_info()->exec_domain 540 signal = current_thread_info()->exec_domain
541 && current_thread_info()->exec_domain->signal_invmap 541 && current_thread_info()->exec_domain->signal_invmap
542 && sig < 32 542 && sig < 32
543 ? current_thread_info()->exec_domain->signal_invmap[sig] 543 ? current_thread_info()->exec_domain->signal_invmap[sig]
544 : sig; 544 : sig;
545 545
546 err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]); 546 err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]);
547 547
548 if (_NSIG_WORDS > 1) { 548 if (_NSIG_WORDS > 1) {
549 err |= __copy_to_user(frame->extramask, &set->sig[1], 549 err |= __copy_to_user(frame->extramask, &set->sig[1],
550 sizeof(frame->extramask)); 550 sizeof(frame->extramask));
551 } 551 }
552 552
553 /* Create sys_sigreturn syscall in stack frame */ 553 /* Create sys_sigreturn syscall in stack frame */
554 err |= gen_return_code(frame->retcode, USE_SIGRETURN); 554 err |= gen_return_code(frame->retcode, USE_SIGRETURN);
555 555
556 if (err) 556 if (err)
557 goto give_sigsegv; 557 goto give_sigsegv;
558 558
559 /* Create signal handler execution context. 559 /* Create signal handler execution context.
560 * Return context not modified until this point. 560 * Return context not modified until this point.
561 */ 561 */
562 set_thread_state(regs, frame, frame->retcode, 562 set_thread_state(regs, frame, frame->retcode,
563 ka->sa.sa_handler, signal, &frame->sc, NULL); 563 ka->sa.sa_handler, signal, &frame->sc, NULL);
564 564
565 /* Set access mode to USER_DS. Nomenclature is outdated, but 565 /* Set access mode to USER_DS. Nomenclature is outdated, but
566 * functionality is used in uaccess.h 566 * functionality is used in uaccess.h
567 */ 567 */
568 set_fs(USER_DS); 568 set_fs(USER_DS);
569 569
570 570
571 #if DEBUG_SIG 571 #if DEBUG_SIG
572 printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n", 572 printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
573 current->comm, current->pid, signal, frame, regs->pc); 573 current->comm, current->pid, signal, frame, regs->pc);
574 #endif 574 #endif
575 575
576 return; 576 return;
577 577
578 give_sigsegv: 578 give_sigsegv:
579 if (sig == SIGSEGV) 579 if (sig == SIGSEGV)
580 ka->sa.sa_handler = SIG_DFL; 580 ka->sa.sa_handler = SIG_DFL;
581 force_sig(SIGSEGV, current); 581 force_sig(SIGSEGV, current);
582 } 582 }
583 583
584 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 584 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
585 sigset_t *set, struct pt_regs *regs) 585 sigset_t *set, struct pt_regs *regs)
586 { 586 {
587 struct rt_sigframe *frame; 587 struct rt_sigframe *frame;
588 int err = 0; 588 int err = 0;
589 int signal; 589 int signal;
590 590
591 frame = get_sigframe(ka, regs->areg[1], sizeof(*frame)); 591 frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
592 if (regs->depc > 64) 592 if (regs->depc > 64)
593 panic ("Double exception sys_sigreturn\n"); 593 panic ("Double exception sys_sigreturn\n");
594 594
595 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 595 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
596 goto give_sigsegv; 596 goto give_sigsegv;
597 597
598 signal = current_thread_info()->exec_domain 598 signal = current_thread_info()->exec_domain
599 && current_thread_info()->exec_domain->signal_invmap 599 && current_thread_info()->exec_domain->signal_invmap
600 && sig < 32 600 && sig < 32
601 ? current_thread_info()->exec_domain->signal_invmap[sig] 601 ? current_thread_info()->exec_domain->signal_invmap[sig]
602 : sig; 602 : sig;
603 603
604 err |= copy_siginfo_to_user(&frame->info, info); 604 err |= copy_siginfo_to_user(&frame->info, info);
605 605
606 /* Create the ucontext. */ 606 /* Create the ucontext. */
607 err |= __put_user(0, &frame->uc.uc_flags); 607 err |= __put_user(0, &frame->uc.uc_flags);
608 err |= __put_user(0, &frame->uc.uc_link); 608 err |= __put_user(0, &frame->uc.uc_link);
609 err |= __put_user((void *)current->sas_ss_sp, 609 err |= __put_user((void *)current->sas_ss_sp,
610 &frame->uc.uc_stack.ss_sp); 610 &frame->uc.uc_stack.ss_sp);
611 err |= __put_user(sas_ss_flags(regs->areg[1]), 611 err |= __put_user(sas_ss_flags(regs->areg[1]),
612 &frame->uc.uc_stack.ss_flags); 612 &frame->uc.uc_stack.ss_flags);
613 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 613 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
614 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate, 614 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
615 regs, set->sig[0]); 615 regs, set->sig[0]);
616 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 616 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
617 617
618 /* Create sys_rt_sigreturn syscall in stack frame */ 618 /* Create sys_rt_sigreturn syscall in stack frame */
619 err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN); 619 err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN);
620 620
621 if (err) 621 if (err)
622 goto give_sigsegv; 622 goto give_sigsegv;
623 623
624 /* Create signal handler execution context. 624 /* Create signal handler execution context.
625 * Return context not modified until this point. 625 * Return context not modified until this point.
626 */ 626 */
627 set_thread_state(regs, frame, frame->retcode, 627 set_thread_state(regs, frame, frame->retcode,
628 ka->sa.sa_handler, signal, &frame->info, &frame->uc); 628 ka->sa.sa_handler, signal, &frame->info, &frame->uc);
629 629
630 /* Set access mode to USER_DS. Nomenclature is outdated, but 630 /* Set access mode to USER_DS. Nomenclature is outdated, but
631 * functionality is used in uaccess.h 631 * functionality is used in uaccess.h
632 */ 632 */
633 set_fs(USER_DS); 633 set_fs(USER_DS);
634 634
635 #if DEBUG_SIG 635 #if DEBUG_SIG
636 printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n", 636 printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
637 current->comm, current->pid, signal, frame, regs->pc); 637 current->comm, current->pid, signal, frame, regs->pc);
638 #endif 638 #endif
639 639
640 return; 640 return;
641 641
642 give_sigsegv: 642 give_sigsegv:
643 if (sig == SIGSEGV) 643 if (sig == SIGSEGV)
644 ka->sa.sa_handler = SIG_DFL; 644 ka->sa.sa_handler = SIG_DFL;
645 force_sig(SIGSEGV, current); 645 force_sig(SIGSEGV, current);
646 } 646 }
647 647
648 648
649 649
650 /* 650 /*
651 * Note that 'init' is a special process: it doesn't get signals it doesn't 651 * Note that 'init' is a special process: it doesn't get signals it doesn't
652 * want to handle. Thus you cannot kill init even with a SIGKILL even by 652 * want to handle. Thus you cannot kill init even with a SIGKILL even by
653 * mistake. 653 * mistake.
654 * 654 *
655 * Note that we go through the signals twice: once to check the signals that 655 * Note that we go through the signals twice: once to check the signals that
656 * the kernel can handle, and then we build all the user-level signal handling 656 * the kernel can handle, and then we build all the user-level signal handling
657 * stack-frames in one go after that. 657 * stack-frames in one go after that.
658 */ 658 */
659 int do_signal(struct pt_regs *regs, sigset_t *oldset) 659 int do_signal(struct pt_regs *regs, sigset_t *oldset)
660 { 660 {
661 siginfo_t info; 661 siginfo_t info;
662 int signr; 662 int signr;
663 struct k_sigaction ka; 663 struct k_sigaction ka;
664 664
665 if (!oldset) 665 if (!oldset)
666 oldset = &current->blocked; 666 oldset = &current->blocked;
667 667
668 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 668 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
669 669
670 /* Are we from a system call? */ 670 /* Are we from a system call? */
671 if (regs->syscall >= 0) { 671 if (regs->syscall >= 0) {
672 /* If so, check system call restarting.. */ 672 /* If so, check system call restarting.. */
673 switch (regs->areg[2]) { 673 switch (regs->areg[2]) {
674 case ERESTARTNOHAND: 674 case ERESTARTNOHAND:
675 case ERESTART_RESTARTBLOCK: 675 case ERESTART_RESTARTBLOCK:
676 regs->areg[2] = -EINTR; 676 regs->areg[2] = -EINTR;
677 break; 677 break;
678 678
679 case ERESTARTSYS: 679 case ERESTARTSYS:
680 if (!(ka.sa.sa_flags & SA_RESTART)) { 680 if (!(ka.sa.sa_flags & SA_RESTART)) {
681 regs->areg[2] = -EINTR; 681 regs->areg[2] = -EINTR;
682 break; 682 break;
683 } 683 }
684 /* fallthrough */ 684 /* fallthrough */
685 case ERESTARTNOINTR: 685 case ERESTARTNOINTR:
686 regs->areg[2] = regs->syscall; 686 regs->areg[2] = regs->syscall;
687 regs->pc -= 3; 687 regs->pc -= 3;
688 } 688 }
689 } 689 }
690 690
691 if (signr == 0) 691 if (signr == 0)
692 return 0; /* no signals delivered */ 692 return 0; /* no signals delivered */
693 693
694 /* Whee! Actually deliver the signal. */ 694 /* Whee! Actually deliver the signal. */
695 695
696 /* Set up the stack frame */ 696 /* Set up the stack frame */
697 if (ka.sa.sa_flags & SA_SIGINFO) 697 if (ka.sa.sa_flags & SA_SIGINFO)
698 setup_rt_frame(signr, &ka, &info, oldset, regs); 698 setup_rt_frame(signr, &ka, &info, oldset, regs);
699 else 699 else
700 setup_frame(signr, &ka, oldset, regs); 700 setup_frame(signr, &ka, oldset, regs);
701 701
702 if (ka.sa.sa_flags & SA_ONESHOT) 702 if (ka.sa.sa_flags & SA_ONESHOT)
703 ka.sa.sa_handler = SIG_DFL; 703 ka.sa.sa_handler = SIG_DFL;
704 704
705 spin_lock_irq(&current->sighand->siglock); 705 spin_lock_irq(&current->sighand->siglock);
706 sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask); 706 sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
707 if (!(ka.sa.sa_flags & SA_NODEFER)) 707 if (!(ka.sa.sa_flags & SA_NODEFER))
708 sigaddset(&current->blocked, signr); 708 sigaddset(&current->blocked, signr);
709 recalc_sigpending(); 709 recalc_sigpending();
710 spin_unlock_irq(&current->sighand->siglock); 710 spin_unlock_irq(&current->sighand->siglock);
711 return 1; 711 return 1;
712 } 712 }
713 713