diff options
Diffstat (limited to 'arch/powerpc/kernel/entry_64.S')
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 62 |
1 files changed, 31 insertions, 31 deletions
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index f8a7a1a1a9f4..ef2074c3e906 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -588,23 +588,19 @@ _GLOBAL(ret_from_except_lite) | |||
588 | fast_exc_return_irq: | 588 | fast_exc_return_irq: |
589 | restore: | 589 | restore: |
590 | /* | 590 | /* |
591 | * This is the main kernel exit path, we first check if we | 591 | * This is the main kernel exit path. First we check if we |
592 | * have to change our interrupt state. | 592 | * are about to re-enable interrupts |
593 | */ | 593 | */ |
594 | ld r5,SOFTE(r1) | 594 | ld r5,SOFTE(r1) |
595 | lbz r6,PACASOFTIRQEN(r13) | 595 | lbz r6,PACASOFTIRQEN(r13) |
596 | cmpwi cr1,r5,0 | 596 | cmpwi cr0,r5,0 |
597 | cmpw cr0,r5,r6 | 597 | beq restore_irq_off |
598 | beq cr0,4f | ||
599 | 598 | ||
600 | /* We do, handle disable first, which is easy */ | 599 | /* We are enabling, were we already enabled ? Yes, just return */ |
601 | bne cr1,3f; | 600 | cmpwi cr0,r6,1 |
602 | li r0,0 | 601 | beq cr0,do_restore |
603 | stb r0,PACASOFTIRQEN(r13); | ||
604 | TRACE_DISABLE_INTS | ||
605 | b 4f | ||
606 | 602 | ||
607 | 3: /* | 603 | /* |
608 | * We are about to soft-enable interrupts (we are hard disabled | 604 | * We are about to soft-enable interrupts (we are hard disabled |
609 | * at this point). We check if there's anything that needs to | 605 | * at this point). We check if there's anything that needs to |
610 | * be replayed first. | 606 | * be replayed first. |
@@ -626,7 +622,7 @@ restore_no_replay: | |||
626 | /* | 622 | /* |
627 | * Final return path. BookE is handled in a different file | 623 | * Final return path. BookE is handled in a different file |
628 | */ | 624 | */ |
629 | 4: | 625 | do_restore: |
630 | #ifdef CONFIG_PPC_BOOK3E | 626 | #ifdef CONFIG_PPC_BOOK3E |
631 | b .exception_return_book3e | 627 | b .exception_return_book3e |
632 | #else | 628 | #else |
@@ -700,6 +696,25 @@ fast_exception_return: | |||
700 | #endif /* CONFIG_PPC_BOOK3E */ | 696 | #endif /* CONFIG_PPC_BOOK3E */ |
701 | 697 | ||
702 | /* | 698 | /* |
699 | * We are returning to a context with interrupts soft disabled. | ||
700 | * | ||
701 | * However, we may also about to hard enable, so we need to | ||
702 | * make sure that in this case, we also clear PACA_IRQ_HARD_DIS | ||
703 | * or that bit can get out of sync and bad things will happen | ||
704 | */ | ||
705 | restore_irq_off: | ||
706 | ld r3,_MSR(r1) | ||
707 | lbz r7,PACAIRQHAPPENED(r13) | ||
708 | andi. r0,r3,MSR_EE | ||
709 | beq 1f | ||
710 | rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS | ||
711 | stb r7,PACAIRQHAPPENED(r13) | ||
712 | 1: li r0,0 | ||
713 | stb r0,PACASOFTIRQEN(r13); | ||
714 | TRACE_DISABLE_INTS | ||
715 | b do_restore | ||
716 | |||
717 | /* | ||
703 | * Something did happen, check if a re-emit is needed | 718 | * Something did happen, check if a re-emit is needed |
704 | * (this also clears paca->irq_happened) | 719 | * (this also clears paca->irq_happened) |
705 | */ | 720 | */ |
@@ -748,6 +763,9 @@ restore_check_irq_replay: | |||
748 | #endif /* CONFIG_PPC_BOOK3E */ | 763 | #endif /* CONFIG_PPC_BOOK3E */ |
749 | 1: b .ret_from_except /* What else to do here ? */ | 764 | 1: b .ret_from_except /* What else to do here ? */ |
750 | 765 | ||
766 | |||
767 | |||
768 | 3: | ||
751 | do_work: | 769 | do_work: |
752 | #ifdef CONFIG_PREEMPT | 770 | #ifdef CONFIG_PREEMPT |
753 | andi. r0,r3,MSR_PR /* Returning to user mode? */ | 771 | andi. r0,r3,MSR_PR /* Returning to user mode? */ |
@@ -767,16 +785,6 @@ do_work: | |||
767 | SOFT_DISABLE_INTS(r3,r4) | 785 | SOFT_DISABLE_INTS(r3,r4) |
768 | 1: bl .preempt_schedule_irq | 786 | 1: bl .preempt_schedule_irq |
769 | 787 | ||
770 | /* Hard-disable interrupts again (and update PACA) */ | ||
771 | #ifdef CONFIG_PPC_BOOK3E | ||
772 | wrteei 0 | ||
773 | #else | ||
774 | ld r10,PACAKMSR(r13) /* Get kernel MSR without EE */ | ||
775 | mtmsrd r10,1 | ||
776 | #endif /* CONFIG_PPC_BOOK3E */ | ||
777 | li r0,PACA_IRQ_HARD_DIS | ||
778 | stb r0,PACAIRQHAPPENED(r13) | ||
779 | |||
780 | /* Re-test flags and eventually loop */ | 788 | /* Re-test flags and eventually loop */ |
781 | clrrdi r9,r1,THREAD_SHIFT | 789 | clrrdi r9,r1,THREAD_SHIFT |
782 | ld r4,TI_FLAGS(r9) | 790 | ld r4,TI_FLAGS(r9) |
@@ -787,14 +795,6 @@ do_work: | |||
787 | user_work: | 795 | user_work: |
788 | #endif /* CONFIG_PREEMPT */ | 796 | #endif /* CONFIG_PREEMPT */ |
789 | 797 | ||
790 | /* Enable interrupts */ | ||
791 | #ifdef CONFIG_PPC_BOOK3E | ||
792 | wrteei 1 | ||
793 | #else | ||
794 | ori r10,r10,MSR_EE | ||
795 | mtmsrd r10,1 | ||
796 | #endif /* CONFIG_PPC_BOOK3E */ | ||
797 | |||
798 | andi. r0,r4,_TIF_NEED_RESCHED | 798 | andi. r0,r4,_TIF_NEED_RESCHED |
799 | beq 1f | 799 | beq 1f |
800 | bl .restore_interrupts | 800 | bl .restore_interrupts |