KVM: PPC: Export __giveup_vsx
[safe/jmp/linux-2.6] / arch / powerpc / kernel / entry_64.S
index 383ed6e..07109d8 100644 (file)
@@ -120,9 +120,15 @@ BEGIN_FW_FTR_SECTION
 2:
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
+
+       /* Hard enable interrupts */
+#ifdef CONFIG_PPC_BOOK3E
+       wrteei  1
+#else
        mfmsr   r11
        ori     r11,r11,MSR_EE
        mtmsrd  r11,1
+#endif /* CONFIG_PPC_BOOK3E */
 
 #ifdef SHOW_SYSCALLS
        bl      .do_show_syscall
@@ -168,15 +174,25 @@ syscall_exit:
 #endif
        clrrdi  r12,r1,THREAD_SHIFT
 
-       /* disable interrupts so current_thread_info()->flags can't change,
-          and so that we don't get interrupted after loading SRR0/1. */
        ld      r8,_MSR(r1)
+#ifdef CONFIG_PPC_BOOK3S
+       /* No MSR:RI on BookE */
        andi.   r10,r8,MSR_RI
        beq-    unrecov_restore
+#endif
+
+       /* 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
        mtmsrd  r10,1
+#endif /* CONFIG_PPC_BOOK3E */
+
        ld      r9,TI_FLAGS(r12)
        li      r11,-_LAST_ERRNO
        andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
@@ -194,9 +210,13 @@ syscall_error_cont:
         * userspace and we take an exception after restoring r13,
         * we end up corrupting the userspace r13 value.
         */
+#ifdef CONFIG_PPC_BOOK3S
+       /* No MSR:RI on BookE */
        li      r12,MSR_RI
        andc    r11,r10,r12
        mtmsrd  r11,1                   /* clear MSR.RI */
+#endif /* CONFIG_PPC_BOOK3S */
+
        beq-    1f
        ACCOUNT_CPU_USER_EXIT(r11, r12)
        ld      r13,GPR13(r1)   /* only restore r13 if returning to usermode */
@@ -206,7 +226,7 @@ syscall_error_cont:
        mtcr    r5
        mtspr   SPRN_SRR0,r7
        mtspr   SPRN_SRR1,r8
-       rfid
+       RFI
        b       .       /* prevent speculative execution */
 
 syscall_error: 
@@ -276,9 +296,13 @@ syscall_exit_work:
        beq     .ret_from_except_lite
 
        /* Re-enable interrupts */
+#ifdef CONFIG_PPC_BOOK3E
+       wrteei  1
+#else
        mfmsr   r10
        ori     r10,r10,MSR_EE
        mtmsrd  r10,1
+#endif /* CONFIG_PPC_BOOK3E */
 
        bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
@@ -380,7 +404,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        and.    r0,r0,r22
        beq+    1f
        andc    r22,r22,r0
-       mtmsrd  r22
+       MTMSRD(r22)
        isync
 1:     std     r20,_NIP(r1)
        mfcr    r23
@@ -399,6 +423,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        std     r6,PACACURRENT(r13)     /* Set new 'current' */
 
        ld      r8,KSP(r4)      /* new stack pointer */
+#ifdef CONFIG_PPC_BOOK3S
 BEGIN_FTR_SECTION
   BEGIN_FTR_SECTION_NESTED(95)
        clrrdi  r6,r8,28        /* get its ESID */
@@ -445,8 +470,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
        slbie   r6              /* Workaround POWER5 < DD2.1 issue */
        slbmte  r7,r0
        isync
-
 2:
+#endif /* !CONFIG_PPC_BOOK3S */
+
        clrrdi  r7,r8,THREAD_SHIFT      /* base of new stack */
        /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
           because we don't need to leave the 288-byte ABI gap at the
@@ -490,10 +516,14 @@ _GLOBAL(ret_from_except_lite)
         * can't change between when we test it and when we return
         * from the interrupt.
         */
+#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 */
+#endif /* CONFIG_PPC_BOOK3E */
 
 #ifdef CONFIG_PREEMPT
        clrrdi  r9,r1,THREAD_SHIFT      /* current_thread_info() */
@@ -521,16 +551,28 @@ restore:
 BEGIN_FW_FTR_SECTION
        ld      r5,SOFTE(r1)
 FW_FTR_SECTION_ELSE
-       b       iseries_check_pending_irqs
+       b       .Liseries_check_pending_irqs
 ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
 2:
        TRACE_AND_RESTORE_IRQ(r5);
 
+#ifdef CONFIG_PERF_EVENTS
+       /* check paca->perf_event_pending if we're enabling ints */
+       lbz     r3,PACAPERFPEND(r13)
+       and.    r3,r3,r5
+       beq     27f
+       bl      .perf_event_do_pending
+27:
+#endif /* CONFIG_PERF_EVENTS */
+
        /* extract EE bit and use it to restore paca->hard_enabled */
        ld      r3,_MSR(r1)
        rldicl  r4,r3,49,63             /* r0 = (r3 >> 15) & 1 */
        stb     r4,PACAHARDIRQEN(r13)
 
