diff options
| -rw-r--r-- | arch/sparc64/kernel/rtrap.S | 6 | ||||
| -rw-r--r-- | arch/sparc64/kernel/signal.c | 21 | ||||
| -rw-r--r-- | arch/sparc64/kernel/signal32.c | 13 | ||||
| -rw-r--r-- | include/asm-sparc64/thread_info.h | 28 |
4 files changed, 44 insertions, 24 deletions
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index b9b785fd8b46..16689b2930db 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S | |||
| @@ -46,7 +46,7 @@ __handle_user_windows: | |||
| 46 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 46 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
| 47 | ldx [%g6 + TI_FLAGS], %l0 | 47 | ldx [%g6 + TI_FLAGS], %l0 |
| 48 | 48 | ||
| 49 | 1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 | 49 | 1: andcc %l0, _TIF_SIGPENDING, %g0 |
| 50 | be,pt %xcc, __handle_user_windows_continue | 50 | be,pt %xcc, __handle_user_windows_continue |
| 51 | nop | 51 | nop |
| 52 | mov %l5, %o1 | 52 | mov %l5, %o1 |
| @@ -86,7 +86,7 @@ __handle_perfctrs: | |||
| 86 | wrpr %g0, RTRAP_PSTATE, %pstate | 86 | wrpr %g0, RTRAP_PSTATE, %pstate |
| 87 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 87 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
| 88 | ldx [%g6 + TI_FLAGS], %l0 | 88 | ldx [%g6 + TI_FLAGS], %l0 |
| 89 | 1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 | 89 | 1: andcc %l0, _TIF_SIGPENDING, %g0 |
| 90 | 90 | ||
| 91 | be,pt %xcc, __handle_perfctrs_continue | 91 | be,pt %xcc, __handle_perfctrs_continue |
| 92 | sethi %hi(TSTATE_PEF), %o0 | 92 | sethi %hi(TSTATE_PEF), %o0 |
| @@ -195,7 +195,7 @@ __handle_preemption_continue: | |||
| 195 | andcc %l1, %o0, %g0 | 195 | andcc %l1, %o0, %g0 |
| 196 | andcc %l0, _TIF_NEED_RESCHED, %g0 | 196 | andcc %l0, _TIF_NEED_RESCHED, %g0 |
| 197 | bne,pn %xcc, __handle_preemption | 197 | bne,pn %xcc, __handle_preemption |
| 198 | andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 | 198 | andcc %l0, _TIF_SIGPENDING, %g0 |
| 199 | bne,pn %xcc, __handle_signal | 199 | bne,pn %xcc, __handle_signal |
| 200 | __handle_signal_continue: | 200 | __handle_signal_continue: |
| 201 | ldub [%g6 + TI_WSAVED], %o2 | 201 | ldub [%g6 + TI_WSAVED], %o2 |
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 2378482c2aab..6e4dc67d16af 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
| @@ -247,7 +247,9 @@ static long _sigpause_common(old_sigset_t set) | |||
| 247 | 247 | ||
| 248 | current->state = TASK_INTERRUPTIBLE; | 248 | current->state = TASK_INTERRUPTIBLE; |
| 249 | schedule(); | 249 | schedule(); |
| 250 | set_thread_flag(TIF_RESTORE_SIGMASK); | 250 | |
| 251 | set_restore_sigmask(); | ||
| 252 | |||
| 251 | return -ERESTARTNOHAND; | 253 | return -ERESTARTNOHAND; |
| 252 | } | 254 | } |
| 253 | 255 | ||
| @@ -537,7 +539,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
| 537 | } else | 539 | } else |
| 538 | restart_syscall = 0; | 540 | restart_syscall = 0; |
| 539 | 541 | ||
| 540 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 542 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) |
| 541 | oldset = ¤t->saved_sigmask; | 543 | oldset = ¤t->saved_sigmask; |
| 542 | else | 544 | else |
| 543 | oldset = ¤t->blocked; | 545 | oldset = ¤t->blocked; |
| @@ -566,13 +568,12 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
| 566 | syscall_restart(orig_i0, regs, &ka.sa); | 568 | syscall_restart(orig_i0, regs, &ka.sa); |
| 567 | handle_signal(signr, &ka, &info, oldset, regs); | 569 | handle_signal(signr, &ka, &info, oldset, regs); |
| 568 | 570 | ||
| 569 | /* a signal was successfully delivered; the saved | 571 | /* A signal was successfully delivered; the saved |
| 570 | * sigmask will have been stored in the signal frame, | 572 | * sigmask will have been stored in the signal frame, |
| 571 | * and will be restored by sigreturn, so we can simply | 573 | * and will be restored by sigreturn, so we can simply |
| 572 | * clear the TIF_RESTORE_SIGMASK flag. | 574 | * clear the TS_RESTORE_SIGMASK flag. |
| 573 | */ | 575 | */ |
| 574 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 576 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
| 575 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 576 | return; | 577 | return; |
| 577 | } | 578 | } |
| 578 | if (restart_syscall && | 579 | if (restart_syscall && |
| @@ -591,17 +592,17 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
| 591 | regs->tnpc -= 4; | 592 | regs->tnpc -= 4; |
| 592 | } | 593 | } |
| 593 | 594 | ||
| 594 | /* if there's no signal to deliver, we just put the saved sigmask | 595 | /* If there's no signal to deliver, we just put the saved sigmask |
| 595 | * back | 596 | * back |
| 596 | */ | 597 | */ |
| 597 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 598 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { |
| 598 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 599 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
| 599 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 600 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
| 600 | } | 601 | } |
| 601 | } | 602 | } |
| 602 | 603 | ||
| 603 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) | 604 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) |
| 604 | { | 605 | { |
| 605 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 606 | if (thread_info_flags & _TIF_SIGPENDING) |
| 606 | do_signal(regs, orig_i0); | 607 | do_signal(regs, orig_i0); |
| 607 | } | 608 | } |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 3f19e9af3d1b..97cdd1bf4a10 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
| @@ -788,13 +788,12 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
| 788 | syscall_restart32(orig_i0, regs, &ka.sa); | 788 | syscall_restart32(orig_i0, regs, &ka.sa); |
| 789 | handle_signal32(signr, &ka, &info, oldset, regs); | 789 | handle_signal32(signr, &ka, &info, oldset, regs); |
| 790 | 790 | ||
| 791 | /* a signal was successfully delivered; the saved | 791 | /* A signal was successfully delivered; the saved |
| 792 | * sigmask will have been stored in the signal frame, | 792 | * sigmask will have been stored in the signal frame, |
| 793 | * and will be restored by sigreturn, so we can simply | 793 | * and will be restored by sigreturn, so we can simply |
| 794 | * clear the TIF_RESTORE_SIGMASK flag. | 794 | * clear the TS_RESTORE_SIGMASK flag. |
| 795 | */ | 795 | */ |
| 796 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 796 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
| 797 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 798 | return; | 797 | return; |
| 799 | } | 798 | } |
| 800 | if (restart_syscall && | 799 | if (restart_syscall && |
| @@ -813,11 +812,11 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
| 813 | regs->tnpc -= 4; | 812 | regs->tnpc -= 4; |
| 814 | } | 813 | } |
| 815 | 814 | ||
| 816 | /* if there's no signal to deliver, we just put the saved sigmask | 815 | /* If there's no signal to deliver, we just put the saved sigmask |
| 817 | * back | 816 | * back |
| 818 | */ | 817 | */ |
| 819 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 818 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { |
| 820 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 819 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
| 821 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 820 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
| 822 | } | 821 | } |
| 823 | } | 822 | } |
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index 71e42d1a80d9..e5873e385306 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h | |||
| @@ -38,7 +38,7 @@ struct thread_info { | |||
| 38 | struct task_struct *task; | 38 | struct task_struct *task; |
| 39 | unsigned long flags; | 39 | unsigned long flags; |
| 40 | __u8 fpsaved[7]; | 40 | __u8 fpsaved[7]; |
| 41 | __u8 pad; | 41 | __u8 status; |
| 42 | unsigned long ksp; | 42 | unsigned long ksp; |
| 43 | 43 | ||
| 44 | /* D$ line 2 */ | 44 | /* D$ line 2 */ |
| @@ -217,7 +217,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
| 217 | * nop | 217 | * nop |
| 218 | */ | 218 | */ |
| 219 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 219 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
| 220 | #define TIF_RESTORE_SIGMASK 1 /* restore signal mask in do_signal() */ | 220 | /* flags bit 1 is available */ |
| 221 | #define TIF_SIGPENDING 2 /* signal pending */ | 221 | #define TIF_SIGPENDING 2 /* signal pending */ |
| 222 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | 222 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
| 223 | #define TIF_PERFCTR 4 /* performance counters active */ | 223 | #define TIF_PERFCTR 4 /* performance counters active */ |
| @@ -244,14 +244,34 @@ register struct thread_info *current_thread_info_reg asm("g6"); | |||
| 244 | #define _TIF_32BIT (1<<TIF_32BIT) | 244 | #define _TIF_32BIT (1<<TIF_32BIT) |
| 245 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) | 245 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) |
| 246 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 246 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
| 247 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | ||
| 248 | #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) | 247 | #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) |
| 249 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 248 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
| 250 | 249 | ||
| 251 | #define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ | 250 | #define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ |
| 252 | (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | \ | 251 | (_TIF_SIGPENDING | \ |
| 253 | _TIF_NEED_RESCHED | _TIF_PERFCTR)) | 252 | _TIF_NEED_RESCHED | _TIF_PERFCTR)) |
| 254 | 253 | ||
| 254 | /* | ||
| 255 | * Thread-synchronous status. | ||
| 256 | * | ||
| 257 | * This is different from the flags in that nobody else | ||
| 258 | * ever touches our thread-synchronous status, so we don't | ||
| 259 | * have to worry about atomic accesses. | ||
| 260 | * | ||
| 261 | * Note that there are only 8 bits available. | ||
| 262 | */ | ||
| 263 | #define TS_RESTORE_SIGMASK 0x0001 /* restore signal mask in do_signal() */ | ||
| 264 | |||
| 265 | #ifndef __ASSEMBLY__ | ||
| 266 | #define HAVE_SET_RESTORE_SIGMASK 1 | ||
| 267 | static inline void set_restore_sigmask(void) | ||
| 268 | { | ||
| 269 | struct thread_info *ti = current_thread_info(); | ||
| 270 | ti->status |= TS_RESTORE_SIGMASK; | ||
| 271 | set_bit(TIF_SIGPENDING, &ti->flags); | ||
| 272 | } | ||
| 273 | #endif /* !__ASSEMBLY__ */ | ||
| 274 | |||
| 255 | #endif /* __KERNEL__ */ | 275 | #endif /* __KERNEL__ */ |
| 256 | 276 | ||
| 257 | #endif /* _ASM_THREAD_INFO_H */ | 277 | #endif /* _ASM_THREAD_INFO_H */ |
