[RFC PATCH v1 3/3] powerpc/8xx: Enable CONFIG_VMAP_STACK

Christophe Leroy christophe.leroy at c-s.fr
Tue Dec 11 22:23:56 AEDT 2018


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.leroy at 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 at ha; /* exception frame marker */ \
+	addi	r10, r10, STACK_FRAME_REGS_MARKER at 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 at 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



More information about the Linuxppc-dev mailing list