]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kernel/entry_64.S
powerpc: Replace mfmsr instructions with load from PACA kernel_msr field
[karo-tx-linux.git] / arch / powerpc / kernel / entry_64.S
index d834425186aeaa7fae6905bd8bffb50d0d99354d..c513beb78b3b0a6b187086d843b407d3eef392f0 100644 (file)
@@ -115,39 +115,33 @@ BEGIN_FW_FTR_SECTION
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING && CONFIG_PPC_SPLPAR */
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-       bl      .trace_hardirqs_on
-       REST_GPR(0,r1)
-       REST_4GPRS(3,r1)
-       REST_2GPRS(7,r1)
-       addi    r9,r1,STACK_FRAME_OVERHEAD
-       ld      r12,_MSR(r1)
-#endif /* CONFIG_TRACE_IRQFLAGS */
-       li      r10,1
-       stb     r10,PACASOFTIRQEN(r13)
-       stb     r10,PACAHARDIRQEN(r13)
-       std     r10,SOFTE(r1)
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
-       /* Hack for handling interrupts when soft-enabling on iSeries */
-       cmpdi   cr1,r0,0x5555           /* syscall 0x5555 */
-       andi.   r10,r12,MSR_PR          /* from kernel */
-       crand   4*cr0+eq,4*cr1+eq,4*cr0+eq
-       bne     2f
-       b       hardware_interrupt_entry
-2:
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif /* CONFIG_PPC_ISERIES */
+       /*
+        * A syscall should always be called with interrupts enabled
+        * so we just unconditionally hard-enable here. When some kind
+        * of irq tracing is used, we additionally check that condition
+        * is correct
+        */
+#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_BUG)
+       lbz     r10,PACASOFTIRQEN(r13)
+       xori    r10,r10,1
+1:     tdnei   r10,0
+       EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING
+#endif
 
-       /* Hard enable interrupts */
 #ifdef CONFIG_PPC_BOOK3E
        wrteei  1
 #else
-       mfmsr   r11
+       ld      r11,PACAKMSR(r13)
        ori     r11,r11,MSR_EE
        mtmsrd  r11,1
 #endif /* CONFIG_PPC_BOOK3E */
 
+       /* We do need to set SOFTE in the stack frame or the return
+        * from interrupt will be painful
+        */
+       li      r10,1
+       std     r10,SOFTE(r1)
+
 #ifdef SHOW_SYSCALLS
        bl      .do_show_syscall
        REST_GPR(0,r1)
@@ -198,16 +192,14 @@ syscall_exit:
        andi.   r10,r8,MSR_RI
        beq-    unrecov_restore
 #endif
-
-       /* Disable interrupts so current_thread_info()->flags can't change,
+       /*
+        * Disable interrupts so current_thread_info()->flags can't change,
         * and so that we don't get interrupted after loading SRR0/1.
         */
 #ifdef CONFIG_PPC_BOOK3E
        wrteei  0
 #else
-       mfmsr   r10
-       rldicl  r10,r10,48,1
-       rotldi  r10,r10,16
+       ld      r10,PACAKMSR(r13)
        mtmsrd  r10,1
 #endif /* CONFIG_PPC_BOOK3E */
 
@@ -319,7 +311,7 @@ syscall_exit_work:
 #ifdef CONFIG_PPC_BOOK3E
        wrteei  1
 #else
-       mfmsr   r10
+       ld      r10,PACAKMSR(r13)
        ori     r10,r10,MSR_EE
        mtmsrd  r10,1
 #endif /* CONFIG_PPC_BOOK3E */
@@ -565,10 +557,8 @@ _GLOBAL(ret_from_except_lite)
 #ifdef CONFIG_PPC_BOOK3E
        wrteei  0
 #else
-       mfmsr   r10             /* Get current interrupt state */
-       rldicl  r9,r10,48,1     /* clear MSR_EE */
-       rotldi  r9,r9,16
-       mtmsrd  r9,1            /* Update machine state */
+       ld      r10,PACAKMSR(r13) /* Get kernel MSR without EE */
+       mtmsrd  r10,1             /* Update machine state */
 #endif /* CONFIG_PPC_BOOK3E */
 
 #ifdef CONFIG_PREEMPT
@@ -591,15 +581,10 @@ _GLOBAL(ret_from_except_lite)
        ld      r4,TI_FLAGS(r9)
        andi.   r0,r4,_TIF_USER_WORK_MASK
        bne     do_work
-#endif
+#endif /* !CONFIG_PREEMPT */
 
 restore:
-BEGIN_FW_FTR_SECTION
        ld      r5,SOFTE(r1)
-FW_FTR_SECTION_ELSE
-       b       .Liseries_check_pending_irqs
-ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
-2:
        TRACE_AND_RESTORE_IRQ(r5);
 
        /* extract EE bit and use it to restore paca->hard_enabled */
@@ -638,8 +623,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
         * userspace and we take an exception after restoring r13,
         * we end up corrupting the userspace r13 value.
         */
-       mfmsr   r4
-       andc    r4,r4,r0        /* r0 contains MSR_RI here */
+       ld      r4,PACAKMSR(r13) /* Get kernel MSR without EE */
+       andc    r4,r4,r0         /* r0 contains MSR_RI here */
        mtmsrd  r4,1
 
        /*
@@ -669,30 +654,6 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
 
 #endif /* CONFIG_PPC_BOOK3E */
 
-.Liseries_check_pending_irqs:
-#ifdef CONFIG_PPC_ISERIES
-       ld      r5,SOFTE(r1)
-       cmpdi   0,r5,0
-       beq     2b
-       /* Check for pending interrupts (iSeries) */
-       ld      r3,PACALPPACAPTR(r13)
-       ld      r3,LPPACAANYINT(r3)
-       cmpdi   r3,0
-       beq+    2b                      /* skip do_IRQ if no interrupts */
-
-       li      r3,0
-       stb     r3,PACASOFTIRQEN(r13)   /* ensure we are soft-disabled */
-#ifdef CONFIG_TRACE_IRQFLAGS
-       bl      .trace_hardirqs_off
-       mfmsr   r10
-#endif
-       ori     r10,r10,MSR_EE
-       mtmsrd  r10                     /* hard-enable again */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_IRQ
-       b       .ret_from_except_lite           /* loop back and handle more */
-#endif
-
 do_work:
 #ifdef CONFIG_PREEMPT
        andi.   r0,r3,MSR_PR    /* Returning to user mode? */
@@ -723,9 +684,7 @@ do_work:
 #ifdef CONFIG_PPC_BOOK3E
        wrteei  0
 #else
-       mfmsr   r10
-       rldicl  r10,r10,48,1
-       rotldi  r10,r10,16
+       ld      r10,PACAKMSR(r13) /* Get kernel MSR without EE */
        mtmsrd  r10,1
 #endif /* CONFIG_PPC_BOOK3E */
        li      r0,0
@@ -751,12 +710,16 @@ user_work:
 
        andi.   r0,r4,_TIF_NEED_RESCHED
        beq     1f
+       li      r5,1
+       TRACE_AND_RESTORE_IRQ(r5);
        bl      .schedule
        b       .ret_from_except_lite
 
 1:     bl      .save_nvgprs
+       li      r5,1
+       TRACE_AND_RESTORE_IRQ(r5);
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_signal
+       bl      .do_notify_resume
        b       .ret_from_except
 
 unrecov_restore: