diff options
Diffstat (limited to 'arch/arm/kernel/entry-common.S')
-rw-r--r-- | arch/arm/kernel/entry-common.S | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 53a7e0dea44d..3f8d0e3aefab 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -9,19 +9,10 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | 11 | ||
12 | #include <asm/thread_info.h> | ||
13 | #include <asm/ptrace.h> | ||
14 | #include <asm/unistd.h> | 12 | #include <asm/unistd.h> |
15 | 13 | ||
16 | #include "entry-header.S" | 14 | #include "entry-header.S" |
17 | 15 | ||
18 | /* | ||
19 | * We rely on the fact that R0 is at the bottom of the stack (due to | ||
20 | * slow/fast restore user regs). | ||
21 | */ | ||
22 | #if S_R0 != 0 | ||
23 | #error "Please fix" | ||
24 | #endif | ||
25 | 16 | ||
26 | .align 5 | 17 | .align 5 |
27 | /* | 18 | /* |
@@ -30,11 +21,19 @@ | |||
30 | * stack. | 21 | * stack. |
31 | */ | 22 | */ |
32 | ret_fast_syscall: | 23 | ret_fast_syscall: |
33 | disable_irq r1 @ disable interrupts | 24 | disable_irq @ disable interrupts |
34 | ldr r1, [tsk, #TI_FLAGS] | 25 | ldr r1, [tsk, #TI_FLAGS] |
35 | tst r1, #_TIF_WORK_MASK | 26 | tst r1, #_TIF_WORK_MASK |
36 | bne fast_work_pending | 27 | bne fast_work_pending |
37 | fast_restore_user_regs | 28 | |
29 | @ fast_restore_user_regs | ||
30 | ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr | ||
31 | ldr lr, [sp, #S_OFF + S_PC]! @ get pc | ||
32 | msr spsr_cxsf, r1 @ save in spsr_svc | ||
33 | ldmdb sp, {r1 - lr}^ @ get calling r1 - lr | ||
34 | mov r0, r0 | ||
35 | add sp, sp, #S_FRAME_SIZE - S_PC | ||
36 | movs pc, lr @ return & move spsr_svc into cpsr | ||
38 | 37 | ||
39 | /* | 38 | /* |
40 | * Ok, we need to do extra processing, enter the slow path. | 39 | * Ok, we need to do extra processing, enter the slow path. |
@@ -49,7 +48,7 @@ work_pending: | |||
49 | mov r0, sp @ 'regs' | 48 | mov r0, sp @ 'regs' |
50 | mov r2, why @ 'syscall' | 49 | mov r2, why @ 'syscall' |
51 | bl do_notify_resume | 50 | bl do_notify_resume |
52 | disable_irq r1 @ disable interrupts | 51 | disable_irq @ disable interrupts |
53 | b no_work_pending | 52 | b no_work_pending |
54 | 53 | ||
55 | work_resched: | 54 | work_resched: |
@@ -59,12 +58,19 @@ work_resched: | |||
59 | */ | 58 | */ |
60 | ENTRY(ret_to_user) | 59 | ENTRY(ret_to_user) |
61 | ret_slow_syscall: | 60 | ret_slow_syscall: |
62 | disable_irq r1 @ disable interrupts | 61 | disable_irq @ disable interrupts |
63 | ldr r1, [tsk, #TI_FLAGS] | 62 | ldr r1, [tsk, #TI_FLAGS] |
64 | tst r1, #_TIF_WORK_MASK | 63 | tst r1, #_TIF_WORK_MASK |
65 | bne work_pending | 64 | bne work_pending |
66 | no_work_pending: | 65 | no_work_pending: |
67 | slow_restore_user_regs | 66 | @ slow_restore_user_regs |
67 | ldr r1, [sp, #S_PSR] @ get calling cpsr | ||
68 | ldr lr, [sp, #S_PC]! @ get pc | ||
69 | msr spsr_cxsf, r1 @ save in spsr_svc | ||
70 | ldmdb sp, {r0 - lr}^ @ get calling r1 - lr | ||
71 | mov r0, r0 | ||
72 | add sp, sp, #S_FRAME_SIZE - S_PC | ||
73 | movs pc, lr @ return & move spsr_svc into cpsr | ||
68 | 74 | ||
69 | /* | 75 | /* |
70 | * This is how we return from a fork. | 76 | * This is how we return from a fork. |
@@ -116,9 +122,26 @@ ENTRY(ret_from_fork) | |||
116 | 122 | ||
117 | .align 5 | 123 | .align 5 |
118 | ENTRY(vector_swi) | 124 | ENTRY(vector_swi) |
119 | save_user_regs | 125 | sub sp, sp, #S_FRAME_SIZE |
126 | stmia sp, {r0 - r12} @ Calling r0 - r12 | ||
127 | add r8, sp, #S_PC | ||
128 | stmdb r8, {sp, lr}^ @ Calling sp, lr | ||
129 | mrs r8, spsr @ called from non-FIQ mode, so ok. | ||
130 | str lr, [sp, #S_PC] @ Save calling PC | ||
131 | str r8, [sp, #S_PSR] @ Save CPSR | ||
132 | str r0, [sp, #S_OLD_R0] @ Save OLD_R0 | ||
120 | zero_fp | 133 | zero_fp |
121 | get_scno | 134 | |
135 | /* | ||
136 | * Get the system call number. | ||
137 | */ | ||
138 | #ifdef CONFIG_ARM_THUMB | ||
139 | tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs | ||
140 | addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in | ||
141 | ldreq scno, [lr, #-4] | ||
142 | #else | ||
143 | ldr scno, [lr, #-4] @ get SWI instruction | ||
144 | #endif | ||
122 | arm710_bug_check scno, ip | 145 | arm710_bug_check scno, ip |
123 | 146 | ||
124 | #ifdef CONFIG_ALIGNMENT_TRAP | 147 | #ifdef CONFIG_ALIGNMENT_TRAP |
@@ -126,14 +149,14 @@ ENTRY(vector_swi) | |||
126 | ldr ip, [ip] | 149 | ldr ip, [ip] |
127 | mcr p15, 0, ip, c1, c0 @ update control register | 150 | mcr p15, 0, ip, c1, c0 @ update control register |
128 | #endif | 151 | #endif |
129 | enable_irq ip | 152 | enable_irq |
130 | 153 | ||
131 | str r4, [sp, #-S_OFF]! @ push fifth arg | 154 | str r4, [sp, #-S_OFF]! @ push fifth arg |
132 | 155 | ||
133 | get_thread_info tsk | 156 | get_thread_info tsk |
134 | ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing | 157 | ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing |
135 | bic scno, scno, #0xff000000 @ mask off SWI op-code | 158 | bic scno, scno, #0xff000000 @ mask off SWI op-code |
136 | eor scno, scno, #OS_NUMBER << 20 @ check OS number | 159 | eor scno, scno, #__NR_SYSCALL_BASE @ check OS number |
137 | adr tbl, sys_call_table @ load syscall table pointer | 160 | adr tbl, sys_call_table @ load syscall table pointer |
138 | tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? | 161 | tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? |
139 | bne __sys_trace | 162 | bne __sys_trace |
@@ -144,8 +167,8 @@ ENTRY(vector_swi) | |||
144 | 167 | ||
145 | add r1, sp, #S_OFF | 168 | add r1, sp, #S_OFF |
146 | 2: mov why, #0 @ no longer a real syscall | 169 | 2: mov why, #0 @ no longer a real syscall |
147 | cmp scno, #ARMSWI_OFFSET | 170 | cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) |
148 | eor r0, scno, #OS_NUMBER << 20 @ put OS number back | 171 | eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back |
149 | bcs arm_syscall | 172 | bcs arm_syscall |
150 | b sys_ni_syscall @ not private func | 173 | b sys_ni_syscall @ not private func |
151 | 174 | ||
@@ -190,7 +213,7 @@ ENTRY(sys_call_table) | |||
190 | @ r5 = syscall table | 213 | @ r5 = syscall table |
191 | .type sys_syscall, #function | 214 | .type sys_syscall, #function |
192 | sys_syscall: | 215 | sys_syscall: |
193 | eor scno, r0, #OS_NUMBER << 20 | 216 | eor scno, r0, #__NR_SYSCALL_BASE |
194 | cmp scno, #__NR_syscall - __NR_SYSCALL_BASE | 217 | cmp scno, #__NR_syscall - __NR_SYSCALL_BASE |
195 | cmpne scno, #NR_syscalls @ check range | 218 | cmpne scno, #NR_syscalls @ check range |
196 | stmloia sp, {r5, r6} @ shuffle args | 219 | stmloia sp, {r5, r6} @ shuffle args |