Enable CONFIG_VMAP_STACK on the 8xx
cover Enable CONFIG_VMAP_STACK on the 8xx
The purpose of this serie is to enable CONFIG_VMAP_STACK on the 8xx.
I'm sending it now to get early feedback if any.
For the time being, there is no proper handling of stack overflow.
This serie applies on the top of the serie "powerpc: Switch to CONFIG_THREAD_INFO_IN_TASK"
Christophe Leroy (3):
powerpc/32: prepare for CONFIG_VMAP_STACK
powerpc/8xx: Use alternative scratch registers in DTLB miss handler powerpc/8xx: Enable CONFIG_VMAP_STACK
arch/powerpc/Kconfig | 1 + 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 +++++ arch/powerpc/kernel/head_8xx.S | 114 ++++++++++++++++++++++++++------- arch/powerpc/perf/8xx-pmu.c | 12 ++-- 7 files changed, 132 insertions(+), 26 deletions(-)
Signature · 1 line
2.13.3
RFC PATCH 1/3 powerpc/32: prepare for CONFIG_VMAP_STACK
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.
--- 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(+)
arch/powerpc/include/asm/processor.h +5 -0
@@ -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;
arch/powerpc/include/asm/thread_info.h +5 -0
@@ -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)
arch/powerpc/kernel/asm-offsets.c +5 -0
@@ -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);
arch/powerpc/kernel/entry_32.S +16 -0
@@ -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)
Signature · 1 line
2.13.3
RFC PATCH 2/3 powerpc/8xx: Use alternative scratch registers in DTLB miss handler
In reply to Christophe LeroyIn preparation of handling CONFIG_VMAP_STACK, we need DTLB miss handler to use different scratch registers than other exception handlers in order to not jeopardise exception entry on stack DTLB misses.
--- arch/powerpc/kernel/head_8xx.S | 27 ++++++++++++++------------- arch/powerpc/perf/8xx-pmu.c | 12 ++++++++---- 2 files changed, 22 insertions(+), 17 deletions(-)
arch/powerpc/kernel/head_8xx.S +14 -13
@@ -421,8 +421,8 @@ ITLBMissLinear: . = 0x1200 DataStoreTLBMiss: - mtspr SPRN_SPRG_SCRATCH0, r10 - mtspr SPRN_SPRG_SCRATCH1, r11 + mtspr SPRN_DAR, r10 + mtspr SPRN_M_TW, r11 mfcr r11 /* If we are faulting a kernel address, we have to use the
@@ -487,10 +487,10 @@ DataStoreTLBMiss: mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ /* Restore registers */ - mtspr SPRN_DAR, r11 /* Tag DAR */ -0: mfspr r10, SPRN_SPRG_SCRATCH0 - mfspr r11, SPRN_SPRG_SCRATCH1 +0: mfspr r10, SPRN_DAR + mtspr SPRN_DAR, r11 /* Tag DAR */ + mfspr r11, SPRN_M_TW rfi patch_site 0b, patch__dtlbmiss_exit_1
@@ -499,8 +499,9 @@ DataStoreTLBMiss: 0: lwz r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0) addi r10, r10, 1 stw r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0) - mfspr r10, SPRN_SPRG_SCRATCH0 - mfspr r11, SPRN_SPRG_SCRATCH1 + mfspr r10, SPRN_DAR + mtspr SPRN_DAR, r11 /* Tag DAR */ + mfspr r11, SPRN_M_TW rfi #endif
@@ -516,10 +517,10 @@ DTLBMissIMMR: mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ li r11, RPN_PATTERN - mtspr SPRN_DAR, r11 /* Tag DAR */ -0: mfspr r10, SPRN_SPRG_SCRATCH0 - mfspr r11, SPRN_SPRG_SCRATCH1 +0: mfspr r10, SPRN_DAR + mtspr SPRN_DAR, r11 /* Tag DAR */ + mfspr r11, SPRN_M_TW rfi patch_site 0b, patch__dtlbmiss_exit_2
@@ -534,10 +535,10 @@ DTLBMissLinear: mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ li r11, RPN_PATTERN - mtspr SPRN_DAR, r11 /* Tag DAR */ -0: mfspr r10, SPRN_SPRG_SCRATCH0 - mfspr r11, SPRN_SPRG_SCRATCH1 +0: mfspr r10, SPRN_DAR + mtspr SPRN_DAR, r11 /* Tag DAR */ + mfspr r11, SPRN_M_TW rfi patch_site 0b, patch__dtlbmiss_exit_3
arch/powerpc/perf/8xx-pmu.c +8 -4
@@ -161,10 +161,6 @@ static void mpc8xx_pmu_read(struct perf_event *event)static void mpc8xx_pmu_del (struct perf_event *event,int flags) { -/* mfspr r10, SPRN_SPRG_SCRATCH0 */ -unsigned int insn =PPC_INST_MFSPR |__PPC_RS (R10 ) | -__PPC_SPR (SPRN_SPRG_SCRATCH0 ); -mpc8xx_pmu_read (event);/* If it was the last user, stop counting to avoid useles overhead */
@@ -177,6 +173,10 @@ static void mpc8xx_pmu_del(struct perf_event *event, int flags)break ;case PERF_8xx_ID_ITLB_LOAD_MISS:if (atomic_dec_return (&itlb_miss_ref) ==0 ) { +/* mfspr r10, SPRN_SPRG_SCRATCH0 */ +unsigned int insn =PPC_INST_MFSPR |__PPC_RS (R10 ) | +__PPC_SPR (SPRN_SPRG_SCRATCH0 ); +patch_instruction_site (&patch__itlbmiss_exit_1, insn);#ifndef CONFIG_PIN_TLB_TEXT patch_instruction_site (&patch__itlbmiss_exit_2, insn);
@@ -185,6 +185,10 @@ static void mpc8xx_pmu_del(struct perf_event *event, int flags)break ;case PERF_8xx_ID_DTLB_LOAD_MISS:if (atomic_dec_return (&dtlb_miss_ref) ==0 ) { +/* mfspr r10, SPRN_DAR */ +unsigned int insn =PPC_INST_MFSPR |__PPC_RS (R10 ) | +__PPC_SPR (SPRN_DAR ); +patch_instruction_site (&patch__dtlbmiss_exit_1, insn);patch_instruction_site (&patch__dtlbmiss_exit_2, insn);patch_instruction_site (&patch__dtlbmiss_exit_3, insn);
Signature · 1 line
2.13.3
RFC PATCH 3/3 powerpc/8xx: Enable CONFIG_VMAP_STACK
In reply to Christophe LeroyThis 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.
--- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/head_8xx.S | 87 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 79 insertions(+), 9 deletions(-)
arch/powerpc/Kconfig +1 -0
@@ -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)
arch/powerpc/kernel/head_8xx.S +78 -9
151 lines not on this page · raw message
Signature · 1 line
2.13.3