+#ifdef CONFIG_PPC_BOOK3E
+       b       .exception_return_book3e
+#else
        ld      r4,_CTR(r1)
        ld      r0,_LINK(r1)
        mtctr   r4
@@ -579,7 +621,9 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
        rfid
        b       .       /* prevent speculative execution */
 
-iseries_check_pending_irqs:
+#endif /* CONFIG_PPC_BOOK3E */
+
+.Liseries_check_pending_irqs:
 #ifdef CONFIG_PPC_ISERIES
        ld      r5,SOFTE(r1)
        cmpdi   0,r5,0
@@ -614,39 +658,50 @@ do_work:
        cmpdi   r0,0
        crandc  eq,cr1*4+eq,eq
        bne     restore
-       /* here we are preempting the current task */
-1:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       bl      .trace_hardirqs_on
-       /* Note: we just clobbered r10 which used to contain the previous
-        * MSR before the hard-disabling done by the caller of do_work.
-        * We don't have that value anymore, but it doesn't matter as
-        * we will hard-enable unconditionally, we can just reload the
-        * current MSR into r10
+
+       /* Here we are preempting the current task.
+        *
+        * Ensure interrupts are soft-disabled. We also properly mark
+        * the PACA to reflect the fact that they are hard-disabled
+        * and trace the change
         */
-       mfmsr   r10
-#endif /* CONFIG_TRACE_IRQFLAGS */
-       li      r0,1
+       li      r0,0
        stb     r0,PACASOFTIRQEN(r13)
        stb     r0,PACAHARDIRQEN(r13)
-       ori     r10,r10,MSR_EE
-       mtmsrd  r10,1           /* reenable interrupts */
-       bl      .preempt_schedule
+       TRACE_DISABLE_INTS
+
+       /* Call the scheduler with soft IRQs off */
+1:     bl      .preempt_schedule_irq
+
+       /* Hard-disable interrupts again (and update PACA) */
+#ifdef CONFIG_PPC_BOOK3E
+       wrteei  0
+#else
        mfmsr   r10
-       clrrdi  r9,r1,THREAD_SHIFT
-       rldicl  r10,r10,48,1    /* disable interrupts again */
+       rldicl  r10,r10,48,1
        rotldi  r10,r10,16
        mtmsrd  r10,1
+#endif /* CONFIG_PPC_BOOK3E */
+       li      r0,0
+       stb     r0,PACAHARDIRQEN(r13)
+
+       /* Re-test flags and eventually loop */
+       clrrdi  r9,r1,THREAD_SHIFT
        ld      r4,TI_FLAGS(r9)
        andi.   r0,r4,_TIF_NEED_RESCHED
        bne     1b
        b       restore
 
 user_work:
-#endif
+#endif /* CONFIG_PREEMPT */
+
        /* Enable interrupts */
+#ifdef CONFIG_PPC_BOOK3E
+       wrteei  1
+#else
        ori     r10,r10,MSR_EE
        mtmsrd  r10,1
+#endif /* CONFIG_PPC_BOOK3E */
 
        andi.   r0,r4,_TIF_NEED_RESCHED
        beq     1f
@@ -736,9 +791,8 @@ _GLOBAL(enter_rtas)
        
         li      r9,1
         rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
-       ori     r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
+       ori     r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI
        andc    r6,r0,r9
-       ori     r6,r6,MSR_RI
        sync                            /* disable interrupts so SRR0/1 */
        mtmsrd  r0                      /* don't get trashed */
 
@@ -753,7 +807,7 @@ _GLOBAL(enter_rtas)
 
 _STATIC(rtas_return_loc)
        /* relocation is off at this point */
-       mfspr   r4,SPRN_SPRG3           /* Get PACA */
+       mfspr   r4,SPRN_SPRG_PACA       /* Get PACA */
        clrldi  r4,r4,2                 /* convert to realmode address */
 
        bcl     20,31,$+4
@@ -784,7 +838,7 @@ _STATIC(rtas_restore_regs)
        REST_8GPRS(14, r1)              /* Restore the non-volatiles */
        REST_10GPRS(22, r1)             /* ditto */
 
-       mfspr   r13,SPRN_SPRG3
+       mfspr   r13,SPRN_SPRG_PACA
 
        ld      r4,_CCR(r1)
        mtcr    r4
@@ -814,33 +868,24 @@ _GLOBAL(enter_prom)
         * of all registers that it saves.  We therefore save those registers
         * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
         */
-       SAVE_8GPRS(2, r1)
+       SAVE_GPR(2, r1)
        SAVE_GPR(13, r1)
        SAVE_8GPRS(14, r1)
        SAVE_10GPRS(22, r1)
-       mfcr    r4
-       std     r4,_CCR(r1)
-       mfctr   r5
-       std     r5,_CTR(r1)
-       mfspr   r6,SPRN_XER
-       std     r6,_XER(r1)
-       mfdar   r7
-       std     r7,_DAR(r1)
-       mfdsisr r8
-       std     r8,_DSISR(r1)
-       mfsrr0  r9
-       std     r9,_SRR0(r1)
-       mfsrr1  r10
-       std     r10,_SRR1(r1)
+       mfcr    r10
        mfmsr   r11
