diff options
Diffstat (limited to 'arch/s390/kernel/entry64.S')
-rw-r--r-- | arch/s390/kernel/entry64.S | 372 |
1 files changed, 186 insertions, 186 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 7b2e03afd017..c329446a951d 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -91,7 +91,7 @@ _PIF_WORK = (_PIF_PER_TRAP) | |||
91 | .if \reason==1 | 91 | .if \reason==1 |
92 | # Some program interrupts are suppressing (e.g. protection). | 92 | # Some program interrupts are suppressing (e.g. protection). |
93 | # We must also check the instruction after SIE in that case. | 93 | # We must also check the instruction after SIE in that case. |
94 | # do_protection_exception will rewind to rewind_pad | 94 | # do_protection_exception will rewind to .Lrewind_pad |
95 | jh .+42 | 95 | jh .+42 |
96 | .else | 96 | .else |
97 | jhe .+42 | 97 | jhe .+42 |
@@ -192,7 +192,7 @@ ENTRY(__switch_to) | |||
192 | lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task | 192 | lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task |
193 | br %r14 | 193 | br %r14 |
194 | 194 | ||
195 | __critical_start: | 195 | .L__critical_start: |
196 | /* | 196 | /* |
197 | * SVC interrupt handler routine. System calls are synchronous events and | 197 | * SVC interrupt handler routine. System calls are synchronous events and |
198 | * are executed with interrupts enabled. | 198 | * are executed with interrupts enabled. |
@@ -200,15 +200,15 @@ __critical_start: | |||
200 | 200 | ||
201 | ENTRY(system_call) | 201 | ENTRY(system_call) |
202 | stpt __LC_SYNC_ENTER_TIMER | 202 | stpt __LC_SYNC_ENTER_TIMER |
203 | sysc_stmg: | 203 | .Lsysc_stmg: |
204 | stmg %r8,%r15,__LC_SAVE_AREA_SYNC | 204 | stmg %r8,%r15,__LC_SAVE_AREA_SYNC |
205 | lg %r10,__LC_LAST_BREAK | 205 | lg %r10,__LC_LAST_BREAK |
206 | lg %r12,__LC_THREAD_INFO | 206 | lg %r12,__LC_THREAD_INFO |
207 | lghi %r14,_PIF_SYSCALL | 207 | lghi %r14,_PIF_SYSCALL |
208 | sysc_per: | 208 | .Lsysc_per: |
209 | lg %r15,__LC_KERNEL_STACK | 209 | lg %r15,__LC_KERNEL_STACK |
210 | la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs | 210 | la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs |
211 | sysc_vtime: | 211 | .Lsysc_vtime: |
212 | UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER | 212 | UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER |
213 | LAST_BREAK %r13 | 213 | LAST_BREAK %r13 |
214 | stmg %r0,%r7,__PT_R0(%r11) | 214 | stmg %r0,%r7,__PT_R0(%r11) |
@@ -216,39 +216,39 @@ sysc_vtime: | |||
216 | mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW | 216 | mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW |
217 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC | 217 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC |
218 | stg %r14,__PT_FLAGS(%r11) | 218 | stg %r14,__PT_FLAGS(%r11) |
219 | sysc_do_svc: | 219 | .Lsysc_do_svc: |
220 | lg %r10,__TI_sysc_table(%r12) # address of system call table | 220 | lg %r10,__TI_sysc_table(%r12) # address of system call table |
221 | llgh %r8,__PT_INT_CODE+2(%r11) | 221 | llgh %r8,__PT_INT_CODE+2(%r11) |
222 | slag %r8,%r8,2 # shift and test for svc 0 | 222 | slag %r8,%r8,2 # shift and test for svc 0 |
223 | jnz sysc_nr_ok | 223 | jnz .Lsysc_nr_ok |
224 | # svc 0: system call number in %r1 | 224 | # svc 0: system call number in %r1 |
225 | llgfr %r1,%r1 # clear high word in r1 | 225 | llgfr %r1,%r1 # clear high word in r1 |
226 | cghi %r1,NR_syscalls | 226 | cghi %r1,NR_syscalls |
227 | jnl sysc_nr_ok | 227 | jnl .Lsysc_nr_ok |
228 | sth %r1,__PT_INT_CODE+2(%r11) | 228 | sth %r1,__PT_INT_CODE+2(%r11) |
229 | slag %r8,%r1,2 | 229 | slag %r8,%r1,2 |
230 | sysc_nr_ok: | 230 | .Lsysc_nr_ok: |
231 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 231 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
232 | stg %r2,__PT_ORIG_GPR2(%r11) | 232 | stg %r2,__PT_ORIG_GPR2(%r11) |
233 | stg %r7,STACK_FRAME_OVERHEAD(%r15) | 233 | stg %r7,STACK_FRAME_OVERHEAD(%r15) |
234 | lgf %r9,0(%r8,%r10) # get system call add. | 234 | lgf %r9,0(%r8,%r10) # get system call add. |
235 | tm __TI_flags+7(%r12),_TIF_TRACE | 235 | tm __TI_flags+7(%r12),_TIF_TRACE |
236 | jnz sysc_tracesys | 236 | jnz .Lsysc_tracesys |
237 | basr %r14,%r9 # call sys_xxxx | 237 | basr %r14,%r9 # call sys_xxxx |
238 | stg %r2,__PT_R2(%r11) # store return value | 238 | stg %r2,__PT_R2(%r11) # store return value |
239 | 239 | ||
240 | sysc_return: | 240 | .Lsysc_return: |
241 | LOCKDEP_SYS_EXIT | 241 | LOCKDEP_SYS_EXIT |
242 | sysc_tif: | 242 | .Lsysc_tif: |
243 | tm __PT_PSW+1(%r11),0x01 # returning to user ? | 243 | tm __PT_PSW+1(%r11),0x01 # returning to user ? |
244 | jno sysc_restore | 244 | jno .Lsysc_restore |
245 | tm __PT_FLAGS+7(%r11),_PIF_WORK | 245 | tm __PT_FLAGS+7(%r11),_PIF_WORK |
246 | jnz sysc_work | 246 | jnz .Lsysc_work |
247 | tm __TI_flags+7(%r12),_TIF_WORK | 247 | tm __TI_flags+7(%r12),_TIF_WORK |
248 | jnz sysc_work # check for work | 248 | jnz .Lsysc_work # check for work |
249 | tm __LC_CPU_FLAGS+7,_CIF_WORK | 249 | tm __LC_CPU_FLAGS+7,_CIF_WORK |
250 | jnz sysc_work | 250 | jnz .Lsysc_work |
251 | sysc_restore: | 251 | .Lsysc_restore: |
252 | lg %r14,__LC_VDSO_PER_CPU | 252 | lg %r14,__LC_VDSO_PER_CPU |
253 | lmg %r0,%r10,__PT_R0(%r11) | 253 | lmg %r0,%r10,__PT_R0(%r11) |
254 | mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) | 254 | mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) |
@@ -256,101 +256,101 @@ sysc_restore: | |||
256 | mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER | 256 | mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER |
257 | lmg %r11,%r15,__PT_R11(%r11) | 257 | lmg %r11,%r15,__PT_R11(%r11) |
258 | lpswe __LC_RETURN_PSW | 258 | lpswe __LC_RETURN_PSW |
259 | sysc_done: | 259 | .Lsysc_done: |
260 | 260 | ||
261 | # | 261 | # |
262 | # One of the work bits is on. Find out which one. | 262 | # One of the work bits is on. Find out which one. |
263 | # | 263 | # |
264 | sysc_work: | 264 | .Lsysc_work: |
265 | tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING | 265 | tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING |
266 | jo sysc_mcck_pending | 266 | jo .Lsysc_mcck_pending |
267 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED | 267 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED |
268 | jo sysc_reschedule | 268 | jo .Lsysc_reschedule |
269 | #ifdef CONFIG_UPROBES | 269 | #ifdef CONFIG_UPROBES |
270 | tm __TI_flags+7(%r12),_TIF_UPROBE | 270 | tm __TI_flags+7(%r12),_TIF_UPROBE |
271 | jo sysc_uprobe_notify | 271 | jo .Lsysc_uprobe_notify |
272 | #endif | 272 | #endif |
273 | tm __PT_FLAGS+7(%r11),_PIF_PER_TRAP | 273 | tm __PT_FLAGS+7(%r11),_PIF_PER_TRAP |
274 | jo sysc_singlestep | 274 | jo .Lsysc_singlestep |
275 | tm __TI_flags+7(%r12),_TIF_SIGPENDING | 275 | tm __TI_flags+7(%r12),_TIF_SIGPENDING |
276 | jo sysc_sigpending | 276 | jo .Lsysc_sigpending |
277 | tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME | 277 | tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME |
278 | jo sysc_notify_resume | 278 | jo .Lsysc_notify_resume |
279 | tm __LC_CPU_FLAGS+7,_CIF_ASCE | 279 | tm __LC_CPU_FLAGS+7,_CIF_ASCE |
280 | jo sysc_uaccess | 280 | jo .Lsysc_uaccess |
281 | j sysc_return # beware of critical section cleanup | 281 | j .Lsysc_return # beware of critical section cleanup |
282 | 282 | ||
283 | # | 283 | # |
284 | # _TIF_NEED_RESCHED is set, call schedule | 284 | # _TIF_NEED_RESCHED is set, call schedule |
285 | # | 285 | # |
286 | sysc_reschedule: | 286 | .Lsysc_reschedule: |
287 | larl %r14,sysc_return | 287 | larl %r14,.Lsysc_return |
288 | jg schedule | 288 | jg schedule |
289 | 289 | ||
290 | # | 290 | # |
291 | # _CIF_MCCK_PENDING is set, call handler | 291 | # _CIF_MCCK_PENDING is set, call handler |
292 | # | 292 | # |
293 | sysc_mcck_pending: | 293 | .Lsysc_mcck_pending: |
294 | larl %r14,sysc_return | 294 | larl %r14,.Lsysc_return |
295 | jg s390_handle_mcck # TIF bit will be cleared by handler | 295 | jg s390_handle_mcck # TIF bit will be cleared by handler |
296 | 296 | ||
297 | # | 297 | # |
298 | # _CIF_ASCE is set, load user space asce | 298 | # _CIF_ASCE is set, load user space asce |
299 | # | 299 | # |
300 | sysc_uaccess: | 300 | .Lsysc_uaccess: |
301 | ni __LC_CPU_FLAGS+7,255-_CIF_ASCE | 301 | ni __LC_CPU_FLAGS+7,255-_CIF_ASCE |
302 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | 302 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce |
303 | j sysc_return | 303 | j .Lsysc_return |
304 | 304 | ||
305 | # | 305 | # |
306 | # _TIF_SIGPENDING is set, call do_signal | 306 | # _TIF_SIGPENDING is set, call do_signal |
307 | # | 307 | # |
308 | sysc_sigpending: | 308 | .Lsysc_sigpending: |
309 | lgr %r2,%r11 # pass pointer to pt_regs | 309 | lgr %r2,%r11 # pass pointer to pt_regs |
310 | brasl %r14,do_signal | 310 | brasl %r14,do_signal |
311 | tm __PT_FLAGS+7(%r11),_PIF_SYSCALL | 311 | tm __PT_FLAGS+7(%r11),_PIF_SYSCALL |
312 | jno sysc_return | 312 | jno .Lsysc_return |
313 | lmg %r2,%r7,__PT_R2(%r11) # load svc arguments | 313 | lmg %r2,%r7,__PT_R2(%r11) # load svc arguments |
314 | lg %r10,__TI_sysc_table(%r12) # address of system call table | 314 | lg %r10,__TI_sysc_table(%r12) # address of system call table |
315 | lghi %r8,0 # svc 0 returns -ENOSYS | 315 | lghi %r8,0 # svc 0 returns -ENOSYS |
316 | llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number | 316 | llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number |
317 | cghi %r1,NR_syscalls | 317 | cghi %r1,NR_syscalls |
318 | jnl sysc_nr_ok # invalid svc number -> do svc 0 | 318 | jnl .Lsysc_nr_ok # invalid svc number -> do svc 0 |
319 | slag %r8,%r1,2 | 319 | slag %r8,%r1,2 |
320 | j sysc_nr_ok # restart svc | 320 | j .Lsysc_nr_ok # restart svc |
321 | 321 | ||
322 | # | 322 | # |
323 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume | 323 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume |
324 | # | 324 | # |
325 | sysc_notify_resume: | 325 | .Lsysc_notify_resume: |
326 | lgr %r2,%r11 # pass pointer to pt_regs | 326 | lgr %r2,%r11 # pass pointer to pt_regs |
327 | larl %r14,sysc_return | 327 | larl %r14,.Lsysc_return |
328 | jg do_notify_resume | 328 | jg do_notify_resume |
329 | 329 | ||
330 | # | 330 | # |
331 | # _TIF_UPROBE is set, call uprobe_notify_resume | 331 | # _TIF_UPROBE is set, call uprobe_notify_resume |
332 | # | 332 | # |
333 | #ifdef CONFIG_UPROBES | 333 | #ifdef CONFIG_UPROBES |
334 | sysc_uprobe_notify: | 334 | .Lsysc_uprobe_notify: |
335 | lgr %r2,%r11 # pass pointer to pt_regs | 335 | lgr %r2,%r11 # pass pointer to pt_regs |
336 | larl %r14,sysc_return | 336 | larl %r14,.Lsysc_return |
337 | jg uprobe_notify_resume | 337 | jg uprobe_notify_resume |
338 | #endif | 338 | #endif |
339 | 339 | ||
340 | # | 340 | # |
341 | # _PIF_PER_TRAP is set, call do_per_trap | 341 | # _PIF_PER_TRAP is set, call do_per_trap |
342 | # | 342 | # |
343 | sysc_singlestep: | 343 | .Lsysc_singlestep: |
344 | ni __PT_FLAGS+7(%r11),255-_PIF_PER_TRAP | 344 | ni __PT_FLAGS+7(%r11),255-_PIF_PER_TRAP |
345 | lgr %r2,%r11 # pass pointer to pt_regs | 345 | lgr %r2,%r11 # pass pointer to pt_regs |
346 | larl %r14,sysc_return | 346 | larl %r14,.Lsysc_return |
347 | jg do_per_trap | 347 | jg do_per_trap |
348 | 348 | ||
349 | # | 349 | # |
350 | # call tracehook_report_syscall_entry/tracehook_report_syscall_exit before | 350 | # call tracehook_report_syscall_entry/tracehook_report_syscall_exit before |
351 | # and after the system call | 351 | # and after the system call |
352 | # | 352 | # |
353 | sysc_tracesys: | 353 | .Lsysc_tracesys: |
354 | lgr %r2,%r11 # pass pointer to pt_regs | 354 | lgr %r2,%r11 # pass pointer to pt_regs |
355 | la %r3,0 | 355 | la %r3,0 |
356 | llgh %r0,__PT_INT_CODE+2(%r11) | 356 | llgh %r0,__PT_INT_CODE+2(%r11) |
@@ -358,20 +358,20 @@ sysc_tracesys: | |||
358 | brasl %r14,do_syscall_trace_enter | 358 | brasl %r14,do_syscall_trace_enter |
359 | lghi %r0,NR_syscalls | 359 | lghi %r0,NR_syscalls |
360 | clgr %r0,%r2 | 360 | clgr %r0,%r2 |
361 | jnh sysc_tracenogo | 361 | jnh .Lsysc_tracenogo |
362 | sllg %r8,%r2,2 | 362 | sllg %r8,%r2,2 |
363 | lgf %r9,0(%r8,%r10) | 363 | lgf %r9,0(%r8,%r10) |
364 | sysc_tracego: | 364 | .Lsysc_tracego: |
365 | lmg %r3,%r7,__PT_R3(%r11) | 365 | lmg %r3,%r7,__PT_R3(%r11) |
366 | stg %r7,STACK_FRAME_OVERHEAD(%r15) | 366 | stg %r7,STACK_FRAME_OVERHEAD(%r15) |
367 | lg %r2,__PT_ORIG_GPR2(%r11) | 367 | lg %r2,__PT_ORIG_GPR2(%r11) |
368 | basr %r14,%r9 # call sys_xxx | 368 | basr %r14,%r9 # call sys_xxx |
369 | stg %r2,__PT_R2(%r11) # store return value | 369 | stg %r2,__PT_R2(%r11) # store return value |
370 | sysc_tracenogo: | 370 | .Lsysc_tracenogo: |
371 | tm __TI_flags+7(%r12),_TIF_TRACE | 371 | tm __TI_flags+7(%r12),_TIF_TRACE |
372 | jz sysc_return | 372 | jz .Lsysc_return |
373 | lgr %r2,%r11 # pass pointer to pt_regs | 373 | lgr %r2,%r11 # pass pointer to pt_regs |
374 | larl %r14,sysc_return | 374 | larl %r14,.Lsysc_return |
375 | jg do_syscall_trace_exit | 375 | jg do_syscall_trace_exit |
376 | 376 | ||
377 | # | 377 | # |
@@ -384,13 +384,13 @@ ENTRY(ret_from_fork) | |||
384 | TRACE_IRQS_ON | 384 | TRACE_IRQS_ON |
385 | ssm __LC_SVC_NEW_PSW # reenable interrupts | 385 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
386 | tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ? | 386 | tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ? |
387 | jne sysc_tracenogo | 387 | jne .Lsysc_tracenogo |
388 | # it's a kernel thread | 388 | # it's a kernel thread |
389 | lmg %r9,%r10,__PT_R9(%r11) # load gprs | 389 | lmg %r9,%r10,__PT_R9(%r11) # load gprs |
390 | ENTRY(kernel_thread_starter) | 390 | ENTRY(kernel_thread_starter) |
391 | la %r2,0(%r10) | 391 | la %r2,0(%r10) |
392 | basr %r14,%r9 | 392 | basr %r14,%r9 |
393 | j sysc_tracenogo | 393 | j .Lsysc_tracenogo |
394 | 394 | ||
395 | /* | 395 | /* |
396 | * Program check handler routine | 396 | * Program check handler routine |
@@ -409,7 +409,7 @@ ENTRY(pgm_check_handler) | |||
409 | tmhh %r8,0x4000 # PER bit set in old PSW ? | 409 | tmhh %r8,0x4000 # PER bit set in old PSW ? |
410 | jnz 0f # -> enabled, can't be a double fault | 410 | jnz 0f # -> enabled, can't be a double fault |
411 | tm __LC_PGM_ILC+3,0x80 # check for per exception | 411 | tm __LC_PGM_ILC+3,0x80 # check for per exception |
412 | jnz pgm_svcper # -> single stepped svc | 412 | jnz .Lpgm_svcper # -> single stepped svc |
413 | 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC | 413 | 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC |
414 | aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 414 | aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) |
415 | j 2f | 415 | j 2f |
@@ -432,7 +432,7 @@ ENTRY(pgm_check_handler) | |||
432 | tm __LC_PGM_ILC+3,0x80 # check for per exception | 432 | tm __LC_PGM_ILC+3,0x80 # check for per exception |
433 | jz 0f | 433 | jz 0f |
434 | tmhh %r8,0x0001 # kernel per event ? | 434 | tmhh %r8,0x0001 # kernel per event ? |
435 | jz pgm_kprobe | 435 | jz .Lpgm_kprobe |
436 | oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP | 436 | oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP |
437 | mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS | 437 | mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS |
438 | mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE | 438 | mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE |
@@ -443,31 +443,31 @@ ENTRY(pgm_check_handler) | |||
443 | llgh %r10,__PT_INT_CODE+2(%r11) | 443 | llgh %r10,__PT_INT_CODE+2(%r11) |
444 | nill %r10,0x007f | 444 | nill %r10,0x007f |
445 | sll %r10,2 | 445 | sll %r10,2 |
446 | je sysc_return | 446 | je .Lsysc_return |
447 | lgf %r1,0(%r10,%r1) # load address of handler routine | 447 | lgf %r1,0(%r10,%r1) # load address of handler routine |
448 | lgr %r2,%r11 # pass pointer to pt_regs | 448 | lgr %r2,%r11 # pass pointer to pt_regs |
449 | basr %r14,%r1 # branch to interrupt-handler | 449 | basr %r14,%r1 # branch to interrupt-handler |
450 | j sysc_return | 450 | j .Lsysc_return |
451 | 451 | ||
452 | # | 452 | # |
453 | # PER event in supervisor state, must be kprobes | 453 | # PER event in supervisor state, must be kprobes |
454 | # | 454 | # |
455 | pgm_kprobe: | 455 | .Lpgm_kprobe: |
456 | REENABLE_IRQS | 456 | REENABLE_IRQS |
457 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 457 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
458 | lgr %r2,%r11 # pass pointer to pt_regs | 458 | lgr %r2,%r11 # pass pointer to pt_regs |
459 | brasl %r14,do_per_trap | 459 | brasl %r14,do_per_trap |
460 | j sysc_return | 460 | j .Lsysc_return |
461 | 461 | ||
462 | # | 462 | # |
463 | # single stepped system call | 463 | # single stepped system call |
464 | # | 464 | # |
465 | pgm_svcper: | 465 | .Lpgm_svcper: |
466 | mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW | 466 | mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW |
467 | larl %r14,sysc_per | 467 | larl %r14,.Lsysc_per |
468 | stg %r14,__LC_RETURN_PSW+8 | 468 | stg %r14,__LC_RETURN_PSW+8 |
469 | lghi %r14,_PIF_SYSCALL | _PIF_PER_TRAP | 469 | lghi %r14,_PIF_SYSCALL | _PIF_PER_TRAP |
470 | lpswe __LC_RETURN_PSW # branch to sysc_per and enable irqs | 470 | lpswe __LC_RETURN_PSW # branch to .Lsysc_per and enable irqs |
471 | 471 | ||
472 | /* | 472 | /* |
473 | * IO interrupt handler routine | 473 | * IO interrupt handler routine |
@@ -483,10 +483,10 @@ ENTRY(io_int_handler) | |||
483 | HANDLE_SIE_INTERCEPT %r14,2 | 483 | HANDLE_SIE_INTERCEPT %r14,2 |
484 | SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT | 484 | SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT |
485 | tmhh %r8,0x0001 # interrupting from user? | 485 | tmhh %r8,0x0001 # interrupting from user? |
486 | jz io_skip | 486 | jz .Lio_skip |
487 | UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER | 487 | UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER |
488 | LAST_BREAK %r14 | 488 | LAST_BREAK %r14 |
489 | io_skip: | 489 | .Lio_skip: |
490 | stmg %r0,%r7,__PT_R0(%r11) | 490 | stmg %r0,%r7,__PT_R0(%r11) |
491 | mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC | 491 | mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC |
492 | stmg %r8,%r9,__PT_PSW(%r11) | 492 | stmg %r8,%r9,__PT_PSW(%r11) |
@@ -494,29 +494,29 @@ io_skip: | |||
494 | xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) | 494 | xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) |
495 | TRACE_IRQS_OFF | 495 | TRACE_IRQS_OFF |
496 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 496 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
497 | io_loop: | 497 | .Lio_loop: |
498 | lgr %r2,%r11 # pass pointer to pt_regs | 498 | lgr %r2,%r11 # pass pointer to pt_regs |
499 | lghi %r3,IO_INTERRUPT | 499 | lghi %r3,IO_INTERRUPT |
500 | tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ? | 500 | tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ? |
501 | jz io_call | 501 | jz .Lio_call |
502 | lghi %r3,THIN_INTERRUPT | 502 | lghi %r3,THIN_INTERRUPT |
503 | io_call: | 503 | .Lio_call: |
504 | brasl %r14,do_IRQ | 504 | brasl %r14,do_IRQ |
505 | tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR | 505 | tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR |
506 | jz io_return | 506 | jz .Lio_return |
507 | tpi 0 | 507 | tpi 0 |
508 | jz io_return | 508 | jz .Lio_return |
509 | mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID | 509 | mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID |
510 | j io_loop | 510 | j .Lio_loop |
511 | io_return: | 511 | .Lio_return: |
512 | LOCKDEP_SYS_EXIT | 512 | LOCKDEP_SYS_EXIT |
513 | TRACE_IRQS_ON | 513 | TRACE_IRQS_ON |
514 | io_tif: | 514 | .Lio_tif: |
515 | tm __TI_flags+7(%r12),_TIF_WORK | 515 | tm __TI_flags+7(%r12),_TIF_WORK |
516 | jnz io_work # there is work to do (signals etc.) | 516 | jnz .Lio_work # there is work to do (signals etc.) |
517 | tm __LC_CPU_FLAGS+7,_CIF_WORK | 517 | tm __LC_CPU_FLAGS+7,_CIF_WORK |
518 | jnz io_work | 518 | jnz .Lio_work |
519 | io_restore: | 519 | .Lio_restore: |
520 | lg %r14,__LC_VDSO_PER_CPU | 520 | lg %r14,__LC_VDSO_PER_CPU |
521 | lmg %r0,%r10,__PT_R0(%r11) | 521 | lmg %r0,%r10,__PT_R0(%r11) |
522 | mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) | 522 | mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) |
@@ -524,7 +524,7 @@ io_restore: | |||
524 | mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER | 524 | mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER |
525 | lmg %r11,%r15,__PT_R11(%r11) | 525 | lmg %r11,%r15,__PT_R11(%r11) |
526 | lpswe __LC_RETURN_PSW | 526 | lpswe __LC_RETURN_PSW |
527 | io_done: | 527 | .Lio_done: |
528 | 528 | ||
529 | # | 529 | # |
530 | # There is work todo, find out in which context we have been interrupted: | 530 | # There is work todo, find out in which context we have been interrupted: |
@@ -535,15 +535,15 @@ io_done: | |||
535 | # the preemption counter and if it is zero call preempt_schedule_irq | 535 | # the preemption counter and if it is zero call preempt_schedule_irq |
536 | # Before any work can be done, a switch to the kernel stack is required. | 536 | # Before any work can be done, a switch to the kernel stack is required. |
537 | # | 537 | # |
538 | io_work: | 538 | .Lio_work: |
539 | tm __PT_PSW+1(%r11),0x01 # returning to user ? | 539 | tm __PT_PSW+1(%r11),0x01 # returning to user ? |
540 | jo io_work_user # yes -> do resched & signal | 540 | jo .Lio_work_user # yes -> do resched & signal |
541 | #ifdef CONFIG_PREEMPT | 541 | #ifdef CONFIG_PREEMPT |
542 | # check for preemptive scheduling | 542 | # check for preemptive scheduling |
543 | icm %r0,15,__TI_precount(%r12) | 543 | icm %r0,15,__TI_precount(%r12) |
544 | jnz io_restore # preemption is disabled | 544 | jnz .Lio_restore # preemption is disabled |
545 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED | 545 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED |
546 | jno io_restore | 546 | jno .Lio_restore |
547 | # switch to kernel stack | 547 | # switch to kernel stack |
548 | lg %r1,__PT_R15(%r11) | 548 | lg %r1,__PT_R15(%r11) |
549 | aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 549 | aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) |
@@ -551,19 +551,19 @@ io_work: | |||
551 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) | 551 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) |
552 | la %r11,STACK_FRAME_OVERHEAD(%r1) | 552 | la %r11,STACK_FRAME_OVERHEAD(%r1) |
553 | lgr %r15,%r1 | 553 | lgr %r15,%r1 |
554 | # TRACE_IRQS_ON already done at io_return, call | 554 | # TRACE_IRQS_ON already done at .Lio_return, call |
555 | # TRACE_IRQS_OFF to keep things symmetrical | 555 | # TRACE_IRQS_OFF to keep things symmetrical |
556 | TRACE_IRQS_OFF | 556 | TRACE_IRQS_OFF |
557 | brasl %r14,preempt_schedule_irq | 557 | brasl %r14,preempt_schedule_irq |
558 | j io_return | 558 | j .Lio_return |
559 | #else | 559 | #else |
560 | j io_restore | 560 | j .Lio_restore |
561 | #endif | 561 | #endif |
562 | 562 | ||
563 | # | 563 | # |
564 | # Need to do work before returning to userspace, switch to kernel stack | 564 | # Need to do work before returning to userspace, switch to kernel stack |
565 | # | 565 | # |
566 | io_work_user: | 566 | .Lio_work_user: |
567 | lg %r1,__LC_KERNEL_STACK | 567 | lg %r1,__LC_KERNEL_STACK |
568 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) | 568 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) |
569 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) | 569 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) |
@@ -573,70 +573,70 @@ io_work_user: | |||
573 | # | 573 | # |
574 | # One of the work bits is on. Find out which one. | 574 | # One of the work bits is on. Find out which one. |
575 | # | 575 | # |
576 | io_work_tif: | 576 | .Lio_work_tif: |
577 | tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING | 577 | tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING |
578 | jo io_mcck_pending | 578 | jo .Lio_mcck_pending |
579 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED | 579 | tm __TI_flags+7(%r12),_TIF_NEED_RESCHED |
580 | jo io_reschedule | 580 | jo .Lio_reschedule |
581 | tm __TI_flags+7(%r12),_TIF_SIGPENDING | 581 | tm __TI_flags+7(%r12),_TIF_SIGPENDING |
582 | jo io_sigpending | 582 | jo .Lio_sigpending |
583 | tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME | 583 | tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME |
584 | jo io_notify_resume | 584 | jo .Lio_notify_resume |
585 | tm __LC_CPU_FLAGS+7,_CIF_ASCE | 585 | tm __LC_CPU_FLAGS+7,_CIF_ASCE |
586 | jo io_uaccess | 586 | jo .Lio_uaccess |
587 | j io_return # beware of critical section cleanup | 587 | j .Lio_return # beware of critical section cleanup |
588 | 588 | ||
589 | # | 589 | # |
590 | # _CIF_MCCK_PENDING is set, call handler | 590 | # _CIF_MCCK_PENDING is set, call handler |
591 | # | 591 | # |
592 | io_mcck_pending: | 592 | .Lio_mcck_pending: |
593 | # TRACE_IRQS_ON already done at io_return | 593 | # TRACE_IRQS_ON already done at .Lio_return |
594 | brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler | 594 | brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler |
595 | TRACE_IRQS_OFF | 595 | TRACE_IRQS_OFF |
596 | j io_return | 596 | j .Lio_return |
597 | 597 | ||
598 | # | 598 | # |
599 | # _CIF_ASCE is set, load user space asce | 599 | # _CIF_ASCE is set, load user space asce |
600 | # | 600 | # |
601 | io_uaccess: | 601 | .Lio_uaccess: |
602 | ni __LC_CPU_FLAGS+7,255-_CIF_ASCE | 602 | ni __LC_CPU_FLAGS+7,255-_CIF_ASCE |
603 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | 603 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce |
604 | j io_return | 604 | j .Lio_return |
605 | 605 | ||
606 | # | 606 | # |
607 | # _TIF_NEED_RESCHED is set, call schedule | 607 | # _TIF_NEED_RESCHED is set, call schedule |
608 | # | 608 | # |
609 | io_reschedule: | 609 | .Lio_reschedule: |
610 | # TRACE_IRQS_ON already done at io_return | 610 | # TRACE_IRQS_ON already done at .Lio_return |
611 | ssm __LC_SVC_NEW_PSW # reenable interrupts | 611 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
612 | brasl %r14,schedule # call scheduler | 612 | brasl %r14,schedule # call scheduler |
613 | ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts | 613 | ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts |
614 | TRACE_IRQS_OFF | 614 | TRACE_IRQS_OFF |
615 | j io_return | 615 | j .Lio_return |
616 | 616 | ||
617 | # | 617 | # |
618 | # _TIF_SIGPENDING or is set, call do_signal | 618 | # _TIF_SIGPENDING or is set, call do_signal |
619 | # | 619 | # |
620 | io_sigpending: | 620 | .Lio_sigpending: |
621 | # TRACE_IRQS_ON already done at io_return | 621 | # TRACE_IRQS_ON already done at .Lio_return |
622 | ssm __LC_SVC_NEW_PSW # reenable interrupts | 622 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
623 | lgr %r2,%r11 # pass pointer to pt_regs | 623 | lgr %r2,%r11 # pass pointer to pt_regs |
624 | brasl %r14,do_signal | 624 | brasl %r14,do_signal |
625 | ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts | 625 | ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts |
626 | TRACE_IRQS_OFF | 626 | TRACE_IRQS_OFF |
627 | j io_return | 627 | j .Lio_return |
628 | 628 | ||
629 | # | 629 | # |
630 | # _TIF_NOTIFY_RESUME or is set, call do_notify_resume | 630 | # _TIF_NOTIFY_RESUME or is set, call do_notify_resume |
631 | # | 631 | # |
632 | io_notify_resume: | 632 | .Lio_notify_resume: |
633 | # TRACE_IRQS_ON already done at io_return | 633 | # TRACE_IRQS_ON already done at .Lio_return |
634 | ssm __LC_SVC_NEW_PSW # reenable interrupts | 634 | ssm __LC_SVC_NEW_PSW # reenable interrupts |
635 | lgr %r2,%r11 # pass pointer to pt_regs | 635 | lgr %r2,%r11 # pass pointer to pt_regs |
636 | brasl %r14,do_notify_resume | 636 | brasl %r14,do_notify_resume |
637 | ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts | 637 | ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts |
638 | TRACE_IRQS_OFF | 638 | TRACE_IRQS_OFF |
639 | j io_return | 639 | j .Lio_return |
640 | 640 | ||
641 | /* | 641 | /* |
642 | * External interrupt handler routine | 642 | * External interrupt handler routine |
@@ -652,10 +652,10 @@ ENTRY(ext_int_handler) | |||
652 | HANDLE_SIE_INTERCEPT %r14,3 | 652 | HANDLE_SIE_INTERCEPT %r14,3 |
653 | SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT | 653 | SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT |
654 | tmhh %r8,0x0001 # interrupting from user ? | 654 | tmhh %r8,0x0001 # interrupting from user ? |
655 | jz ext_skip | 655 | jz .Lext_skip |
656 | UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER | 656 | UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER |
657 | LAST_BREAK %r14 | 657 | LAST_BREAK %r14 |
658 | ext_skip: | 658 | .Lext_skip: |
659 | stmg %r0,%r7,__PT_R0(%r11) | 659 | stmg %r0,%r7,__PT_R0(%r11) |
660 | mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC | 660 | mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC |
661 | stmg %r8,%r9,__PT_PSW(%r11) | 661 | stmg %r8,%r9,__PT_PSW(%r11) |
@@ -669,23 +669,23 @@ ext_skip: | |||
669 | lgr %r2,%r11 # pass pointer to pt_regs | 669 | lgr %r2,%r11 # pass pointer to pt_regs |
670 | lghi %r3,EXT_INTERRUPT | 670 | lghi %r3,EXT_INTERRUPT |
671 | brasl %r14,do_IRQ | 671 | brasl %r14,do_IRQ |
672 | j io_return | 672 | j .Lio_return |
673 | 673 | ||
674 | /* | 674 | /* |
675 | * Load idle PSW. The second "half" of this function is in cleanup_idle. | 675 | * Load idle PSW. The second "half" of this function is in .Lcleanup_idle. |
676 | */ | 676 | */ |
677 | ENTRY(psw_idle) | 677 | ENTRY(psw_idle) |
678 | stg %r3,__SF_EMPTY(%r15) | 678 | stg %r3,__SF_EMPTY(%r15) |
679 | larl %r1,psw_idle_lpsw+4 | 679 | larl %r1,.Lpsw_idle_lpsw+4 |
680 | stg %r1,__SF_EMPTY+8(%r15) | 680 | stg %r1,__SF_EMPTY+8(%r15) |
681 | STCK __CLOCK_IDLE_ENTER(%r2) | 681 | STCK __CLOCK_IDLE_ENTER(%r2) |
682 | stpt __TIMER_IDLE_ENTER(%r2) | 682 | stpt __TIMER_IDLE_ENTER(%r2) |
683 | psw_idle_lpsw: | 683 | .Lpsw_idle_lpsw: |
684 | lpswe __SF_EMPTY(%r15) | 684 | lpswe __SF_EMPTY(%r15) |
685 | br %r14 | 685 | br %r14 |
686 | psw_idle_end: | 686 | .Lpsw_idle_end: |
687 | 687 | ||
688 | __critical_end: | 688 | .L__critical_end: |
689 | 689 | ||
690 | /* | 690 | /* |
691 | * Machine check handler routines | 691 | * Machine check handler routines |
@@ -701,7 +701,7 @@ ENTRY(mcck_int_handler) | |||
701 | lmg %r8,%r9,__LC_MCK_OLD_PSW | 701 | lmg %r8,%r9,__LC_MCK_OLD_PSW |
702 | HANDLE_SIE_INTERCEPT %r14,4 | 702 | HANDLE_SIE_INTERCEPT %r14,4 |
703 | tm __LC_MCCK_CODE,0x80 # system damage? | 703 | tm __LC_MCCK_CODE,0x80 # system damage? |
704 | jo mcck_panic # yes -> rest of mcck code invalid | 704 | jo .Lmcck_panic # yes -> rest of mcck code invalid |
705 | lghi %r14,__LC_CPU_TIMER_SAVE_AREA | 705 | lghi %r14,__LC_CPU_TIMER_SAVE_AREA |
706 | mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) | 706 | mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) |
707 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | 707 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? |
@@ -719,13 +719,13 @@ ENTRY(mcck_int_handler) | |||
719 | 2: spt 0(%r14) | 719 | 2: spt 0(%r14) |
720 | mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) | 720 | mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) |
721 | 3: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? | 721 | 3: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? |
722 | jno mcck_panic # no -> skip cleanup critical | 722 | jno .Lmcck_panic # no -> skip cleanup critical |
723 | SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT | 723 | SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT |
724 | tm %r8,0x0001 # interrupting from user ? | 724 | tm %r8,0x0001 # interrupting from user ? |
725 | jz mcck_skip | 725 | jz .Lmcck_skip |
726 | UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER | 726 | UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER |
727 | LAST_BREAK %r14 | 727 | LAST_BREAK %r14 |
728 | mcck_skip: | 728 | .Lmcck_skip: |
729 | lghi %r14,__LC_GPREGS_SAVE_AREA+64 | 729 | lghi %r14,__LC_GPREGS_SAVE_AREA+64 |
730 | stmg %r0,%r7,__PT_R0(%r11) | 730 | stmg %r0,%r7,__PT_R0(%r11) |
731 | mvc __PT_R8(64,%r11),0(%r14) | 731 | mvc __PT_R8(64,%r11),0(%r14) |
@@ -735,7 +735,7 @@ mcck_skip: | |||
735 | lgr %r2,%r11 # pass pointer to pt_regs | 735 | lgr %r2,%r11 # pass pointer to pt_regs |
736 | brasl %r14,s390_do_machine_check | 736 | brasl %r14,s390_do_machine_check |
737 | tm __PT_PSW+1(%r11),0x01 # returning to user ? | 737 | tm __PT_PSW+1(%r11),0x01 # returning to user ? |
738 | jno mcck_return | 738 | jno .Lmcck_return |
739 | lg %r1,__LC_KERNEL_STACK # switch to kernel stack | 739 | lg %r1,__LC_KERNEL_STACK # switch to kernel stack |
740 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) | 740 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) |
741 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) | 741 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) |
@@ -743,11 +743,11 @@ mcck_skip: | |||
743 | lgr %r15,%r1 | 743 | lgr %r15,%r1 |
744 | ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off | 744 | ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off |
745 | tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING | 745 | tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING |
746 | jno mcck_return | 746 | jno .Lmcck_return |
747 | TRACE_IRQS_OFF | 747 | TRACE_IRQS_OFF |
748 | brasl %r14,s390_handle_mcck | 748 | brasl %r14,s390_handle_mcck |
749 | TRACE_IRQS_ON | 749 | TRACE_IRQS_ON |
750 | mcck_return: | 750 | .Lmcck_return: |
751 | lg %r14,__LC_VDSO_PER_CPU | 751 | lg %r14,__LC_VDSO_PER_CPU |
752 | lmg %r0,%r10,__PT_R0(%r11) | 752 | lmg %r0,%r10,__PT_R0(%r11) |
753 | mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW | 753 | mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW |
@@ -758,14 +758,14 @@ mcck_return: | |||
758 | 0: lmg %r11,%r15,__PT_R11(%r11) | 758 | 0: lmg %r11,%r15,__PT_R11(%r11) |
759 | lpswe __LC_RETURN_MCCK_PSW | 759 | lpswe __LC_RETURN_MCCK_PSW |
760 | 760 | ||
761 | mcck_panic: | 761 | .Lmcck_panic: |
762 | lg %r14,__LC_PANIC_STACK | 762 | lg %r14,__LC_PANIC_STACK |
763 | slgr %r14,%r15 | 763 | slgr %r14,%r15 |
764 | srag %r14,%r14,PAGE_SHIFT | 764 | srag %r14,%r14,PAGE_SHIFT |
765 | jz 0f | 765 | jz 0f |
766 | lg %r15,__LC_PANIC_STACK | 766 | lg %r15,__LC_PANIC_STACK |
767 | 0: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 767 | 0: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) |
768 | j mcck_skip | 768 | j .Lmcck_skip |
769 | 769 | ||
770 | # | 770 | # |
771 | # PSW restart interrupt handler | 771 | # PSW restart interrupt handler |
@@ -815,69 +815,69 @@ stack_overflow: | |||
815 | #endif | 815 | #endif |
816 | 816 | ||
817 | .align 8 | 817 | .align 8 |
818 | cleanup_table: | 818 | .Lcleanup_table: |
819 | .quad system_call | 819 | .quad system_call |
820 | .quad sysc_do_svc | 820 | .quad .Lsysc_do_svc |
821 | .quad sysc_tif | 821 | .quad .Lsysc_tif |
822 | .quad sysc_restore | 822 | .quad .Lsysc_restore |
823 | .quad sysc_done | 823 | .quad .Lsysc_done |
824 | .quad io_tif | 824 | .quad .Lio_tif |
825 | .quad io_restore | 825 | .quad .Lio_restore |
826 | .quad io_done | 826 | .quad .Lio_done |
827 | .quad psw_idle | 827 | .quad psw_idle |
828 | .quad psw_idle_end | 828 | .quad .Lpsw_idle_end |
829 | 829 | ||
830 | cleanup_critical: | 830 | cleanup_critical: |
831 | clg %r9,BASED(cleanup_table) # system_call | 831 | clg %r9,BASED(.Lcleanup_table) # system_call |
832 | jl 0f | 832 | jl 0f |
833 | clg %r9,BASED(cleanup_table+8) # sysc_do_svc | 833 | clg %r9,BASED(.Lcleanup_table+8) # .Lsysc_do_svc |
834 | jl cleanup_system_call | 834 | jl .Lcleanup_system_call |
835 | clg %r9,BASED(cleanup_table+16) # sysc_tif | 835 | clg %r9,BASED(.Lcleanup_table+16) # .Lsysc_tif |
836 | jl 0f | 836 | jl 0f |
837 | clg %r9,BASED(cleanup_table+24) # sysc_restore | 837 | clg %r9,BASED(.Lcleanup_table+24) # .Lsysc_restore |
838 | jl cleanup_sysc_tif | 838 | jl .Lcleanup_sysc_tif |
839 | clg %r9,BASED(cleanup_table+32) # sysc_done | 839 | clg %r9,BASED(.Lcleanup_table+32) # .Lsysc_done |
840 | jl cleanup_sysc_restore | 840 | jl .Lcleanup_sysc_restore |
841 | clg %r9,BASED(cleanup_table+40) # io_tif | 841 | clg %r9,BASED(.Lcleanup_table+40) # .Lio_tif |
842 | jl 0f | 842 | jl 0f |
843 | clg %r9,BASED(cleanup_table+48) # io_restore | 843 | clg %r9,BASED(.Lcleanup_table+48) # .Lio_restore |
844 | jl cleanup_io_tif | 844 | jl .Lcleanup_io_tif |
845 | clg %r9,BASED(cleanup_table+56) # io_done | 845 | clg %r9,BASED(.Lcleanup_table+56) # .Lio_done |
846 | jl cleanup_io_restore | 846 | jl .Lcleanup_io_restore |
847 | clg %r9,BASED(cleanup_table+64) # psw_idle | 847 | clg %r9,BASED(.Lcleanup_table+64) # psw_idle |
848 | jl 0f | 848 | jl 0f |
849 | clg %r9,BASED(cleanup_table+72) # psw_idle_end | 849 | clg %r9,BASED(.Lcleanup_table+72) # .Lpsw_idle_end |
850 | jl cleanup_idle | 850 | jl .Lcleanup_idle |
851 | 0: br %r14 | 851 | 0: br %r14 |
852 | 852 | ||
853 | 853 | ||
854 | cleanup_system_call: | 854 | .Lcleanup_system_call: |
855 | # check if stpt has been executed | 855 | # check if stpt has been executed |
856 | clg %r9,BASED(cleanup_system_call_insn) | 856 | clg %r9,BASED(.Lcleanup_system_call_insn) |
857 | jh 0f | 857 | jh 0f |
858 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER | 858 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER |
859 | cghi %r11,__LC_SAVE_AREA_ASYNC | 859 | cghi %r11,__LC_SAVE_AREA_ASYNC |
860 | je 0f | 860 | je 0f |
861 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER | 861 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER |
862 | 0: # check if stmg has been executed | 862 | 0: # check if stmg has been executed |
863 | clg %r9,BASED(cleanup_system_call_insn+8) | 863 | clg %r9,BASED(.Lcleanup_system_call_insn+8) |
864 | jh 0f | 864 | jh 0f |
865 | mvc __LC_SAVE_AREA_SYNC(64),0(%r11) | 865 | mvc __LC_SAVE_AREA_SYNC(64),0(%r11) |
866 | 0: # check if base register setup + TIF bit load has been done | 866 | 0: # check if base register setup + TIF bit load has been done |
867 | clg %r9,BASED(cleanup_system_call_insn+16) | 867 | clg %r9,BASED(.Lcleanup_system_call_insn+16) |
868 | jhe 0f | 868 | jhe 0f |
869 | # set up saved registers r10 and r12 | 869 | # set up saved registers r10 and r12 |
870 | stg %r10,16(%r11) # r10 last break | 870 | stg %r10,16(%r11) # r10 last break |
871 | stg %r12,32(%r11) # r12 thread-info pointer | 871 | stg %r12,32(%r11) # r12 thread-info pointer |
872 | 0: # check if the user time update has been done | 872 | 0: # check if the user time update has been done |
873 | clg %r9,BASED(cleanup_system_call_insn+24) | 873 | clg %r9,BASED(.Lcleanup_system_call_insn+24) |
874 | jh 0f | 874 | jh 0f |
875 | lg %r15,__LC_EXIT_TIMER | 875 | lg %r15,__LC_EXIT_TIMER |
876 | slg %r15,__LC_SYNC_ENTER_TIMER | 876 | slg %r15,__LC_SYNC_ENTER_TIMER |
877 | alg %r15,__LC_USER_TIMER | 877 | alg %r15,__LC_USER_TIMER |
878 | stg %r15,__LC_USER_TIMER | 878 | stg %r15,__LC_USER_TIMER |
879 | 0: # check if the system time update has been done | 879 | 0: # check if the system time update has been done |
880 | clg %r9,BASED(cleanup_system_call_insn+32) | 880 | clg %r9,BASED(.Lcleanup_system_call_insn+32) |
881 | jh 0f | 881 | jh 0f |
882 | lg %r15,__LC_LAST_UPDATE_TIMER | 882 | lg %r15,__LC_LAST_UPDATE_TIMER |
883 | slg %r15,__LC_EXIT_TIMER | 883 | slg %r15,__LC_EXIT_TIMER |
@@ -904,21 +904,21 @@ cleanup_system_call: | |||
904 | # setup saved register r15 | 904 | # setup saved register r15 |
905 | stg %r15,56(%r11) # r15 stack pointer | 905 | stg %r15,56(%r11) # r15 stack pointer |
906 | # set new psw address and exit | 906 | # set new psw address and exit |
907 | larl %r9,sysc_do_svc | 907 | larl %r9,.Lsysc_do_svc |
908 | br %r14 | 908 | br %r14 |
909 | cleanup_system_call_insn: | 909 | .Lcleanup_system_call_insn: |
910 | .quad system_call | 910 | .quad system_call |
911 | .quad sysc_stmg | 911 | .quad .Lsysc_stmg |
912 | .quad sysc_per | 912 | .quad .Lsysc_per |
913 | .quad sysc_vtime+18 | 913 | .quad .Lsysc_vtime+18 |
914 | .quad sysc_vtime+42 | 914 | .quad .Lsysc_vtime+42 |
915 | 915 | ||
916 | cleanup_sysc_tif: | 916 | .Lcleanup_sysc_tif: |
917 | larl %r9,sysc_tif | 917 | larl %r9,.Lsysc_tif |
918 | br %r14 | 918 | br %r14 |
919 | 919 | ||
920 | cleanup_sysc_restore: | 920 | .Lcleanup_sysc_restore: |
921 | clg %r9,BASED(cleanup_sysc_restore_insn) | 921 | clg %r9,BASED(.Lcleanup_sysc_restore_insn) |
922 | je 0f | 922 | je 0f |
923 | lg %r9,24(%r11) # get saved pointer to pt_regs | 923 | lg %r9,24(%r11) # get saved pointer to pt_regs |
924 | mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) | 924 | mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) |
@@ -926,15 +926,15 @@ cleanup_sysc_restore: | |||
926 | lmg %r0,%r7,__PT_R0(%r9) | 926 | lmg %r0,%r7,__PT_R0(%r9) |
927 | 0: lmg %r8,%r9,__LC_RETURN_PSW | 927 | 0: lmg %r8,%r9,__LC_RETURN_PSW |
928 | br %r14 | 928 | br %r14 |
929 | cleanup_sysc_restore_insn: | 929 | .Lcleanup_sysc_restore_insn: |
930 | .quad sysc_done - 4 | 930 | .quad .Lsysc_done - 4 |
931 | 931 | ||
932 | cleanup_io_tif: | 932 | .Lcleanup_io_tif: |
933 | larl %r9,io_tif | 933 | larl %r9,.Lio_tif |
934 | br %r14 | 934 | br %r14 |
935 | 935 | ||
936 | cleanup_io_restore: | 936 | .Lcleanup_io_restore: |
937 | clg %r9,BASED(cleanup_io_restore_insn) | 937 | clg %r9,BASED(.Lcleanup_io_restore_insn) |
938 | je 0f | 938 | je 0f |
939 | lg %r9,24(%r11) # get saved r11 pointer to pt_regs | 939 | lg %r9,24(%r11) # get saved r11 pointer to pt_regs |
940 | mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) | 940 | mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) |
@@ -942,10 +942,10 @@ cleanup_io_restore: | |||
942 | lmg %r0,%r7,__PT_R0(%r9) | 942 | lmg %r0,%r7,__PT_R0(%r9) |
943 | 0: lmg %r8,%r9,__LC_RETURN_PSW | 943 | 0: lmg %r8,%r9,__LC_RETURN_PSW |
944 | br %r14 | 944 | br %r14 |
945 | cleanup_io_restore_insn: | 945 | .Lcleanup_io_restore_insn: |
946 | .quad io_done - 4 | 946 | .quad .Lio_done - 4 |
947 | 947 | ||
948 | cleanup_idle: | 948 | .Lcleanup_idle: |
949 | # copy interrupt clock & cpu timer | 949 | # copy interrupt clock & cpu timer |
950 | mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK | 950 | mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK |
951 | mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER | 951 | mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER |
@@ -954,7 +954,7 @@ cleanup_idle: | |||
954 | mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK | 954 | mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK |
955 | mvc __TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER | 955 | mvc __TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER |
956 | 0: # check if stck & stpt have been executed | 956 | 0: # check if stck & stpt have been executed |
957 | clg %r9,BASED(cleanup_idle_insn) | 957 | clg %r9,BASED(.Lcleanup_idle_insn) |
958 | jhe 1f | 958 | jhe 1f |
959 | mvc __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2) | 959 | mvc __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2) |
960 | mvc __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2) | 960 | mvc __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2) |
@@ -973,17 +973,17 @@ cleanup_idle: | |||
973 | nihh %r8,0xfcfd # clear irq & wait state bits | 973 | nihh %r8,0xfcfd # clear irq & wait state bits |
974 | lg %r9,48(%r11) # return from psw_idle | 974 | lg %r9,48(%r11) # return from psw_idle |
975 | br %r14 | 975 | br %r14 |
976 | cleanup_idle_insn: | 976 | .Lcleanup_idle_insn: |
977 | .quad psw_idle_lpsw | 977 | .quad .Lpsw_idle_lpsw |
978 | 978 | ||
979 | /* | 979 | /* |
980 | * Integer constants | 980 | * Integer constants |
981 | */ | 981 | */ |
982 | .align 8 | 982 | .align 8 |
983 | .Lcritical_start: | 983 | .Lcritical_start: |
984 | .quad __critical_start | 984 | .quad .L__critical_start |
985 | .Lcritical_length: | 985 | .Lcritical_length: |
986 | .quad __critical_end - __critical_start | 986 | .quad .L__critical_end - .L__critical_start |
987 | 987 | ||
988 | 988 | ||
989 | #if IS_ENABLED(CONFIG_KVM) | 989 | #if IS_ENABLED(CONFIG_KVM) |
@@ -1000,25 +1000,25 @@ ENTRY(sie64a) | |||
1000 | lmg %r0,%r13,0(%r3) # load guest gprs 0-13 | 1000 | lmg %r0,%r13,0(%r3) # load guest gprs 0-13 |
1001 | lg %r14,__LC_GMAP # get gmap pointer | 1001 | lg %r14,__LC_GMAP # get gmap pointer |
1002 | ltgr %r14,%r14 | 1002 | ltgr %r14,%r14 |
1003 | jz sie_gmap | 1003 | jz .Lsie_gmap |
1004 | lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce | 1004 | lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce |
1005 | sie_gmap: | 1005 | .Lsie_gmap: |
1006 | lg %r14,__SF_EMPTY(%r15) # get control block pointer | 1006 | lg %r14,__SF_EMPTY(%r15) # get control block pointer |
1007 | oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now | 1007 | oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now |
1008 | tm __SIE_PROG20+3(%r14),1 # last exit... | 1008 | tm __SIE_PROG20+3(%r14),1 # last exit... |
1009 | jnz sie_done | 1009 | jnz .Lsie_done |
1010 | LPP __SF_EMPTY(%r15) # set guest id | 1010 | LPP __SF_EMPTY(%r15) # set guest id |
1011 | sie 0(%r14) | 1011 | sie 0(%r14) |
1012 | sie_done: | 1012 | .Lsie_done: |
1013 | LPP __SF_EMPTY+16(%r15) # set host id | 1013 | LPP __SF_EMPTY+16(%r15) # set host id |
1014 | ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE | 1014 | ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE |
1015 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | 1015 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce |
1016 | # some program checks are suppressing. C code (e.g. do_protection_exception) | 1016 | # some program checks are suppressing. C code (e.g. do_protection_exception) |
1017 | # will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other | 1017 | # will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other |
1018 | # instructions between sie64a and sie_done should not cause program | 1018 | # instructions between sie64a and .Lsie_done should not cause program |
1019 | # interrupts. So lets use a nop (47 00 00 00) as a landing pad. | 1019 | # interrupts. So lets use a nop (47 00 00 00) as a landing pad. |
1020 | # See also HANDLE_SIE_INTERCEPT | 1020 | # See also HANDLE_SIE_INTERCEPT |
1021 | rewind_pad: | 1021 | .Lrewind_pad: |
1022 | nop 0 | 1022 | nop 0 |
1023 | .globl sie_exit | 1023 | .globl sie_exit |
1024 | sie_exit: | 1024 | sie_exit: |
@@ -1027,19 +1027,19 @@ sie_exit: | |||
1027 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers | 1027 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers |
1028 | lg %r2,__SF_EMPTY+24(%r15) # return exit reason code | 1028 | lg %r2,__SF_EMPTY+24(%r15) # return exit reason code |
1029 | br %r14 | 1029 | br %r14 |
1030 | sie_fault: | 1030 | .Lsie_fault: |
1031 | lghi %r14,-EFAULT | 1031 | lghi %r14,-EFAULT |
1032 | stg %r14,__SF_EMPTY+24(%r15) # set exit reason code | 1032 | stg %r14,__SF_EMPTY+24(%r15) # set exit reason code |
1033 | j sie_exit | 1033 | j sie_exit |
1034 | 1034 | ||
1035 | .align 8 | 1035 | .align 8 |
1036 | .Lsie_critical: | 1036 | .Lsie_critical: |
1037 | .quad sie_gmap | 1037 | .quad .Lsie_gmap |
1038 | .Lsie_critical_length: | 1038 | .Lsie_critical_length: |
1039 | .quad sie_done - sie_gmap | 1039 | .quad .Lsie_done - .Lsie_gmap |
1040 | 1040 | ||
1041 | EX_TABLE(rewind_pad,sie_fault) | 1041 | EX_TABLE(.Lrewind_pad,.Lsie_fault) |
1042 | EX_TABLE(sie_exit,sie_fault) | 1042 | EX_TABLE(sie_exit,.Lsie_fault) |
1043 | #endif | 1043 | #endif |
1044 | 1044 | ||
1045 | .section .rodata, "a" | 1045 | .section .rodata, "a" |