To support CONFIG_VMAP_STACK, the kernel must be able to activate
Data MMU Translation for accessing the stack. Before doing that
it must save SRR0, SRR1 and DAR in order to not loose them in
case there is a Data TLB Miss once the translation is reactivated.

This patch defines fields in the thread struct for saving those
registers. It also prepares entry_32.S to handle exception entry
with Data MMU Translation enabled.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 arch/powerpc/include/asm/processor.h   |  5 +++++
 arch/powerpc/include/asm/thread_info.h |  5 +++++
 arch/powerpc/kernel/asm-offsets.c      |  5 +++++
 arch/powerpc/kernel/entry_32.S         | 16 ++++++++++++++++
 4 files changed, 31 insertions(+)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index 8179b64871ed..e839a1231b17 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -218,6 +218,11 @@ struct thread_struct {
 #ifdef CONFIG_PPC32
        void            *pgdir;         /* root of page-table tree */
        unsigned long   ksp_limit;      /* if ksp <= ksp_limit stack overflow */
+#ifdef CONFIG_VMAP_STACK
+       unsigned long   dar;
+       unsigned long   srr0;
+       unsigned long   srr1;
+#endif
 #endif
        /* Debug Registers */
        struct debug_reg debug;
diff --git a/arch/powerpc/include/asm/thread_info.h 
b/arch/powerpc/include/asm/thread_info.h
index 8e1d0195ac36..488d5c4670ff 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -10,10 +10,15 @@
 #define _ASM_POWERPC_THREAD_INFO_H
 
 #include <asm/asm-const.h>
+#include <asm/page.h>
 
 #ifdef __KERNEL__
 
+#if defined(CONFIG_VMAP_STACK) && CONFIG_THREAD_SHIFT < PAGE_SHIFT
+#define THREAD_SHIFT           PAGE_SHIFT
+#else
 #define THREAD_SHIFT           CONFIG_THREAD_SHIFT
+#endif
 
 #define THREAD_SIZE            (1 << THREAD_SHIFT)
 
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 03439785c2ea..985523ef23e8 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -128,6 +128,11 @@ int main(void)
        OFFSET(KSP_VSID, thread_struct, ksp_vsid);
 #else /* CONFIG_PPC64 */
        OFFSET(PGDIR, thread_struct, pgdir);
+#ifdef CONFIG_VMAP_STACK
+       OFFSET(SRR0, thread_struct, srr0);
+       OFFSET(SRR1, thread_struct, srr1);
+       OFFSET(DAR, thread_struct, dar);
+#endif
 #ifdef CONFIG_SPE
        OFFSET(THREAD_EVR0, thread_struct, evr[0]);
        OFFSET(THREAD_ACC, thread_struct, acc);
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 52a061f14c7d..6e2c45fdd2c0 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -150,8 +150,13 @@ transfer_to_handler:
        stw     r12,_CTR(r11)
        stw     r2,_XER(r11)
        mfspr   r12,SPRN_SPRG_THREAD
+#ifdef CONFIG_VMAP_STACK
+       tovirt(r12, r12)
+#endif
        addi    r2,r12,-THREAD
+#ifndef CONFIG_VMAP_STACK
        tovirt(r2,r2)                   /* set r2 to current */
+#endif
        beq     2f                      /* if from user, fix up THREAD.regs */
        addi    r11,r1,STACK_FRAME_OVERHEAD
        stw     r11,PT_REGS(r12)
@@ -179,9 +184,13 @@ transfer_to_handler:
        stw     r12,4(r11)
 #endif
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+#ifdef CONFIG_VMAP_STACK
+       ACCOUNT_CPU_USER_ENTRY(r2, r11, r12)
+#else
        tophys(r9, r2)
        ACCOUNT_CPU_USER_ENTRY(r9, r11, r12)
 #endif
+#endif
 
        b       3f
 
@@ -193,8 +202,12 @@ transfer_to_handler:
        ble-    stack_ovf               /* then the kernel stack overflowed */
 5:
 #if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_E500)
+#ifdef CONFIG_VMAP_STACK
+       lwz     r12, TI_LOCAL_FLAGS(r2)
+#else
        tophys(r9,r2)                   /* check local flags */
        lwz     r12,TI_LOCAL_FLAGS(r9)
+#endif
        mtcrf   0x01,r12
        bt-     31-TLF_NAPPING,4f
        bt-     31-TLF_SLEEPING,7f
@@ -203,6 +216,9 @@ transfer_to_handler:
 transfer_to_handler_cont:
 3:
        mflr    r9
+#ifdef CONFIG_VMAP_STACK
+       tovirt(r9,r9)
+#endif
        lwz     r11,0(r9)               /* virtual address of handler */
        lwz     r9,4(r9)                /* where to go when done */
 #if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
-- 
2.13.3

Reply via email to