This patch enables CONFIG_VMAP_STACK. For that, a few changes are
done in head_8xx.S to re-activation DATA MMU Translation before
accessing to the stack.

Due to the growing of exception prolog, a few rearrangement is also
done in a few exception handlers.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 arch/powerpc/Kconfig           |  1 +
 arch/powerpc/kernel/head_8xx.S | 87 +++++++++++++++++++++++++++++++++++++-----
 2 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 94b46624068d..323b8a1efb3e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -180,6 +180,7 @@ config PPC
        select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
+       select HAVE_ARCH_VMAP_STACK             if PPC_8xx
        select HAVE_CBPF_JIT                    if !PPC64
        select HAVE_STACKPROTECTOR              if PPC64 && 
$(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13)
        select HAVE_STACKPROTECTOR              if PPC32 && 
$(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 48996a424075..ded66a6fdfeb 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -136,6 +136,53 @@ instruction_counter:
        EXCEPTION_PROLOG_1;     \
        EXCEPTION_PROLOG_2
 
+#ifdef CONFIG_VMAP_STACK
+#define EXCEPTION_PROLOG_1     \
+       mtspr   SPRN_SPRG_SCRATCH2, r12;        \
+       mfspr   r12, SPRN_SPRG_THREAD;  \
+       mfspr   r11, SPRN_SRR0; \
+       stw     r11, SRR0(r12); \
+       mfspr   r11, SPRN_DAR;  \
+       stw     r11, DAR(r12);  \
+       mfspr   r11,SPRN_SRR1;          /* check whether user or kernel */ \
+       stw     r11, SRR1(r12); \
+       andi.   r11,r11,MSR_PR
+
+#define EXCEPTION_PROLOG_2     \
+       li      r11, MSR_KERNEL & ~(MSR_IR | MSR_RI); /* can take DTLB miss */ \
+       mtmsr   r11;            \
+       tovirt(r12, r12);       \
+       subi    r11, r1, INT_FRAME_SIZE;        /* use r1 if kernel */ \
+       beq     1f;             \
+       lwz     r11, TASK_STACK-THREAD(r12);    \
+       addi    r11, r11, THREAD_SIZE - INT_FRAME_SIZE; \
+1:     stw     r10,_CCR(r11);          /* save registers */ \
+       stw     r9,GPR9(r11);   \
+       mfspr   r10,SPRN_SPRG_SCRATCH0; \
+       stw     r10,GPR10(r11); \
+       mfspr   r10,SPRN_SPRG_SCRATCH1; \
+       stw     r10,GPR11(r11); \
+       mfspr   r10,SPRN_SPRG_SCRATCH2; \
+       stw     r10,GPR12(r11); \
+       mflr    r10;            \
+       stw     r10,_LINK(r11); \
+       lwz     r10, DAR(r12);  \
+       stw     r10, _DAR(r11); \
+       lwz     r9, SRR1(r12);  \
+       lwz     r12, SRR0(r12); \
+       stw     r1,GPR1(r11);   \
+       stw     r1,0(r11);      \
+       mr      r1, r11;                        /* set new kernel sp */ \
+       li      r10,MSR_KERNEL & ~MSR_IR; /* can take exceptions */ \
+       mtmsr   r10;            \
+       stw     r0,GPR0(r11);   \
+       lis     r10, STACK_FRAME_REGS_MARKER@ha; /* exception frame marker */ \
+       addi    r10, r10, STACK_FRAME_REGS_MARKER@l; \
+       stw     r10, 8(r11);    \
+       SAVE_4GPRS(3, r11);     \
+       SAVE_2GPRS(7, r11)
+
+#else
 #define EXCEPTION_PROLOG_1     \
        mfspr   r11,SPRN_SRR1;          /* check whether user or kernel */ \
        andi.   r11,r11,MSR_PR; \
@@ -172,6 +219,8 @@ instruction_counter:
        SAVE_4GPRS(3, r11);     \
        SAVE_2GPRS(7, r11)
 
+#endif
+
 /*
  * Note: code which follows this uses cr0.eq (set if from kernel),
  * r11, r12 (SRR0), and r9 (SRR1).
@@ -226,8 +275,12 @@ i##n:                                                      
        \
        . = 0x200
 MachineCheck:
        EXCEPTION_PROLOG
+#ifdef CONFIG_VMAP_STACK
+       lwz r4, _DAR(r11)
+#else
        mfspr r4,SPRN_DAR
        stw r4,_DAR(r11)
+#endif
        li r5,RPN_PATTERN
        mtspr SPRN_DAR,r5       /* Tag DAR, to be used in DTLB Error */
        mfspr r5,SPRN_DSISR
@@ -254,8 +307,12 @@ InstructionAccess:
        . = 0x600
 Alignment:
        EXCEPTION_PROLOG
+#ifdef CONFIG_VMAP_STACK
+       lwz r4, _DAR(r11)
+#else
        mfspr   r4,SPRN_DAR
        stw     r4,_DAR(r11)
+#endif
        li      r5,RPN_PATTERN
        mtspr   SPRN_DAR,r5     /* Tag DAR, to be used in DTLB Error */
        mfspr   r5,SPRN_DSISR
@@ -573,20 +630,31 @@ DataTLBError:
        beq-    FixupDAR        /* must be a buggy dcbX, icbi insn. */
 DARFixed:/* Return from dcbx instruction bug workaround */
        EXCEPTION_PROLOG_1
+#ifdef CONFIG_VMAP_STACK
+       li      r11, RPN_PATTERN
+       mtspr   SPRN_DAR, r11   /* Tag DAR, to be used in DTLB Error */
+#endif
        EXCEPTION_PROLOG_2
        mfspr   r5,SPRN_DSISR
        stw     r5,_DSISR(r11)
+#ifdef CONFIG_VMAP_STACK
+       lwz r4, _DAR(r11)
+#else
        mfspr   r4,SPRN_DAR
+#endif
        andis.  r10,r5,DSISR_NOHPTE@h
        beq+    1f
        tlbie   r4
 dtlbie:
-1:     li      r10,RPN_PATTERN
+1:
+#ifndef CONFIG_VMAP_STACK
+       li      r10, RPN_PATTERN
        mtspr   SPRN_DAR,r10    /* Tag DAR, to be used in DTLB Error */
+#endif
        /* 0x300 is DataAccess exception, needed by bad_page_fault() */
        EXC_XFER_LITE(0x300, handle_page_fault)
 
-       EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+/*     EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)*/
        EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
        EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
        EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
@@ -598,6 +666,12 @@ dtlbie:
  * support of breakpoints and such.  Someday I will get around to
  * using them.
  */
+11:
+       mtcr    r10
+       mfspr   r10, SPRN_SPRG_SCRATCH0
+       mfspr   r11, SPRN_SPRG_SCRATCH1
+       rfi
+
        . = 0x1c00
 DataBreakpoint:
        mtspr   SPRN_SPRG_SCRATCH0, r10
@@ -606,8 +680,8 @@ DataBreakpoint:
        mfspr   r11, SPRN_SRR0
        cmplwi  cr0, r11, (dtlbie - PAGE_OFFSET)@l
        cmplwi  cr7, r11, (itlbie - PAGE_OFFSET)@l
-       beq-    cr0, 11f
-       beq-    cr7, 11f
+       beq-    cr0, 11b
+       beq-    cr7, 11b
        EXCEPTION_PROLOG_1
        EXCEPTION_PROLOG_2
        addi    r3,r1,STACK_FRAME_OVERHEAD
@@ -615,11 +689,6 @@ DataBreakpoint:
        stw     r4,_DAR(r11)
        mfspr   r5,SPRN_DSISR
        EXC_XFER_EE(0x1c00, do_break)
-11:
-       mtcr    r10
-       mfspr   r10, SPRN_SPRG_SCRATCH0
-       mfspr   r11, SPRN_SPRG_SCRATCH1
-       rfi
 
 #ifdef CONFIG_PERF_EVENTS
        . = 0x1d00
-- 
2.13.3

Reply via email to