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