aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/entry64.S')
-rw-r--r--arch/s390/kernel/entry64.S122
1 files changed, 53 insertions, 69 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 8bccec15ea90..d61967e2eab0 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -51,7 +51,7 @@ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
51STACK_SIZE = 1 << STACK_SHIFT 51STACK_SIZE = 1 << STACK_SHIFT
52 52
53_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 53_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
54 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 54 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_PER_TRAP )
55_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 55_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
56 _TIF_MCCK_PENDING) 56 _TIF_MCCK_PENDING)
57_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ 57_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
@@ -79,25 +79,9 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
79 basr %r2,%r0 79 basr %r2,%r0
80 brasl %r14,trace_hardirqs_off_caller 80 brasl %r14,trace_hardirqs_off_caller
81 .endm 81 .endm
82
83 .macro TRACE_IRQS_CHECK_ON
84 tm SP_PSW(%r15),0x03 # irqs enabled?
85 jz 0f
86 TRACE_IRQS_ON
870:
88 .endm
89
90 .macro TRACE_IRQS_CHECK_OFF
91 tm SP_PSW(%r15),0x03 # irqs enabled?
92 jz 0f
93 TRACE_IRQS_OFF
940:
95 .endm
96#else 82#else
97#define TRACE_IRQS_ON 83#define TRACE_IRQS_ON
98#define TRACE_IRQS_OFF 84#define TRACE_IRQS_OFF
99#define TRACE_IRQS_CHECK_ON
100#define TRACE_IRQS_CHECK_OFF
101#endif 85#endif
102 86
103#ifdef CONFIG_LOCKDEP 87#ifdef CONFIG_LOCKDEP
@@ -207,6 +191,14 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
2070: 1910:
208 .endm 192 .endm
209 193
194 .macro REENABLE_IRQS
195 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15)
196 ni __SF_EMPTY(%r15),0xbf
197 ssm __SF_EMPTY(%r15)
198 .endm
199
200 .section .kprobes.text, "ax"
201
210/* 202/*
211 * Scheduler resume function, called by switch_to 203 * Scheduler resume function, called by switch_to
212 * gpr2 = (task_struct *) prev 204 * gpr2 = (task_struct *) prev
@@ -216,30 +208,22 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
216 */ 208 */
217 .globl __switch_to 209 .globl __switch_to
218__switch_to: 210__switch_to:
219 tm __THREAD_per+4(%r3),0xe8 # is the new process using per ? 211 lg %r4,__THREAD_info(%r2) # get thread_info of prev
220 jz __switch_to_noper # if not we're fine 212 lg %r5,__THREAD_info(%r3) # get thread_info of next
221 stctg %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff
222 clc __THREAD_per(24,%r3),__SF_EMPTY(%r15)
223 je __switch_to_noper # we got away without bashing TLB's
224 lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't
225__switch_to_noper:
226 lg %r4,__THREAD_info(%r2) # get thread_info of prev
227 tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? 213 tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending?
228 jz __switch_to_no_mcck 214 jz 0f
229 ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev 215 ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
230 lg %r4,__THREAD_info(%r3) # get thread_info of next 216 oi __TI_flags+7(%r5),_TIF_MCCK_PENDING # set it in next
231 oi __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next 2170: stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
232__switch_to_no_mcck: 218 stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev
233 stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task 219 lg %r15,__THREAD_ksp(%r3) # load kernel stack of next
234 stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp 220 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
235 lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp 221 lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
236 lmg %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task 222 stg %r3,__LC_CURRENT # store task struct of next
237 stg %r3,__LC_CURRENT # __LC_CURRENT = current task struct 223 mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
238 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 224 stg %r5,__LC_THREAD_INFO # store thread info of next
239 lg %r3,__THREAD_info(%r3) # load thread_info from task struct 225 aghi %r5,STACK_SIZE # end of kernel stack of next
240 stg %r3,__LC_THREAD_INFO 226 stg %r5,__LC_KERNEL_STACK # store end of kernel stack
241 aghi %r3,STACK_SIZE
242 stg %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack
243 br %r14 227 br %r14
244 228
245__critical_start: 229__critical_start:
@@ -256,7 +240,6 @@ sysc_saveall:
256 CREATE_STACK_FRAME __LC_SAVE_AREA 240 CREATE_STACK_FRAME __LC_SAVE_AREA
257 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 241 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
258 mvc SP_ILC(4,%r15),__LC_SVC_ILC 242 mvc SP_ILC(4,%r15),__LC_SVC_ILC
259 stg %r7,SP_ARGS(%r15)
260 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 243 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
261sysc_vtime: 244sysc_vtime:
262 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 245 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -284,6 +267,7 @@ sysc_nr_ok:
284sysc_noemu: 267sysc_noemu:
285#endif 268#endif
286 tm __TI_flags+6(%r12),_TIF_SYSCALL 269 tm __TI_flags+6(%r12),_TIF_SYSCALL
270 mvc SP_ARGS(8,%r15),SP_R7(%r15)
287 lgf %r8,0(%r7,%r10) # load address of system call routine 271 lgf %r8,0(%r7,%r10) # load address of system call routine
288 jnz sysc_tracesys 272 jnz sysc_tracesys
289 basr %r14,%r8 # call sys_xxxx 273 basr %r14,%r8 # call sys_xxxx
@@ -319,7 +303,7 @@ sysc_work_tif:
319 jo sysc_notify_resume 303 jo sysc_notify_resume
320 tm __TI_flags+7(%r12),_TIF_RESTART_SVC 304 tm __TI_flags+7(%r12),_TIF_RESTART_SVC
321 jo sysc_restart 305 jo sysc_restart
322 tm __TI_flags+7(%r12),_TIF_SINGLE_STEP 306 tm __TI_flags+7(%r12),_TIF_PER_TRAP
323 jo sysc_singlestep 307 jo sysc_singlestep
324 j sysc_return # beware of critical section cleanup 308 j sysc_return # beware of critical section cleanup
325 309
@@ -341,12 +325,12 @@ sysc_mcck_pending:
341# _TIF_SIGPENDING is set, call do_signal 325# _TIF_SIGPENDING is set, call do_signal
342# 326#
343sysc_sigpending: 327sysc_sigpending:
344 ni __TI_flags+7(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP 328 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
345 la %r2,SP_PTREGS(%r15) # load pt_regs 329 la %r2,SP_PTREGS(%r15) # load pt_regs
346 brasl %r14,do_signal # call do_signal 330 brasl %r14,do_signal # call do_signal
347 tm __TI_flags+7(%r12),_TIF_RESTART_SVC 331 tm __TI_flags+7(%r12),_TIF_RESTART_SVC
348 jo sysc_restart 332 jo sysc_restart
349 tm __TI_flags+7(%r12),_TIF_SINGLE_STEP 333 tm __TI_flags+7(%r12),_TIF_PER_TRAP
350 jo sysc_singlestep 334 jo sysc_singlestep
351 j sysc_return 335 j sysc_return
352 336
@@ -371,14 +355,14 @@ sysc_restart:
371 j sysc_nr_ok # restart svc 355 j sysc_nr_ok # restart svc
372 356
373# 357#
374# _TIF_SINGLE_STEP is set, call do_single_step 358# _TIF_PER_TRAP is set, call do_per_trap
375# 359#
376sysc_singlestep: 360sysc_singlestep:
377 ni __TI_flags+7(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP 361 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
378 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number 362 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
379 la %r2,SP_PTREGS(%r15) # address of register-save area 363 la %r2,SP_PTREGS(%r15) # address of register-save area
380 larl %r14,sysc_return # load adr. of system return 364 larl %r14,sysc_return # load adr. of system return
381 jg do_single_step # branch to do_sigtrap 365 jg do_per_trap
382 366
383# 367#
384# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before 368# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
@@ -397,6 +381,7 @@ sysc_tracesys:
397 lgf %r8,0(%r7,%r10) 381 lgf %r8,0(%r7,%r10)
398sysc_tracego: 382sysc_tracego:
399 lmg %r3,%r6,SP_R3(%r15) 383 lmg %r3,%r6,SP_R3(%r15)
384 mvc SP_ARGS(8,%r15),SP_R7(%r15)
400 lg %r2,SP_ORIG_R2(%r15) 385 lg %r2,SP_ORIG_R2(%r15)
401 basr %r14,%r8 # call sys_xxx 386 basr %r14,%r8 # call sys_xxx
402 stg %r2,SP_R2(%r15) # store return value 387 stg %r2,SP_R2(%r15) # store return value
@@ -443,14 +428,12 @@ kernel_execve:
443 br %r14 428 br %r14
444 # execve succeeded. 429 # execve succeeded.
4450: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 4300: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
446# TRACE_IRQS_OFF
447 lg %r15,__LC_KERNEL_STACK # load ksp 431 lg %r15,__LC_KERNEL_STACK # load ksp
448 aghi %r15,-SP_SIZE # make room for registers & psw 432 aghi %r15,-SP_SIZE # make room for registers & psw
449 lg %r13,__LC_SVC_NEW_PSW+8 433 lg %r13,__LC_SVC_NEW_PSW+8
450 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 434 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
451 lg %r12,__LC_THREAD_INFO 435 lg %r12,__LC_THREAD_INFO
452 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 436 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
453# TRACE_IRQS_ON
454 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 437 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
455 brasl %r14,execve_tail 438 brasl %r14,execve_tail
456 j sysc_return 439 j sysc_return
@@ -490,19 +473,18 @@ pgm_check_handler:
490 LAST_BREAK 473 LAST_BREAK
491pgm_no_vtime: 474pgm_no_vtime:
492 HANDLE_SIE_INTERCEPT 475 HANDLE_SIE_INTERCEPT
493 TRACE_IRQS_CHECK_OFF
494 stg %r11,SP_ARGS(%r15) 476 stg %r11,SP_ARGS(%r15)
495 lgf %r3,__LC_PGM_ILC # load program interruption code 477 lgf %r3,__LC_PGM_ILC # load program interruption code
478 lg %r4,__LC_TRANS_EXC_CODE
479 REENABLE_IRQS
496 lghi %r8,0x7f 480 lghi %r8,0x7f
497 ngr %r8,%r3 481 ngr %r8,%r3
498pgm_do_call:
499 sll %r8,3 482 sll %r8,3
500 larl %r1,pgm_check_table 483 larl %r1,pgm_check_table
501 lg %r1,0(%r8,%r1) # load address of handler routine 484 lg %r1,0(%r8,%r1) # load address of handler routine
502 la %r2,SP_PTREGS(%r15) # address of register-save area 485 la %r2,SP_PTREGS(%r15) # address of register-save area
503 basr %r14,%r1 # branch to interrupt-handler 486 basr %r14,%r1 # branch to interrupt-handler
504pgm_exit: 487pgm_exit:
505 TRACE_IRQS_CHECK_ON
506 j sysc_return 488 j sysc_return
507 489
508# 490#
@@ -533,15 +515,16 @@ pgm_per_std:
533 LAST_BREAK 515 LAST_BREAK
534pgm_no_vtime2: 516pgm_no_vtime2:
535 HANDLE_SIE_INTERCEPT 517 HANDLE_SIE_INTERCEPT
536 TRACE_IRQS_CHECK_OFF
537 lg %r1,__TI_task(%r12) 518 lg %r1,__TI_task(%r12)
538 tm SP_PSW+1(%r15),0x01 # kernel per event ? 519 tm SP_PSW+1(%r15),0x01 # kernel per event ?
539 jz kernel_per 520 jz kernel_per
540 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 521 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
541 mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS 522 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
542 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 523 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
543 oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 524 oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP
544 lgf %r3,__LC_PGM_ILC # load program interruption code 525 lgf %r3,__LC_PGM_ILC # load program interruption code
526 lg %r4,__LC_TRANS_EXC_CODE
527 REENABLE_IRQS
545 lghi %r8,0x7f 528 lghi %r8,0x7f
546 ngr %r8,%r3 # clear per-event-bit and ilc 529 ngr %r8,%r3 # clear per-event-bit and ilc
547 je pgm_exit2 530 je pgm_exit2
@@ -551,8 +534,6 @@ pgm_no_vtime2:
551 la %r2,SP_PTREGS(%r15) # address of register-save area 534 la %r2,SP_PTREGS(%r15) # address of register-save area
552 basr %r14,%r1 # branch to interrupt-handler 535 basr %r14,%r1 # branch to interrupt-handler
553pgm_exit2: 536pgm_exit2:
554 TRACE_IRQS_ON
555 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
556 j sysc_return 537 j sysc_return
557 538
558# 539#
@@ -568,13 +549,11 @@ pgm_svcper:
568 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 549 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
569 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 550 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
570 LAST_BREAK 551 LAST_BREAK
571 TRACE_IRQS_OFF
572 lg %r8,__TI_task(%r12) 552 lg %r8,__TI_task(%r12)
573 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID 553 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
574 mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS 554 mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS
575 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID 555 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
576 oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 556 oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP
577 TRACE_IRQS_ON
578 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 557 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
579 lmg %r2,%r6,SP_R2(%r15) # load svc arguments 558 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
580 j sysc_do_svc 559 j sysc_do_svc
@@ -583,9 +562,10 @@ pgm_svcper:
583# per was called from kernel, must be kprobes 562# per was called from kernel, must be kprobes
584# 563#
585kernel_per: 564kernel_per:
565 REENABLE_IRQS
586 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number 566 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
587 la %r2,SP_PTREGS(%r15) # address of register-save area 567 la %r2,SP_PTREGS(%r15) # address of register-save area
588 brasl %r14,do_single_step 568 brasl %r14,do_per_trap
589 j pgm_exit 569 j pgm_exit
590 570
591/* 571/*
@@ -743,8 +723,11 @@ ext_int_handler:
743ext_no_vtime: 723ext_no_vtime:
744 HANDLE_SIE_INTERCEPT 724 HANDLE_SIE_INTERCEPT
745 TRACE_IRQS_OFF 725 TRACE_IRQS_OFF
726 lghi %r1,4096
746 la %r2,SP_PTREGS(%r15) # address of register-save area 727 la %r2,SP_PTREGS(%r15) # address of register-save area
747 llgh %r3,__LC_EXT_INT_CODE # get interruption code 728 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
729 llgf %r4,__LC_EXT_PARAMS # get external parameter
730 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
748 brasl %r14,do_extint 731 brasl %r14,do_extint
749 j io_return 732 j io_return
750 733
@@ -859,7 +842,7 @@ restart_base:
859 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 842 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
860 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 843 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
861 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 844 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on
862 jg start_secondary 845 brasl %r14,start_secondary
863 .align 8 846 .align 8
864restart_vtime: 847restart_vtime:
865 .long 0x7fffffff,0xffffffff 848 .long 0x7fffffff,0xffffffff
@@ -879,6 +862,8 @@ restart_crash:
879restart_go: 862restart_go:
880#endif 863#endif
881 864
865 .section .kprobes.text, "ax"
866
882#ifdef CONFIG_CHECK_STACK 867#ifdef CONFIG_CHECK_STACK
883/* 868/*
884 * The synchronous or the asynchronous stack overflowed. We are dead. 869 * The synchronous or the asynchronous stack overflowed. We are dead.
@@ -966,7 +951,6 @@ cleanup_system_call:
966 CREATE_STACK_FRAME __LC_SAVE_AREA 951 CREATE_STACK_FRAME __LC_SAVE_AREA
967 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 952 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
968 mvc SP_ILC(4,%r15),__LC_SVC_ILC 953 mvc SP_ILC(4,%r15),__LC_SVC_ILC
969 stg %r7,SP_ARGS(%r15)
970 mvc 8(8,%r12),__LC_THREAD_INFO 954 mvc 8(8,%r12),__LC_THREAD_INFO
971cleanup_vtime: 955cleanup_vtime:
972 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 956 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)