diff options
| -rw-r--r-- | arch/powerpc/kernel/entry_64.S | 97 |
1 files changed, 40 insertions, 57 deletions
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index ed1718feb9d9..5971c85df136 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
| @@ -558,27 +558,54 @@ _GLOBAL(ret_from_except_lite) | |||
| 558 | mtmsrd r10,1 /* Update machine state */ | 558 | mtmsrd r10,1 /* Update machine state */ |
| 559 | #endif /* CONFIG_PPC_BOOK3E */ | 559 | #endif /* CONFIG_PPC_BOOK3E */ |
| 560 | 560 | ||
| 561 | #ifdef CONFIG_PREEMPT | ||
| 562 | clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ | 561 | clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ |
| 563 | li r0,_TIF_NEED_RESCHED /* bits to check */ | ||
| 564 | ld r3,_MSR(r1) | 562 | ld r3,_MSR(r1) |
| 565 | ld r4,TI_FLAGS(r9) | 563 | ld r4,TI_FLAGS(r9) |
| 566 | /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */ | ||
| 567 | rlwimi r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING | ||
| 568 | and. r0,r4,r0 /* check NEED_RESCHED and maybe SIGPENDING */ | ||
| 569 | bne do_work | ||
| 570 | |||
| 571 | #else /* !CONFIG_PREEMPT */ | ||
| 572 | ld r3,_MSR(r1) /* Returning to user mode? */ | ||
| 573 | andi. r3,r3,MSR_PR | 564 | andi. r3,r3,MSR_PR |
| 574 | beq restore /* if not, just restore regs and return */ | 565 | beq resume_kernel |
| 575 | 566 | ||
| 576 | /* Check current_thread_info()->flags */ | 567 | /* Check current_thread_info()->flags */ |
| 568 | andi. r0,r4,_TIF_USER_WORK_MASK | ||
| 569 | beq restore | ||
| 570 | |||
| 571 | andi. r0,r4,_TIF_NEED_RESCHED | ||
| 572 | beq 1f | ||
| 573 | bl .restore_interrupts | ||
| 574 | bl .schedule | ||
| 575 | b .ret_from_except_lite | ||
| 576 | |||
| 577 | 1: bl .save_nvgprs | ||
| 578 | bl .restore_interrupts | ||
| 579 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
| 580 | bl .do_notify_resume | ||
| 581 | b .ret_from_except | ||
| 582 | |||
| 583 | resume_kernel: | ||
| 584 | #ifdef CONFIG_PREEMPT | ||
| 585 | /* Check if we need to preempt */ | ||
| 586 | andi. r0,r4,_TIF_NEED_RESCHED | ||
| 587 | beq+ restore | ||
| 588 | /* Check that preempt_count() == 0 and interrupts are enabled */ | ||
| 589 | lwz r8,TI_PREEMPT(r9) | ||
| 590 | cmpwi cr1,r8,0 | ||
| 591 | ld r0,SOFTE(r1) | ||
| 592 | cmpdi r0,0 | ||
| 593 | crandc eq,cr1*4+eq,eq | ||
| 594 | bne restore | ||
| 595 | |||
| 596 | /* | ||
| 597 | * Here we are preempting the current task. We want to make | ||
| 598 | * sure we are soft-disabled first | ||
| 599 | */ | ||
| 600 | SOFT_DISABLE_INTS(r3,r4) | ||
| 601 | 1: bl .preempt_schedule_irq | ||
| 602 | |||
| 603 | /* Re-test flags and eventually loop */ | ||
| 577 | clrrdi r9,r1,THREAD_SHIFT | 604 | clrrdi r9,r1,THREAD_SHIFT |
| 578 | ld r4,TI_FLAGS(r9) | 605 | ld r4,TI_FLAGS(r9) |
| 579 | andi. r0,r4,_TIF_USER_WORK_MASK | 606 | andi. r0,r4,_TIF_NEED_RESCHED |
| 580 | bne do_work | 607 | bne 1b |
| 581 | #endif /* !CONFIG_PREEMPT */ | 608 | #endif /* CONFIG_PREEMPT */ |
| 582 | 609 | ||
| 583 | .globl fast_exc_return_irq | 610 | .globl fast_exc_return_irq |
| 584 | fast_exc_return_irq: | 611 | fast_exc_return_irq: |
| @@ -759,50 +786,6 @@ restore_check_irq_replay: | |||
| 759 | #endif /* CONFIG_PPC_BOOK3E */ | 786 | #endif /* CONFIG_PPC_BOOK3E */ |
| 760 | 1: b .ret_from_except /* What else to do here ? */ | 787 | 1: b .ret_from_except /* What else to do here ? */ |
| 761 | 788 | ||
| 762 | |||
| 763 | |||
| 764 | 3: | ||
| 765 | do_work: | ||
| 766 | #ifdef CONFIG_PREEMPT | ||
| 767 | andi. r0,r3,MSR_PR /* Returning to user mode? */ | ||
| 768 | bne user_work | ||
| 769 | /* Check that preempt_count() == 0 and interrupts are enabled */ | ||
| 770 | lwz r8,TI_PREEMPT(r9) | ||
| 771 | cmpwi cr1,r8,0 | ||
| 772 | ld r0,SOFTE(r1) | ||
| 773 | cmpdi r0,0 | ||
| 774 | crandc eq,cr1*4+eq,eq | ||
| 775 | bne restore | ||
| 776 | |||
| 777 | /* | ||
| 778 | * Here we are preempting the current task. We want to make | ||
| 779 | * sure we are soft-disabled first | ||
| 780 | */ | ||
| 781 | SOFT_DISABLE_INTS(r3,r4) | ||
| 782 | 1: bl .preempt_schedule_irq | ||
| 783 | |||
| 784 | /* Re-test flags and eventually loop */ | ||
| 785 | clrrdi r9,r1,THREAD_SHIFT | ||
| 786 | ld r4,TI_FLAGS(r9) | ||
| 787 | andi. r0,r4,_TIF_NEED_RESCHED | ||
| 788 | bne 1b | ||
| 789 | b restore | ||
| 790 | |||
| 791 | user_work: | ||
| 792 | #endif /* CONFIG_PREEMPT */ | ||
| 793 | |||
| 794 | andi. r0,r4,_TIF_NEED_RESCHED | ||
| 795 | beq 1f | ||
| 796 | bl .restore_interrupts | ||
| 797 | bl .schedule | ||
| 798 | b .ret_from_except_lite | ||
| 799 | |||
| 800 | 1: bl .save_nvgprs | ||
| 801 | bl .restore_interrupts | ||
| 802 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
| 803 | bl .do_notify_resume | ||
| 804 | b .ret_from_except | ||
| 805 | |||
| 806 | unrecov_restore: | 789 | unrecov_restore: |
| 807 | addi r3,r1,STACK_FRAME_OVERHEAD | 790 | addi r3,r1,STACK_FRAME_OVERHEAD |
| 808 | bl .unrecoverable_exception | 791 | bl .unrecoverable_exception |
