diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2012-04-24 02:03:06 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-21 23:59:47 -0400 |
| commit | 969a96168091f837645a674a9f7ed1a9aaa1424b (patch) | |
| tree | 30b589d6a925bf7bef1528566a03321782d711d1 /arch/microblaze/kernel | |
| parent | 1d5d4dbe810befe63e79b2d6cdcad2066e3b1fc4 (diff) | |
microblaze: handle TIF_NOTIFY_RESUME
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/microblaze/kernel')
| -rw-r--r-- | arch/microblaze/kernel/entry-nommu.S | 12 | ||||
| -rw-r--r-- | arch/microblaze/kernel/entry.S | 18 | ||||
| -rw-r--r-- | arch/microblaze/kernel/signal.c | 34 |
3 files changed, 38 insertions, 26 deletions
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S index f104d276b80..ea2dd42fdc2 100644 --- a/arch/microblaze/kernel/entry-nommu.S +++ b/arch/microblaze/kernel/entry-nommu.S | |||
| @@ -132,11 +132,11 @@ ret_from_intr: | |||
| 132 | beqi r11, 1f | 132 | beqi r11, 1f |
| 133 | bralid r15, schedule | 133 | bralid r15, schedule |
| 134 | nop | 134 | nop |
| 135 | 1: andi r11, r19, _TIF_SIGPENDING | 135 | 1: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME |
| 136 | beqid r11, no_intr_resched | 136 | beqid r11, no_intr_resched |
| 137 | addk r5, r1, r0 | 137 | addk r5, r1, r0 |
| 138 | addk r7, r0, r0 | 138 | addk r7, r0, r0 |
| 139 | bralid r15, do_signal | 139 | bralid r15, do_notify_resume |
| 140 | addk r6, r0, r0 | 140 | addk r6, r0, r0 |
| 141 | 141 | ||
| 142 | no_intr_resched: | 142 | no_intr_resched: |
| @@ -292,8 +292,8 @@ ENTRY(_user_exception) | |||
| 292 | 292 | ||
| 293 | /* | 293 | /* |
| 294 | * Debug traps are like a system call, but entered via brki r14, 0x60 | 294 | * Debug traps are like a system call, but entered via brki r14, 0x60 |
| 295 | * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal | 295 | * All we need to do is send the SIGTRAP signal to current, ptrace and |
| 296 | * will handle the rest | 296 | * do_notify_resume will handle the rest |
| 297 | */ | 297 | */ |
| 298 | ENTRY(_debug_exception) | 298 | ENTRY(_debug_exception) |
| 299 | swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | 299 | swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ |
| @@ -482,11 +482,11 @@ work_pending: | |||
| 482 | beqi r11, 1f | 482 | beqi r11, 1f |
| 483 | bralid r15, schedule | 483 | bralid r15, schedule |
| 484 | nop | 484 | nop |
| 485 | 1: andi r11, r19, _TIF_SIGPENDING | 485 | 1: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME |
| 486 | beqi r11, no_work_pending | 486 | beqi r11, no_work_pending |
| 487 | addk r5, r1, r0 | 487 | addk r5, r1, r0 |
| 488 | addik r7, r0, 1 | 488 | addik r7, r0, 1 |
| 489 | bralid r15, do_signal | 489 | bralid r15, do_notify_resume |
| 490 | addk r6, r0, r0 | 490 | addk r6, r0, r0 |
| 491 | bri no_work_pending | 491 | bri no_work_pending |
| 492 | 492 | ||
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 66e34a3bfe1..3cee9130a39 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S | |||
| @@ -430,12 +430,12 @@ C_ENTRY(ret_from_trap): | |||
| 430 | 5: /* get thread info from current task*/ | 430 | 5: /* get thread info from current task*/ |
| 431 | lwi r11, CURRENT_TASK, TS_THREAD_INFO; | 431 | lwi r11, CURRENT_TASK, TS_THREAD_INFO; |
| 432 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ | 432 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ |
| 433 | andi r11, r11, _TIF_SIGPENDING; | 433 | andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME; |
| 434 | beqi r11, 1f; /* Signals to handle, handle them */ | 434 | beqi r11, 1f; /* Signals to handle, handle them */ |
| 435 | 435 | ||
| 436 | addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ | 436 | addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ |
| 437 | addi r7, r0, 1; /* Arg 3: int in_syscall */ | 437 | addi r7, r0, 1; /* Arg 3: int in_syscall */ |
| 438 | bralid r15, do_signal; /* Handle any signals */ | 438 | bralid r15, do_notify_resume; /* Handle any signals */ |
| 439 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ | 439 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ |
| 440 | 440 | ||
| 441 | /* Finally, return to user state. */ | 441 | /* Finally, return to user state. */ |
| @@ -622,7 +622,7 @@ C_ENTRY(ret_from_exc): | |||
| 622 | /* Maybe handle a signal */ | 622 | /* Maybe handle a signal */ |
| 623 | 5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ | 623 | 5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ |
| 624 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ | 624 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ |
| 625 | andi r11, r11, _TIF_SIGPENDING; | 625 | andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME; |
| 626 | beqi r11, 1f; /* Signals to handle, handle them */ | 626 | beqi r11, 1f; /* Signals to handle, handle them */ |
| 627 | 627 | ||
| 628 | /* | 628 | /* |
| @@ -635,10 +635,10 @@ C_ENTRY(ret_from_exc): | |||
| 635 | * traps), but signal handlers may want to examine or change the | 635 | * traps), but signal handlers may want to examine or change the |
| 636 | * complete register state. Here we save anything not saved by | 636 | * complete register state. Here we save anything not saved by |
| 637 | * the normal entry sequence, so that it may be safely restored | 637 | * the normal entry sequence, so that it may be safely restored |
| 638 | * (in a possibly modified form) after do_signal returns. */ | 638 | * (in a possibly modified form) after do_notify_resume returns. */ |
| 639 | addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ | 639 | addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ |
| 640 | addi r7, r0, 0; /* Arg 3: int in_syscall */ | 640 | addi r7, r0, 0; /* Arg 3: int in_syscall */ |
| 641 | bralid r15, do_signal; /* Handle any signals */ | 641 | bralid r15, do_notify_resume; /* Handle any signals */ |
| 642 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ | 642 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ |
| 643 | 643 | ||
| 644 | /* Finally, return to user state. */ | 644 | /* Finally, return to user state. */ |
| @@ -732,12 +732,12 @@ ret_from_irq: | |||
| 732 | /* Maybe handle a signal */ | 732 | /* Maybe handle a signal */ |
| 733 | 5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */ | 733 | 5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */ |
| 734 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ | 734 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ |
| 735 | andi r11, r11, _TIF_SIGPENDING; | 735 | andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME; |
| 736 | beqid r11, no_intr_resched | 736 | beqid r11, no_intr_resched |
| 737 | /* Handle a signal return; Pending signals should be in r18. */ | 737 | /* Handle a signal return; Pending signals should be in r18. */ |
| 738 | addi r7, r0, 0; /* Arg 3: int in_syscall */ | 738 | addi r7, r0, 0; /* Arg 3: int in_syscall */ |
| 739 | addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ | 739 | addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ |
| 740 | bralid r15, do_signal; /* Handle any signals */ | 740 | bralid r15, do_notify_resume; /* Handle any signals */ |
| 741 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ | 741 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ |
| 742 | 742 | ||
| 743 | /* Finally, return to user state. */ | 743 | /* Finally, return to user state. */ |
| @@ -869,12 +869,12 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */ | |||
| 869 | /* Maybe handle a signal */ | 869 | /* Maybe handle a signal */ |
| 870 | 5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ | 870 | 5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ |
| 871 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ | 871 | lwi r11, r11, TI_FLAGS; /* get flags in thread info */ |
| 872 | andi r11, r11, _TIF_SIGPENDING; | 872 | andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME; |
| 873 | beqi r11, 1f; /* Signals to handle, handle them */ | 873 | beqi r11, 1f; /* Signals to handle, handle them */ |
| 874 | 874 | ||
| 875 | addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ | 875 | addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ |
| 876 | addi r7, r0, 0; /* Arg 3: int in_syscall */ | 876 | addi r7, r0, 0; /* Arg 3: int in_syscall */ |
| 877 | bralid r15, do_signal; /* Handle any signals */ | 877 | bralid r15, do_notify_resume; /* Handle any signals */ |
| 878 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ | 878 | add r6, r0, r0; /* Arg 2: sigset_t *oldset */ |
| 879 | 879 | ||
| 880 | /* Finally, return to user state. */ | 880 | /* Finally, return to user state. */ |
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c index fbdb0264182..449886db35a 100644 --- a/arch/microblaze/kernel/signal.c +++ b/arch/microblaze/kernel/signal.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/personality.h> | 31 | #include <linux/personality.h> |
| 32 | #include <linux/percpu.h> | 32 | #include <linux/percpu.h> |
| 33 | #include <linux/linkage.h> | 33 | #include <linux/linkage.h> |
| 34 | #include <linux/tracehook.h> | ||
| 34 | #include <asm/entry.h> | 35 | #include <asm/entry.h> |
| 35 | #include <asm/ucontext.h> | 36 | #include <asm/ucontext.h> |
| 36 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
| @@ -42,8 +43,6 @@ | |||
| 42 | 43 | ||
| 43 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 44 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
| 44 | 45 | ||
| 45 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall); | ||
| 46 | |||
| 47 | asmlinkage long | 46 | asmlinkage long |
| 48 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 47 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
| 49 | struct pt_regs *regs) | 48 | struct pt_regs *regs) |
| @@ -340,7 +339,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
| 340 | * the kernel can handle, and then we build all the user-level signal handling | 339 | * the kernel can handle, and then we build all the user-level signal handling |
| 341 | * stack-frames in one go after that. | 340 | * stack-frames in one go after that. |
| 342 | */ | 341 | */ |
| 343 | int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) | 342 | static int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) |
| 344 | { | 343 | { |
| 345 | siginfo_t info; | 344 | siginfo_t info; |
| 346 | int signr; | 345 | int signr; |
| @@ -350,14 +349,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) | |||
| 350 | printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1, | 349 | printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1, |
| 351 | regs->r12, current_thread_info()->flags); | 350 | regs->r12, current_thread_info()->flags); |
| 352 | #endif | 351 | #endif |
| 353 | /* | ||
| 354 | * We want the common case to go fast, which | ||
| 355 | * is why we may in certain cases get here from | ||
| 356 | * kernel mode. Just return without doing anything | ||
| 357 | * if so. | ||
| 358 | */ | ||
| 359 | if (kernel_mode(regs)) | ||
| 360 | return 1; | ||
| 361 | 352 | ||
| 362 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) | 353 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) |
| 363 | oldset = ¤t->saved_sigmask; | 354 | oldset = ¤t->saved_sigmask; |
| @@ -397,3 +388,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) | |||
| 397 | /* Did we come from a system call? */ | 388 | /* Did we come from a system call? */ |
| 398 | return 0; | 389 | return 0; |
| 399 | } | 390 | } |
| 391 | |||
| 392 | void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, int in_syscall) | ||
| 393 | { | ||
| 394 | /* | ||
| 395 | * We want the common case to go fast, which | ||
| 396 | * is why we may in certain cases get here from | ||
| 397 | * kernel mode. Just return without doing anything | ||
| 398 | * if so. | ||
| 399 | */ | ||
| 400 | if (kernel_mode(regs)) | ||
| 401 | return; | ||
| 402 | |||
| 403 | if (test_thread_flag(TIF_SIGPENDING)) | ||
| 404 | do_signal(regs, oldset, in_syscall); | ||
| 405 | |||
| 406 | if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) { | ||
| 407 | tracehook_notify_resume(regs); | ||
| 408 | if (current->replacement_session_keyring) | ||
| 409 | key_replace_session_keyring(); | ||
| 410 | } | ||
| 411 | } | ||
