aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-04-29 04:43:50 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-02-03 18:16:02 -0500
commite9f9252667e383c0ccfd3570b358ccb72cd51359 (patch)
treeb4df1eecc63538399cc9781bf2430bb3ec6e94b6 /arch/microblaze
parent14203e19cbc562a79f49117c45c80639a1e65bdd (diff)
microblaze: fix handling of multiple pending signals
We need to keep building sigframes until no pending signals remain. Wrap do_notify_resume() calls into loops; do _not_ allow syscall restart logics to trigger after the first iteration. Incidentally, comments about pending signals that should (somehow) be in r18 are pure BS. Doesn't work that way and cannot work that way, sorry... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/kernel/entry-nommu.S13
-rw-r--r--arch/microblaze/kernel/entry.S58
2 files changed, 42 insertions, 29 deletions
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index 96f97f845495..7e394fc2c439 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -124,6 +124,7 @@ ret_from_intr:
124 lwi r11, r1, PT_MODE 124 lwi r11, r1, PT_MODE
125 bneid r11, no_intr_resched 125 bneid r11, no_intr_resched
126 126
1273:
127 lwi r6, r31, TS_THREAD_INFO /* get thread info */ 128 lwi r6, r31, TS_THREAD_INFO /* get thread info */
128 lwi r19, r6, TI_FLAGS /* get flags in thread info */ 129 lwi r19, r6, TI_FLAGS /* get flags in thread info */
129 /* do an extra work if any bits are set */ 130 /* do an extra work if any bits are set */
@@ -132,11 +133,13 @@ ret_from_intr:
132 beqi r11, 1f 133 beqi r11, 1f
133 bralid r15, schedule 134 bralid r15, schedule
134 nop 135 nop
136 bri 3b
1351: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME 1371: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
136 beqid r11, no_intr_resched 138 beqid r11, no_intr_resched
137 addk r5, r1, r0 139 addk r5, r1, r0
138 bralid r15, do_notify_resume 140 bralid r15, do_notify_resume
139 addk r6, r0, r0 141 addk r6, r0, r0
142 bri 3b
140 143
141no_intr_resched: 144no_intr_resched:
142 /* Disable interrupts, we are now committed to the state restore */ 145 /* Disable interrupts, we are now committed to the state restore */
@@ -486,18 +489,24 @@ ENTRY(ret_from_kernel_thread)
486work_pending: 489work_pending:
487 lwi r11, r1, PT_MODE 490 lwi r11, r1, PT_MODE
488 bneid r11, 2f 491 bneid r11, 2f
4923:
489 enable_irq 493 enable_irq
490
491 andi r11, r19, _TIF_NEED_RESCHED 494 andi r11, r19, _TIF_NEED_RESCHED
492 beqi r11, 1f 495 beqi r11, 1f
493 bralid r15, schedule 496 bralid r15, schedule
494 nop 497 nop
498 bri 4f
4951: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME 4991: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
496 beqi r11, no_work_pending 500 beqi r11, no_work_pending
497 addk r5, r30, r0 501 addk r5, r30, r0
498 bralid r15, do_notify_resume 502 bralid r15, do_notify_resume
499 addik r6, r0, 1 503 addik r6, r0, 1
500 bri no_work_pending 504 addk r30, r0, r0 /* no restarts from now on */
5054:
506 disable_irq
507 lwi r6, r31, TS_THREAD_INFO /* get thread info */
508 lwi r19, r6, TI_FLAGS /* get flags in thread info */
509 bri 3b
501 510
502ENTRY(ret_to_user) 511ENTRY(ret_to_user)
503 disable_irq 512 disable_irq
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 18908d29248b..85b6b5d80c99 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -402,26 +402,27 @@ C_ENTRY(ret_from_trap):
402 * trigger rescheduling. */ 402 * trigger rescheduling. */
403 /* get thread info from current task */ 403 /* get thread info from current task */
404 lwi r11, CURRENT_TASK, TS_THREAD_INFO; 404 lwi r11, CURRENT_TASK, TS_THREAD_INFO;
405 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 405 lwi r19, r11, TI_FLAGS; /* get flags in thread info */
406 andi r11, r11, _TIF_NEED_RESCHED; 406 andi r11, r19, _TIF_NEED_RESCHED;
407 beqi r11, 5f; 407 beqi r11, 5f;
408 408
409 bralid r15, schedule; /* Call scheduler */ 409 bralid r15, schedule; /* Call scheduler */
410 nop; /* delay slot */ 410 nop; /* delay slot */
411 bri 1b
411 412
412 /* Maybe handle a signal */ 413 /* Maybe handle a signal */
4135: /* get thread info from current task*/ 4145:
414 lwi r11, CURRENT_TASK, TS_THREAD_INFO; 415 andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
415 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 416 beqi r11, 4f; /* Signals to handle, handle them */
416 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
417 beqi r11, 1f; /* Signals to handle, handle them */
418 417
419 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 418 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
420 bralid r15, do_notify_resume; /* Handle any signals */ 419 bralid r15, do_notify_resume; /* Handle any signals */
421 add r6, r30, r0; /* Arg 2: int in_syscall */ 420 add r6, r30, r0; /* Arg 2: int in_syscall */
421 add r30, r0, r0 /* no more restarts */
422 bri 1b
422 423
423/* Finally, return to user state. */ 424/* Finally, return to user state. */
4241: set_bip; /* Ints masked for state restore */ 4254: set_bip; /* Ints masked for state restore */
425 swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ 426 swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
426 VM_OFF; 427 VM_OFF;
427 tophys(r1,r1); 428 tophys(r1,r1);
@@ -573,20 +574,20 @@ C_ENTRY(ret_from_exc):
573 574
574 /* We're returning to user mode, so check for various conditions that 575 /* We're returning to user mode, so check for various conditions that
575 trigger rescheduling. */ 576 trigger rescheduling. */
5771:
576 lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 578 lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
577 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 579 lwi r19, r11, TI_FLAGS; /* get flags in thread info */
578 andi r11, r11, _TIF_NEED_RESCHED; 580 andi r11, r19, _TIF_NEED_RESCHED;
579 beqi r11, 5f; 581 beqi r11, 5f;
580 582
581/* Call the scheduler before returning from a syscall/trap. */ 583/* Call the scheduler before returning from a syscall/trap. */
582 bralid r15, schedule; /* Call scheduler */ 584 bralid r15, schedule; /* Call scheduler */
583 nop; /* delay slot */ 585 nop; /* delay slot */
586 bri 1b
584 587
585 /* Maybe handle a signal */ 588 /* Maybe handle a signal */
5865: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 5895: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
587 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 590 beqi r11, 4f; /* Signals to handle, handle them */
588 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
589 beqi r11, 1f; /* Signals to handle, handle them */
590 591
591 /* 592 /*
592 * Handle a signal return; Pending signals should be in r18. 593 * Handle a signal return; Pending signals should be in r18.
@@ -602,9 +603,10 @@ C_ENTRY(ret_from_exc):
602 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 603 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
603 bralid r15, do_notify_resume; /* Handle any signals */ 604 bralid r15, do_notify_resume; /* Handle any signals */
604 addi r6, r0, 0; /* Arg 2: int in_syscall */ 605 addi r6, r0, 0; /* Arg 2: int in_syscall */
606 bri 1b
605 607
606/* Finally, return to user state. */ 608/* Finally, return to user state. */
6071: set_bip; /* Ints masked for state restore */ 6094: set_bip; /* Ints masked for state restore */
608 swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ 610 swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
609 VM_OFF; 611 VM_OFF;
610 tophys(r1,r1); 612 tophys(r1,r1);
@@ -684,22 +686,23 @@ ret_from_irq:
684 lwi r11, r1, PT_MODE; 686 lwi r11, r1, PT_MODE;
685 bnei r11, 2f; 687 bnei r11, 2f;
686 688
6891:
687 lwi r11, CURRENT_TASK, TS_THREAD_INFO; 690 lwi r11, CURRENT_TASK, TS_THREAD_INFO;
688 lwi r11, r11, TI_FLAGS; /* MS: get flags from thread info */ 691 lwi r19, r11, TI_FLAGS; /* MS: get flags from thread info */
689 andi r11, r11, _TIF_NEED_RESCHED; 692 andi r11, r19, _TIF_NEED_RESCHED;
690 beqi r11, 5f 693 beqi r11, 5f
691 bralid r15, schedule; 694 bralid r15, schedule;
692 nop; /* delay slot */ 695 nop; /* delay slot */
696 bri 1b
693 697
694 /* Maybe handle a signal */ 698 /* Maybe handle a signal */
6955: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */ 6995: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
696 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
697 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
698 beqid r11, no_intr_resched 700 beqid r11, no_intr_resched
699/* Handle a signal return; Pending signals should be in r18. */ 701/* Handle a signal return; Pending signals should be in r18. */
700 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 702 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
701 bralid r15, do_notify_resume; /* Handle any signals */ 703 bralid r15, do_notify_resume; /* Handle any signals */
702 addi r6, r0, 0; /* Arg 2: int in_syscall */ 704 addi r6, r0, 0; /* Arg 2: int in_syscall */
705 bri 1b
703 706
704/* Finally, return to user state. */ 707/* Finally, return to user state. */
705no_intr_resched: 708no_intr_resched:
@@ -817,28 +820,29 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
817 lwi r11, r1, PT_MODE; 820 lwi r11, r1, PT_MODE;
818 bnei r11, 2f; 821 bnei r11, 2f;
819/* MS: Return to user space - gdb */ 822/* MS: Return to user space - gdb */
8231:
820 /* Get current task ptr into r11 */ 824 /* Get current task ptr into r11 */
821 lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 825 lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
822 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 826 lwi r19, r11, TI_FLAGS; /* get flags in thread info */
823 andi r11, r11, _TIF_NEED_RESCHED; 827 andi r11, r19, _TIF_NEED_RESCHED;
824 beqi r11, 5f; 828 beqi r11, 5f;
825 829
826 /* Call the scheduler before returning from a syscall/trap. */ 830 /* Call the scheduler before returning from a syscall/trap. */
827 bralid r15, schedule; /* Call scheduler */ 831 bralid r15, schedule; /* Call scheduler */
828 nop; /* delay slot */ 832 nop; /* delay slot */
833 bri 1b
829 834
830 /* Maybe handle a signal */ 835 /* Maybe handle a signal */
8315: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 8365: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
832 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 837 beqi r11, 4f; /* Signals to handle, handle them */
833 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
834 beqi r11, 1f; /* Signals to handle, handle them */
835 838
836 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 839 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
837 bralid r15, do_notify_resume; /* Handle any signals */ 840 bralid r15, do_notify_resume; /* Handle any signals */
838 addi r6, r0, 0; /* Arg 2: int in_syscall */ 841 addi r6, r0, 0; /* Arg 2: int in_syscall */
842 bri 1b
839 843
840/* Finally, return to user state. */ 844/* Finally, return to user state. */
8411: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ 8454: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
842 VM_OFF; 846 VM_OFF;
843 tophys(r1,r1); 847 tophys(r1,r1);
844 /* MS: Restore all regs */ 848 /* MS: Restore all regs */