diff options
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 322 |
1 files changed, 155 insertions, 167 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index bea9ee37ac9d..0476174dfff5 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -9,7 +9,6 @@ | |||
9 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 9 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/sys.h> | ||
13 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
15 | #include <asm/cache.h> | 14 | #include <asm/cache.h> |
@@ -49,7 +48,7 @@ SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR | |||
49 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | 48 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE |
50 | 49 | ||
51 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 50 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
52 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) | 51 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_PER_TRAP ) |
53 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 52 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
54 | _TIF_MCCK_PENDING) | 53 | _TIF_MCCK_PENDING) |
55 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | 54 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ |
@@ -72,25 +71,9 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
72 | l %r1,BASED(.Ltrace_irq_off_caller) | 71 | l %r1,BASED(.Ltrace_irq_off_caller) |
73 | basr %r14,%r1 | 72 | basr %r14,%r1 |
74 | .endm | 73 | .endm |
75 | |||
76 | .macro TRACE_IRQS_CHECK_ON | ||
77 | tm SP_PSW(%r15),0x03 # irqs enabled? | ||
78 | bz BASED(0f) | ||
79 | TRACE_IRQS_ON | ||
80 | 0: | ||
81 | .endm | ||
82 | |||
83 | .macro TRACE_IRQS_CHECK_OFF | ||
84 | tm SP_PSW(%r15),0x03 # irqs enabled? | ||
85 | bz BASED(0f) | ||
86 | TRACE_IRQS_OFF | ||
87 | 0: | ||
88 | .endm | ||
89 | #else | 74 | #else |
90 | #define TRACE_IRQS_ON | 75 | #define TRACE_IRQS_ON |
91 | #define TRACE_IRQS_OFF | 76 | #define TRACE_IRQS_OFF |
92 | #define TRACE_IRQS_CHECK_ON | ||
93 | #define TRACE_IRQS_CHECK_OFF | ||
94 | #endif | 77 | #endif |
95 | 78 | ||
96 | #ifdef CONFIG_LOCKDEP | 79 | #ifdef CONFIG_LOCKDEP |
@@ -126,31 +109,36 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
126 | 1: stm %r10,%r11,\lc_sum | 109 | 1: stm %r10,%r11,\lc_sum |
127 | .endm | 110 | .endm |
128 | 111 | ||
129 | .macro SAVE_ALL_BASE savearea | 112 | .macro SAVE_ALL_SVC psworg,savearea |
130 | stm %r12,%r15,\savearea | 113 | stm %r12,%r15,\savearea |
131 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 | 114 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 |
115 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp | ||
116 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | ||
132 | .endm | 117 | .endm |
133 | 118 | ||
134 | .macro SAVE_ALL_SVC psworg,savearea | 119 | .macro SAVE_ALL_BASE savearea |
135 | la %r12,\psworg | 120 | stm %r12,%r15,\savearea |
136 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp | 121 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 |
137 | .endm | 122 | .endm |
138 | 123 | ||
139 | .macro SAVE_ALL_SYNC psworg,savearea | 124 | .macro SAVE_ALL_PGM psworg,savearea |
140 | la %r12,\psworg | ||
141 | tm \psworg+1,0x01 # test problem state bit | 125 | tm \psworg+1,0x01 # test problem state bit |
142 | bz BASED(2f) # skip stack setup save | ||
143 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp | ||
144 | #ifdef CONFIG_CHECK_STACK | 126 | #ifdef CONFIG_CHECK_STACK |
145 | b BASED(3f) | 127 | bnz BASED(1f) |
146 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD | 128 | tml %r15,STACK_SIZE - CONFIG_STACK_GUARD |
147 | bz BASED(stack_overflow) | 129 | bnz BASED(2f) |
148 | 3: | 130 | la %r12,\psworg |
131 | b BASED(stack_overflow) | ||
132 | #else | ||
133 | bz BASED(2f) | ||
149 | #endif | 134 | #endif |
150 | 2: | 135 | 1: l %r15,__LC_KERNEL_STACK # problem state -> load ksp |
136 | 2: s %r15,BASED(.Lc_spsize) # make room for registers & psw | ||
151 | .endm | 137 | .endm |
152 | 138 | ||
153 | .macro SAVE_ALL_ASYNC psworg,savearea | 139 | .macro SAVE_ALL_ASYNC psworg,savearea |
140 | stm %r12,%r15,\savearea | ||
141 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 | ||
154 | la %r12,\psworg | 142 | la %r12,\psworg |
155 | tm \psworg+1,0x01 # test problem state bit | 143 | tm \psworg+1,0x01 # test problem state bit |
156 | bnz BASED(1f) # from user -> load async stack | 144 | bnz BASED(1f) # from user -> load async stack |
@@ -165,27 +153,23 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
165 | 0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? | 153 | 0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? |
166 | slr %r14,%r15 | 154 | slr %r14,%r15 |
167 | sra %r14,STACK_SHIFT | 155 | sra %r14,STACK_SHIFT |
168 | be BASED(2f) | ||
169 | 1: l %r15,__LC_ASYNC_STACK | ||
170 | #ifdef CONFIG_CHECK_STACK | 156 | #ifdef CONFIG_CHECK_STACK |
171 | b BASED(3f) | 157 | bnz BASED(1f) |
172 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD | 158 | tml %r15,STACK_SIZE - CONFIG_STACK_GUARD |
173 | bz BASED(stack_overflow) | 159 | bnz BASED(2f) |
174 | 3: | 160 | b BASED(stack_overflow) |
161 | #else | ||
162 | bz BASED(2f) | ||
175 | #endif | 163 | #endif |
176 | 2: | 164 | 1: l %r15,__LC_ASYNC_STACK |
165 | 2: s %r15,BASED(.Lc_spsize) # make room for registers & psw | ||
177 | .endm | 166 | .endm |
178 | 167 | ||
179 | .macro CREATE_STACK_FRAME psworg,savearea | 168 | .macro CREATE_STACK_FRAME savearea |
180 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 169 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
181 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | ||
182 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 | 170 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 |
183 | icm %r12,12,__LC_SVC_ILC | ||
184 | stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack | ||
185 | st %r12,SP_ILC(%r15) | ||
186 | mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack | 171 | mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack |
187 | la %r12,0 | 172 | stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack |
188 | st %r12,__SF_BACKCHAIN(%r15) # clear back chain | ||
189 | .endm | 173 | .endm |
190 | 174 | ||
191 | .macro RESTORE_ALL psworg,sync | 175 | .macro RESTORE_ALL psworg,sync |
@@ -198,6 +182,14 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
198 | lpsw \psworg # back to caller | 182 | lpsw \psworg # back to caller |
199 | .endm | 183 | .endm |
200 | 184 | ||
185 | .macro REENABLE_IRQS | ||
186 | mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) | ||
187 | ni __SF_EMPTY(%r15),0xbf | ||
188 | ssm __SF_EMPTY(%r15) | ||
189 | .endm | ||
190 | |||
191 | .section .kprobes.text, "ax" | ||
192 | |||
201 | /* | 193 | /* |
202 | * Scheduler resume function, called by switch_to | 194 | * Scheduler resume function, called by switch_to |
203 | * gpr2 = (task_struct *) prev | 195 | * gpr2 = (task_struct *) prev |
@@ -208,31 +200,22 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
208 | .globl __switch_to | 200 | .globl __switch_to |
209 | __switch_to: | 201 | __switch_to: |
210 | basr %r1,0 | 202 | basr %r1,0 |
211 | __switch_to_base: | 203 | 0: l %r4,__THREAD_info(%r2) # get thread_info of prev |
212 | tm __THREAD_per(%r3),0xe8 # new process is using per ? | 204 | l %r5,__THREAD_info(%r3) # get thread_info of next |
213 | bz __switch_to_noper-__switch_to_base(%r1) # if not we're fine | ||
214 | stctl %c9,%c11,__SF_EMPTY(%r15) # We are using per stuff | ||
215 | clc __THREAD_per(12,%r3),__SF_EMPTY(%r15) | ||
216 | be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's | ||
217 | lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't | ||
218 | __switch_to_noper: | ||
219 | l %r4,__THREAD_info(%r2) # get thread_info of prev | ||
220 | tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? | 205 | tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? |
221 | bz __switch_to_no_mcck-__switch_to_base(%r1) | 206 | bz 1f-0b(%r1) |
222 | ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev | 207 | ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev |
223 | l %r4,__THREAD_info(%r3) # get thread_info of next | 208 | oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next |
224 | oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next | 209 | 1: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task |
225 | __switch_to_no_mcck: | 210 | st %r15,__THREAD_ksp(%r2) # store kernel stack of prev |
226 | stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task | 211 | l %r15,__THREAD_ksp(%r3) # load kernel stack of next |
227 | st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp | 212 | lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 |
228 | l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp | 213 | lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task |
229 | lm %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task | 214 | st %r3,__LC_CURRENT # store task struct of next |
230 | st %r3,__LC_CURRENT # __LC_CURRENT = current task struct | 215 | mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next |
231 | lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 | 216 | st %r5,__LC_THREAD_INFO # store thread info of next |
232 | l %r3,__THREAD_info(%r3) # load thread_info from task struct | 217 | ahi %r5,STACK_SIZE # end of kernel stack of next |
233 | st %r3,__LC_THREAD_INFO | 218 | st %r5,__LC_KERNEL_STACK # store end of kernel stack |
234 | ahi %r3,STACK_SIZE | ||
235 | st %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack | ||
236 | br %r14 | 219 | br %r14 |
237 | 220 | ||
238 | __critical_start: | 221 | __critical_start: |
@@ -245,10 +228,11 @@ __critical_start: | |||
245 | system_call: | 228 | system_call: |
246 | stpt __LC_SYNC_ENTER_TIMER | 229 | stpt __LC_SYNC_ENTER_TIMER |
247 | sysc_saveall: | 230 | sysc_saveall: |
248 | SAVE_ALL_BASE __LC_SAVE_AREA | ||
249 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 231 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
250 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 232 | CREATE_STACK_FRAME __LC_SAVE_AREA |
251 | lh %r7,0x8a # get svc number from lowcore | 233 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW |
234 | mvc SP_ILC(4,%r15),__LC_SVC_ILC | ||
235 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
252 | sysc_vtime: | 236 | sysc_vtime: |
253 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 237 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
254 | sysc_stime: | 238 | sysc_stime: |
@@ -256,21 +240,20 @@ sysc_stime: | |||
256 | sysc_update: | 240 | sysc_update: |
257 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 241 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
258 | sysc_do_svc: | 242 | sysc_do_svc: |
259 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 243 | xr %r7,%r7 |
260 | ltr %r7,%r7 # test for svc 0 | 244 | icm %r7,3,SP_SVCNR(%r15) # load svc number and test for svc 0 |
261 | bnz BASED(sysc_nr_ok) # svc number > 0 | 245 | bnz BASED(sysc_nr_ok) # svc number > 0 |
262 | # svc 0: system call number in %r1 | 246 | # svc 0: system call number in %r1 |
263 | cl %r1,BASED(.Lnr_syscalls) | 247 | cl %r1,BASED(.Lnr_syscalls) |
264 | bnl BASED(sysc_nr_ok) | 248 | bnl BASED(sysc_nr_ok) |
249 | sth %r1,SP_SVCNR(%r15) | ||
265 | lr %r7,%r1 # copy svc number to %r7 | 250 | lr %r7,%r1 # copy svc number to %r7 |
266 | sysc_nr_ok: | 251 | sysc_nr_ok: |
267 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | ||
268 | sysc_do_restart: | ||
269 | sth %r7,SP_SVCNR(%r15) | ||
270 | sll %r7,2 # svc number *4 | 252 | sll %r7,2 # svc number *4 |
271 | l %r8,BASED(.Lsysc_table) | 253 | l %r10,BASED(.Lsysc_table) |
272 | tm __TI_flags+2(%r9),_TIF_SYSCALL | 254 | tm __TI_flags+2(%r12),_TIF_SYSCALL |
273 | l %r8,0(%r7,%r8) # get system call addr. | 255 | mvc SP_ARGS(4,%r15),SP_R7(%r15) |
256 | l %r8,0(%r7,%r10) # get system call addr. | ||
274 | bnz BASED(sysc_tracesys) | 257 | bnz BASED(sysc_tracesys) |
275 | basr %r14,%r8 # call sys_xxxx | 258 | basr %r14,%r8 # call sys_xxxx |
276 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) | 259 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) |
@@ -278,7 +261,7 @@ sysc_do_restart: | |||
278 | sysc_return: | 261 | sysc_return: |
279 | LOCKDEP_SYS_EXIT | 262 | LOCKDEP_SYS_EXIT |
280 | sysc_tif: | 263 | sysc_tif: |
281 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | 264 | tm __TI_flags+3(%r12),_TIF_WORK_SVC |
282 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 265 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
283 | sysc_restore: | 266 | sysc_restore: |
284 | RESTORE_ALL __LC_RETURN_PSW,1 | 267 | RESTORE_ALL __LC_RETURN_PSW,1 |
@@ -295,17 +278,17 @@ sysc_work: | |||
295 | # One of the work bits is on. Find out which one. | 278 | # One of the work bits is on. Find out which one. |
296 | # | 279 | # |
297 | sysc_work_tif: | 280 | sysc_work_tif: |
298 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 281 | tm __TI_flags+3(%r12),_TIF_MCCK_PENDING |
299 | bo BASED(sysc_mcck_pending) | 282 | bo BASED(sysc_mcck_pending) |
300 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 283 | tm __TI_flags+3(%r12),_TIF_NEED_RESCHED |
301 | bo BASED(sysc_reschedule) | 284 | bo BASED(sysc_reschedule) |
302 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 285 | tm __TI_flags+3(%r12),_TIF_SIGPENDING |
303 | bo BASED(sysc_sigpending) | 286 | bo BASED(sysc_sigpending) |
304 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | 287 | tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME |
305 | bo BASED(sysc_notify_resume) | 288 | bo BASED(sysc_notify_resume) |
306 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC | 289 | tm __TI_flags+3(%r12),_TIF_RESTART_SVC |
307 | bo BASED(sysc_restart) | 290 | bo BASED(sysc_restart) |
308 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 291 | tm __TI_flags+3(%r12),_TIF_PER_TRAP |
309 | bo BASED(sysc_singlestep) | 292 | bo BASED(sysc_singlestep) |
310 | b BASED(sysc_return) # beware of critical section cleanup | 293 | b BASED(sysc_return) # beware of critical section cleanup |
311 | 294 | ||
@@ -329,13 +312,13 @@ sysc_mcck_pending: | |||
329 | # _TIF_SIGPENDING is set, call do_signal | 312 | # _TIF_SIGPENDING is set, call do_signal |
330 | # | 313 | # |
331 | sysc_sigpending: | 314 | sysc_sigpending: |
332 | ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP | 315 | ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP |
333 | la %r2,SP_PTREGS(%r15) # load pt_regs | 316 | la %r2,SP_PTREGS(%r15) # load pt_regs |
334 | l %r1,BASED(.Ldo_signal) | 317 | l %r1,BASED(.Ldo_signal) |
335 | basr %r14,%r1 # call do_signal | 318 | basr %r14,%r1 # call do_signal |
336 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC | 319 | tm __TI_flags+3(%r12),_TIF_RESTART_SVC |
337 | bo BASED(sysc_restart) | 320 | bo BASED(sysc_restart) |
338 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 321 | tm __TI_flags+3(%r12),_TIF_PER_TRAP |
339 | bo BASED(sysc_singlestep) | 322 | bo BASED(sysc_singlestep) |
340 | b BASED(sysc_return) | 323 | b BASED(sysc_return) |
341 | 324 | ||
@@ -353,23 +336,23 @@ sysc_notify_resume: | |||
353 | # _TIF_RESTART_SVC is set, set up registers and restart svc | 336 | # _TIF_RESTART_SVC is set, set up registers and restart svc |
354 | # | 337 | # |
355 | sysc_restart: | 338 | sysc_restart: |
356 | ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC | 339 | ni __TI_flags+3(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC |
357 | l %r7,SP_R2(%r15) # load new svc number | 340 | l %r7,SP_R2(%r15) # load new svc number |
358 | mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument | 341 | mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument |
359 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | 342 | lm %r2,%r6,SP_R2(%r15) # load svc arguments |
360 | b BASED(sysc_do_restart) # restart svc | 343 | sth %r7,SP_SVCNR(%r15) |
344 | b BASED(sysc_nr_ok) # restart svc | ||
361 | 345 | ||
362 | # | 346 | # |
363 | # _TIF_SINGLE_STEP is set, call do_single_step | 347 | # _TIF_PER_TRAP is set, call do_per_trap |
364 | # | 348 | # |
365 | sysc_singlestep: | 349 | sysc_singlestep: |
366 | ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP | 350 | ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP |
367 | mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check | 351 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number |
368 | mvi SP_SVCNR+1(%r15),0xff | ||
369 | la %r2,SP_PTREGS(%r15) # address of register-save area | 352 | la %r2,SP_PTREGS(%r15) # address of register-save area |
370 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 353 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
371 | la %r14,BASED(sysc_return) # load adr. of system return | 354 | la %r14,BASED(sysc_return) # load adr. of system return |
372 | br %r1 # branch to do_single_step | 355 | br %r1 # branch to do_per_trap |
373 | 356 | ||
374 | # | 357 | # |
375 | # call tracehook_report_syscall_entry/tracehook_report_syscall_exit before | 358 | # call tracehook_report_syscall_entry/tracehook_report_syscall_exit before |
@@ -379,22 +362,23 @@ sysc_tracesys: | |||
379 | l %r1,BASED(.Ltrace_entry) | 362 | l %r1,BASED(.Ltrace_entry) |
380 | la %r2,SP_PTREGS(%r15) # load pt_regs | 363 | la %r2,SP_PTREGS(%r15) # load pt_regs |
381 | la %r3,0 | 364 | la %r3,0 |
382 | srl %r7,2 | 365 | xr %r0,%r0 |
383 | st %r7,SP_R2(%r15) | 366 | icm %r0,3,SP_SVCNR(%r15) |
367 | st %r0,SP_R2(%r15) | ||
384 | basr %r14,%r1 | 368 | basr %r14,%r1 |
385 | cl %r2,BASED(.Lnr_syscalls) | 369 | cl %r2,BASED(.Lnr_syscalls) |
386 | bnl BASED(sysc_tracenogo) | 370 | bnl BASED(sysc_tracenogo) |
387 | l %r8,BASED(.Lsysc_table) | ||
388 | lr %r7,%r2 | 371 | lr %r7,%r2 |
389 | sll %r7,2 # svc number *4 | 372 | sll %r7,2 # svc number *4 |
390 | l %r8,0(%r7,%r8) | 373 | l %r8,0(%r7,%r10) |
391 | sysc_tracego: | 374 | sysc_tracego: |
392 | lm %r3,%r6,SP_R3(%r15) | 375 | lm %r3,%r6,SP_R3(%r15) |
376 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | ||
393 | l %r2,SP_ORIG_R2(%r15) | 377 | l %r2,SP_ORIG_R2(%r15) |
394 | basr %r14,%r8 # call sys_xxx | 378 | basr %r14,%r8 # call sys_xxx |
395 | st %r2,SP_R2(%r15) # store return value | 379 | st %r2,SP_R2(%r15) # store return value |
396 | sysc_tracenogo: | 380 | sysc_tracenogo: |
397 | tm __TI_flags+2(%r9),_TIF_SYSCALL | 381 | tm __TI_flags+2(%r12),_TIF_SYSCALL |
398 | bz BASED(sysc_return) | 382 | bz BASED(sysc_return) |
399 | l %r1,BASED(.Ltrace_exit) | 383 | l %r1,BASED(.Ltrace_exit) |
400 | la %r2,SP_PTREGS(%r15) # load pt_regs | 384 | la %r2,SP_PTREGS(%r15) # load pt_regs |
@@ -407,7 +391,7 @@ sysc_tracenogo: | |||
407 | .globl ret_from_fork | 391 | .globl ret_from_fork |
408 | ret_from_fork: | 392 | ret_from_fork: |
409 | l %r13,__LC_SVC_NEW_PSW+4 | 393 | l %r13,__LC_SVC_NEW_PSW+4 |
410 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 394 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
411 | tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? | 395 | tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? |
412 | bo BASED(0f) | 396 | bo BASED(0f) |
413 | st %r15,SP_R15(%r15) # store stack pointer for new kthread | 397 | st %r15,SP_R15(%r15) # store stack pointer for new kthread |
@@ -440,13 +424,11 @@ kernel_execve: | |||
440 | br %r14 | 424 | br %r14 |
441 | # execve succeeded. | 425 | # execve succeeded. |
442 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts | 426 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts |
443 | TRACE_IRQS_OFF | ||
444 | l %r15,__LC_KERNEL_STACK # load ksp | 427 | l %r15,__LC_KERNEL_STACK # load ksp |
445 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 428 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
446 | l %r9,__LC_THREAD_INFO | ||
447 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs | 429 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs |
430 | l %r12,__LC_THREAD_INFO | ||
448 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 431 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
449 | TRACE_IRQS_ON | ||
450 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 432 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
451 | l %r1,BASED(.Lexecve_tail) | 433 | l %r1,BASED(.Lexecve_tail) |
452 | basr %r14,%r1 | 434 | basr %r14,%r1 |
@@ -475,27 +457,28 @@ pgm_check_handler: | |||
475 | SAVE_ALL_BASE __LC_SAVE_AREA | 457 | SAVE_ALL_BASE __LC_SAVE_AREA |
476 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 458 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
477 | bnz BASED(pgm_per) # got per exception -> special case | 459 | bnz BASED(pgm_per) # got per exception -> special case |
478 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 460 | SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
479 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 461 | CREATE_STACK_FRAME __LC_SAVE_AREA |
462 | xc SP_ILC(4,%r15),SP_ILC(%r15) | ||
463 | mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW | ||
464 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
480 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 465 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
481 | bz BASED(pgm_no_vtime) | 466 | bz BASED(pgm_no_vtime) |
482 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 467 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
483 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 468 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
484 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 469 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
485 | pgm_no_vtime: | 470 | pgm_no_vtime: |
486 | TRACE_IRQS_CHECK_OFF | ||
487 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
488 | l %r3,__LC_PGM_ILC # load program interruption code | 471 | l %r3,__LC_PGM_ILC # load program interruption code |
472 | l %r4,__LC_TRANS_EXC_CODE | ||
473 | REENABLE_IRQS | ||
489 | la %r8,0x7f | 474 | la %r8,0x7f |
490 | nr %r8,%r3 | 475 | nr %r8,%r3 |
491 | pgm_do_call: | ||
492 | l %r7,BASED(.Ljump_table) | ||
493 | sll %r8,2 | 476 | sll %r8,2 |
494 | l %r7,0(%r8,%r7) # load address of handler routine | 477 | l %r1,BASED(.Ljump_table) |
478 | l %r1,0(%r8,%r1) # load address of handler routine | ||
495 | la %r2,SP_PTREGS(%r15) # address of register-save area | 479 | la %r2,SP_PTREGS(%r15) # address of register-save area |
496 | basr %r14,%r7 # branch to interrupt-handler | 480 | basr %r14,%r1 # branch to interrupt-handler |
497 | pgm_exit: | 481 | pgm_exit: |
498 | TRACE_IRQS_CHECK_ON | ||
499 | b BASED(sysc_return) | 482 | b BASED(sysc_return) |
500 | 483 | ||
501 | # | 484 | # |
@@ -515,55 +498,54 @@ pgm_per: | |||
515 | # Normal per exception | 498 | # Normal per exception |
516 | # | 499 | # |
517 | pgm_per_std: | 500 | pgm_per_std: |
518 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 501 | SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
519 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 502 | CREATE_STACK_FRAME __LC_SAVE_AREA |
503 | mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW | ||
504 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
520 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 505 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
521 | bz BASED(pgm_no_vtime2) | 506 | bz BASED(pgm_no_vtime2) |
522 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 507 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
523 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 508 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
524 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 509 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
525 | pgm_no_vtime2: | 510 | pgm_no_vtime2: |
526 | TRACE_IRQS_CHECK_OFF | 511 | l %r1,__TI_task(%r12) |
527 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
528 | l %r1,__TI_task(%r9) | ||
529 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | 512 | tm SP_PSW+1(%r15),0x01 # kernel per event ? |
530 | bz BASED(kernel_per) | 513 | bz BASED(kernel_per) |
531 | mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID | 514 | mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE |
532 | mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS | 515 | mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS |
533 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID | 516 | mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID |
534 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 517 | oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP |
535 | l %r3,__LC_PGM_ILC # load program interruption code | 518 | l %r3,__LC_PGM_ILC # load program interruption code |
519 | l %r4,__LC_TRANS_EXC_CODE | ||
520 | REENABLE_IRQS | ||
536 | la %r8,0x7f | 521 | la %r8,0x7f |
537 | nr %r8,%r3 # clear per-event-bit and ilc | 522 | nr %r8,%r3 # clear per-event-bit and ilc |
538 | be BASED(pgm_exit2) # only per or per+check ? | 523 | be BASED(pgm_exit2) # only per or per+check ? |
539 | l %r7,BASED(.Ljump_table) | ||
540 | sll %r8,2 | 524 | sll %r8,2 |
541 | l %r7,0(%r8,%r7) # load address of handler routine | 525 | l %r1,BASED(.Ljump_table) |
526 | l %r1,0(%r8,%r1) # load address of handler routine | ||
542 | la %r2,SP_PTREGS(%r15) # address of register-save area | 527 | la %r2,SP_PTREGS(%r15) # address of register-save area |
543 | basr %r14,%r7 # branch to interrupt-handler | 528 | basr %r14,%r1 # branch to interrupt-handler |
544 | pgm_exit2: | 529 | pgm_exit2: |
545 | TRACE_IRQS_ON | ||
546 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | ||
547 | b BASED(sysc_return) | 530 | b BASED(sysc_return) |
548 | 531 | ||
549 | # | 532 | # |
550 | # it was a single stepped SVC that is causing all the trouble | 533 | # it was a single stepped SVC that is causing all the trouble |
551 | # | 534 | # |
552 | pgm_svcper: | 535 | pgm_svcper: |
553 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 536 | SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
554 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 537 | CREATE_STACK_FRAME __LC_SAVE_AREA |
538 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW | ||
539 | mvc SP_ILC(4,%r15),__LC_SVC_ILC | ||
540 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
555 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 541 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
556 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 542 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
557 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 543 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
558 | lh %r7,0x8a # get svc number from lowcore | 544 | l %r8,__TI_task(%r12) |
559 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 545 | mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE |
560 | TRACE_IRQS_OFF | 546 | mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS |
561 | l %r8,__TI_task(%r9) | 547 | mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID |
562 | mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID | 548 | oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP |
563 | mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS | ||
564 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID | ||
565 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | ||
566 | TRACE_IRQS_ON | ||
567 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 549 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
568 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | 550 | lm %r2,%r6,SP_R2(%r15) # load svc arguments |
569 | b BASED(sysc_do_svc) | 551 | b BASED(sysc_do_svc) |
@@ -572,8 +554,8 @@ pgm_svcper: | |||
572 | # per was called from kernel, must be kprobes | 554 | # per was called from kernel, must be kprobes |
573 | # | 555 | # |
574 | kernel_per: | 556 | kernel_per: |
575 | mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check | 557 | REENABLE_IRQS |
576 | mvi SP_SVCNR+1(%r15),0xff | 558 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) |
577 | la %r2,SP_PTREGS(%r15) # address of register-save area | 559 | la %r2,SP_PTREGS(%r15) # address of register-save area |
578 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 560 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
579 | basr %r14,%r1 # branch to do_single_step | 561 | basr %r14,%r1 # branch to do_single_step |
@@ -587,9 +569,10 @@ kernel_per: | |||
587 | io_int_handler: | 569 | io_int_handler: |
588 | stck __LC_INT_CLOCK | 570 | stck __LC_INT_CLOCK |
589 | stpt __LC_ASYNC_ENTER_TIMER | 571 | stpt __LC_ASYNC_ENTER_TIMER |
590 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | ||
591 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | 572 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 |
592 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | 573 | CREATE_STACK_FRAME __LC_SAVE_AREA+16 |
574 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | ||
575 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
593 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 576 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
594 | bz BASED(io_no_vtime) | 577 | bz BASED(io_no_vtime) |
595 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 578 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
@@ -597,7 +580,6 @@ io_int_handler: | |||
597 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 580 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
598 | io_no_vtime: | 581 | io_no_vtime: |
599 | TRACE_IRQS_OFF | 582 | TRACE_IRQS_OFF |
600 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
601 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ | 583 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ |
602 | la %r2,SP_PTREGS(%r15) # address of register-save area | 584 | la %r2,SP_PTREGS(%r15) # address of register-save area |
603 | basr %r14,%r1 # branch to standard irq handler | 585 | basr %r14,%r1 # branch to standard irq handler |
@@ -605,7 +587,7 @@ io_return: | |||
605 | LOCKDEP_SYS_EXIT | 587 | LOCKDEP_SYS_EXIT |
606 | TRACE_IRQS_ON | 588 | TRACE_IRQS_ON |
607 | io_tif: | 589 | io_tif: |
608 | tm __TI_flags+3(%r9),_TIF_WORK_INT | 590 | tm __TI_flags+3(%r12),_TIF_WORK_INT |
609 | bnz BASED(io_work) # there is work to do (signals etc.) | 591 | bnz BASED(io_work) # there is work to do (signals etc.) |
610 | io_restore: | 592 | io_restore: |
611 | RESTORE_ALL __LC_RETURN_PSW,0 | 593 | RESTORE_ALL __LC_RETURN_PSW,0 |
@@ -623,9 +605,9 @@ io_work: | |||
623 | bo BASED(io_work_user) # yes -> do resched & signal | 605 | bo BASED(io_work_user) # yes -> do resched & signal |
624 | #ifdef CONFIG_PREEMPT | 606 | #ifdef CONFIG_PREEMPT |
625 | # check for preemptive scheduling | 607 | # check for preemptive scheduling |
626 | icm %r0,15,__TI_precount(%r9) | 608 | icm %r0,15,__TI_precount(%r12) |
627 | bnz BASED(io_restore) # preemption disabled | 609 | bnz BASED(io_restore) # preemption disabled |
628 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 610 | tm __TI_flags+3(%r12),_TIF_NEED_RESCHED |
629 | bno BASED(io_restore) | 611 | bno BASED(io_restore) |
630 | # switch to kernel stack | 612 | # switch to kernel stack |
631 | l %r1,SP_R15(%r15) | 613 | l %r1,SP_R15(%r15) |
@@ -659,13 +641,13 @@ io_work_user: | |||
659 | # and _TIF_MCCK_PENDING | 641 | # and _TIF_MCCK_PENDING |
660 | # | 642 | # |
661 | io_work_tif: | 643 | io_work_tif: |
662 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 644 | tm __TI_flags+3(%r12),_TIF_MCCK_PENDING |
663 | bo BASED(io_mcck_pending) | 645 | bo BASED(io_mcck_pending) |
664 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 646 | tm __TI_flags+3(%r12),_TIF_NEED_RESCHED |
665 | bo BASED(io_reschedule) | 647 | bo BASED(io_reschedule) |
666 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 648 | tm __TI_flags+3(%r12),_TIF_SIGPENDING |
667 | bo BASED(io_sigpending) | 649 | bo BASED(io_sigpending) |
668 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | 650 | tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME |
669 | bo BASED(io_notify_resume) | 651 | bo BASED(io_notify_resume) |
670 | b BASED(io_return) # beware of critical section cleanup | 652 | b BASED(io_return) # beware of critical section cleanup |
671 | 653 | ||
@@ -725,19 +707,20 @@ io_notify_resume: | |||
725 | ext_int_handler: | 707 | ext_int_handler: |
726 | stck __LC_INT_CLOCK | 708 | stck __LC_INT_CLOCK |
727 | stpt __LC_ASYNC_ENTER_TIMER | 709 | stpt __LC_ASYNC_ENTER_TIMER |
728 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | ||
729 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | 710 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 |
730 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | 711 | CREATE_STACK_FRAME __LC_SAVE_AREA+16 |
712 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | ||
713 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
731 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 714 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
732 | bz BASED(ext_no_vtime) | 715 | bz BASED(ext_no_vtime) |
733 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 716 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
734 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 717 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
735 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 718 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
736 | ext_no_vtime: | 719 | ext_no_vtime: |
737 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
738 | TRACE_IRQS_OFF | 720 | TRACE_IRQS_OFF |
739 | la %r2,SP_PTREGS(%r15) # address of register-save area | 721 | la %r2,SP_PTREGS(%r15) # address of register-save area |
740 | lh %r3,__LC_EXT_INT_CODE # get interruption code | 722 | l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code |
723 | l %r4,__LC_EXT_PARAMS # get external parameters | ||
741 | l %r1,BASED(.Ldo_extint) | 724 | l %r1,BASED(.Ldo_extint) |
742 | basr %r14,%r1 | 725 | basr %r14,%r1 |
743 | b BASED(io_return) | 726 | b BASED(io_return) |
@@ -788,7 +771,10 @@ mcck_int_main: | |||
788 | sra %r14,PAGE_SHIFT | 771 | sra %r14,PAGE_SHIFT |
789 | be BASED(0f) | 772 | be BASED(0f) |
790 | l %r15,__LC_PANIC_STACK # load panic stack | 773 | l %r15,__LC_PANIC_STACK # load panic stack |
791 | 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 | 774 | 0: s %r15,BASED(.Lc_spsize) # make room for registers & psw |
775 | CREATE_STACK_FRAME __LC_SAVE_AREA+32 | ||
776 | mvc SP_PSW(8,%r15),0(%r12) | ||
777 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
792 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | 778 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? |
793 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical | 779 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical |
794 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 780 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -797,7 +783,6 @@ mcck_int_main: | |||
797 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 783 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
798 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER | 784 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER |
799 | mcck_no_vtime: | 785 | mcck_no_vtime: |
800 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
801 | la %r2,SP_PTREGS(%r15) # load pt_regs | 786 | la %r2,SP_PTREGS(%r15) # load pt_regs |
802 | l %r1,BASED(.Ls390_mcck) | 787 | l %r1,BASED(.Ls390_mcck) |
803 | basr %r14,%r1 # call machine check handler | 788 | basr %r14,%r1 # call machine check handler |
@@ -809,7 +794,7 @@ mcck_no_vtime: | |||
809 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 794 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
810 | lr %r15,%r1 | 795 | lr %r15,%r1 |
811 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | 796 | stosm __SF_EMPTY(%r15),0x04 # turn dat on |
812 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 797 | tm __TI_flags+3(%r12),_TIF_MCCK_PENDING |
813 | bno BASED(mcck_return) | 798 | bno BASED(mcck_return) |
814 | TRACE_IRQS_OFF | 799 | TRACE_IRQS_OFF |
815 | l %r1,BASED(.Ls390_handle_mcck) | 800 | l %r1,BASED(.Ls390_handle_mcck) |
@@ -852,7 +837,7 @@ restart_base: | |||
852 | stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on | 837 | stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on |
853 | basr %r14,0 | 838 | basr %r14,0 |
854 | l %r14,restart_addr-.(%r14) | 839 | l %r14,restart_addr-.(%r14) |
855 | br %r14 # branch to start_secondary | 840 | basr %r14,%r14 # branch to start_secondary |
856 | restart_addr: | 841 | restart_addr: |
857 | .long start_secondary | 842 | .long start_secondary |
858 | .align 8 | 843 | .align 8 |
@@ -874,6 +859,8 @@ restart_crash: | |||
874 | restart_go: | 859 | restart_go: |
875 | #endif | 860 | #endif |
876 | 861 | ||
862 | .section .kprobes.text, "ax" | ||
863 | |||
877 | #ifdef CONFIG_CHECK_STACK | 864 | #ifdef CONFIG_CHECK_STACK |
878 | /* | 865 | /* |
879 | * The synchronous or the asynchronous stack overflowed. We are dead. | 866 | * The synchronous or the asynchronous stack overflowed. We are dead. |
@@ -956,12 +943,13 @@ cleanup_system_call: | |||
956 | bh BASED(0f) | 943 | bh BASED(0f) |
957 | mvc __LC_SAVE_AREA(16),0(%r12) | 944 | mvc __LC_SAVE_AREA(16),0(%r12) |
958 | 0: st %r13,4(%r12) | 945 | 0: st %r13,4(%r12) |
959 | st %r12,__LC_SAVE_AREA+48 # argh | 946 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp |
960 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 947 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
961 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
962 | l %r12,__LC_SAVE_AREA+48 # argh | ||
963 | st %r15,12(%r12) | 948 | st %r15,12(%r12) |
964 | lh %r7,0x8a | 949 | CREATE_STACK_FRAME __LC_SAVE_AREA |
950 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW | ||
951 | mvc SP_ILC(4,%r15),__LC_SVC_ILC | ||
952 | mvc 0(4,%r12),__LC_THREAD_INFO | ||
965 | cleanup_vtime: | 953 | cleanup_vtime: |
966 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) | 954 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) |
967 | bhe BASED(cleanup_stime) | 955 | bhe BASED(cleanup_stime) |
@@ -1059,7 +1047,7 @@ cleanup_io_restore_insn: | |||
1059 | .Ldo_signal: .long do_signal | 1047 | .Ldo_signal: .long do_signal |
1060 | .Ldo_notify_resume: | 1048 | .Ldo_notify_resume: |
1061 | .long do_notify_resume | 1049 | .long do_notify_resume |
1062 | .Lhandle_per: .long do_single_step | 1050 | .Lhandle_per: .long do_per_trap |
1063 | .Ldo_execve: .long do_execve | 1051 | .Ldo_execve: .long do_execve |
1064 | .Lexecve_tail: .long execve_tail | 1052 | .Lexecve_tail: .long execve_tail |
1065 | .Ljump_table: .long pgm_check_table | 1053 | .Ljump_table: .long pgm_check_table |