aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mn10300/kernel/signal.c')
-rw-r--r--arch/mn10300/kernel/signal.c102
1 files changed, 38 insertions, 64 deletions
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 9dfac5cd16e6..a6c0858592c3 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -186,20 +186,11 @@ static int setup_sigcontext(struct sigcontext __user *sc,
186/* 186/*
187 * determine which stack to use.. 187 * determine which stack to use..
188 */ 188 */
189static inline void __user *get_sigframe(struct k_sigaction *ka, 189static inline void __user *get_sigframe(struct ksignal *ksig,
190 struct pt_regs *regs, 190 struct pt_regs *regs,
191 size_t frame_size) 191 size_t frame_size)
192{ 192{
193 unsigned long sp; 193 unsigned long sp = sigsp(regs->sp, ksig);
194
195 /* default to using normal stack */
196 sp = regs->sp;
197
198 /* this is the X/Open sanctioned signal stack switching. */
199 if (ka->sa.sa_flags & SA_ONSTACK) {
200 if (sas_ss_flags(sp) == 0)
201 sp = current->sas_ss_sp + current->sas_ss_size;
202 }
203 194
204 return (void __user *) ((sp - frame_size) & ~7UL); 195 return (void __user *) ((sp - frame_size) & ~7UL);
205} 196}
@@ -207,16 +198,16 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
207/* 198/*
208 * set up a normal signal frame 199 * set up a normal signal frame
209 */ 200 */
210static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 201static int setup_frame(struct ksignal *ksig, sigset_t *set,
211 struct pt_regs *regs) 202 struct pt_regs *regs)
212{ 203{
213 struct sigframe __user *frame; 204 struct sigframe __user *frame;
214 int rsig; 205 int rsig, sig = ksig->sig;
215 206
216 frame = get_sigframe(ka, regs, sizeof(*frame)); 207 frame = get_sigframe(ksig, regs, sizeof(*frame));
217 208
218 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 209 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
219 goto give_sigsegv; 210 return -EFAULT;
220 211
221 rsig = sig; 212 rsig = sig;
222 if (sig < 32 && 213 if (sig < 32 &&
@@ -226,40 +217,40 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
226 217
227 if (__put_user(rsig, &frame->sig) < 0 || 218 if (__put_user(rsig, &frame->sig) < 0 ||
228 __put_user(&frame->sc, &frame->psc) < 0) 219 __put_user(&frame->sc, &frame->psc) < 0)
229 goto give_sigsegv; 220 return -EFAULT;
230 221
231 if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0])) 222 if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0]))
232 goto give_sigsegv; 223 return -EFAULT;
233 224
234 if (_NSIG_WORDS > 1) { 225 if (_NSIG_WORDS > 1) {
235 if (__copy_to_user(frame->extramask, &set->sig[1], 226 if (__copy_to_user(frame->extramask, &set->sig[1],
236 sizeof(frame->extramask))) 227 sizeof(frame->extramask)))
237 goto give_sigsegv; 228 return -EFAULT;
238 } 229 }
239 230
240 /* set up to return from userspace. If provided, use a stub already in 231 /* set up to return from userspace. If provided, use a stub already in
241 * userspace */ 232 * userspace */
242 if (ka->sa.sa_flags & SA_RESTORER) { 233 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
243 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 234 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
244 goto give_sigsegv; 235 return -EFAULT;
245 } else { 236 } else {
246 if (__put_user((void (*)(void))frame->retcode, 237 if (__put_user((void (*)(void))frame->retcode,
247 &frame->pretcode)) 238 &frame->pretcode))
248 goto give_sigsegv; 239 return -EFAULT;
249 /* this is mov $,d0; syscall 0 */ 240 /* this is mov $,d0; syscall 0 */
250 if (__put_user(0x2c, (char *)(frame->retcode + 0)) || 241 if (__put_user(0x2c, (char *)(frame->retcode + 0)) ||
251 __put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) || 242 __put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) ||
252 __put_user(0x00, (char *)(frame->retcode + 2)) || 243 __put_user(0x00, (char *)(frame->retcode + 2)) ||
253 __put_user(0xf0, (char *)(frame->retcode + 3)) || 244 __put_user(0xf0, (char *)(frame->retcode + 3)) ||
254 __put_user(0xe0, (char *)(frame->retcode + 4))) 245 __put_user(0xe0, (char *)(frame->retcode + 4)))
255 goto give_sigsegv; 246 return -EFAULT;
256 flush_icache_range((unsigned long) frame->retcode, 247 flush_icache_range((unsigned long) frame->retcode,
257 (unsigned long) frame->retcode + 5); 248 (unsigned long) frame->retcode + 5);
258 } 249 }
259 250
260 /* set up registers for signal handler */ 251 /* set up registers for signal handler */
261 regs->sp = (unsigned long) frame; 252 regs->sp = (unsigned long) frame;
262 regs->pc = (unsigned long) ka->sa.sa_handler; 253 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
263 regs->d0 = sig; 254 regs->d0 = sig;
264 regs->d1 = (unsigned long) &frame->sc; 255 regs->d1 = (unsigned long) &frame->sc;
265 256
@@ -270,25 +261,21 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
270#endif 261#endif
271 262
272 return 0; 263 return 0;
273
274give_sigsegv:
275 force_sigsegv(sig, current);
276 return -EFAULT;
277} 264}
278 265
279/* 266/*
280 * set up a realtime signal frame 267 * set up a realtime signal frame
281 */ 268 */
282static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 269static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
283 sigset_t *set, struct pt_regs *regs) 270 struct pt_regs *regs)
284{ 271{
285 struct rt_sigframe __user *frame; 272 struct rt_sigframe __user *frame;
286 int rsig; 273 int rsig, sig = ksig->sig;
287 274
288 frame = get_sigframe(ka, regs, sizeof(*frame)); 275 frame = get_sigframe(ksig, regs, sizeof(*frame));
289 276
290 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 277 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
291 goto give_sigsegv; 278 return -EFAULT;
292 279
293 rsig = sig; 280 rsig = sig;
294 if (sig < 32 && 281 if (sig < 32 &&
@@ -299,8 +286,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
299 if (__put_user(rsig, &frame->sig) || 286 if (__put_user(rsig, &frame->sig) ||
300 __put_user(&frame->info, &frame->pinfo) || 287 __put_user(&frame->info, &frame->pinfo) ||
301 __put_user(&frame->uc, &frame->puc) || 288 __put_user(&frame->uc, &frame->puc) ||
302 copy_siginfo_to_user(&frame->info, info)) 289 copy_siginfo_to_user(&frame->info, &ksig->info))
303 goto give_sigsegv; 290 return -EFAULT;
304 291
305 /* create the ucontext. */ 292 /* create the ucontext. */
306 if (__put_user(0, &frame->uc.uc_flags) || 293 if (__put_user(0, &frame->uc.uc_flags) ||
@@ -309,13 +296,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
309 setup_sigcontext(&frame->uc.uc_mcontext, 296 setup_sigcontext(&frame->uc.uc_mcontext,
310 &frame->fpuctx, regs, set->sig[0]) || 297 &frame->fpuctx, regs, set->sig[0]) ||
311 __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) 298 __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
312 goto give_sigsegv; 299 return -EFAULT;
313 300
314 /* set up to return from userspace. If provided, use a stub already in 301 /* set up to return from userspace. If provided, use a stub already in
315 * userspace */ 302 * userspace */
316 if (ka->sa.sa_flags & SA_RESTORER) { 303 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
317 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 304 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
318 goto give_sigsegv; 305 return -EFAULT;
306
319 } else { 307 } else {
320 if (__put_user((void(*)(void))frame->retcode, 308 if (__put_user((void(*)(void))frame->retcode,
321 &frame->pretcode) || 309 &frame->pretcode) ||
@@ -326,7 +314,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
326 __put_user(0x00, (char *)(frame->retcode + 2)) || 314 __put_user(0x00, (char *)(frame->retcode + 2)) ||
327 __put_user(0xf0, (char *)(frame->retcode + 3)) || 315 __put_user(0xf0, (char *)(frame->retcode + 3)) ||
328 __put_user(0xe0, (char *)(frame->retcode + 4))) 316 __put_user(0xe0, (char *)(frame->retcode + 4)))
329 goto give_sigsegv; 317 return -EFAULT;
330 318
331 flush_icache_range((u_long) frame->retcode, 319 flush_icache_range((u_long) frame->retcode,
332 (u_long) frame->retcode + 5); 320 (u_long) frame->retcode + 5);
@@ -334,7 +322,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
334 322
335 /* Set up registers for signal handler */ 323 /* Set up registers for signal handler */
336 regs->sp = (unsigned long) frame; 324 regs->sp = (unsigned long) frame;
337 regs->pc = (unsigned long) ka->sa.sa_handler; 325 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
338 regs->d0 = sig; 326 regs->d0 = sig;
339 regs->d1 = (long) &frame->info; 327 regs->d1 = (long) &frame->info;
340 328
@@ -345,10 +333,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
345#endif 333#endif
346 334
347 return 0; 335 return 0;
348
349give_sigsegv:
350 force_sigsegv(sig, current);
351 return -EFAULT;
352} 336}
353 337
354static inline void stepback(struct pt_regs *regs) 338static inline void stepback(struct pt_regs *regs)
@@ -360,9 +344,7 @@ static inline void stepback(struct pt_regs *regs)
360/* 344/*
361 * handle the actual delivery of a signal to userspace 345 * handle the actual delivery of a signal to userspace
362 */ 346 */
363static int handle_signal(int sig, 347static int handle_signal(struct ksignal *ksig, struct pt_regs *regs)
364 siginfo_t *info, struct k_sigaction *ka,
365 struct pt_regs *regs)
366{ 348{
367 sigset_t *oldset = sigmask_to_save(); 349 sigset_t *oldset = sigmask_to_save();
368 int ret; 350 int ret;
@@ -377,7 +359,7 @@ static int handle_signal(int sig,
377 break; 359 break;
378 360
379 case -ERESTARTSYS: 361 case -ERESTARTSYS:
380 if (!(ka->sa.sa_flags & SA_RESTART)) { 362 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
381 regs->d0 = -EINTR; 363 regs->d0 = -EINTR;
382 break; 364 break;
383 } 365 }
@@ -390,15 +372,12 @@ static int handle_signal(int sig,
390 } 372 }
391 373
392 /* Set up the stack frame */ 374 /* Set up the stack frame */
393 if (ka->sa.sa_flags & SA_SIGINFO) 375 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
394 ret = setup_rt_frame(sig, ka, info, oldset, regs); 376 ret = setup_rt_frame(ksig, oldset, regs);
395 else 377 else
396 ret = setup_frame(sig, ka, oldset, regs); 378 ret = setup_frame(ksig, oldset, regs);
397 if (ret)
398 return ret;
399 379
400 signal_delivered(sig, info, ka, regs, 380 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
401 test_thread_flag(TIF_SINGLESTEP));
402 return 0; 381 return 0;
403} 382}
404 383
@@ -407,15 +386,10 @@ static int handle_signal(int sig,
407 */ 386 */
408static void do_signal(struct pt_regs *regs) 387static void do_signal(struct pt_regs *regs)
409{ 388{
410 struct k_sigaction ka; 389 struct ksignal ksig;
411 siginfo_t info;
412 int signr;
413
414 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
415 if (signr > 0) {
416 if (handle_signal(signr, &info, &ka, regs) == 0) {
417 }
418 390
391 if (get_signal(&ksig)) {
392 handle_signal(&ksig, regs);
419 return; 393 return;
420 } 394 }
421 395