diff options
-rw-r--r-- | arch/m68k/include/asm/sun3_pgtable.h | 5 | ||||
-rw-r--r-- | arch/m68k/include/asm/thread_info.h | 1 | ||||
-rw-r--r-- | arch/m68k/include/asm/unistd.h | 1 | ||||
-rw-r--r-- | arch/m68k/kernel/entry.S | 30 | ||||
-rw-r--r-- | arch/m68k/kernel/signal.c | 314 | ||||
-rw-r--r-- | arch/m68knommu/kernel/entry.S | 16 | ||||
-rw-r--r-- | arch/m68knommu/kernel/signal.c | 188 | ||||
-rw-r--r-- | arch/m68knommu/platform/68328/entry.S | 7 | ||||
-rw-r--r-- | arch/m68knommu/platform/68360/entry.S | 7 | ||||
-rw-r--r-- | arch/m68knommu/platform/coldfire/entry.S | 5 |
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 | ||
101 | ENTRY(ret_from_signal) | 101 | ENTRY(ret_from_signal) |
102 | RESTORE_SWITCH_STACK | 102 | tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) |
103 | jge 1f | ||
104 | jbsr syscall_trace | ||
105 | 1: 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 | ||
188 | do_delayed_trace: | 186 | do_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 | ||
293 | ENTRY(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 | |||
301 | ENTRY(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 | |||
309 | ENTRY(sys_sigreturn) | 291 | ENTRY(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 | ||
54 | asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); | ||
55 | |||
56 | const int frame_extra_sizes[16] = { | 54 | const 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 | */ |
77 | asmlinkage int do_sigsuspend(struct pt_regs *regs) | 75 | asmlinkage int |
76 | sys_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(¤t->sighand->siglock); |
80 | current->saved_sigmask = current->blocked; | ||
84 | siginitset(¤t->blocked, mask); | 81 | siginitset(¤t->blocked, mask); |
85 | recalc_sigpending(); | 82 | recalc_sigpending(); |
83 | spin_unlock_irq(¤t->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 | |||
96 | asmlinkage int | ||
97 | do_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 | ||
124 | asmlinkage int | 92 | asmlinkage 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 | ||
321 | static inline int | 289 | static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, |
322 | restore_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; | 340 | static inline int |
402 | return err; | 341 | restore_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 | ||
404 | badframe: | 372 | badframe: |
405 | return 1; | 373 | return 1; |
@@ -407,9 +375,9 @@ badframe: | |||
407 | 375 | ||
408 | static inline int | 376 | static inline int |
409 | rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, | 377 | rt_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 | ||
506 | badframe: | 425 | badframe: |
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 | ||
535 | badframe: | 453 | badframe: |
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 | ||
562 | badframe: | 479 | badframe: |
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 | ||
778 | static void setup_frame (int sig, struct k_sigaction *ka, | 695 | static 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 | ||
833 | adjust_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 | ||
850 | give_sigsegv: | 775 | give_sigsegv: |
851 | force_sigsegv(sig, current); | 776 | force_sigsegv(sig, current); |
852 | goto adjust_stack; | 777 | return err; |
853 | } | 778 | } |
854 | 779 | ||
855 | static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, | 780 | static 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 | ||
921 | adjust_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 | ||
938 | give_sigsegv: | 871 | give_sigsegv: |
939 | force_sigsegv(sig, current); | 872 | force_sigsegv(sig, current); |
940 | goto adjust_stack; | 873 | return err; |
941 | } | 874 | } |
942 | 875 | ||
943 | static inline void | 876 | static inline void |
@@ -995,6 +928,7 @@ static void | |||
995 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | 928 | handle_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(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 946 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
1013 | if (!(ka->sa.sa_flags & SA_NODEFER)) | 947 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
1014 | sigaddset(¤t->blocked,sig); | 948 | sigaddset(¤t->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 | */ |
1023 | asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) | 964 | asmlinkage 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 = ¤t->saved_sigmask; | ||
975 | else | ||
1032 | oldset = ¤t->blocked; | 976 | oldset = ¤t->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, ¤t->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 | ||
115 | ENTRY(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 | |||
123 | ENTRY(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 | |||
131 | ENTRY(sys_sigreturn) | 115 | ENTRY(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 | ||
54 | void ret_from_user_signal(void); | 54 | void ret_from_user_signal(void); |
55 | void ret_from_user_rt_signal(void); | 55 | void ret_from_user_rt_signal(void); |
56 | asmlinkage 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 | */ |
61 | asmlinkage int do_sigsuspend(struct pt_regs *regs) | 60 | asmlinkage int |
61 | sys_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(¤t->sighand->siglock); | 64 | spin_lock_irq(¤t->sighand->siglock); |
68 | saveset = current->blocked; | 65 | current->saved_sigmask = current->blocked; |
69 | siginitset(¤t->blocked, mask); | 66 | siginitset(¤t->blocked, mask); |
70 | recalc_sigpending(); | 67 | recalc_sigpending(); |
71 | spin_unlock_irq(¤t->sighand->siglock); | 68 | spin_unlock_irq(¤t->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 | |||
82 | asmlinkage int | ||
83 | do_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(¤t->sighand->siglock); | ||
98 | saveset = current->blocked; | ||
99 | current->blocked = newset; | ||
100 | recalc_sigpending(); | ||
101 | spin_unlock_irq(¤t->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 | ||
112 | asmlinkage int | 77 | asmlinkage int |
113 | sys_sigaction(int sig, const struct old_sigaction *act, | 78 | sys_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 | ||
144 | asmlinkage int | 109 | asmlinkage int |
145 | sys_sigaltstack(const stack_t *uss, stack_t *uoss) | 110 | sys_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 | ||
158 | struct sigframe | 123 | struct 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 | ||
169 | struct rt_sigframe | 134 | struct 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 | ||
221 | static inline int rt_restore_fpu_state(struct ucontext *uc) | 186 | static 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 | ||
274 | static inline int | 239 | static inline int |
275 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, | 240 | restore_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 | ||
313 | static inline int | 278 | static inline int |
314 | rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, | 279 | rt_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 | ||
456 | static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs) | 421 | static 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 | ||
519 | static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) | 484 | static 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 | ||
550 | static inline void * | 515 | static inline void __user * |
551 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | 516 | get_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 | ||
566 | static void setup_frame (int sig, struct k_sigaction *ka, | 531 | static 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 | ||
622 | give_sigsegv: | 587 | give_sigsegv: |
623 | force_sigsegv(sig, current); | 588 | force_sigsegv(sig, current); |
624 | goto adjust_stack; | 589 | goto adjust_stack; |
625 | } | 590 | } |
626 | 591 | ||
627 | static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, | 592 | static 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 | ||
686 | give_sigsegv: | 651 | give_sigsegv: |
687 | force_sigsegv(sig, current); | 652 | force_sigsegv(sig, current); |
@@ -728,6 +693,7 @@ static void | |||
728 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | 693 | handle_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(¤t->sighand->siglock); | 711 | spin_lock_irq(¤t->sighand->siglock); |
746 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 712 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -748,6 +714,8 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
748 | sigaddset(¤t->blocked,sig); | 714 | sigaddset(¤t->blocked,sig); |
749 | recalc_sigpending(); | 715 | recalc_sigpending(); |
750 | spin_unlock_irq(¤t->sighand->siglock); | 716 | spin_unlock_irq(¤t->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 | */ |
758 | asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) | 726 | asmlinkage 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 = ¤t->saved_sigmask; | ||
744 | else | ||
774 | oldset = ¤t->blocked; | 745 | oldset = ¤t->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, ¤t->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 |
109 | 1: | ||
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 |
128 | Lreturn: | 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 |
105 | 1: | ||
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 |
124 | Lreturn: | 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 |