From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Thompson Subject: [PATCH v4 07/13] ARM: Move some macros from entry-armv to entry-header Date: Thu, 19 Jun 2014 11:38:17 +0100 Message-ID: <1403174303-25456-8-git-send-email-daniel.thompson@linaro.org> References: <1401961994-18033-1-git-send-email-daniel.thompson@linaro.org> <1403174303-25456-1-git-send-email-daniel.thompson@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1403174303-25456-1-git-send-email-daniel.thompson@linaro.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: Jason Wessel Cc: Mark Rutland , kernel@stlinux.com, kgdb-bugreport@lists.sourceforge.net, Linus Walleij , Jiri Slaby , Daniel Thompson , Dirk Behme , Russell King , Nicolas Pitre , Ian Campbell , Anton Vorontsov , "David A. Long" , linux-serial@vger.kernel.org, Catalin Marinas , kernel-team@android.com, devicetree@vger.kernel.org, linaro-kernel@lists.linaro.org, Pawel Moll , patches@linaro.org, Kumar Gala , Rob Herring , John Stultz , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, Greg Kroah-Hartman List-Id: devicetree@vger.kernel.org From: Anton Vorontsov Just move the macros into header file as we would want to use them for KGDB FIQ entry code. The following macros were moved: - svc_entry - usr_entry - kuser_cmpxchg_check - vector_stub To make kuser_cmpxchg_check actually work across different files, we also have to make kuser_cmpxchg64_fixup global. Signed-off-by: Anton Vorontsov Signed-off-by: John Stultz Signed-off-by: Daniel Thompson Cc: Russell King Cc: Nicolas Pitre Cc: Catalin Marinas Cc: Frederic Weisbecker --- arch/arm/kernel/entry-armv.S | 151 +----------------- arch/arm/kernel/entry-header.S | 350 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 351 insertions(+), 150 deletions(-) diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 52a949a..4172cd6 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -140,53 +140,6 @@ ENDPROC(__und_invalid) * SVC mode handlers */ -#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) -#define SPFIX(code...) code -#else -#define SPFIX(code...) -#endif - - .macro svc_entry, stack_hole=0 - UNWIND(.fnstart ) - UNWIND(.save {r0 - pc} ) - sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) -#ifdef CONFIG_THUMB2_KERNEL - SPFIX( str r0, [sp] ) @ temporarily saved - SPFIX( mov r0, sp ) - SPFIX( tst r0, #4 ) @ test original stack alignment - SPFIX( ldr r0, [sp] ) @ restored -#else - SPFIX( tst sp, #4 ) -#endif - SPFIX( subeq sp, sp, #4 ) - stmia sp, {r1 - r12} - - ldmia r0, {r3 - r5} - add r7, sp, #S_SP - 4 @ here for interlock avoidance - mov r6, #-1 @ "" "" "" "" - add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4) - SPFIX( addeq r2, r2, #4 ) - str r3, [sp, #-4]! @ save the "real" r0 copied - @ from the exception stack - - mov r3, lr - - @ - @ We are now ready to fill in the remaining blanks on the stack: - @ - @ r2 - sp_svc - @ r3 - lr_svc - @ r4 - lr_, already fixed up for correct return/restart - @ r5 - spsr_ - @ r6 - orig_r0 (see pt_regs definition in ptrace.h) - @ - stmia r7, {r2 - r6} - -#ifdef CONFIG_TRACE_IRQFLAGS - bl trace_hardirqs_off -#endif - .endm - .align 5 __dabt_svc: svc_entry @@ -306,73 +259,8 @@ ENDPROC(__pabt_svc) /* * User mode handlers - * - * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE */ -#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7) -#error "sizeof(struct pt_regs) must be a multiple of 8" -#endif - - .macro usr_entry - UNWIND(.fnstart ) - UNWIND(.cantunwind ) @ don't unwind the user space - sub sp, sp, #S_FRAME_SIZE - ARM( stmib sp, {r1 - r12} ) - THUMB( stmia sp, {r0 - r12} ) - - ldmia r0, {r3 - r5} - add r0, sp, #S_PC @ here for interlock avoidance - mov r6, #-1 @ "" "" "" "" - - str r3, [sp] @ save the "real" r0 copied - @ from the exception stack - - @ - @ We are now ready to fill in the remaining blanks on the stack: - @ - @ r4 - lr_, already fixed up for correct return/restart - @ r5 - spsr_ - @ r6 - orig_r0 (see pt_regs definition in ptrace.h) - @ - @ Also, separately save sp_usr and lr_usr - @ - stmia r0, {r4 - r6} - ARM( stmdb r0, {sp, lr}^ ) - THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) - - @ - @ Enable the alignment trap while in kernel mode - @ - alignment_trap r0, .LCcralign - - @ - @ Clear FP to mark the first stack frame - @ - zero_fp - -#ifdef CONFIG_IRQSOFF_TRACER - bl trace_hardirqs_off -#endif - ct_user_exit save = 0 - .endm - - .macro kuser_cmpxchg_check -#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ - !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) -#ifndef CONFIG_MMU -#warning "NPTL on non MMU needs fixing" -#else - @ Make sure our user space atomic helper is restarted - @ if it was interrupted in a critical region. Here we - @ perform a quick test inline since it should be false - @ 99.9999% of the time. The rest is done out of line. - cmp r4, #TASK_SIZE - blhs kuser_cmpxchg64_fixup -#endif -#endif - .endm - .align 5 __dabt_usr: usr_entry @@ -823,6 +711,7 @@ __kuser_cmpxchg64: @ 0xffff0f60 ldmfd sp!, {r4, r5, r6, pc} .text + .global kuser_cmpxchg64_fixup kuser_cmpxchg64_fixup: @ Called from kuser_cmpxchg_fixup. @ r4 = address of interrupted insn (must be preserved). @@ -964,44 +853,6 @@ __kuser_helper_end: * SP points to a minimal amount of processor-private memory, the address * of which is copied into r0 for the mode specific abort handler. */ - .macro vector_stub, name, mode, correction=0 - .align 5 - -vector_\name: - .if \correction - sub lr, lr, #\correction - .endif - - @ - @ Save r0, lr_ (parent PC) and spsr_ - @ (parent CPSR) - @ - stmia sp, {r0, lr} @ save r0, lr - mrs lr, spsr - str lr, [sp, #8] @ save spsr - - @ - @ Prepare for SVC32 mode. IRQs remain disabled. - @ - mrs r0, cpsr - eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE) - msr spsr_cxsf, r0 - - @ - @ the branch table must immediately follow this code - @ - and lr, lr, #0x0f - THUMB( adr r0, 1f ) - THUMB( ldr lr, [r0, lr, lsl #2] ) - mov r0, sp - ARM( ldr lr, [pc, lr, lsl #2] ) - movs pc, lr @ branch to handler in SVC mode -ENDPROC(vector_\name) - - .align 2 - @ handler addresses follow this label -1: - .endm .section .stubs, "ax", %progbits __stubs_start: diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 5d702f8..572f4b4 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -356,3 +356,353 @@ scno .req r7 @ syscall number tbl .req r8 @ syscall table pointer why .req r8 @ Linux syscall (!= 0) tsk .req r9 @ current thread_info + +/* + * SVC mode handler macros + */ + +#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) +#define SPFIX(code...) code +#else +#define SPFIX(code...) +#endif + + .macro svc_entry, stack_hole=0 + UNWIND(.fnstart ) + UNWIND(.save {r0 - pc} ) + sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) +#ifdef CONFIG_THUMB2_KERNEL + SPFIX( str r0, [sp] ) @ temporarily saved + SPFIX( mov r0, sp ) + SPFIX( tst r0, #4 ) @ test original stack alignment + SPFIX( ldr r0, [sp] ) @ restored +#else + SPFIX( tst sp, #4 ) +#endif + SPFIX( subeq sp, sp, #4 ) + stmia sp, {r1 - r12} + + ldmia r0, {r3 - r5} + add r7, sp, #S_SP - 4 @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4) + SPFIX( addeq r2, r2, #4 ) + str r3, [sp, #-4]! @ save the "real" r0 copied + @ from the exception stack + + mov r3, lr + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r2 - sp_svc + @ r3 - lr_svc + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + stmia r7, {r2 - r6} + +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_off +#endif + .endm + +/* + * User mode handler macros + * + * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE + */ + +#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7) +#error "sizeof(struct pt_regs) must be a multiple of 8" +#endif + + .macro usr_entry + UNWIND(.fnstart ) + UNWIND(.cantunwind ) @ don't unwind the user space + sub sp, sp, #S_FRAME_SIZE + ARM( stmib sp, {r1 - r12} ) + THUMB( stmia sp, {r0 - r12} ) + + ldmia r0, {r3 - r5} + add r0, sp, #S_PC @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + + str r3, [sp] @ save the "real" r0 copied + @ from the exception stack + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r0, {r4 - r6} + ARM( stmdb r0, {sp, lr}^ ) + THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r0, .LCcralign + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + +#ifdef CONFIG_IRQSOFF_TRACER + bl trace_hardirqs_off +#endif + ct_user_exit save = 0 + .endm + + .macro kuser_cmpxchg_check +#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ + !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ Make sure our user space atomic helper is restarted + @ if it was interrupted in a critical region. Here we + @ perform a quick test inline since it should be false + @ 99.9999% of the time. The rest is done out of line. + cmp r4, #TASK_SIZE + blhs kuser_cmpxchg64_fixup +#endif +#endif + .endm + +#error "sizeof(struct pt_regs) must be a multiple of 8" +#endif + + .macro usr_entry + UNWIND(.fnstart ) + UNWIND(.cantunwind ) @ don't unwind the user space + sub sp, sp, #S_FRAME_SIZE + ARM( stmib sp, {r1 - r12} ) + THUMB( stmia sp, {r0 - r12} ) + + ldmia r0, {r3 - r5} + add r0, sp, #S_PC @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + + str r3, [sp] @ save the "real" r0 copied + @ from the exception stack + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r0, {r4 - r6} + ARM( stmdb r0, {sp, lr}^ ) + THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r0, .LCcralign + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + +#ifdef CONFIG_IRQSOFF_TRACER + bl trace_hardirqs_off +#endif + ct_user_exit save = 0 + .endm + + .macro kuser_cmpxchg_check +#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ + !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ Make sure our user space atomic helper is restarted + @ if it was interrupted in a critical region. Here we + @ perform a quick test inline since it should be false + @ 99.9999% of the time. The rest is done out of line. + cmp r4, #TASK_SIZE + blhs kuser_cmpxchg64_fixup +#endif +#endif + .endm + +#error "sizeof(struct pt_regs) must be a multiple of 8" +#endif + + .macro usr_entry + UNWIND(.fnstart ) + UNWIND(.cantunwind ) @ don't unwind the user space + sub sp, sp, #S_FRAME_SIZE + ARM( stmib sp, {r1 - r12} ) + THUMB( stmia sp, {r0 - r12} ) + + ldmia r0, {r3 - r5} + add r0, sp, #S_PC @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + + str r3, [sp] @ save the "real" r0 copied + @ from the exception stack + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r0, {r4 - r6} + ARM( stmdb r0, {sp, lr}^ ) + THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r0, .LCcralign + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + +#ifdef CONFIG_IRQSOFF_TRACER + bl trace_hardirqs_off +#endif + ct_user_exit save = 0 + .endm + + .macro kuser_cmpxchg_check +#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ + !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ Make sure our user space atomic helper is restarted + @ if it was interrupted in a critical region. Here we + @ perform a quick test inline since it should be false + @ 99.9999% of the time. The rest is done out of line. + cmp r4, #TASK_SIZE + blhs kuser_cmpxchg64_fixup +#endif +#endif + .endm + +#error "sizeof(struct pt_regs) must be a multiple of 8" +#endif + + .macro usr_entry + UNWIND(.fnstart ) + UNWIND(.cantunwind ) @ don't unwind the user space + sub sp, sp, #S_FRAME_SIZE + ARM( stmib sp, {r1 - r12} ) + THUMB( stmia sp, {r0 - r12} ) + + ldmia r0, {r3 - r5} + add r0, sp, #S_PC @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + + str r3, [sp] @ save the "real" r0 copied + @ from the exception stack + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r0, {r4 - r6} + ARM( stmdb r0, {sp, lr}^ ) + THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r0 + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + +#ifdef CONFIG_IRQSOFF_TRACER + bl trace_hardirqs_off +#endif + ct_user_exit save = 0 + .endm + + .macro kuser_cmpxchg_check +#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ + !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ Make sure our user space atomic helper is restarted + @ if it was interrupted in a critical region. Here we + @ perform a quick test inline since it should be false + @ 99.9999% of the time. The rest is done out of line. + cmp r4, #TASK_SIZE + blhs kuser_cmpxchg64_fixup +#endif +#endif + .endm + +/* + * Vector stubs macro. + */ + .macro vector_stub, name, mode, correction=0 + .align 5 + +vector_\name: + .if \correction + sub lr, lr, #\correction + .endif + + @ + @ Save r0, lr_ (parent PC) and spsr_ + @ (parent CPSR) + @ + stmia sp, {r0, lr} @ save r0, lr + mrs lr, spsr + str lr, [sp, #8] @ save spsr + + @ + @ Prepare for SVC32 mode. IRQs remain disabled. + @ + mrs r0, cpsr + eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE) + msr spsr_cxsf, r0 + + @ + @ the branch table must immediately follow this code + @ + and lr, lr, #0x0f + THUMB( adr r0, 1f ) + THUMB( ldr lr, [r0, lr, lsl #2] ) + mov r0, sp + ARM( ldr lr, [pc, lr, lsl #2] ) + movs pc, lr @ branch to handler in SVC mode +ENDPROC(vector_\name) + + .align 2 + @ handler addresses follow this label +1: + .endm + + -- 1.9.3 From mboxrd@z Thu Jan 1 00:00:00 1970 From: daniel.thompson@linaro.org (Daniel Thompson) Date: Thu, 19 Jun 2014 11:38:17 +0100 Subject: [PATCH v4 07/13] ARM: Move some macros from entry-armv to entry-header In-Reply-To: <1403174303-25456-1-git-send-email-daniel.thompson@linaro.org> References: <1401961994-18033-1-git-send-email-daniel.thompson@linaro.org> <1403174303-25456-1-git-send-email-daniel.thompson@linaro.org> Message-ID: <1403174303-25456-8-git-send-email-daniel.thompson@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org From: Anton Vorontsov Just move the macros into header file as we would want to use them for KGDB FIQ entry code. The following macros were moved: - svc_entry - usr_entry - kuser_cmpxchg_check - vector_stub To make kuser_cmpxchg_check actually work across different files, we also have to make kuser_cmpxchg64_fixup global. Signed-off-by: Anton Vorontsov Signed-off-by: John Stultz Signed-off-by: Daniel Thompson Cc: Russell King Cc: Nicolas Pitre Cc: Catalin Marinas Cc: Frederic Weisbecker --- arch/arm/kernel/entry-armv.S | 151 +----------------- arch/arm/kernel/entry-header.S | 350 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 351 insertions(+), 150 deletions(-) diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 52a949a..4172cd6 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -140,53 +140,6 @@ ENDPROC(__und_invalid) * SVC mode handlers */ -#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) -#define SPFIX(code...) code -#else -#define SPFIX(code...) -#endif - - .macro svc_entry, stack_hole=0 - UNWIND(.fnstart ) - UNWIND(.save {r0 - pc} ) - sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) -#ifdef CONFIG_THUMB2_KERNEL - SPFIX( str r0, [sp] ) @ temporarily saved - SPFIX( mov r0, sp ) - SPFIX( tst r0, #4 ) @ test original stack alignment - SPFIX( ldr r0, [sp] ) @ restored -#else - SPFIX( tst sp, #4 ) -#endif - SPFIX( subeq sp, sp, #4 ) - stmia sp, {r1 - r12} - - ldmia r0, {r3 - r5} - add r7, sp, #S_SP - 4 @ here for interlock avoidance - mov r6, #-1 @ "" "" "" "" - add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4) - SPFIX( addeq r2, r2, #4 ) - str r3, [sp, #-4]! @ save the "real" r0 copied - @ from the exception stack - - mov r3, lr - - @ - @ We are now ready to fill in the remaining blanks on the stack: - @ - @ r2 - sp_svc - @ r3 - lr_svc - @ r4 - lr_, already fixed up for correct return/restart - @ r5 - spsr_ - @ r6 - orig_r0 (see pt_regs definition in ptrace.h) - @ - stmia r7, {r2 - r6} - -#ifdef CONFIG_TRACE_IRQFLAGS - bl trace_hardirqs_off -#endif - .endm - .align 5 __dabt_svc: svc_entry @@ -306,73 +259,8 @@ ENDPROC(__pabt_svc) /* * User mode handlers - * - * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE */ -#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7) -#error "sizeof(struct pt_regs) must be a multiple of 8" -#endif - - .macro usr_entry - UNWIND(.fnstart ) - UNWIND(.cantunwind ) @ don't unwind the user space - sub sp, sp, #S_FRAME_SIZE - ARM( stmib sp, {r1 - r12} ) - THUMB( stmia sp, {r0 - r12} ) - - ldmia r0, {r3 - r5} - add r0, sp, #S_PC @ here for interlock avoidance - mov r6, #-1 @ "" "" "" "" - - str r3, [sp] @ save the "real" r0 copied - @ from the exception stack - - @ - @ We are now ready to fill in the remaining blanks on the stack: - @ - @ r4 - lr_, already fixed up for correct return/restart - @ r5 - spsr_ - @ r6 - orig_r0 (see pt_regs definition in ptrace.h) - @ - @ Also, separately save sp_usr and lr_usr - @ - stmia r0, {r4 - r6} - ARM( stmdb r0, {sp, lr}^ ) - THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) - - @ - @ Enable the alignment trap while in kernel mode - @ - alignment_trap r0, .LCcralign - - @ - @ Clear FP to mark the first stack frame - @ - zero_fp - -#ifdef CONFIG_IRQSOFF_TRACER - bl trace_hardirqs_off -#endif - ct_user_exit save = 0 - .endm - - .macro kuser_cmpxchg_check -#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ - !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) -#ifndef CONFIG_MMU -#warning "NPTL on non MMU needs fixing" -#else - @ Make sure our user space atomic helper is restarted - @ if it was interrupted in a critical region. Here we - @ perform a quick test inline since it should be false - @ 99.9999% of the time. The rest is done out of line. - cmp r4, #TASK_SIZE - blhs kuser_cmpxchg64_fixup -#endif -#endif - .endm - .align 5 __dabt_usr: usr_entry @@ -823,6 +711,7 @@ __kuser_cmpxchg64: @ 0xffff0f60 ldmfd sp!, {r4, r5, r6, pc} .text + .global kuser_cmpxchg64_fixup kuser_cmpxchg64_fixup: @ Called from kuser_cmpxchg_fixup. @ r4 = address of interrupted insn (must be preserved). @@ -964,44 +853,6 @@ __kuser_helper_end: * SP points to a minimal amount of processor-private memory, the address * of which is copied into r0 for the mode specific abort handler. */ - .macro vector_stub, name, mode, correction=0 - .align 5 - -vector_\name: - .if \correction - sub lr, lr, #\correction - .endif - - @ - @ Save r0, lr_ (parent PC) and spsr_ - @ (parent CPSR) - @ - stmia sp, {r0, lr} @ save r0, lr - mrs lr, spsr - str lr, [sp, #8] @ save spsr - - @ - @ Prepare for SVC32 mode. IRQs remain disabled. - @ - mrs r0, cpsr - eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE) - msr spsr_cxsf, r0 - - @ - @ the branch table must immediately follow this code - @ - and lr, lr, #0x0f - THUMB( adr r0, 1f ) - THUMB( ldr lr, [r0, lr, lsl #2] ) - mov r0, sp - ARM( ldr lr, [pc, lr, lsl #2] ) - movs pc, lr @ branch to handler in SVC mode -ENDPROC(vector_\name) - - .align 2 - @ handler addresses follow this label -1: - .endm .section .stubs, "ax", %progbits __stubs_start: diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 5d702f8..572f4b4 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -356,3 +356,353 @@ scno .req r7 @ syscall number tbl .req r8 @ syscall table pointer why .req r8 @ Linux syscall (!= 0) tsk .req r9 @ current thread_info + +/* + * SVC mode handler macros + */ + +#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) +#define SPFIX(code...) code +#else +#define SPFIX(code...) +#endif + + .macro svc_entry, stack_hole=0 + UNWIND(.fnstart ) + UNWIND(.save {r0 - pc} ) + sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) +#ifdef CONFIG_THUMB2_KERNEL + SPFIX( str r0, [sp] ) @ temporarily saved + SPFIX( mov r0, sp ) + SPFIX( tst r0, #4 ) @ test original stack alignment + SPFIX( ldr r0, [sp] ) @ restored +#else + SPFIX( tst sp, #4 ) +#endif + SPFIX( subeq sp, sp, #4 ) + stmia sp, {r1 - r12} + + ldmia r0, {r3 - r5} + add r7, sp, #S_SP - 4 @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4) + SPFIX( addeq r2, r2, #4 ) + str r3, [sp, #-4]! @ save the "real" r0 copied + @ from the exception stack + + mov r3, lr + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r2 - sp_svc + @ r3 - lr_svc + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + stmia r7, {r2 - r6} + +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_off +#endif + .endm + +/* + * User mode handler macros + * + * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE + */ + +#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7) +#error "sizeof(struct pt_regs) must be a multiple of 8" +#endif + + .macro usr_entry + UNWIND(.fnstart ) + UNWIND(.cantunwind ) @ don't unwind the user space + sub sp, sp, #S_FRAME_SIZE + ARM( stmib sp, {r1 - r12} ) + THUMB( stmia sp, {r0 - r12} ) + + ldmia r0, {r3 - r5} + add r0, sp, #S_PC @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + + str r3, [sp] @ save the "real" r0 copied + @ from the exception stack + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r0, {r4 - r6} + ARM( stmdb r0, {sp, lr}^ ) + THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r0, .LCcralign + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + +#ifdef CONFIG_IRQSOFF_TRACER + bl trace_hardirqs_off +#endif + ct_user_exit save = 0 + .endm + + .macro kuser_cmpxchg_check +#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ + !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ Make sure our user space atomic helper is restarted + @ if it was interrupted in a critical region. Here we + @ perform a quick test inline since it should be false + @ 99.9999% of the time. The rest is done out of line. + cmp r4, #TASK_SIZE + blhs kuser_cmpxchg64_fixup +#endif +#endif + .endm + +#error "sizeof(struct pt_regs) must be a multiple of 8" +#endif + + .macro usr_entry + UNWIND(.fnstart ) + UNWIND(.cantunwind ) @ don't unwind the user space + sub sp, sp, #S_FRAME_SIZE + ARM( stmib sp, {r1 - r12} ) + THUMB( stmia sp, {r0 - r12} ) + + ldmia r0, {r3 - r5} + add r0, sp, #S_PC @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + + str r3, [sp] @ save the "real" r0 copied + @ from the exception stack + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r0, {r4 - r6} + ARM( stmdb r0, {sp, lr}^ ) + THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r0, .LCcralign + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + +#ifdef CONFIG_IRQSOFF_TRACER + bl trace_hardirqs_off +#endif + ct_user_exit save = 0 + .endm + + .macro kuser_cmpxchg_check +#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ + !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ Make sure our user space atomic helper is restarted + @ if it was interrupted in a critical region. Here we + @ perform a quick test inline since it should be false + @ 99.9999% of the time. The rest is done out of line. + cmp r4, #TASK_SIZE + blhs kuser_cmpxchg64_fixup +#endif +#endif + .endm + +#error "sizeof(struct pt_regs) must be a multiple of 8" +#endif + + .macro usr_entry + UNWIND(.fnstart ) + UNWIND(.cantunwind ) @ don't unwind the user space + sub sp, sp, #S_FRAME_SIZE + ARM( stmib sp, {r1 - r12} ) + THUMB( stmia sp, {r0 - r12} ) + + ldmia r0, {r3 - r5} + add r0, sp, #S_PC @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + + str r3, [sp] @ save the "real" r0 copied + @ from the exception stack + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r0, {r4 - r6} + ARM( stmdb r0, {sp, lr}^ ) + THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r0, .LCcralign + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + +#ifdef CONFIG_IRQSOFF_TRACER + bl trace_hardirqs_off +#endif + ct_user_exit save = 0 + .endm + + .macro kuser_cmpxchg_check +#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ + !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ Make sure our user space atomic helper is restarted + @ if it was interrupted in a critical region. Here we + @ perform a quick test inline since it should be false + @ 99.9999% of the time. The rest is done out of line. + cmp r4, #TASK_SIZE + blhs kuser_cmpxchg64_fixup +#endif +#endif + .endm + +#error "sizeof(struct pt_regs) must be a multiple of 8" +#endif + + .macro usr_entry + UNWIND(.fnstart ) + UNWIND(.cantunwind ) @ don't unwind the user space + sub sp, sp, #S_FRAME_SIZE + ARM( stmib sp, {r1 - r12} ) + THUMB( stmia sp, {r0 - r12} ) + + ldmia r0, {r3 - r5} + add r0, sp, #S_PC @ here for interlock avoidance + mov r6, #-1 @ "" "" "" "" + + str r3, [sp] @ save the "real" r0 copied + @ from the exception stack + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r4 - lr_, already fixed up for correct return/restart + @ r5 - spsr_ + @ r6 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r0, {r4 - r6} + ARM( stmdb r0, {sp, lr}^ ) + THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r0 + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + +#ifdef CONFIG_IRQSOFF_TRACER + bl trace_hardirqs_off +#endif + ct_user_exit save = 0 + .endm + + .macro kuser_cmpxchg_check +#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ + !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#ifndef CONFIG_MMU +#warning "NPTL on non MMU needs fixing" +#else + @ Make sure our user space atomic helper is restarted + @ if it was interrupted in a critical region. Here we + @ perform a quick test inline since it should be false + @ 99.9999% of the time. The rest is done out of line. + cmp r4, #TASK_SIZE + blhs kuser_cmpxchg64_fixup +#endif +#endif + .endm + +/* + * Vector stubs macro. + */ + .macro vector_stub, name, mode, correction=0 + .align 5 + +vector_\name: + .if \correction + sub lr, lr, #\correction + .endif + + @ + @ Save r0, lr_ (parent PC) and spsr_ + @ (parent CPSR) + @ + stmia sp, {r0, lr} @ save r0, lr + mrs lr, spsr + str lr, [sp, #8] @ save spsr + + @ + @ Prepare for SVC32 mode. IRQs remain disabled. + @ + mrs r0, cpsr + eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE) + msr spsr_cxsf, r0 + + @ + @ the branch table must immediately follow this code + @ + and lr, lr, #0x0f + THUMB( adr r0, 1f ) + THUMB( ldr lr, [r0, lr, lsl #2] ) + mov r0, sp + ARM( ldr lr, [pc, lr, lsl #2] ) + movs pc, lr @ branch to handler in SVC mode +ENDPROC(vector_\name) + + .align 2 + @ handler addresses follow this label +1: + .endm + + -- 1.9.3