aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-10 18:39:23 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-10 18:39:23 -0500
commit0caca697a2d173c6beff3c24e7d9481b732bd131 (patch)
tree5a39998978a385b9d0efd0692fe9db34c3aa839d
parentecacc6c70cf77a52a22af66c879873202522d6ce (diff)
parent751c88a2c362a4a8985f9a2cb5daf7cd9ce1c4d0 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k: m68knommu: Need to check __get_user()/__put_user() result m68knommu: signal.c __user annotations m68knommu: Equivalent of "m68k: handle new gcc's" m68knommu: f_pcr has been gone since headers' merge m68knommu: Don't lose state if sigframe setup fails m68knommu: Handle multiple pending signals m68knommu: Switch to saner sigsuspend m68knommu: Don't bother with SA_ONESHOT m68k: Check __get_user()/__put_user() return value m68k: Missing syscall_trace() on sigreturn m68k: Fix stack mangling logics in sigreturn m68k: If we fail to set sigframe up, just leave regs alone... m68k: Don't lose state if sigframe setup fails m68k: Simplify the singlestepping handling in signals m68k: Switch to saner sigsuspend() m68k: Resetting sa_handler in local copy of k_sigaction is pointless m68k/sun3: Kill pte_unmap() warnings
-rw-r--r--arch/m68k/include/asm/sun3_pgtable.h5
-rw-r--r--arch/m68k/include/asm/thread_info.h1
-rw-r--r--arch/m68k/include/asm/unistd.h1
-rw-r--r--arch/m68k/kernel/entry.S30
-rw-r--r--arch/m68k/kernel/signal.c314
-rw-r--r--arch/m68knommu/kernel/entry.S16
-rw-r--r--arch/m68knommu/kernel/signal.c188
-rw-r--r--arch/m68knommu/platform/68328/entry.S7
-rw-r--r--arch/m68knommu/platform/68360/entry.S7
-rw-r--r--arch/m68knommu/platform/coldfire/entry.S5
10 files changed, 231 insertions, 343 deletions
diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h
index cf5fad9b5250..f55aa04161e8 100644
--- a/arch/m68k/include/asm/sun3_pgtable.h
+++ b/arch/m68k/include/asm/sun3_pgtable.h
@@ -217,9 +217,8 @@ static inline pte_t pgoff_to_pte(unsigned off)
217/* Find an entry in the third-level pagetable. */ 217/* Find an entry in the third-level pagetable. */
218#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) 218#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
219#define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address)) 219#define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address))
220/* FIXME: should we bother with kmap() here? */ 220#define pte_offset_map(pmd, address) ((pte_t *)page_address(pmd_page(*pmd)) + pte_index(address))
221#define pte_offset_map(pmd, address) ((pte_t *)kmap(pmd_page(*pmd)) + pte_index(address)) 221#define pte_unmap(pte) do { } while (0)
222#define pte_unmap(pte) kunmap(pte)
223 222
224/* Macros to (de)construct the fake PTEs representing swap pages. */ 223/* Macros to (de)construct the fake PTEs representing swap pages. */
225#define __swp_type(x) ((x).val & 0x7F) 224#define __swp_type(x) ((x).val & 0x7F)
diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h
index 1da5d53a00eb..790988967ba7 100644
--- a/arch/m68k/include/asm/thread_info.h
+++ b/arch/m68k/include/asm/thread_info.h
@@ -104,5 +104,6 @@ static inline struct thread_info *current_thread_info(void)
104#define TIF_SYSCALL_TRACE 15 /* syscall trace active */ 104#define TIF_SYSCALL_TRACE 15 /* syscall trace active */
105#define TIF_MEMDIE 16 /* is terminating due to OOM killer */ 105#define TIF_MEMDIE 16 /* is terminating due to OOM killer */
106#define TIF_FREEZE 17 /* thread is freezing for suspend */ 106#define TIF_FREEZE 17 /* thread is freezing for suspend */
107#define TIF_RESTORE_SIGMASK 18 /* restore signal mask in do_signal */
107 108
108#endif /* _ASM_M68K_THREAD_INFO_H */ 109#endif /* _ASM_M68K_THREAD_INFO_H */
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index b43b36beafe3..26d851d385bb 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -373,6 +373,7 @@
373#define __ARCH_WANT_SYS_SIGPENDING 373#define __ARCH_WANT_SYS_SIGPENDING
374#define __ARCH_WANT_SYS_SIGPROCMASK 374#define __ARCH_WANT_SYS_SIGPROCMASK
375#define __ARCH_WANT_SYS_RT_SIGACTION 375#define __ARCH_WANT_SYS_RT_SIGACTION
376#define __ARCH_WANT_SYS_RT_SIGSUSPEND
376 377
377/* 378/*
378 * "Conditional" syscalls 379 * "Conditional" syscalls
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 6360c437dcf5..1559dea36e55 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -99,7 +99,10 @@ do_trace_exit:
99 jra .Lret_from_exception 99 jra .Lret_from_exception
100 100
101ENTRY(ret_from_signal) 101ENTRY(ret_from_signal)
102 RESTORE_SWITCH_STACK 102 tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)
103 jge 1f
104 jbsr syscall_trace
1051: RESTORE_SWITCH_STACK
103 addql #4,%sp 106 addql #4,%sp
104/* on 68040 complete pending writebacks if any */ 107/* on 68040 complete pending writebacks if any */
105#ifdef CONFIG_M68040 108#ifdef CONFIG_M68040
@@ -174,16 +177,11 @@ do_signal_return:
174 subql #4,%sp | dummy return address 177 subql #4,%sp | dummy return address
175 SAVE_SWITCH_STACK 178 SAVE_SWITCH_STACK
176 pea %sp@(SWITCH_STACK_SIZE) 179 pea %sp@(SWITCH_STACK_SIZE)
177 clrl %sp@-
178 bsrl do_signal 180 bsrl do_signal
179 addql #8,%sp 181 addql #4,%sp
180 RESTORE_SWITCH_STACK 182 RESTORE_SWITCH_STACK
181 addql #4,%sp 183 addql #4,%sp
182 tstl %d0 184 jbra resume_userspace
183 jeq resume_userspace
184 | when single stepping into handler stop at the first insn
185 btst #6,%curptr@(TASK_INFO+TINFO_FLAGS+2)
186 jeq resume_userspace
187 185
188do_delayed_trace: 186do_delayed_trace:
189 bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR 187 bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR
@@ -290,22 +288,6 @@ ENTRY(sys_vfork)
290 RESTORE_SWITCH_STACK 288 RESTORE_SWITCH_STACK
291 rts 289 rts
292 290
293ENTRY(sys_sigsuspend)
294 SAVE_SWITCH_STACK
295 pea %sp@(SWITCH_STACK_SIZE)
296 jbsr do_sigsuspend
297 addql #4,%sp
298 RESTORE_SWITCH_STACK
299 rts
300
301ENTRY(sys_rt_sigsuspend)
302 SAVE_SWITCH_STACK
303 pea %sp@(SWITCH_STACK_SIZE)
304 jbsr do_rt_sigsuspend
305 addql #4,%sp
306 RESTORE_SWITCH_STACK
307 rts
308
309ENTRY(sys_sigreturn) 291ENTRY(sys_sigreturn)
310 SAVE_SWITCH_STACK 292 SAVE_SWITCH_STACK
311 jbsr do_sigreturn 293 jbsr do_sigreturn
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index 4b387538706f..d12c3b0d9e4f 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -51,8 +51,6 @@
51 51
52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
53 53
54asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
55
56const int frame_extra_sizes[16] = { 54const int frame_extra_sizes[16] = {
57 [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ 55 [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
58 [2] = sizeof(((struct frame *)0)->un.fmt2), 56 [2] = sizeof(((struct frame *)0)->un.fmt2),
@@ -74,51 +72,21 @@ const int frame_extra_sizes[16] = {
74/* 72/*
75 * Atomically swap in the new signal mask, and wait for a signal. 73 * Atomically swap in the new signal mask, and wait for a signal.
76 */ 74 */
77asmlinkage int do_sigsuspend(struct pt_regs *regs) 75asmlinkage int
76sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
78{ 77{
79 old_sigset_t mask = regs->d3;
80 sigset_t saveset;
81
82 mask &= _BLOCKABLE; 78 mask &= _BLOCKABLE;
83 saveset = current->blocked; 79 spin_lock_irq(&current->sighand->siglock);
80 current->saved_sigmask = current->blocked;
84 siginitset(&current->blocked, mask); 81 siginitset(&current->blocked, mask);
85 recalc_sigpending(); 82 recalc_sigpending();
83 spin_unlock_irq(&current->sighand->siglock);
86 84
87 regs->d0 = -EINTR; 85 current->state = TASK_INTERRUPTIBLE;
88 while (1) { 86 schedule();
89 current->state = TASK_INTERRUPTIBLE; 87 set_restore_sigmask();
90 schedule();
91 if (do_signal(&saveset, regs))
92 return -EINTR;
93 }
94}
95
96asmlinkage int
97do_rt_sigsuspend(struct pt_regs *regs)
98{
99 sigset_t __user *unewset = (sigset_t __user *)regs->d1;
100 size_t sigsetsize = (size_t)regs->d2;
101 sigset_t saveset, newset;
102
103 /* XXX: Don't preclude handling different sized sigset_t's. */
104 if (sigsetsize != sizeof(sigset_t))
105 return -EINVAL;
106 88
107 if (copy_from_user(&newset, unewset, sizeof(newset))) 89 return -ERESTARTNOHAND;
108 return -EFAULT;
109 sigdelsetmask(&newset, ~_BLOCKABLE);
110
111 saveset = current->blocked;
112 current->blocked = newset;
113 recalc_sigpending();
114
115 regs->d0 = -EINTR;
116 while (1) {
117 current->state = TASK_INTERRUPTIBLE;
118 schedule();
119 if (do_signal(&saveset, regs))
120 return -EINTR;
121 }
122} 90}
123 91
124asmlinkage int 92asmlinkage int
@@ -132,10 +100,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
132 old_sigset_t mask; 100 old_sigset_t mask;
133 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 101 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
134 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 102 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
135 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 103 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
104 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
105 __get_user(mask, &act->sa_mask))
136 return -EFAULT; 106 return -EFAULT;
137 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
138 __get_user(mask, &act->sa_mask);
139 siginitset(&new_ka.sa.sa_mask, mask); 107 siginitset(&new_ka.sa.sa_mask, mask);
140 } 108 }
141 109
@@ -144,10 +112,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
144 if (!ret && oact) { 112 if (!ret && oact) {
145 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 113 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
146 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 114 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
147 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 115 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
116 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
117 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
148 return -EFAULT; 118 return -EFAULT;
149 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
150 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
151 } 119 }
152 120
153 return ret; 121 return ret;
@@ -318,36 +286,10 @@ out:
318 return err; 286 return err;
319} 287}
320 288
321static inline int 289static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
322restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp, 290 void __user *fp)
323 int *pd0)
324{ 291{
325 int fsize, formatvec; 292 int fsize = frame_extra_sizes[formatvec >> 12];
326 struct sigcontext context;
327 int err;
328
329 /* Always make any pending restarted system calls return -EINTR */
330 current_thread_info()->restart_block.fn = do_no_restart_syscall;
331
332 /* get previous context */
333 if (copy_from_user(&context, usc, sizeof(context)))
334 goto badframe;
335
336 /* restore passed registers */
337 regs->d1 = context.sc_d1;
338 regs->a0 = context.sc_a0;
339 regs->a1 = context.sc_a1;
340 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
341 regs->pc = context.sc_pc;
342 regs->orig_d0 = -1; /* disable syscall checks */
343 wrusp(context.sc_usp);
344 formatvec = context.sc_formatvec;
345 regs->format = formatvec >> 12;
346 regs->vector = formatvec & 0xfff;
347
348 err = restore_fpu_state(&context);
349
350 fsize = frame_extra_sizes[regs->format];
351 if (fsize < 0) { 293 if (fsize < 0) {
352 /* 294 /*
353 * user process trying to return with weird frame format 295 * user process trying to return with weird frame format
@@ -355,16 +297,22 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u
355#ifdef DEBUG 297#ifdef DEBUG
356 printk("user process returning with weird frame format\n"); 298 printk("user process returning with weird frame format\n");
357#endif 299#endif
358 goto badframe; 300 return 1;
359 } 301 }
302 if (!fsize) {
303 regs->format = formatvec >> 12;
304 regs->vector = formatvec & 0xfff;
305 } else {
306 struct switch_stack *sw = (struct switch_stack *)regs - 1;
307 unsigned long buf[fsize / 2]; /* yes, twice as much */
360 308
361 /* OK. Make room on the supervisor stack for the extra junk, 309 /* that'll make sure that expansion won't crap over data */
362 * if necessary. 310 if (copy_from_user(buf + fsize / 4, fp, fsize))
363 */ 311 return 1;
364 312
365 if (fsize) { 313 /* point of no return */
366 struct switch_stack *sw = (struct switch_stack *)regs - 1; 314 regs->format = formatvec >> 12;
367 regs->d0 = context.sc_d0; 315 regs->vector = formatvec & 0xfff;
368#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) 316#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
369 __asm__ __volatile__ 317 __asm__ __volatile__
370 (" movel %0,%/a0\n\t" 318 (" movel %0,%/a0\n\t"
@@ -376,30 +324,50 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u
376 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ 324 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
377 " lsrl #2,%1\n\t" 325 " lsrl #2,%1\n\t"
378 " subql #1,%1\n\t" 326 " subql #1,%1\n\t"
379 "2: movesl %4@+,%2\n\t" 327 /* copy to the gap we'd made */
380 "3: movel %2,%/a0@+\n\t" 328 "2: movel %4@+,%/a0@+\n\t"
381 " dbra %1,2b\n\t" 329 " dbra %1,2b\n\t"
382 " bral ret_from_signal\n" 330 " bral ret_from_signal\n"
383 "4:\n"
384 ".section __ex_table,\"a\"\n"
385 " .align 4\n"
386 " .long 2b,4b\n"
387 " .long 3b,4b\n"
388 ".previous"
389 : /* no outputs, it doesn't ever return */ 331 : /* no outputs, it doesn't ever return */
390 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), 332 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
391 "n" (frame_offset), "a" (fp) 333 "n" (frame_offset), "a" (buf + fsize/4)
392 : "a0"); 334 : "a0");
393#undef frame_offset 335#undef frame_offset
394 /*
395 * If we ever get here an exception occurred while
396 * building the above stack-frame.
397 */
398 goto badframe;
399 } 336 }
337 return 0;
338}
400 339
401 *pd0 = context.sc_d0; 340static inline int
402 return err; 341restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp)
342{
343 int formatvec;
344 struct sigcontext context;
345 int err;
346
347 /* Always make any pending restarted system calls return -EINTR */
348 current_thread_info()->restart_block.fn = do_no_restart_syscall;
349
350 /* get previous context */
351 if (copy_from_user(&context, usc, sizeof(context)))
352 goto badframe;
353
354 /* restore passed registers */
355 regs->d0 = context.sc_d0;
356 regs->d1 = context.sc_d1;
357 regs->a0 = context.sc_a0;
358 regs->a1 = context.sc_a1;
359 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
360 regs->pc = context.sc_pc;
361 regs->orig_d0 = -1; /* disable syscall checks */
362 wrusp(context.sc_usp);
363 formatvec = context.sc_formatvec;
364
365 err = restore_fpu_state(&context);
366
367 if (err || mangle_kernel_stack(regs, formatvec, fp))
368 goto badframe;
369
370 return 0;
403 371
404badframe: 372badframe:
405 return 1; 373 return 1;
@@ -407,9 +375,9 @@ badframe:
407 375
408static inline int 376static inline int
409rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, 377rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
410 struct ucontext __user *uc, int *pd0) 378 struct ucontext __user *uc)
411{ 379{
412 int fsize, temp; 380 int temp;
413 greg_t __user *gregs = uc->uc_mcontext.gregs; 381 greg_t __user *gregs = uc->uc_mcontext.gregs;
414 unsigned long usp; 382 unsigned long usp;
415 int err; 383 int err;
@@ -443,65 +411,16 @@ rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
443 regs->sr = (regs->sr & 0xff00) | (temp & 0xff); 411 regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
444 regs->orig_d0 = -1; /* disable syscall checks */ 412 regs->orig_d0 = -1; /* disable syscall checks */
445 err |= __get_user(temp, &uc->uc_formatvec); 413 err |= __get_user(temp, &uc->uc_formatvec);
446 regs->format = temp >> 12;
447 regs->vector = temp & 0xfff;
448 414
449 err |= rt_restore_fpu_state(uc); 415 err |= rt_restore_fpu_state(uc);
450 416
451 if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) 417 if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
452 goto badframe; 418 goto badframe;
453 419
454 fsize = frame_extra_sizes[regs->format]; 420 if (mangle_kernel_stack(regs, temp, &uc->uc_extra))
455 if (fsize < 0) {
456 /*
457 * user process trying to return with weird frame format
458 */
459#ifdef DEBUG
460 printk("user process returning with weird frame format\n");
461#endif
462 goto badframe; 421 goto badframe;
463 }
464
465 /* OK. Make room on the supervisor stack for the extra junk,
466 * if necessary.
467 */
468 422
469 if (fsize) { 423 return 0;
470#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
471 __asm__ __volatile__
472 (" movel %0,%/a0\n\t"
473 " subl %1,%/a0\n\t" /* make room on stack */
474 " movel %/a0,%/sp\n\t" /* set stack pointer */
475 /* move switch_stack and pt_regs */
476 "1: movel %0@+,%/a0@+\n\t"
477 " dbra %2,1b\n\t"
478 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
479 " lsrl #2,%1\n\t"
480 " subql #1,%1\n\t"
481 "2: movesl %4@+,%2\n\t"
482 "3: movel %2,%/a0@+\n\t"
483 " dbra %1,2b\n\t"
484 " bral ret_from_signal\n"
485 "4:\n"
486 ".section __ex_table,\"a\"\n"
487 " .align 4\n"
488 " .long 2b,4b\n"
489 " .long 3b,4b\n"
490 ".previous"
491 : /* no outputs, it doesn't ever return */
492 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
493 "n" (frame_offset), "a" (&uc->uc_extra)
494 : "a0");
495#undef frame_offset
496 /*
497 * If we ever get here an exception occurred while
498 * building the above stack-frame.
499 */
500 goto badframe;
501 }
502
503 *pd0 = regs->d0;
504 return err;
505 424
506badframe: 425badframe:
507 return 1; 426 return 1;
@@ -514,7 +433,6 @@ asmlinkage int do_sigreturn(unsigned long __unused)
514 unsigned long usp = rdusp(); 433 unsigned long usp = rdusp();
515 struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); 434 struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
516 sigset_t set; 435 sigset_t set;
517 int d0;
518 436
519 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 437 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
520 goto badframe; 438 goto badframe;
@@ -528,9 +446,9 @@ asmlinkage int do_sigreturn(unsigned long __unused)
528 current->blocked = set; 446 current->blocked = set;
529 recalc_sigpending(); 447 recalc_sigpending();
530 448
531 if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0)) 449 if (restore_sigcontext(regs, &frame->sc, frame + 1))
532 goto badframe; 450 goto badframe;
533 return d0; 451 return regs->d0;
534 452
535badframe: 453badframe:
536 force_sig(SIGSEGV, current); 454 force_sig(SIGSEGV, current);
@@ -544,7 +462,6 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
544 unsigned long usp = rdusp(); 462 unsigned long usp = rdusp();
545 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); 463 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
546 sigset_t set; 464 sigset_t set;
547 int d0;
548 465
549 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 466 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
550 goto badframe; 467 goto badframe;
@@ -555,9 +472,9 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
555 current->blocked = set; 472 current->blocked = set;
556 recalc_sigpending(); 473 recalc_sigpending();
557 474
558 if (rt_restore_ucontext(regs, sw, &frame->uc, &d0)) 475 if (rt_restore_ucontext(regs, sw, &frame->uc))
559 goto badframe; 476 goto badframe;
560 return d0; 477 return regs->d0;
561 478
562badframe: 479badframe:
563 force_sig(SIGSEGV, current); 480 force_sig(SIGSEGV, current);
@@ -775,7 +692,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
775 return (void __user *)((usp - frame_size) & -8UL); 692 return (void __user *)((usp - frame_size) & -8UL);
776} 693}
777 694
778static void setup_frame (int sig, struct k_sigaction *ka, 695static int setup_frame (int sig, struct k_sigaction *ka,
779 sigset_t *set, struct pt_regs *regs) 696 sigset_t *set, struct pt_regs *regs)
780{ 697{
781 struct sigframe __user *frame; 698 struct sigframe __user *frame;
@@ -793,10 +710,8 @@ static void setup_frame (int sig, struct k_sigaction *ka,
793 710
794 frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); 711 frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
795 712
796 if (fsize) { 713 if (fsize)
797 err |= copy_to_user (frame + 1, regs + 1, fsize); 714 err |= copy_to_user (frame + 1, regs + 1, fsize);
798 regs->stkadj = fsize;
799 }
800 715
801 err |= __put_user((current_thread_info()->exec_domain 716 err |= __put_user((current_thread_info()->exec_domain
802 && current_thread_info()->exec_domain->signal_invmap 717 && current_thread_info()->exec_domain->signal_invmap
@@ -826,11 +741,21 @@ static void setup_frame (int sig, struct k_sigaction *ka,
826 741
827 push_cache ((unsigned long) &frame->retcode); 742 push_cache ((unsigned long) &frame->retcode);
828 743
829 /* Set up registers for signal handler */ 744 /*
745 * Set up registers for signal handler. All the state we are about
746 * to destroy is successfully copied to sigframe.
747 */
830 wrusp ((unsigned long) frame); 748 wrusp ((unsigned long) frame);
831 regs->pc = (unsigned long) ka->sa.sa_handler; 749 regs->pc = (unsigned long) ka->sa.sa_handler;
832 750
833adjust_stack: 751 /*
752 * This is subtle; if we build more than one sigframe, all but the
753 * first one will see frame format 0 and have fsize == 0, so we won't
754 * screw stkadj.
755 */
756 if (fsize)
757 regs->stkadj = fsize;
758
834 /* Prepare to skip over the extra stuff in the exception frame. */ 759 /* Prepare to skip over the extra stuff in the exception frame. */
835 if (regs->stkadj) { 760 if (regs->stkadj) {
836 struct pt_regs *tregs = 761 struct pt_regs *tregs =
@@ -845,14 +770,14 @@ adjust_stack:
845 tregs->pc = regs->pc; 770 tregs->pc = regs->pc;
846 tregs->sr = regs->sr; 771 tregs->sr = regs->sr;
847 } 772 }
848 return; 773 return 0;
849 774
850give_sigsegv: 775give_sigsegv:
851 force_sigsegv(sig, current); 776 force_sigsegv(sig, current);
852 goto adjust_stack; 777 return err;
853} 778}
854 779
855static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 780static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
856 sigset_t *set, struct pt_regs *regs) 781 sigset_t *set, struct pt_regs *regs)
857{ 782{
858 struct rt_sigframe __user *frame; 783 struct rt_sigframe __user *frame;
@@ -869,10 +794,8 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
869 794
870 frame = get_sigframe(ka, regs, sizeof(*frame)); 795 frame = get_sigframe(ka, regs, sizeof(*frame));
871 796
872 if (fsize) { 797 if (fsize)
873 err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); 798 err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
874 regs->stkadj = fsize;
875 }
876 799
877 err |= __put_user((current_thread_info()->exec_domain 800 err |= __put_user((current_thread_info()->exec_domain
878 && current_thread_info()->exec_domain->signal_invmap 801 && current_thread_info()->exec_domain->signal_invmap
@@ -914,11 +837,21 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
914 837
915 push_cache ((unsigned long) &frame->retcode); 838 push_cache ((unsigned long) &frame->retcode);
916 839
917 /* Set up registers for signal handler */ 840 /*
841 * Set up registers for signal handler. All the state we are about
842 * to destroy is successfully copied to sigframe.
843 */
918 wrusp ((unsigned long) frame); 844 wrusp ((unsigned long) frame);
919 regs->pc = (unsigned long) ka->sa.sa_handler; 845 regs->pc = (unsigned long) ka->sa.sa_handler;
920 846
921adjust_stack: 847 /*
848 * This is subtle; if we build more than one sigframe, all but the
849 * first one will see frame format 0 and have fsize == 0, so we won't
850 * screw stkadj.
851 */
852 if (fsize)
853 regs->stkadj = fsize;
854
922 /* Prepare to skip over the extra stuff in the exception frame. */ 855 /* Prepare to skip over the extra stuff in the exception frame. */
923 if (regs->stkadj) { 856 if (regs->stkadj) {
924 struct pt_regs *tregs = 857 struct pt_regs *tregs =
@@ -933,11 +866,11 @@ adjust_stack:
933 tregs->pc = regs->pc; 866 tregs->pc = regs->pc;
934 tregs->sr = regs->sr; 867 tregs->sr = regs->sr;
935 } 868 }
936 return; 869 return 0;
937 870
938give_sigsegv: 871give_sigsegv:
939 force_sigsegv(sig, current); 872 force_sigsegv(sig, current);
940 goto adjust_stack; 873 return err;
941} 874}
942 875
943static inline void 876static inline void
@@ -995,6 +928,7 @@ static void
995handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 928handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
996 sigset_t *oldset, struct pt_regs *regs) 929 sigset_t *oldset, struct pt_regs *regs)
997{ 930{
931 int err;
998 /* are we from a system call? */ 932 /* are we from a system call? */
999 if (regs->orig_d0 >= 0) 933 if (regs->orig_d0 >= 0)
1000 /* If so, check system call restarting.. */ 934 /* If so, check system call restarting.. */
@@ -1002,17 +936,24 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
1002 936
1003 /* set up the stack frame */ 937 /* set up the stack frame */
1004 if (ka->sa.sa_flags & SA_SIGINFO) 938 if (ka->sa.sa_flags & SA_SIGINFO)
1005 setup_rt_frame(sig, ka, info, oldset, regs); 939 err = setup_rt_frame(sig, ka, info, oldset, regs);
1006 else 940 else
1007 setup_frame(sig, ka, oldset, regs); 941 err = setup_frame(sig, ka, oldset, regs);
1008 942
1009 if (ka->sa.sa_flags & SA_ONESHOT) 943 if (err)
1010 ka->sa.sa_handler = SIG_DFL; 944 return;
1011 945
1012 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 946 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1013 if (!(ka->sa.sa_flags & SA_NODEFER)) 947 if (!(ka->sa.sa_flags & SA_NODEFER))
1014 sigaddset(&current->blocked,sig); 948 sigaddset(&current->blocked,sig);
1015 recalc_sigpending(); 949 recalc_sigpending();
950
951 if (test_thread_flag(TIF_DELAYED_TRACE)) {
952 regs->sr &= ~0x8000;
953 send_sig(SIGTRAP, current, 1);
954 }
955
956 clear_thread_flag(TIF_RESTORE_SIGMASK);
1016} 957}
1017 958
1018/* 959/*
@@ -1020,22 +961,25 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
1020 * want to handle. Thus you cannot kill init even with a SIGKILL even by 961 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1021 * mistake. 962 * mistake.
1022 */ 963 */
1023asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) 964asmlinkage void do_signal(struct pt_regs *regs)
1024{ 965{
1025 siginfo_t info; 966 siginfo_t info;
1026 struct k_sigaction ka; 967 struct k_sigaction ka;
1027 int signr; 968 int signr;
969 sigset_t *oldset;
1028 970
1029 current->thread.esp0 = (unsigned long) regs; 971 current->thread.esp0 = (unsigned long) regs;
1030 972
1031 if (!oldset) 973 if (test_thread_flag(TIF_RESTORE_SIGMASK))
974 oldset = &current->saved_sigmask;
975 else
1032 oldset = &current->blocked; 976 oldset = &current->blocked;
1033 977
1034 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 978 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
1035 if (signr > 0) { 979 if (signr > 0) {
1036 /* Whee! Actually deliver the signal. */ 980 /* Whee! Actually deliver the signal. */
1037 handle_signal(signr, &ka, &info, oldset, regs); 981 handle_signal(signr, &ka, &info, oldset, regs);
1038 return 1; 982 return;
1039 } 983 }
1040 984
1041 /* Did we come from a system call? */ 985 /* Did we come from a system call? */
@@ -1043,5 +987,9 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
1043 /* Restart the system call - no handlers present */ 987 /* Restart the system call - no handlers present */
1044 handle_restart(regs, NULL, 0); 988 handle_restart(regs, NULL, 0);
1045 989
1046 return 0; 990 /* If there's no signal to deliver, we just restore the saved mask. */
991 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
992 clear_thread_flag(TIF_RESTORE_SIGMASK);
993 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
994 }
1047} 995}
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
index aff6f57ef8b5..2783f25e38bd 100644
--- a/arch/m68knommu/kernel/entry.S
+++ b/arch/m68knommu/kernel/entry.S
@@ -112,22 +112,6 @@ ENTRY(sys_clone)
112 RESTORE_SWITCH_STACK 112 RESTORE_SWITCH_STACK
113 rts 113 rts
114 114
115ENTRY(sys_sigsuspend)
116 SAVE_SWITCH_STACK
117 pea %sp@(SWITCH_STACK_SIZE)
118 jbsr do_sigsuspend
119 addql #4,%sp
120 RESTORE_SWITCH_STACK
121 rts
122
123ENTRY(sys_rt_sigsuspend)
124 SAVE_SWITCH_STACK
125 pea %sp@(SWITCH_STACK_SIZE)
126 jbsr do_rt_sigsuspend
127 addql #4,%sp
128 RESTORE_SWITCH_STACK
129 rts
130
131ENTRY(sys_sigreturn) 115ENTRY(sys_sigreturn)
132 SAVE_SWITCH_STACK 116 SAVE_SWITCH_STACK
133 jbsr do_sigreturn 117 jbsr do_sigreturn
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
index 5ab6a04af14e..36a81bb6835a 100644
--- a/arch/m68knommu/kernel/signal.c
+++ b/arch/m68knommu/kernel/signal.c
@@ -53,65 +53,30 @@
53 53
54void ret_from_user_signal(void); 54void ret_from_user_signal(void);
55void ret_from_user_rt_signal(void); 55void ret_from_user_rt_signal(void);
56asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
57 56
58/* 57/*
59 * Atomically swap in the new signal mask, and wait for a signal. 58 * Atomically swap in the new signal mask, and wait for a signal.
60 */ 59 */
61asmlinkage int do_sigsuspend(struct pt_regs *regs) 60asmlinkage int
61sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
62{ 62{
63 old_sigset_t mask = regs->d3;
64 sigset_t saveset;
65
66 mask &= _BLOCKABLE; 63 mask &= _BLOCKABLE;
67 spin_lock_irq(&current->sighand->siglock); 64 spin_lock_irq(&current->sighand->siglock);
68 saveset = current->blocked; 65 current->saved_sigmask = current->blocked;
69 siginitset(&current->blocked, mask); 66 siginitset(&current->blocked, mask);
70 recalc_sigpending(); 67 recalc_sigpending();
71 spin_unlock_irq(&current->sighand->siglock); 68 spin_unlock_irq(&current->sighand->siglock);
72 69
73 regs->d0 = -EINTR; 70 current->state = TASK_INTERRUPTIBLE;
74 while (1) { 71 schedule();
75 current->state = TASK_INTERRUPTIBLE; 72 set_restore_sigmask();
76 schedule();
77 if (do_signal(&saveset, regs))
78 return -EINTR;
79 }
80}
81
82asmlinkage int
83do_rt_sigsuspend(struct pt_regs *regs)
84{
85 sigset_t *unewset = (sigset_t *)regs->d1;
86 size_t sigsetsize = (size_t)regs->d2;
87 sigset_t saveset, newset;
88
89 /* XXX: Don't preclude handling different sized sigset_t's. */
90 if (sigsetsize != sizeof(sigset_t))
91 return -EINVAL;
92 73
93 if (copy_from_user(&newset, unewset, sizeof(newset))) 74 return -ERESTARTNOHAND;
94 return -EFAULT;
95 sigdelsetmask(&newset, ~_BLOCKABLE);
96
97 spin_lock_irq(&current->sighand->siglock);
98 saveset = current->blocked;
99 current->blocked = newset;
100 recalc_sigpending();
101 spin_unlock_irq(&current->sighand->siglock);
102
103 regs->d0 = -EINTR;
104 while (1) {
105 current->state = TASK_INTERRUPTIBLE;
106 schedule();
107 if (do_signal(&saveset, regs))
108 return -EINTR;
109 }
110} 75}
111 76
112asmlinkage int 77asmlinkage int
113sys_sigaction(int sig, const struct old_sigaction *act, 78sys_sigaction(int sig, const struct old_sigaction __user *act,
114 struct old_sigaction *oact) 79 struct old_sigaction __user *oact)
115{ 80{
116 struct k_sigaction new_ka, old_ka; 81 struct k_sigaction new_ka, old_ka;
117 int ret; 82 int ret;
@@ -120,10 +85,10 @@ sys_sigaction(int sig, const struct old_sigaction *act,
120 old_sigset_t mask; 85 old_sigset_t mask;
121 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 86 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
122 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 87 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
123 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 88 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
89 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
90 __get_user(mask, &act->sa_mask))
124 return -EFAULT; 91 return -EFAULT;
125 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
126 __get_user(mask, &act->sa_mask);
127 siginitset(&new_ka.sa.sa_mask, mask); 92 siginitset(&new_ka.sa.sa_mask, mask);
128 } 93 }
129 94
@@ -132,17 +97,17 @@ sys_sigaction(int sig, const struct old_sigaction *act,
132 if (!ret && oact) { 97 if (!ret && oact) {
133 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 98 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
134 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 99 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
135 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 100 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
101 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
102 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
136 return -EFAULT; 103 return -EFAULT;
137 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
138 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
139 } 104 }
140 105
141 return ret; 106 return ret;
142} 107}
143 108
144asmlinkage int 109asmlinkage int
145sys_sigaltstack(const stack_t *uss, stack_t *uoss) 110sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
146{ 111{
147 return do_sigaltstack(uss, uoss, rdusp()); 112 return do_sigaltstack(uss, uoss, rdusp());
148} 113}
@@ -157,10 +122,10 @@ sys_sigaltstack(const stack_t *uss, stack_t *uoss)
157 122
158struct sigframe 123struct sigframe
159{ 124{
160 char *pretcode; 125 char __user *pretcode;
161 int sig; 126 int sig;
162 int code; 127 int code;
163 struct sigcontext *psc; 128 struct sigcontext __user *psc;
164 char retcode[8]; 129 char retcode[8];
165 unsigned long extramask[_NSIG_WORDS-1]; 130 unsigned long extramask[_NSIG_WORDS-1];
166 struct sigcontext sc; 131 struct sigcontext sc;
@@ -168,10 +133,10 @@ struct sigframe
168 133
169struct rt_sigframe 134struct rt_sigframe
170{ 135{
171 char *pretcode; 136 char __user *pretcode;
172 int sig; 137 int sig;
173 struct siginfo *pinfo; 138 struct siginfo __user *pinfo;
174 void *puc; 139 void __user *puc;
175 char retcode[8]; 140 char retcode[8];
176 struct siginfo info; 141 struct siginfo info;
177 struct ucontext uc; 142 struct ucontext uc;
@@ -198,8 +163,8 @@ static inline int restore_fpu_state(struct sigcontext *sc)
198 goto out; 163 goto out;
199 164
200 __asm__ volatile (".chip 68k/68881\n\t" 165 __asm__ volatile (".chip 68k/68881\n\t"
201 "fmovemx %0,%/fp0-%/fp1\n\t" 166 "fmovemx %0,%%fp0-%%fp1\n\t"
202 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t" 167 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
203 ".chip 68k" 168 ".chip 68k"
204 : /* no outputs */ 169 : /* no outputs */
205 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); 170 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
@@ -218,7 +183,7 @@ out:
218#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] 183#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
219#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] 184#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
220 185
221static inline int rt_restore_fpu_state(struct ucontext *uc) 186static inline int rt_restore_fpu_state(struct ucontext __user *uc)
222{ 187{
223 unsigned char fpstate[FPCONTEXT_SIZE]; 188 unsigned char fpstate[FPCONTEXT_SIZE];
224 int context_size = 0; 189 int context_size = 0;
@@ -228,7 +193,7 @@ static inline int rt_restore_fpu_state(struct ucontext *uc)
228 if (FPU_IS_EMU) { 193 if (FPU_IS_EMU) {
229 /* restore fpu control register */ 194 /* restore fpu control register */
230 if (__copy_from_user(current->thread.fpcntl, 195 if (__copy_from_user(current->thread.fpcntl,
231 &uc->uc_mcontext.fpregs.f_pcr, 12)) 196 uc->uc_mcontext.fpregs.f_fpcntl, 12))
232 goto out; 197 goto out;
233 /* restore all other fpu register */ 198 /* restore all other fpu register */
234 if (__copy_from_user(current->thread.fp, 199 if (__copy_from_user(current->thread.fp,
@@ -237,7 +202,7 @@ static inline int rt_restore_fpu_state(struct ucontext *uc)
237 return 0; 202 return 0;
238 } 203 }
239 204
240 if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate)) 205 if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
241 goto out; 206 goto out;
242 if (fpstate[0]) { 207 if (fpstate[0]) {
243 context_size = fpstate[1]; 208 context_size = fpstate[1];
@@ -249,15 +214,15 @@ static inline int rt_restore_fpu_state(struct ucontext *uc)
249 sizeof(fpregs))) 214 sizeof(fpregs)))
250 goto out; 215 goto out;
251 __asm__ volatile (".chip 68k/68881\n\t" 216 __asm__ volatile (".chip 68k/68881\n\t"
252 "fmovemx %0,%/fp0-%/fp7\n\t" 217 "fmovemx %0,%%fp0-%%fp7\n\t"
253 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t" 218 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
254 ".chip 68k" 219 ".chip 68k"
255 : /* no outputs */ 220 : /* no outputs */
256 : "m" (*fpregs.f_fpregs), 221 : "m" (*fpregs.f_fpregs),
257 "m" (fpregs.f_pcr)); 222 "m" (*fpregs.f_fpcntl));
258 } 223 }
259 if (context_size && 224 if (context_size &&
260 __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1, 225 __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
261 context_size)) 226 context_size))
262 goto out; 227 goto out;
263 __asm__ volatile (".chip 68k/68881\n\t" 228 __asm__ volatile (".chip 68k/68881\n\t"
@@ -272,7 +237,7 @@ out:
272#endif 237#endif
273 238
274static inline int 239static inline int
275restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, 240restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp,
276 int *pd0) 241 int *pd0)
277{ 242{
278 int formatvec; 243 int formatvec;
@@ -312,10 +277,10 @@ badframe:
312 277
313static inline int 278static inline int
314rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, 279rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
315 struct ucontext *uc, int *pd0) 280 struct ucontext __user *uc, int *pd0)
316{ 281{
317 int temp; 282 int temp;
318 greg_t *gregs = uc->uc_mcontext.gregs; 283 greg_t __user *gregs = uc->uc_mcontext.gregs;
319 unsigned long usp; 284 unsigned long usp;
320 int err; 285 int err;
321 286
@@ -365,7 +330,7 @@ asmlinkage int do_sigreturn(unsigned long __unused)
365 struct switch_stack *sw = (struct switch_stack *) &__unused; 330 struct switch_stack *sw = (struct switch_stack *) &__unused;
366 struct pt_regs *regs = (struct pt_regs *) (sw + 1); 331 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
367 unsigned long usp = rdusp(); 332 unsigned long usp = rdusp();
368 struct sigframe *frame = (struct sigframe *)(usp - 4); 333 struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
369 sigset_t set; 334 sigset_t set;
370 int d0; 335 int d0;
371 336
@@ -397,7 +362,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
397 struct switch_stack *sw = (struct switch_stack *) &__unused; 362 struct switch_stack *sw = (struct switch_stack *) &__unused;
398 struct pt_regs *regs = (struct pt_regs *) (sw + 1); 363 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
399 unsigned long usp = rdusp(); 364 unsigned long usp = rdusp();
400 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); 365 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
401 sigset_t set; 366 sigset_t set;
402 int d0; 367 int d0;
403 368
@@ -443,17 +408,17 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
443 if (sc->sc_fpstate[0]) { 408 if (sc->sc_fpstate[0]) {
444 fpu_version = sc->sc_fpstate[0]; 409 fpu_version = sc->sc_fpstate[0];
445 __asm__ volatile (".chip 68k/68881\n\t" 410 __asm__ volatile (".chip 68k/68881\n\t"
446 "fmovemx %/fp0-%/fp1,%0\n\t" 411 "fmovemx %%fp0-%%fp1,%0\n\t"
447 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t" 412 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
448 ".chip 68k" 413 ".chip 68k"
449 : /* no outputs */ 414 : "=m" (*sc->sc_fpregs),
450 : "m" (*sc->sc_fpregs), 415 "=m" (*sc->sc_fpcntl)
451 "m" (*sc->sc_fpcntl) 416 : /* no inputs */
452 : "memory"); 417 : "memory");
453 } 418 }
454} 419}
455 420
456static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs) 421static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
457{ 422{
458 unsigned char fpstate[FPCONTEXT_SIZE]; 423 unsigned char fpstate[FPCONTEXT_SIZE];
459 int context_size = 0; 424 int context_size = 0;
@@ -461,7 +426,7 @@ static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
461 426
462 if (FPU_IS_EMU) { 427 if (FPU_IS_EMU) {
463 /* save fpu control register */ 428 /* save fpu control register */
464 err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr, 429 err |= copy_to_user(uc->uc_mcontext.fpregs.f_pcntl,
465 current->thread.fpcntl, 12); 430 current->thread.fpcntl, 12);
466 /* save all other fpu register */ 431 /* save all other fpu register */
467 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, 432 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
@@ -474,24 +439,24 @@ static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
474 ".chip 68k" 439 ".chip 68k"
475 : : "m" (*fpstate) : "memory"); 440 : : "m" (*fpstate) : "memory");
476 441
477 err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate); 442 err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
478 if (fpstate[0]) { 443 if (fpstate[0]) {
479 fpregset_t fpregs; 444 fpregset_t fpregs;
480 context_size = fpstate[1]; 445 context_size = fpstate[1];
481 fpu_version = fpstate[0]; 446 fpu_version = fpstate[0];
482 __asm__ volatile (".chip 68k/68881\n\t" 447 __asm__ volatile (".chip 68k/68881\n\t"
483 "fmovemx %/fp0-%/fp7,%0\n\t" 448 "fmovemx %%fp0-%%fp7,%0\n\t"
484 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t" 449 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
485 ".chip 68k" 450 ".chip 68k"
486 : /* no outputs */ 451 : "=m" (*fpregs.f_fpregs),
487 : "m" (*fpregs.f_fpregs), 452 "=m" (*fpregs.f_fpcntl)
488 "m" (fpregs.f_pcr) 453 : /* no inputs */
489 : "memory"); 454 : "memory");
490 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, 455 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
491 sizeof(fpregs)); 456 sizeof(fpregs));
492 } 457 }
493 if (context_size) 458 if (context_size)
494 err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4, 459 err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,
495 context_size); 460 context_size);
496 return err; 461 return err;
497} 462}
@@ -516,10 +481,10 @@ static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
516#endif 481#endif
517} 482}
518 483
519static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) 484static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
520{ 485{
521 struct switch_stack *sw = (struct switch_stack *)regs - 1; 486 struct switch_stack *sw = (struct switch_stack *)regs - 1;
522 greg_t *gregs = uc->uc_mcontext.gregs; 487 greg_t __user *gregs = uc->uc_mcontext.gregs;
523 int err = 0; 488 int err = 0;
524 489
525 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); 490 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
@@ -547,7 +512,7 @@ static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
547 return err; 512 return err;
548} 513}
549 514
550static inline void * 515static inline void __user *
551get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 516get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
552{ 517{
553 unsigned long usp; 518 unsigned long usp;
@@ -560,13 +525,13 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
560 if (!sas_ss_flags(usp)) 525 if (!sas_ss_flags(usp))
561 usp = current->sas_ss_sp + current->sas_ss_size; 526 usp = current->sas_ss_sp + current->sas_ss_size;
562 } 527 }
563 return (void *)((usp - frame_size) & -8UL); 528 return (void __user *)((usp - frame_size) & -8UL);
564} 529}
565 530
566static void setup_frame (int sig, struct k_sigaction *ka, 531static int setup_frame (int sig, struct k_sigaction *ka,
567 sigset_t *set, struct pt_regs *regs) 532 sigset_t *set, struct pt_regs *regs)
568{ 533{
569 struct sigframe *frame; 534 struct sigframe __user *frame;
570 struct sigcontext context; 535 struct sigcontext context;
571 int err = 0; 536 int err = 0;
572 537
@@ -617,17 +582,17 @@ adjust_stack:
617 tregs->pc = regs->pc; 582 tregs->pc = regs->pc;
618 tregs->sr = regs->sr; 583 tregs->sr = regs->sr;
619 } 584 }
620 return; 585 return err;
621 586
622give_sigsegv: 587give_sigsegv:
623 force_sigsegv(sig, current); 588 force_sigsegv(sig, current);
624 goto adjust_stack; 589 goto adjust_stack;
625} 590}
626 591
627static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 592static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
628 sigset_t *set, struct pt_regs *regs) 593 sigset_t *set, struct pt_regs *regs)
629{ 594{
630 struct rt_sigframe *frame; 595 struct rt_sigframe __user *frame;
631 int err = 0; 596 int err = 0;
632 597
633 frame = get_sigframe(ka, regs, sizeof(*frame)); 598 frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -644,8 +609,8 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
644 609
645 /* Create the ucontext. */ 610 /* Create the ucontext. */
646 err |= __put_user(0, &frame->uc.uc_flags); 611 err |= __put_user(0, &frame->uc.uc_flags);
647 err |= __put_user(0, &frame->uc.uc_link); 612 err |= __put_user(NULL, &frame->uc.uc_link);
648 err |= __put_user((void *)current->sas_ss_sp, 613 err |= __put_user((void __user *)current->sas_ss_sp,
649 &frame->uc.uc_stack.ss_sp); 614 &frame->uc.uc_stack.ss_sp);
650 err |= __put_user(sas_ss_flags(rdusp()), 615 err |= __put_user(sas_ss_flags(rdusp()),
651 &frame->uc.uc_stack.ss_flags); 616 &frame->uc.uc_stack.ss_flags);
@@ -681,7 +646,7 @@ adjust_stack:
681 tregs->pc = regs->pc; 646 tregs->pc = regs->pc;
682 tregs->sr = regs->sr; 647 tregs->sr = regs->sr;
683 } 648 }
684 return; 649 return err;
685 650
686give_sigsegv: 651give_sigsegv:
687 force_sigsegv(sig, current); 652 force_sigsegv(sig, current);
@@ -728,6 +693,7 @@ static void
728handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 693handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
729 sigset_t *oldset, struct pt_regs *regs) 694 sigset_t *oldset, struct pt_regs *regs)
730{ 695{
696 int err;
731 /* are we from a system call? */ 697 /* are we from a system call? */
732 if (regs->orig_d0 >= 0) 698 if (regs->orig_d0 >= 0)
733 /* If so, check system call restarting.. */ 699 /* If so, check system call restarting.. */
@@ -735,12 +701,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
735 701
736 /* set up the stack frame */ 702 /* set up the stack frame */
737 if (ka->sa.sa_flags & SA_SIGINFO) 703 if (ka->sa.sa_flags & SA_SIGINFO)
738 setup_rt_frame(sig, ka, info, oldset, regs); 704 err = setup_rt_frame(sig, ka, info, oldset, regs);
739 else 705 else
740 setup_frame(sig, ka, oldset, regs); 706 err = setup_frame(sig, ka, oldset, regs);
741 707
742 if (ka->sa.sa_flags & SA_ONESHOT) 708 if (err)
743 ka->sa.sa_handler = SIG_DFL; 709 return;
744 710
745 spin_lock_irq(&current->sighand->siglock); 711 spin_lock_irq(&current->sighand->siglock);
746 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 712 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -748,6 +714,8 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
748 sigaddset(&current->blocked,sig); 714 sigaddset(&current->blocked,sig);
749 recalc_sigpending(); 715 recalc_sigpending();
750 spin_unlock_irq(&current->sighand->siglock); 716 spin_unlock_irq(&current->sighand->siglock);
717
718 clear_thread_flag(TIF_RESTORE_SIGMASK);
751} 719}
752 720
753/* 721/*
@@ -755,11 +723,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
755 * want to handle. Thus you cannot kill init even with a SIGKILL even by 723 * want to handle. Thus you cannot kill init even with a SIGKILL even by
756 * mistake. 724 * mistake.
757 */ 725 */
758asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) 726asmlinkage void do_signal(struct pt_regs *regs)
759{ 727{
760 struct k_sigaction ka; 728 struct k_sigaction ka;
761 siginfo_t info; 729 siginfo_t info;
762 int signr; 730 int signr;
731 sigset_t *oldset;
763 732
764 /* 733 /*
765 * We want the common case to go fast, which 734 * We want the common case to go fast, which
@@ -768,16 +737,18 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
768 * if so. 737 * if so.
769 */ 738 */
770 if (!user_mode(regs)) 739 if (!user_mode(regs))
771 return 1; 740 return;
772 741
773 if (!oldset) 742 if (test_thread_flag(TIF_RESTORE_SIGMASK))
743 oldset = &current->saved_sigmask;
744 else
774 oldset = &current->blocked; 745 oldset = &current->blocked;
775 746
776 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 747 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
777 if (signr > 0) { 748 if (signr > 0) {
778 /* Whee! Actually deliver the signal. */ 749 /* Whee! Actually deliver the signal. */
779 handle_signal(signr, &ka, &info, oldset, regs); 750 handle_signal(signr, &ka, &info, oldset, regs);
780 return 1; 751 return;
781 } 752 }
782 753
783 /* Did we come from a system call? */ 754 /* Did we come from a system call? */
@@ -785,5 +756,10 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
785 /* Restart the system call - no handlers present */ 756 /* Restart the system call - no handlers present */
786 handle_restart(regs, NULL, 0); 757 handle_restart(regs, NULL, 0);
787 } 758 }
788 return 0; 759
760 /* If there's no signal to deliver, we just restore the saved mask. */
761 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
762 clear_thread_flag(TIF_RESTORE_SIGMASK);
763 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
764 }
789} 765}
diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S
index 27241e16a526..240a7a6e25c8 100644
--- a/arch/m68knommu/platform/68328/entry.S
+++ b/arch/m68knommu/platform/68328/entry.S
@@ -106,6 +106,7 @@ Luser_return:
106 movel %sp,%d1 /* get thread_info pointer */ 106 movel %sp,%d1 /* get thread_info pointer */
107 andl #-THREAD_SIZE,%d1 107 andl #-THREAD_SIZE,%d1
108 movel %d1,%a2 108 movel %d1,%a2
1091:
109 move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ 110 move %a2@(TI_FLAGS),%d1 /* thread_info->flags */
110 andl #_TIF_WORK_MASK,%d1 111 andl #_TIF_WORK_MASK,%d1
111 jne Lwork_to_do 112 jne Lwork_to_do
@@ -120,13 +121,11 @@ Lsignal_return:
120 subql #4,%sp /* dummy return address*/ 121 subql #4,%sp /* dummy return address*/
121 SAVE_SWITCH_STACK 122 SAVE_SWITCH_STACK
122 pea %sp@(SWITCH_STACK_SIZE) 123 pea %sp@(SWITCH_STACK_SIZE)
123 clrl %sp@-
124 bsrw do_signal 124 bsrw do_signal
125 addql #8,%sp 125 addql #4,%sp
126 RESTORE_SWITCH_STACK 126 RESTORE_SWITCH_STACK
127 addql #4,%sp 127 addql #4,%sp
128Lreturn: 128 jra 1b
129 RESTORE_ALL
130 129
131/* 130/*
132 * This is the main interrupt handler, responsible for calling process_int() 131 * This is the main interrupt handler, responsible for calling process_int()
diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S
index c131c6e1d92d..8a28788c0eea 100644
--- a/arch/m68knommu/platform/68360/entry.S
+++ b/arch/m68knommu/platform/68360/entry.S
@@ -102,6 +102,7 @@ Luser_return:
102 movel %sp,%d1 /* get thread_info pointer */ 102 movel %sp,%d1 /* get thread_info pointer */
103 andl #-THREAD_SIZE,%d1 103 andl #-THREAD_SIZE,%d1
104 movel %d1,%a2 104 movel %d1,%a2
1051:
105 move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ 106 move %a2@(TI_FLAGS),%d1 /* thread_info->flags */
106 andl #_TIF_WORK_MASK,%d1 107 andl #_TIF_WORK_MASK,%d1
107 jne Lwork_to_do 108 jne Lwork_to_do
@@ -116,13 +117,11 @@ Lsignal_return:
116 subql #4,%sp /* dummy return address*/ 117 subql #4,%sp /* dummy return address*/
117 SAVE_SWITCH_STACK 118 SAVE_SWITCH_STACK
118 pea %sp@(SWITCH_STACK_SIZE) 119 pea %sp@(SWITCH_STACK_SIZE)
119 clrl %sp@-
120 bsrw do_signal 120 bsrw do_signal
121 addql #8,%sp 121 addql #4,%sp
122 RESTORE_SWITCH_STACK 122 RESTORE_SWITCH_STACK
123 addql #4,%sp 123 addql #4,%sp
124Lreturn: 124 jra 1b
125 RESTORE_ALL
126 125
127/* 126/*
128 * This is the main interrupt handler, responsible for calling do_IRQ() 127 * This is the main interrupt handler, responsible for calling do_IRQ()
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S
index 5e92bed94b7e..e1debc8285ef 100644
--- a/arch/m68knommu/platform/coldfire/entry.S
+++ b/arch/m68knommu/platform/coldfire/entry.S
@@ -167,12 +167,11 @@ Lsignal_return:
167 subql #4,%sp /* dummy return address */ 167 subql #4,%sp /* dummy return address */
168 SAVE_SWITCH_STACK 168 SAVE_SWITCH_STACK
169 pea %sp@(SWITCH_STACK_SIZE) 169 pea %sp@(SWITCH_STACK_SIZE)
170 clrl %sp@-
171 jsr do_signal 170 jsr do_signal
172 addql #8,%sp 171 addql #4,%sp
173 RESTORE_SWITCH_STACK 172 RESTORE_SWITCH_STACK
174 addql #4,%sp 173 addql #4,%sp
175 jmp Lreturn 174 jmp Luser_return
176 175
177/* 176/*
178 * This is the generic interrupt handler (for all hardware interrupt 177 * This is the generic interrupt handler (for all hardware interrupt