+       std     r10,_CCR(r1)
        std     r11,_MSR(r1)
 
        /* Get the PROM entrypoint */
-       ld      r0,GPR4(r1)
-       mtlr    r0
+       mtlr    r4
 
        /* Switch MSR to 32 bits mode
         */
+#ifdef CONFIG_PPC_BOOK3E
+       rlwinm  r11,r11,0,1,31
+       mtmsr   r11
+#else /* CONFIG_PPC_BOOK3E */
         mfmsr   r11
         li      r12,1
         rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
@@ -849,10 +894,10 @@ _GLOBAL(enter_prom)
         rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
         andc    r11,r11,r12
         mtmsrd  r11
+#endif /* CONFIG_PPC_BOOK3E */
         isync
 
-       /* Restore arguments & enter PROM here... */
-       ld      r3,GPR3(r1)
+       /* Enter PROM here... */
        blrl
 
        /* Just make sure that r1 top 32 bits didn't get
@@ -862,7 +907,7 @@ _GLOBAL(enter_prom)
 
        /* Restore the MSR (back to 64 bits) */
        ld      r0,_MSR(r1)
-       mtmsrd  r0
+       MTMSRD(r0)
         isync
 
        /* Restore other registers */
@@ -872,18 +917,6 @@ _GLOBAL(enter_prom)
        REST_10GPRS(22, r1)
        ld      r4,_CCR(r1)
        mtcr    r4
-       ld      r5,_CTR(r1)
-       mtctr   r5
-       ld      r6,_XER(r1)
-       mtspr   SPRN_XER,r6
-       ld      r7,_DAR(r1)
-       mtdar   r7
-       ld      r8,_DSISR(r1)
-       mtdsisr r8
-       ld      r9,_SRR0(r1)
-       mtsrr0  r9
-       ld      r10,_SRR1(r1)
-       mtsrr1  r10
        
         addi   r1,r1,PROM_FRAME_SIZE
        ld      r0,16(r1)
@@ -908,6 +941,12 @@ _GLOBAL(ftrace_caller)
 ftrace_call:
        bl      ftrace_stub
        nop
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+.globl ftrace_graph_call
+ftrace_graph_call:
+       b       ftrace_graph_stub
+_GLOBAL(ftrace_graph_stub)
+#endif
        ld      r0, 128(r1)
        mtlr    r0
        addi    r1, r1, 112
@@ -931,13 +970,89 @@ _GLOBAL(_mcount)
        ld      r5,0(r5)
        mtctr   r5
        bctrl
-
        nop
+
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       b       ftrace_graph_caller
+#endif
        ld      r0, 128(r1)
        mtlr    r0
        addi    r1, r1, 112
 _GLOBAL(ftrace_stub)
        blr
 
-#endif
-#endif
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+_GLOBAL(ftrace_graph_caller)
+       /* load r4 with local address */
+       ld      r4, 128(r1)
+       subi    r4, r4, MCOUNT_INSN_SIZE
+
+       /* get the parent address */
+       ld      r11, 112(r1)
+       addi    r3, r11, 16
+
+       bl      .prepare_ftrace_return
+       nop
+
+       ld      r0, 128(r1)
+       mtlr    r0
+       addi    r1, r1, 112
+       blr
+
+_GLOBAL(return_to_handler)
+       /* need to save return values */
+       std     r4,  -24(r1)
+       std     r3,  -16(r1)
+       std     r31, -8(r1)
+       mr      r31, r1
+       stdu    r1, -112(r1)
+
+       bl      .ftrace_return_to_handler
+       nop
+
+       /* return value has real return address */
+       mtlr    r3
+
+       ld      r1, 0(r1)
+       ld      r4,  -24(r1)
+       ld      r3,  -16(r1)
+       ld      r31, -8(r1)
+
+       /* Jump back to real return address */
+       blr
+
+_GLOBAL(mod_return_to_handler)
+       /* need to save return values */
+       std     r4,  -32(r1)
+       std     r3,  -24(r1)
+       /* save TOC */
+       std     r2,  -16(r1)
+       std     r31, -8(r1)
+       mr      r31, r1
+       stdu    r1, -112(r1)
+
+       /*
+        * We are in a module using the module's TOC.
+        * Switch to our TOC to run inside the core kernel.
+        */
+       ld      r2, PACATOC(r13)
+
+       bl      .ftrace_return_to_handler
+       nop
+
+       /* return value has real return address */
+       mtlr    r3
+
+       ld      r1, 0(r1)
+       ld      r4,  -32(r1)
+       ld      r3,  -24(r1)
+       ld      r2,  -16(r1)
+       ld      r31, -8(r1)
+
+       /* Jump back to real return address */
+       blr
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#endif /* CONFIG_FUNCTION_TRACER */