diff options
| author | David Woodhouse <dwmw2@infradead.org> | 2006-01-18 20:44:01 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-18 22:20:30 -0500 |
| commit | f27201da5c8f118cfe266f51447bdd108d5f081d (patch) | |
| tree | 9d889f4afec179b5b6f422b58dd36fa7606f3eee | |
| parent | 283828f3c19ceb3a64a8544d42cc189003e8b0fe (diff) | |
[PATCH] TIF_RESTORE_SIGMASK support for arch/powerpc
Implement the TIF_RESTORE_SIGMASK flag in the new arch/powerpc kernel, for
both 32-bit and 64-bit system call paths.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | arch/powerpc/kernel/entry_32.S | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/entry_64.S | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/signal_32.c | 20 | ||||
| -rw-r--r-- | arch/powerpc/kernel/signal_64.c | 20 | ||||
| -rw-r--r-- | arch/powerpc/kernel/systbl.S | 2 | ||||
| -rw-r--r-- | include/asm-powerpc/thread_info.h | 5 | ||||
| -rw-r--r-- | include/asm-powerpc/unistd.h | 4 |
7 files changed, 47 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index d8da2a35c0a4..f20a67261ec7 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
| @@ -227,7 +227,7 @@ ret_from_syscall: | |||
| 227 | MTMSRD(r10) | 227 | MTMSRD(r10) |
| 228 | lwz r9,TI_FLAGS(r12) | 228 | lwz r9,TI_FLAGS(r12) |
| 229 | li r8,-_LAST_ERRNO | 229 | li r8,-_LAST_ERRNO |
| 230 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) | 230 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK) |
| 231 | bne- syscall_exit_work | 231 | bne- syscall_exit_work |
| 232 | cmplw 0,r3,r8 | 232 | cmplw 0,r3,r8 |
| 233 | blt+ syscall_exit_cont | 233 | blt+ syscall_exit_cont |
| @@ -357,7 +357,7 @@ save_user_nvgprs_cont: | |||
| 357 | lwz r5,_MSR(r1) | 357 | lwz r5,_MSR(r1) |
| 358 | andi. r5,r5,MSR_PR | 358 | andi. r5,r5,MSR_PR |
| 359 | beq ret_from_except | 359 | beq ret_from_except |
| 360 | andi. r0,r9,_TIF_SIGPENDING | 360 | andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK |
| 361 | beq ret_from_except | 361 | beq ret_from_except |
| 362 | b do_user_signal | 362 | b do_user_signal |
| 363 | 8: | 363 | 8: |
| @@ -683,7 +683,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ | |||
| 683 | /* Check current_thread_info()->flags */ | 683 | /* Check current_thread_info()->flags */ |
| 684 | rlwinm r9,r1,0,0,(31-THREAD_SHIFT) | 684 | rlwinm r9,r1,0,0,(31-THREAD_SHIFT) |
| 685 | lwz r9,TI_FLAGS(r9) | 685 | lwz r9,TI_FLAGS(r9) |
| 686 | andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) | 686 | andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK) |
| 687 | bne do_work | 687 | bne do_work |
| 688 | 688 | ||
| 689 | restore_user: | 689 | restore_user: |
| @@ -917,7 +917,7 @@ recheck: | |||
| 917 | lwz r9,TI_FLAGS(r9) | 917 | lwz r9,TI_FLAGS(r9) |
| 918 | andi. r0,r9,_TIF_NEED_RESCHED | 918 | andi. r0,r9,_TIF_NEED_RESCHED |
| 919 | bne- do_resched | 919 | bne- do_resched |
| 920 | andi. r0,r9,_TIF_SIGPENDING | 920 | andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK |
| 921 | beq restore_user | 921 | beq restore_user |
| 922 | do_user_signal: /* r10 contains MSR_KERNEL here */ | 922 | do_user_signal: /* r10 contains MSR_KERNEL here */ |
| 923 | ori r10,r10,MSR_EE | 923 | ori r10,r10,MSR_EE |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 542036318866..388f861b8ed1 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
| @@ -160,7 +160,7 @@ syscall_exit: | |||
| 160 | mtmsrd r10,1 | 160 | mtmsrd r10,1 |
| 161 | ld r9,TI_FLAGS(r12) | 161 | ld r9,TI_FLAGS(r12) |
| 162 | li r11,-_LAST_ERRNO | 162 | li r11,-_LAST_ERRNO |
| 163 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR) | 163 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR|_TIF_RESTORE_SIGMASK) |
| 164 | bne- syscall_exit_work | 164 | bne- syscall_exit_work |
| 165 | cmpld r3,r11 | 165 | cmpld r3,r11 |
| 166 | ld r5,_CCR(r1) | 166 | ld r5,_CCR(r1) |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 7f0d5ce2567d..3747ab0dac3f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
| @@ -1128,7 +1128,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
| 1128 | { | 1128 | { |
| 1129 | siginfo_t info; | 1129 | siginfo_t info; |
| 1130 | struct k_sigaction ka; | 1130 | struct k_sigaction ka; |
| 1131 | unsigned int frame, newsp; | 1131 | unsigned int newsp; |
| 1132 | int signr, ret; | 1132 | int signr, ret; |
| 1133 | 1133 | ||
| 1134 | #ifdef CONFIG_PPC32 | 1134 | #ifdef CONFIG_PPC32 |
| @@ -1139,11 +1139,11 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
| 1139 | } | 1139 | } |
| 1140 | #endif | 1140 | #endif |
| 1141 | 1141 | ||
| 1142 | if (!oldset) | 1142 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
| 1143 | oldset = ¤t->saved_sigmask; | ||
| 1144 | else if (!oldset) | ||
| 1143 | oldset = ¤t->blocked; | 1145 | oldset = ¤t->blocked; |
| 1144 | 1146 | ||
| 1145 | newsp = frame = 0; | ||
| 1146 | |||
| 1147 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 1147 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
| 1148 | #ifdef CONFIG_PPC32 | 1148 | #ifdef CONFIG_PPC32 |
| 1149 | no_signal: | 1149 | no_signal: |
| @@ -1173,8 +1173,14 @@ no_signal: | |||
| 1173 | } | 1173 | } |
| 1174 | } | 1174 | } |
| 1175 | 1175 | ||
| 1176 | if (signr == 0) | 1176 | if (signr == 0) { |
| 1177 | /* No signal to deliver -- put the saved sigmask back */ | ||
| 1178 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
| 1179 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 1180 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
| 1181 | } | ||
| 1177 | return 0; /* no signals delivered */ | 1182 | return 0; /* no signals delivered */ |
| 1183 | } | ||
| 1178 | 1184 | ||
| 1179 | if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size | 1185 | if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size |
| 1180 | && !on_sig_stack(regs->gpr[1])) | 1186 | && !on_sig_stack(regs->gpr[1])) |
| @@ -1207,6 +1213,10 @@ no_signal: | |||
| 1207 | sigaddset(¤t->blocked, signr); | 1213 | sigaddset(¤t->blocked, signr); |
| 1208 | recalc_sigpending(); | 1214 | recalc_sigpending(); |
| 1209 | spin_unlock_irq(¤t->sighand->siglock); | 1215 | spin_unlock_irq(¤t->sighand->siglock); |
| 1216 | /* A signal was successfully delivered; the saved sigmask is in | ||
| 1217 | its frame, and we can clear the TIF_RESTORE_SIGMASK flag */ | ||
| 1218 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 1219 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 1210 | } | 1220 | } |
| 1211 | 1221 | ||
| 1212 | return ret; | 1222 | return ret; |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index a4a6812e815e..b3193116e686 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
| @@ -520,11 +520,15 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
| 520 | if (test_thread_flag(TIF_32BIT)) | 520 | if (test_thread_flag(TIF_32BIT)) |
| 521 | return do_signal32(oldset, regs); | 521 | return do_signal32(oldset, regs); |
| 522 | 522 | ||
| 523 | if (!oldset) | 523 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
| 524 | oldset = ¤t->saved_sigmask; | ||
| 525 | else if (!oldset) | ||
| 524 | oldset = ¤t->blocked; | 526 | oldset = ¤t->blocked; |
| 525 | 527 | ||
| 526 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 528 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
| 527 | if (signr > 0) { | 529 | if (signr > 0) { |
| 530 | int ret; | ||
| 531 | |||
| 528 | /* Whee! Actually deliver the signal. */ | 532 | /* Whee! Actually deliver the signal. */ |
| 529 | if (TRAP(regs) == 0x0C00) | 533 | if (TRAP(regs) == 0x0C00) |
| 530 | syscall_restart(regs, &ka); | 534 | syscall_restart(regs, &ka); |
| @@ -537,7 +541,14 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
| 537 | if (current->thread.dabr) | 541 | if (current->thread.dabr) |
| 538 | set_dabr(current->thread.dabr); | 542 | set_dabr(current->thread.dabr); |
| 539 | 543 | ||
| 540 | return handle_signal(signr, &ka, &info, oldset, regs); | 544 | ret = handle_signal(signr, &ka, &info, oldset, regs); |
| 545 | |||
| 546 | /* If a signal was successfully delivered, the saved sigmask is in | ||
| 547 | its frame, and we can clear the TIF_RESTORE_SIGMASK flag */ | ||
| 548 | if (ret && test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 549 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 550 | |||
| 551 | return ret; | ||
| 541 | } | 552 | } |
| 542 | 553 | ||
| 543 | if (TRAP(regs) == 0x0C00) { /* System Call! */ | 554 | if (TRAP(regs) == 0x0C00) { /* System Call! */ |
| @@ -553,6 +564,11 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
| 553 | regs->result = 0; | 564 | regs->result = 0; |
| 554 | } | 565 | } |
| 555 | } | 566 | } |
| 567 | /* No signal to deliver -- put the saved sigmask back */ | ||
| 568 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
| 569 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 570 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
| 571 | } | ||
| 556 | 572 | ||
| 557 | return 0; | 573 | return 0; |
| 558 | } | 574 | } |
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 68013179a503..007b15ee36d2 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S | |||
| @@ -321,3 +321,5 @@ SYSCALL(inotify_add_watch) | |||
| 321 | SYSCALL(inotify_rm_watch) | 321 | SYSCALL(inotify_rm_watch) |
| 322 | SYSCALL(spu_run) | 322 | SYSCALL(spu_run) |
| 323 | SYSCALL(spu_create) | 323 | SYSCALL(spu_create) |
| 324 | COMPAT_SYS(pselect6) | ||
| 325 | COMPAT_SYS(ppoll) | ||
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index 7e09d7cda933..67cdaf3ae9fc 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h | |||
| @@ -122,6 +122,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 122 | #define TIF_RESTOREALL 12 /* Restore all regs (implies NOERROR) */ | 122 | #define TIF_RESTOREALL 12 /* Restore all regs (implies NOERROR) */ |
| 123 | #define TIF_SAVE_NVGPRS 13 /* Save r14-r31 in signal frame */ | 123 | #define TIF_SAVE_NVGPRS 13 /* Save r14-r31 in signal frame */ |
| 124 | #define TIF_NOERROR 14 /* Force successful syscall return */ | 124 | #define TIF_NOERROR 14 /* Force successful syscall return */ |
| 125 | #define TIF_RESTORE_SIGMASK 15 /* Restore signal mask in do_signal */ | ||
| 125 | 126 | ||
| 126 | /* as above, but as bit values */ | 127 | /* as above, but as bit values */ |
| 127 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 128 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
| @@ -138,10 +139,12 @@ static inline struct thread_info *current_thread_info(void) | |||
| 138 | #define _TIF_RESTOREALL (1<<TIF_RESTOREALL) | 139 | #define _TIF_RESTOREALL (1<<TIF_RESTOREALL) |
| 139 | #define _TIF_SAVE_NVGPRS (1<<TIF_SAVE_NVGPRS) | 140 | #define _TIF_SAVE_NVGPRS (1<<TIF_SAVE_NVGPRS) |
| 140 | #define _TIF_NOERROR (1<<TIF_NOERROR) | 141 | #define _TIF_NOERROR (1<<TIF_NOERROR) |
| 142 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | ||
| 141 | #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP) | 143 | #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP) |
| 142 | 144 | ||
| 143 | #define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ | 145 | #define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ |
| 144 | _TIF_NEED_RESCHED | _TIF_RESTOREALL) | 146 | _TIF_NEED_RESCHED | _TIF_RESTOREALL | \ |
| 147 | _TIF_RESTORE_SIGMASK) | ||
| 145 | #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR|_TIF_SAVE_NVGPRS) | 148 | #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR|_TIF_SAVE_NVGPRS) |
| 146 | 149 | ||
| 147 | #endif /* __KERNEL__ */ | 150 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index 76daec496062..a40cdff21a88 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h | |||
| @@ -298,8 +298,10 @@ | |||
| 298 | #define __NR_inotify_rm_watch 277 | 298 | #define __NR_inotify_rm_watch 277 |
| 299 | #define __NR_spu_run 278 | 299 | #define __NR_spu_run 278 |
| 300 | #define __NR_spu_create 279 | 300 | #define __NR_spu_create 279 |
| 301 | #define __NR_pselect6 280 | ||
| 302 | #define __NR_ppoll 281 | ||
| 301 | 303 | ||
| 302 | #define __NR_syscalls 280 | 304 | #define __NR_syscalls 282 |
| 303 | 305 | ||
| 304 | #ifdef __KERNEL__ | 306 | #ifdef __KERNEL__ |
| 305 | #define __NR__exit __NR_exit | 307 | #define __NR__exit __NR_exit |
