aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2010-05-17 04:00:02 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-05-17 04:00:15 -0400
commit6a2df3a87276cdc08fd87070d09ea18d1fb9d622 (patch)
tree384b646d0a826ab5c2bafa63e9bea4a057815fe2 /arch/s390
parent43d399d2ab7e96cb8d952d0ba4e9131587b7c8b9 (diff)
[S390] improve irq tracing code in entry[64].S
The system call path in entry[64].S is run with interrupts enabled. Remove the irq tracing check from the system call exit code. If a program check interrupted a context enabled for interrupts do a call to trace_irq_off_caller in the program check handler before branching to the system call exit code. Restructure the system call and io interrupt return code to avoid avoid the lpsw[e] to disable machine checks. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/system.h5
-rw-r--r--arch/s390/kernel/entry.S205
-rw-r--r--arch/s390/kernel/entry64.S197
-rw-r--r--arch/s390/kernel/setup.c4
4 files changed, 183 insertions, 228 deletions
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index 1741c1556a4e..cef66210c846 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -459,11 +459,6 @@ extern void (*_machine_power_off)(void);
459 459
460#define arch_align_stack(x) (x) 460#define arch_align_stack(x) (x)
461 461
462#ifdef CONFIG_TRACE_IRQFLAGS
463extern psw_t sysc_restore_trace_psw;
464extern psw_t io_restore_trace_psw;
465#endif
466
467static inline int tprot(unsigned long addr) 462static inline int tprot(unsigned long addr)
468{ 463{
469 int rc = -EFAULT; 464 int rc = -EFAULT;
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index ffebfb64b913..07d849995dac 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -73,21 +73,24 @@ STACK_SIZE = 1 << STACK_SHIFT
73 basr %r14,%r1 73 basr %r14,%r1
74 .endm 74 .endm
75 75
76 .macro TRACE_IRQS_CHECK 76 .macro TRACE_IRQS_CHECK_ON
77 basr %r2,%r0
78 tm SP_PSW(%r15),0x03 # irqs enabled? 77 tm SP_PSW(%r15),0x03 # irqs enabled?
79 jz 0f 78 bz BASED(0f)
80 l %r1,BASED(.Ltrace_irq_on_caller) 79 TRACE_IRQS_ON
81 basr %r14,%r1 800:
82 j 1f 81 .endm
830: l %r1,BASED(.Ltrace_irq_off_caller) 82
84 basr %r14,%r1 83 .macro TRACE_IRQS_CHECK_OFF
851: 84 tm SP_PSW(%r15),0x03 # irqs enabled?
85 bz BASED(0f)
86 TRACE_IRQS_OFF
870:
86 .endm 88 .endm
87#else 89#else
88#define TRACE_IRQS_ON 90#define TRACE_IRQS_ON
89#define TRACE_IRQS_OFF 91#define TRACE_IRQS_OFF
90#define TRACE_IRQS_CHECK 92#define TRACE_IRQS_CHECK_ON
93#define TRACE_IRQS_CHECK_OFF
91#endif 94#endif
92 95
93#ifdef CONFIG_LOCKDEP 96#ifdef CONFIG_LOCKDEP
@@ -273,33 +276,14 @@ sysc_do_restart:
273 st %r2,SP_R2(%r15) # store return value (change R2 on stack) 276 st %r2,SP_R2(%r15) # store return value (change R2 on stack)
274 277
275sysc_return: 278sysc_return:
279 LOCKDEP_SYS_EXIT
280sysc_tif:
276 tm __TI_flags+3(%r9),_TIF_WORK_SVC 281 tm __TI_flags+3(%r9),_TIF_WORK_SVC
277 bnz BASED(sysc_work) # there is work to do (signals etc.) 282 bnz BASED(sysc_work) # there is work to do (signals etc.)
278sysc_restore: 283sysc_restore:
279#ifdef CONFIG_TRACE_IRQFLAGS
280 la %r1,BASED(sysc_restore_trace_psw_addr)
281 l %r1,0(%r1)
282 lpsw 0(%r1)
283sysc_restore_trace:
284 TRACE_IRQS_CHECK
285 LOCKDEP_SYS_EXIT
286#endif
287sysc_leave:
288 RESTORE_ALL __LC_RETURN_PSW,1 284 RESTORE_ALL __LC_RETURN_PSW,1
289sysc_done: 285sysc_done:
290 286
291#ifdef CONFIG_TRACE_IRQFLAGS
292sysc_restore_trace_psw_addr:
293 .long sysc_restore_trace_psw
294
295 .section .data,"aw",@progbits
296 .align 8
297 .globl sysc_restore_trace_psw
298sysc_restore_trace_psw:
299 .long 0, sysc_restore_trace + 0x80000000
300 .previous
301#endif
302
303# 287#
304# There is work to do, but first we need to check if we return to userspace. 288# There is work to do, but first we need to check if we return to userspace.
305# 289#
@@ -310,7 +294,7 @@ sysc_work:
310# 294#
311# One of the work bits is on. Find out which one. 295# One of the work bits is on. Find out which one.
312# 296#
313sysc_work_loop: 297sysc_work_tif:
314 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING 298 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
315 bo BASED(sysc_mcck_pending) 299 bo BASED(sysc_mcck_pending)
316 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 300 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
@@ -330,7 +314,7 @@ sysc_work_loop:
330# 314#
331sysc_reschedule: 315sysc_reschedule:
332 l %r1,BASED(.Lschedule) 316 l %r1,BASED(.Lschedule)
333 la %r14,BASED(sysc_work_loop) 317 la %r14,BASED(sysc_return)
334 br %r1 # call scheduler 318 br %r1 # call scheduler
335 319
336# 320#
@@ -338,7 +322,7 @@ sysc_reschedule:
338# 322#
339sysc_mcck_pending: 323sysc_mcck_pending:
340 l %r1,BASED(.Ls390_handle_mcck) 324 l %r1,BASED(.Ls390_handle_mcck)
341 la %r14,BASED(sysc_work_loop) 325 la %r14,BASED(sysc_return)
342 br %r1 # TIF bit will be cleared by handler 326 br %r1 # TIF bit will be cleared by handler
343 327
344# 328#
@@ -353,7 +337,7 @@ sysc_sigpending:
353 bo BASED(sysc_restart) 337 bo BASED(sysc_restart)
354 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP 338 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
355 bo BASED(sysc_singlestep) 339 bo BASED(sysc_singlestep)
356 b BASED(sysc_work_loop) 340 b BASED(sysc_return)
357 341
358# 342#
359# _TIF_NOTIFY_RESUME is set, call do_notify_resume 343# _TIF_NOTIFY_RESUME is set, call do_notify_resume
@@ -361,7 +345,7 @@ sysc_sigpending:
361sysc_notify_resume: 345sysc_notify_resume:
362 la %r2,SP_PTREGS(%r15) # load pt_regs 346 la %r2,SP_PTREGS(%r15) # load pt_regs
363 l %r1,BASED(.Ldo_notify_resume) 347 l %r1,BASED(.Ldo_notify_resume)
364 la %r14,BASED(sysc_work_loop) 348 la %r14,BASED(sysc_return)
365 br %r1 # call do_notify_resume 349 br %r1 # call do_notify_resume
366 350
367 351
@@ -384,7 +368,7 @@ sysc_singlestep:
384 mvi SP_SVCNR+1(%r15),0xff 368 mvi SP_SVCNR+1(%r15),0xff
385 la %r2,SP_PTREGS(%r15) # address of register-save area 369 la %r2,SP_PTREGS(%r15) # address of register-save area
386 l %r1,BASED(.Lhandle_per) # load adr. of per handler 370 l %r1,BASED(.Lhandle_per) # load adr. of per handler
387 la %r14,BASED(sysc_work_loop) # load adr. of system return 371 la %r14,BASED(sysc_return) # load adr. of system return
388 br %r1 # branch to do_single_step 372 br %r1 # branch to do_single_step
389 373
390# 374#
@@ -456,11 +440,13 @@ kernel_execve:
456 br %r14 440 br %r14
457 # execve succeeded. 441 # execve succeeded.
4580: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 4420: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
443 TRACE_IRQS_OFF
459 l %r15,__LC_KERNEL_STACK # load ksp 444 l %r15,__LC_KERNEL_STACK # load ksp
460 s %r15,BASED(.Lc_spsize) # make room for registers & psw 445 s %r15,BASED(.Lc_spsize) # make room for registers & psw
461 l %r9,__LC_THREAD_INFO 446 l %r9,__LC_THREAD_INFO
462 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 447 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
463 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 448 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
449 TRACE_IRQS_ON
464 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 450 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
465 l %r1,BASED(.Lexecve_tail) 451 l %r1,BASED(.Lexecve_tail)
466 basr %r14,%r1 452 basr %r14,%r1
@@ -497,8 +483,8 @@ pgm_check_handler:
497 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 483 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
498 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 484 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
499pgm_no_vtime: 485pgm_no_vtime:
486 TRACE_IRQS_CHECK_OFF
500 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 487 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
501 TRACE_IRQS_OFF
502 l %r3,__LC_PGM_ILC # load program interruption code 488 l %r3,__LC_PGM_ILC # load program interruption code
503 la %r8,0x7f 489 la %r8,0x7f
504 nr %r8,%r3 490 nr %r8,%r3
@@ -507,8 +493,10 @@ pgm_do_call:
507 sll %r8,2 493 sll %r8,2
508 l %r7,0(%r8,%r7) # load address of handler routine 494 l %r7,0(%r8,%r7) # load address of handler routine
509 la %r2,SP_PTREGS(%r15) # address of register-save area 495 la %r2,SP_PTREGS(%r15) # address of register-save area
510 la %r14,BASED(sysc_return) 496 basr %r14,%r7 # branch to interrupt-handler
511 br %r7 # branch to interrupt-handler 497pgm_exit:
498 TRACE_IRQS_CHECK_ON
499 b BASED(sysc_return)
512 500
513# 501#
514# handle per exception 502# handle per exception
@@ -535,19 +523,19 @@ pgm_per_std:
535 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 523 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
536 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 524 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
537pgm_no_vtime2: 525pgm_no_vtime2:
526 TRACE_IRQS_CHECK_OFF
538 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 527 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
539 TRACE_IRQS_OFF
540 l %r1,__TI_task(%r9) 528 l %r1,__TI_task(%r9)
529 tm SP_PSW+1(%r15),0x01 # kernel per event ?
530 bz BASED(kernel_per)
541 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 531 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
542 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 532 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
543 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 533 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
544 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 534 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
545 tm SP_PSW+1(%r15),0x01 # kernel per event ?
546 bz BASED(kernel_per)
547 l %r3,__LC_PGM_ILC # load program interruption code 535 l %r3,__LC_PGM_ILC # load program interruption code
548 la %r8,0x7f 536 la %r8,0x7f
549 nr %r8,%r3 # clear per-event-bit and ilc 537 nr %r8,%r3 # clear per-event-bit and ilc
550 be BASED(sysc_return) # only per or per+check ? 538 be BASED(pgm_exit) # only per or per+check ?
551 b BASED(pgm_do_call) 539 b BASED(pgm_do_call)
552 540
553# 541#
@@ -568,8 +556,8 @@ pgm_svcper:
568 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID 556 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
569 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 557 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
570 TRACE_IRQS_ON 558 TRACE_IRQS_ON
571 lm %r2,%r6,SP_R2(%r15) # load svc arguments
572 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 559 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
560 lm %r2,%r6,SP_R2(%r15) # load svc arguments
573 b BASED(sysc_do_svc) 561 b BASED(sysc_do_svc)
574 562
575# 563#
@@ -580,8 +568,8 @@ kernel_per:
580 mvi SP_SVCNR+1(%r15),0xff 568 mvi SP_SVCNR+1(%r15),0xff
581 la %r2,SP_PTREGS(%r15) # address of register-save area 569 la %r2,SP_PTREGS(%r15) # address of register-save area
582 l %r1,BASED(.Lhandle_per) # load adr. of per handler 570 l %r1,BASED(.Lhandle_per) # load adr. of per handler
583 la %r14,BASED(sysc_restore)# load adr. of system return 571 basr %r14,%r1 # branch to do_single_step
584 br %r1 # branch to do_single_step 572 b BASED(pgm_exit)
585 573
586/* 574/*
587 * IO interrupt handler routine 575 * IO interrupt handler routine
@@ -600,39 +588,21 @@ io_int_handler:
600 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 588 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
601 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 589 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
602io_no_vtime: 590io_no_vtime:
603 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
604 TRACE_IRQS_OFF 591 TRACE_IRQS_OFF
592 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
605 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 593 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
606 la %r2,SP_PTREGS(%r15) # address of register-save area 594 la %r2,SP_PTREGS(%r15) # address of register-save area
607 basr %r14,%r1 # branch to standard irq handler 595 basr %r14,%r1 # branch to standard irq handler
608io_return: 596io_return:
597 LOCKDEP_SYS_EXIT
598 TRACE_IRQS_ON
599io_tif:
609 tm __TI_flags+3(%r9),_TIF_WORK_INT 600 tm __TI_flags+3(%r9),_TIF_WORK_INT
610 bnz BASED(io_work) # there is work to do (signals etc.) 601 bnz BASED(io_work) # there is work to do (signals etc.)
611io_restore: 602io_restore:
612#ifdef CONFIG_TRACE_IRQFLAGS
613 la %r1,BASED(io_restore_trace_psw_addr)
614 l %r1,0(%r1)
615 lpsw 0(%r1)
616io_restore_trace:
617 TRACE_IRQS_CHECK
618 LOCKDEP_SYS_EXIT
619#endif
620io_leave:
621 RESTORE_ALL __LC_RETURN_PSW,0 603 RESTORE_ALL __LC_RETURN_PSW,0
622io_done: 604io_done:
623 605
624#ifdef CONFIG_TRACE_IRQFLAGS
625io_restore_trace_psw_addr:
626 .long io_restore_trace_psw
627
628 .section .data,"aw",@progbits
629 .align 8
630 .globl io_restore_trace_psw
631io_restore_trace_psw:
632 .long 0, io_restore_trace + 0x80000000
633 .previous
634#endif
635
636# 606#
637# There is work todo, find out in which context we have been interrupted: 607# There is work todo, find out in which context we have been interrupted:
638# 1) if we return to user space we can do all _TIF_WORK_INT work 608# 1) if we return to user space we can do all _TIF_WORK_INT work
@@ -647,19 +617,23 @@ io_work:
647 # check for preemptive scheduling 617 # check for preemptive scheduling
648 icm %r0,15,__TI_precount(%r9) 618 icm %r0,15,__TI_precount(%r9)
649 bnz BASED(io_restore) # preemption disabled 619 bnz BASED(io_restore) # preemption disabled
620 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
621 bno BASED(io_restore)
650 # switch to kernel stack 622 # switch to kernel stack
651 l %r1,SP_R15(%r15) 623 l %r1,SP_R15(%r15)
652 s %r1,BASED(.Lc_spsize) 624 s %r1,BASED(.Lc_spsize)
653 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 625 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
654 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 626 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
655 lr %r15,%r1 627 lr %r15,%r1
656io_resume_loop: 628 # TRACE_IRQS_ON already done at io_return, call
629 # TRACE_IRQS_OFF to keep things symmetrical
630 TRACE_IRQS_OFF
657 l %r1,BASED(.Lpreempt_schedule_irq) 631 l %r1,BASED(.Lpreempt_schedule_irq)
658 la %r14,BASED(io_resume_loop) 632 basr %r14,%r1 # call preempt_schedule_irq
659 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 633 b BASED(io_return)
660 bor %r1 # call preempt_schedule_irq 634#else
661#endif
662 b BASED(io_restore) 635 b BASED(io_restore)
636#endif
663 637
664# 638#
665# Need to do work before returning to userspace, switch to kernel stack 639# Need to do work before returning to userspace, switch to kernel stack
@@ -670,12 +644,13 @@ io_work_user:
670 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 644 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
671 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 645 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
672 lr %r15,%r1 646 lr %r15,%r1
647
673# 648#
674# One of the work bits is on. Find out which one. 649# One of the work bits is on. Find out which one.
675# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED 650# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED
676# and _TIF_MCCK_PENDING 651# and _TIF_MCCK_PENDING
677# 652#
678io_work_loop: 653io_work_tif:
679 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING 654 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
680 bo BASED(io_mcck_pending) 655 bo BASED(io_mcck_pending)
681 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 656 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
@@ -690,47 +665,49 @@ io_work_loop:
690# _TIF_MCCK_PENDING is set, call handler 665# _TIF_MCCK_PENDING is set, call handler
691# 666#
692io_mcck_pending: 667io_mcck_pending:
668 # TRACE_IRQS_ON already done at io_return
693 l %r1,BASED(.Ls390_handle_mcck) 669 l %r1,BASED(.Ls390_handle_mcck)
694 basr %r14,%r1 # TIF bit will be cleared by handler 670 basr %r14,%r1 # TIF bit will be cleared by handler
695 b BASED(io_work_loop) 671 TRACE_IRQS_OFF
672 b BASED(io_return)
696 673
697# 674#
698# _TIF_NEED_RESCHED is set, call schedule 675# _TIF_NEED_RESCHED is set, call schedule
699# 676#
700io_reschedule: 677io_reschedule:
701 TRACE_IRQS_ON 678 # TRACE_IRQS_ON already done at io_return
702 l %r1,BASED(.Lschedule) 679 l %r1,BASED(.Lschedule)
703 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 680 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
704 basr %r14,%r1 # call scheduler 681 basr %r14,%r1 # call scheduler
705 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 682 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
706 TRACE_IRQS_OFF 683 TRACE_IRQS_OFF
707 b BASED(io_work_loop) 684 b BASED(io_return)
708 685
709# 686#
710# _TIF_SIGPENDING is set, call do_signal 687# _TIF_SIGPENDING is set, call do_signal
711# 688#
712io_sigpending: 689io_sigpending:
713 TRACE_IRQS_ON 690 # TRACE_IRQS_ON already done at io_return
714 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 691 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
715 la %r2,SP_PTREGS(%r15) # load pt_regs 692 la %r2,SP_PTREGS(%r15) # load pt_regs
716 l %r1,BASED(.Ldo_signal) 693 l %r1,BASED(.Ldo_signal)
717 basr %r14,%r1 # call do_signal 694 basr %r14,%r1 # call do_signal
718 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 695 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
719 TRACE_IRQS_OFF 696 TRACE_IRQS_OFF
720 b BASED(io_work_loop) 697 b BASED(io_return)
721 698
722# 699#
723# _TIF_SIGPENDING is set, call do_signal 700# _TIF_SIGPENDING is set, call do_signal
724# 701#
725io_notify_resume: 702io_notify_resume:
726 TRACE_IRQS_ON 703 # TRACE_IRQS_ON already done at io_return
727 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 704 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
728 la %r2,SP_PTREGS(%r15) # load pt_regs 705 la %r2,SP_PTREGS(%r15) # load pt_regs
729 l %r1,BASED(.Ldo_notify_resume) 706 l %r1,BASED(.Ldo_notify_resume)
730 basr %r14,%r1 # call do_signal 707 basr %r14,%r1 # call do_signal
731 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 708 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
732 TRACE_IRQS_OFF 709 TRACE_IRQS_OFF
733 b BASED(io_work_loop) 710 b BASED(io_return)
734 711
735/* 712/*
736 * External interrupt handler routine 713 * External interrupt handler routine
@@ -918,14 +895,14 @@ stack_overflow:
918 895
919cleanup_table_system_call: 896cleanup_table_system_call:
920 .long system_call + 0x80000000, sysc_do_svc + 0x80000000 897 .long system_call + 0x80000000, sysc_do_svc + 0x80000000
921cleanup_table_sysc_return: 898cleanup_table_sysc_tif:
922 .long sysc_return + 0x80000000, sysc_leave + 0x80000000 899 .long sysc_tif + 0x80000000, sysc_restore + 0x80000000
923cleanup_table_sysc_leave: 900cleanup_table_sysc_restore:
924 .long sysc_leave + 0x80000000, sysc_done + 0x80000000 901 .long sysc_restore + 0x80000000, sysc_done + 0x80000000
925cleanup_table_io_return: 902cleanup_table_io_tif:
926 .long io_return + 0x80000000, io_leave + 0x80000000 903 .long io_tif + 0x80000000, io_restore + 0x80000000
927cleanup_table_io_leave: 904cleanup_table_io_restore:
928 .long io_leave + 0x80000000, io_done + 0x80000000 905 .long io_restore + 0x80000000, io_done + 0x80000000
929 906
930cleanup_critical: 907cleanup_critical:
931 clc 4(4,%r12),BASED(cleanup_table_system_call) 908 clc 4(4,%r12),BASED(cleanup_table_system_call)
@@ -933,25 +910,25 @@ cleanup_critical:
933 clc 4(4,%r12),BASED(cleanup_table_system_call+4) 910 clc 4(4,%r12),BASED(cleanup_table_system_call+4)
934 bl BASED(cleanup_system_call) 911 bl BASED(cleanup_system_call)
9350: 9120:
936 clc 4(4,%r12),BASED(cleanup_table_sysc_return) 913 clc 4(4,%r12),BASED(cleanup_table_sysc_tif)
937 bl BASED(0f) 914 bl BASED(0f)
938 clc 4(4,%r12),BASED(cleanup_table_sysc_return+4) 915 clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4)
939 bl BASED(cleanup_sysc_return) 916 bl BASED(cleanup_sysc_tif)
9400: 9170:
941 clc 4(4,%r12),BASED(cleanup_table_sysc_leave) 918 clc 4(4,%r12),BASED(cleanup_table_sysc_restore)
942 bl BASED(0f) 919 bl BASED(0f)
943 clc 4(4,%r12),BASED(cleanup_table_sysc_leave+4) 920 clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4)
944 bl BASED(cleanup_sysc_leave) 921 bl BASED(cleanup_sysc_restore)
9450: 9220:
946 clc 4(4,%r12),BASED(cleanup_table_io_return) 923 clc 4(4,%r12),BASED(cleanup_table_io_tif)
947 bl BASED(0f) 924 bl BASED(0f)
948 clc 4(4,%r12),BASED(cleanup_table_io_return+4) 925 clc 4(4,%r12),BASED(cleanup_table_io_tif+4)
949 bl BASED(cleanup_io_return) 926 bl BASED(cleanup_io_tif)
9500: 9270:
951 clc 4(4,%r12),BASED(cleanup_table_io_leave) 928 clc 4(4,%r12),BASED(cleanup_table_io_restore)
952 bl BASED(0f) 929 bl BASED(0f)
953 clc 4(4,%r12),BASED(cleanup_table_io_leave+4) 930 clc 4(4,%r12),BASED(cleanup_table_io_restore+4)
954 bl BASED(cleanup_io_leave) 931 bl BASED(cleanup_io_restore)
9550: 9320:
956 br %r14 933 br %r14
957 934
@@ -998,17 +975,17 @@ cleanup_system_call_insn:
998 .long sysc_stime + 0x80000000 975 .long sysc_stime + 0x80000000
999 .long sysc_update + 0x80000000 976 .long sysc_update + 0x80000000
1000 977
1001cleanup_sysc_return: 978cleanup_sysc_tif:
1002 mvc __LC_RETURN_PSW(4),0(%r12) 979 mvc __LC_RETURN_PSW(4),0(%r12)
1003 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_return) 980 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif)
1004 la %r12,__LC_RETURN_PSW 981 la %r12,__LC_RETURN_PSW
1005 br %r14 982 br %r14
1006 983
1007cleanup_sysc_leave: 984cleanup_sysc_restore:
1008 clc 4(4,%r12),BASED(cleanup_sysc_leave_insn) 985 clc 4(4,%r12),BASED(cleanup_sysc_restore_insn)
1009 be BASED(2f) 986 be BASED(2f)
1010 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 987 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
1011 clc 4(4,%r12),BASED(cleanup_sysc_leave_insn+4) 988 clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4)
1012 be BASED(2f) 989 be BASED(2f)
1013 mvc __LC_RETURN_PSW(8),SP_PSW(%r15) 990 mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
1014 c %r12,BASED(.Lmck_old_psw) 991 c %r12,BASED(.Lmck_old_psw)
@@ -1020,21 +997,21 @@ cleanup_sysc_leave:
1020 l %r15,SP_R15(%r15) 997 l %r15,SP_R15(%r15)
10212: la %r12,__LC_RETURN_PSW 9982: la %r12,__LC_RETURN_PSW
1022 br %r14 999 br %r14
1023cleanup_sysc_leave_insn: 1000cleanup_sysc_restore_insn:
1024 .long sysc_done - 4 + 0x80000000 1001 .long sysc_done - 4 + 0x80000000
1025 .long sysc_done - 8 + 0x80000000 1002 .long sysc_done - 8 + 0x80000000
1026 1003
1027cleanup_io_return: 1004cleanup_io_tif:
1028 mvc __LC_RETURN_PSW(4),0(%r12) 1005 mvc __LC_RETURN_PSW(4),0(%r12)
1029 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return) 1006 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif)
1030 la %r12,__LC_RETURN_PSW 1007 la %r12,__LC_RETURN_PSW
1031 br %r14 1008 br %r14
1032 1009
1033cleanup_io_leave: 1010cleanup_io_restore:
1034 clc 4(4,%r12),BASED(cleanup_io_leave_insn) 1011 clc 4(4,%r12),BASED(cleanup_io_restore_insn)
1035 be BASED(2f) 1012 be BASED(2f)
1036 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 1013 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
1037 clc 4(4,%r12),BASED(cleanup_io_leave_insn+4) 1014 clc 4(4,%r12),BASED(cleanup_io_restore_insn+4)
1038 be BASED(2f) 1015 be BASED(2f)
1039 mvc __LC_RETURN_PSW(8),SP_PSW(%r15) 1016 mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
1040 c %r12,BASED(.Lmck_old_psw) 1017 c %r12,BASED(.Lmck_old_psw)
@@ -1046,7 +1023,7 @@ cleanup_io_leave:
1046 l %r15,SP_R15(%r15) 1023 l %r15,SP_R15(%r15)
10472: la %r12,__LC_RETURN_PSW 10242: la %r12,__LC_RETURN_PSW
1048 br %r14 1025 br %r14
1049cleanup_io_leave_insn: 1026cleanup_io_restore_insn:
1050 .long io_done - 4 + 0x80000000 1027 .long io_done - 4 + 0x80000000
1051 .long io_done - 8 + 0x80000000 1028 .long io_done - 8 + 0x80000000
1052 1029
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index ca02b10a2c32..860cea1d1c8a 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -61,28 +61,33 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
61 61
62#ifdef CONFIG_TRACE_IRQFLAGS 62#ifdef CONFIG_TRACE_IRQFLAGS
63 .macro TRACE_IRQS_ON 63 .macro TRACE_IRQS_ON
64 basr %r2,%r0 64 basr %r2,%r0
65 brasl %r14,trace_hardirqs_on_caller 65 brasl %r14,trace_hardirqs_on_caller
66 .endm 66 .endm
67 67
68 .macro TRACE_IRQS_OFF 68 .macro TRACE_IRQS_OFF
69 basr %r2,%r0 69 basr %r2,%r0
70 brasl %r14,trace_hardirqs_off_caller 70 brasl %r14,trace_hardirqs_off_caller
71 .endm 71 .endm
72 72
73 .macro TRACE_IRQS_CHECK 73 .macro TRACE_IRQS_CHECK_ON
74 basr %r2,%r0
75 tm SP_PSW(%r15),0x03 # irqs enabled? 74 tm SP_PSW(%r15),0x03 # irqs enabled?
76 jz 0f 75 jz 0f
77 brasl %r14,trace_hardirqs_on_caller 76 TRACE_IRQS_ON
78 j 1f 770:
790: brasl %r14,trace_hardirqs_off_caller 78 .endm
801: 79
80 .macro TRACE_IRQS_CHECK_OFF
81 tm SP_PSW(%r15),0x03 # irqs enabled?
82 jz 0f
83 TRACE_IRQS_OFF
840:
81 .endm 85 .endm
82#else 86#else
83#define TRACE_IRQS_ON 87#define TRACE_IRQS_ON
84#define TRACE_IRQS_OFF 88#define TRACE_IRQS_OFF
85#define TRACE_IRQS_CHECK 89#define TRACE_IRQS_CHECK_ON
90#define TRACE_IRQS_CHECK_OFF
86#endif 91#endif
87 92
88#ifdef CONFIG_LOCKDEP 93#ifdef CONFIG_LOCKDEP
@@ -267,29 +272,14 @@ sysc_noemu:
267 stg %r2,SP_R2(%r15) # store return value (change R2 on stack) 272 stg %r2,SP_R2(%r15) # store return value (change R2 on stack)
268 273
269sysc_return: 274sysc_return:
275 LOCKDEP_SYS_EXIT
276sysc_tif:
270 tm __TI_flags+7(%r9),_TIF_WORK_SVC 277 tm __TI_flags+7(%r9),_TIF_WORK_SVC
271 jnz sysc_work # there is work to do (signals etc.) 278 jnz sysc_work # there is work to do (signals etc.)
272sysc_restore: 279sysc_restore:
273#ifdef CONFIG_TRACE_IRQFLAGS
274 larl %r1,sysc_restore_trace_psw
275 lpswe 0(%r1)
276sysc_restore_trace:
277 TRACE_IRQS_CHECK
278 LOCKDEP_SYS_EXIT
279#endif
280sysc_leave:
281 RESTORE_ALL __LC_RETURN_PSW,1 280 RESTORE_ALL __LC_RETURN_PSW,1
282sysc_done: 281sysc_done:
283 282
284#ifdef CONFIG_TRACE_IRQFLAGS
285 .section .data,"aw",@progbits
286 .align 8
287 .globl sysc_restore_trace_psw
288sysc_restore_trace_psw:
289 .quad 0, sysc_restore_trace
290 .previous
291#endif
292
293# 283#
294# There is work to do, but first we need to check if we return to userspace. 284# There is work to do, but first we need to check if we return to userspace.
295# 285#
@@ -300,7 +290,7 @@ sysc_work:
300# 290#
301# One of the work bits is on. Find out which one. 291# One of the work bits is on. Find out which one.
302# 292#
303sysc_work_loop: 293sysc_work_tif:
304 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING 294 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
305 jo sysc_mcck_pending 295 jo sysc_mcck_pending
306 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED 296 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
@@ -319,14 +309,14 @@ sysc_work_loop:
319# _TIF_NEED_RESCHED is set, call schedule 309# _TIF_NEED_RESCHED is set, call schedule
320# 310#
321sysc_reschedule: 311sysc_reschedule:
322 larl %r14,sysc_work_loop 312 larl %r14,sysc_return
323 jg schedule # return point is sysc_work_loop 313 jg schedule # return point is sysc_return
324 314
325# 315#
326# _TIF_MCCK_PENDING is set, call handler 316# _TIF_MCCK_PENDING is set, call handler
327# 317#
328sysc_mcck_pending: 318sysc_mcck_pending:
329 larl %r14,sysc_work_loop 319 larl %r14,sysc_return
330 jg s390_handle_mcck # TIF bit will be cleared by handler 320 jg s390_handle_mcck # TIF bit will be cleared by handler
331 321
332# 322#
@@ -340,14 +330,14 @@ sysc_sigpending:
340 jo sysc_restart 330 jo sysc_restart
341 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP 331 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
342 jo sysc_singlestep 332 jo sysc_singlestep
343 j sysc_work_loop 333 j sysc_return
344 334
345# 335#
346# _TIF_NOTIFY_RESUME is set, call do_notify_resume 336# _TIF_NOTIFY_RESUME is set, call do_notify_resume
347# 337#
348sysc_notify_resume: 338sysc_notify_resume:
349 la %r2,SP_PTREGS(%r15) # load pt_regs 339 la %r2,SP_PTREGS(%r15) # load pt_regs
350 larl %r14,sysc_work_loop 340 larl %r14,sysc_return
351 jg do_notify_resume # call do_notify_resume 341 jg do_notify_resume # call do_notify_resume
352 342
353# 343#
@@ -367,7 +357,7 @@ sysc_singlestep:
367 ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP 357 ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
368 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number 358 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
369 la %r2,SP_PTREGS(%r15) # address of register-save area 359 la %r2,SP_PTREGS(%r15) # address of register-save area
370 larl %r14,sysc_work_loop # load adr. of system return 360 larl %r14,sysc_return # load adr. of system return
371 jg do_single_step # branch to do_sigtrap 361 jg do_single_step # branch to do_sigtrap
372 362
373# 363#
@@ -433,12 +423,14 @@ kernel_execve:
433 br %r14 423 br %r14
434 # execve succeeded. 424 # execve succeeded.
4350: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 4250: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
426# TRACE_IRQS_OFF
436 lg %r15,__LC_KERNEL_STACK # load ksp 427 lg %r15,__LC_KERNEL_STACK # load ksp
437 aghi %r15,-SP_SIZE # make room for registers & psw 428 aghi %r15,-SP_SIZE # make room for registers & psw
438 lg %r13,__LC_SVC_NEW_PSW+8 429 lg %r13,__LC_SVC_NEW_PSW+8
439 lg %r9,__LC_THREAD_INFO 430 lg %r9,__LC_THREAD_INFO
440 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 431 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
441 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 432 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
433# TRACE_IRQS_ON
442 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 434 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
443 brasl %r14,execve_tail 435 brasl %r14,execve_tail
444 j sysc_return 436 j sysc_return
@@ -474,9 +466,9 @@ pgm_check_handler:
474 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 466 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
475 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 467 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
476pgm_no_vtime: 468pgm_no_vtime:
469 TRACE_IRQS_CHECK_OFF
477 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 470 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
478 mvc SP_ARGS(8,%r15),__LC_LAST_BREAK 471 mvc SP_ARGS(8,%r15),__LC_LAST_BREAK
479 TRACE_IRQS_OFF
480 lgf %r3,__LC_PGM_ILC # load program interruption code 472 lgf %r3,__LC_PGM_ILC # load program interruption code
481 lghi %r8,0x7f 473 lghi %r8,0x7f
482 ngr %r8,%r3 474 ngr %r8,%r3
@@ -485,8 +477,10 @@ pgm_do_call:
485 larl %r1,pgm_check_table 477 larl %r1,pgm_check_table
486 lg %r1,0(%r8,%r1) # load address of handler routine 478 lg %r1,0(%r8,%r1) # load address of handler routine
487 la %r2,SP_PTREGS(%r15) # address of register-save area 479 la %r2,SP_PTREGS(%r15) # address of register-save area
488 larl %r14,sysc_return 480 basr %r14,%r1 # branch to interrupt-handler
489 br %r1 # branch to interrupt-handler 481pgm_exit:
482 TRACE_IRQS_CHECK_ON
483 j sysc_return
490 484
491# 485#
492# handle per exception 486# handle per exception
@@ -513,8 +507,8 @@ pgm_per_std:
513 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 507 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
514 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 508 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
515pgm_no_vtime2: 509pgm_no_vtime2:
510 TRACE_IRQS_CHECK_OFF
516 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 511 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
517 TRACE_IRQS_OFF
518 lg %r1,__TI_task(%r9) 512 lg %r1,__TI_task(%r9)
519 tm SP_PSW+1(%r15),0x01 # kernel per event ? 513 tm SP_PSW+1(%r15),0x01 # kernel per event ?
520 jz kernel_per 514 jz kernel_per
@@ -525,7 +519,7 @@ pgm_no_vtime2:
525 lgf %r3,__LC_PGM_ILC # load program interruption code 519 lgf %r3,__LC_PGM_ILC # load program interruption code
526 lghi %r8,0x7f 520 lghi %r8,0x7f
527 ngr %r8,%r3 # clear per-event-bit and ilc 521 ngr %r8,%r3 # clear per-event-bit and ilc
528 je sysc_return 522 je pgm_exit
529 j pgm_do_call 523 j pgm_do_call
530 524
531# 525#
@@ -539,14 +533,15 @@ pgm_svcper:
539 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 533 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
540 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 534 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
541 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 535 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
536 TRACE_IRQS_OFF
542 lg %r8,__TI_task(%r9) 537 lg %r8,__TI_task(%r9)
543 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID 538 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
544 mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS 539 mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
545 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID 540 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
546 oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 541 oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
547 TRACE_IRQS_ON 542 TRACE_IRQS_ON
548 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
549 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 543 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
544 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
550 j sysc_do_svc 545 j sysc_do_svc
551 546
552# 547#
@@ -555,8 +550,8 @@ pgm_svcper:
555kernel_per: 550kernel_per:
556 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number 551 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
557 la %r2,SP_PTREGS(%r15) # address of register-save area 552 la %r2,SP_PTREGS(%r15) # address of register-save area
558 larl %r14,sysc_restore # load adr. of system ret, no work 553 brasl %r14,do_single_step
559 jg do_single_step # branch to do_single_step 554 j pgm_exit
560 555
561/* 556/*
562 * IO interrupt handler routine 557 * IO interrupt handler routine
@@ -579,29 +574,15 @@ io_no_vtime:
579 la %r2,SP_PTREGS(%r15) # address of register-save area 574 la %r2,SP_PTREGS(%r15) # address of register-save area
580 brasl %r14,do_IRQ # call standard irq handler 575 brasl %r14,do_IRQ # call standard irq handler
581io_return: 576io_return:
577 LOCKDEP_SYS_EXIT
578 TRACE_IRQS_ON
579io_tif:
582 tm __TI_flags+7(%r9),_TIF_WORK_INT 580 tm __TI_flags+7(%r9),_TIF_WORK_INT
583 jnz io_work # there is work to do (signals etc.) 581 jnz io_work # there is work to do (signals etc.)
584io_restore: 582io_restore:
585#ifdef CONFIG_TRACE_IRQFLAGS
586 larl %r1,io_restore_trace_psw
587 lpswe 0(%r1)
588io_restore_trace:
589 TRACE_IRQS_CHECK
590 LOCKDEP_SYS_EXIT
591#endif
592io_leave:
593 RESTORE_ALL __LC_RETURN_PSW,0 583 RESTORE_ALL __LC_RETURN_PSW,0
594io_done: 584io_done:
595 585
596#ifdef CONFIG_TRACE_IRQFLAGS
597 .section .data,"aw",@progbits
598 .align 8
599 .globl io_restore_trace_psw
600io_restore_trace_psw:
601 .quad 0, io_restore_trace
602 .previous
603#endif
604
605# 586#
606# There is work todo, find out in which context we have been interrupted: 587# There is work todo, find out in which context we have been interrupted:
607# 1) if we return to user space we can do all _TIF_WORK_INT work 588# 1) if we return to user space we can do all _TIF_WORK_INT work
@@ -627,18 +608,22 @@ io_work:
627 # check for preemptive scheduling 608 # check for preemptive scheduling
628 icm %r0,15,__TI_precount(%r9) 609 icm %r0,15,__TI_precount(%r9)
629 jnz io_restore # preemption is disabled 610 jnz io_restore # preemption is disabled
611 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
612 jno io_restore
630 # switch to kernel stack 613 # switch to kernel stack
631 lg %r1,SP_R15(%r15) 614 lg %r1,SP_R15(%r15)
632 aghi %r1,-SP_SIZE 615 aghi %r1,-SP_SIZE
633 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 616 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
634 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 617 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
635 lgr %r15,%r1 618 lgr %r15,%r1
636io_resume_loop: 619 # TRACE_IRQS_ON already done at io_return, call
637 larl %r14,io_resume_loop 620 # TRACE_IRQS_OFF to keep things symmetrical
638 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 621 TRACE_IRQS_OFF
639 jgo preempt_schedule_irq 622 brasl %r14,preempt_schedule_irq
640#endif 623 j io_return
624#else
641 j io_restore 625 j io_restore
626#endif
642 627
643# 628#
644# Need to do work before returning to userspace, switch to kernel stack 629# Need to do work before returning to userspace, switch to kernel stack
@@ -655,7 +640,7 @@ io_work_user:
655# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED 640# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED
656# and _TIF_MCCK_PENDING 641# and _TIF_MCCK_PENDING
657# 642#
658io_work_loop: 643io_work_tif:
659 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING 644 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
660 jo io_mcck_pending 645 jo io_mcck_pending
661 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED 646 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
@@ -670,43 +655,45 @@ io_work_loop:
670# _TIF_MCCK_PENDING is set, call handler 655# _TIF_MCCK_PENDING is set, call handler
671# 656#
672io_mcck_pending: 657io_mcck_pending:
658 # TRACE_IRQS_ON already done at io_return
673 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler 659 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler
674 j io_work_loop 660 TRACE_IRQS_OFF
661 j io_return
675 662
676# 663#
677# _TIF_NEED_RESCHED is set, call schedule 664# _TIF_NEED_RESCHED is set, call schedule
678# 665#
679io_reschedule: 666io_reschedule:
680 TRACE_IRQS_ON 667 # TRACE_IRQS_ON already done at io_return
681 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 668 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
682 brasl %r14,schedule # call scheduler 669 brasl %r14,schedule # call scheduler
683 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 670 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
684 TRACE_IRQS_OFF 671 TRACE_IRQS_OFF
685 j io_work_loop 672 j io_return
686 673
687# 674#
688# _TIF_SIGPENDING or is set, call do_signal 675# _TIF_SIGPENDING or is set, call do_signal
689# 676#
690io_sigpending: 677io_sigpending:
691 TRACE_IRQS_ON 678 # TRACE_IRQS_ON already done at io_return
692 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 679 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
693 la %r2,SP_PTREGS(%r15) # load pt_regs 680 la %r2,SP_PTREGS(%r15) # load pt_regs
694 brasl %r14,do_signal # call do_signal 681 brasl %r14,do_signal # call do_signal
695 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 682 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
696 TRACE_IRQS_OFF 683 TRACE_IRQS_OFF
697 j io_work_loop 684 j io_return
698 685
699# 686#
700# _TIF_NOTIFY_RESUME or is set, call do_notify_resume 687# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
701# 688#
702io_notify_resume: 689io_notify_resume:
703 TRACE_IRQS_ON 690 # TRACE_IRQS_ON already done at io_return
704 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 691 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
705 la %r2,SP_PTREGS(%r15) # load pt_regs 692 la %r2,SP_PTREGS(%r15) # load pt_regs
706 brasl %r14,do_notify_resume # call do_notify_resume 693 brasl %r14,do_notify_resume # call do_notify_resume
707 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 694 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
708 TRACE_IRQS_OFF 695 TRACE_IRQS_OFF
709 j io_work_loop 696 j io_return
710 697
711/* 698/*
712 * External interrupt handler routine 699 * External interrupt handler routine
@@ -883,14 +870,14 @@ stack_overflow:
883 870
884cleanup_table_system_call: 871cleanup_table_system_call:
885 .quad system_call, sysc_do_svc 872 .quad system_call, sysc_do_svc
886cleanup_table_sysc_return: 873cleanup_table_sysc_tif:
887 .quad sysc_return, sysc_leave 874 .quad sysc_tif, sysc_restore
888cleanup_table_sysc_leave: 875cleanup_table_sysc_restore:
889 .quad sysc_leave, sysc_done 876 .quad sysc_restore, sysc_done
890cleanup_table_io_return: 877cleanup_table_io_tif:
891 .quad io_return, io_leave 878 .quad io_tif, io_restore
892cleanup_table_io_leave: 879cleanup_table_io_restore:
893 .quad io_leave, io_done 880 .quad io_restore, io_done
894 881
895cleanup_critical: 882cleanup_critical:
896 clc 8(8,%r12),BASED(cleanup_table_system_call) 883 clc 8(8,%r12),BASED(cleanup_table_system_call)
@@ -898,25 +885,25 @@ cleanup_critical:
898 clc 8(8,%r12),BASED(cleanup_table_system_call+8) 885 clc 8(8,%r12),BASED(cleanup_table_system_call+8)
899 jl cleanup_system_call 886 jl cleanup_system_call
9000: 8870:
901 clc 8(8,%r12),BASED(cleanup_table_sysc_return) 888 clc 8(8,%r12),BASED(cleanup_table_sysc_tif)
902 jl 0f 889 jl 0f
903 clc 8(8,%r12),BASED(cleanup_table_sysc_return+8) 890 clc 8(8,%r12),BASED(cleanup_table_sysc_tif+8)
904 jl cleanup_sysc_return 891 jl cleanup_sysc_tif
9050: 8920:
906 clc 8(8,%r12),BASED(cleanup_table_sysc_leave) 893 clc 8(8,%r12),BASED(cleanup_table_sysc_restore)
907 jl 0f 894 jl 0f
908 clc 8(8,%r12),BASED(cleanup_table_sysc_leave+8) 895 clc 8(8,%r12),BASED(cleanup_table_sysc_restore+8)
909 jl cleanup_sysc_leave 896 jl cleanup_sysc_restore
9100: 8970:
911 clc 8(8,%r12),BASED(cleanup_table_io_return) 898 clc 8(8,%r12),BASED(cleanup_table_io_tif)
912 jl 0f 899 jl 0f
913 clc 8(8,%r12),BASED(cleanup_table_io_return+8) 900 clc 8(8,%r12),BASED(cleanup_table_io_tif+8)
914 jl cleanup_io_return 901 jl cleanup_io_tif
9150: 9020:
916 clc 8(8,%r12),BASED(cleanup_table_io_leave) 903 clc 8(8,%r12),BASED(cleanup_table_io_restore)
917 jl 0f 904 jl 0f
918 clc 8(8,%r12),BASED(cleanup_table_io_leave+8) 905 clc 8(8,%r12),BASED(cleanup_table_io_restore+8)
919 jl cleanup_io_leave 906 jl cleanup_io_restore
9200: 9070:
921 br %r14 908 br %r14
922 909
@@ -963,16 +950,16 @@ cleanup_system_call_insn:
963 .quad sysc_stime 950 .quad sysc_stime
964 .quad sysc_update 951 .quad sysc_update
965 952
966cleanup_sysc_return: 953cleanup_sysc_tif:
967 mvc __LC_RETURN_PSW(8),0(%r12) 954 mvc __LC_RETURN_PSW(8),0(%r12)
968 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_return) 955 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif)
969 la %r12,__LC_RETURN_PSW 956 la %r12,__LC_RETURN_PSW
970 br %r14 957 br %r14
971 958
972cleanup_sysc_leave: 959cleanup_sysc_restore:
973 clc 8(8,%r12),BASED(cleanup_sysc_leave_insn) 960 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn)
974 je 3f 961 je 3f
975 clc 8(8,%r12),BASED(cleanup_sysc_leave_insn+8) 962 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn+8)
976 jhe 0f 963 jhe 0f
977 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 964 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
9780: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 9650: mvc __LC_RETURN_PSW(16),SP_PSW(%r15)
@@ -985,20 +972,20 @@ cleanup_sysc_leave:
985 lg %r15,SP_R15(%r15) 972 lg %r15,SP_R15(%r15)
9863: la %r12,__LC_RETURN_PSW 9733: la %r12,__LC_RETURN_PSW
987 br %r14 974 br %r14
988cleanup_sysc_leave_insn: 975cleanup_sysc_restore_insn:
989 .quad sysc_done - 4 976 .quad sysc_done - 4
990 .quad sysc_done - 16 977 .quad sysc_done - 16
991 978
992cleanup_io_return: 979cleanup_io_tif:
993 mvc __LC_RETURN_PSW(8),0(%r12) 980 mvc __LC_RETURN_PSW(8),0(%r12)
994 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return) 981 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif)
995 la %r12,__LC_RETURN_PSW 982 la %r12,__LC_RETURN_PSW
996 br %r14 983 br %r14
997 984
998cleanup_io_leave: 985cleanup_io_restore:
999 clc 8(8,%r12),BASED(cleanup_io_leave_insn) 986 clc 8(8,%r12),BASED(cleanup_io_restore_insn)
1000 je 3f 987 je 3f
1001 clc 8(8,%r12),BASED(cleanup_io_leave_insn+8) 988 clc 8(8,%r12),BASED(cleanup_io_restore_insn+8)
1002 jhe 0f 989 jhe 0f
1003 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 990 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
10040: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 9910: mvc __LC_RETURN_PSW(16),SP_PSW(%r15)
@@ -1011,7 +998,7 @@ cleanup_io_leave:
1011 lg %r15,SP_R15(%r15) 998 lg %r15,SP_R15(%r15)
10123: la %r12,__LC_RETURN_PSW 9993: la %r12,__LC_RETURN_PSW
1013 br %r14 1000 br %r14
1014cleanup_io_leave_insn: 1001cleanup_io_restore_insn:
1015 .quad io_done - 4 1002 .quad io_done - 4
1016 .quad io_done - 16 1003 .quad io_done - 16
1017 1004
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 6309276516b9..598752499c3e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -369,10 +369,6 @@ static void setup_addressing_mode(void)
369 pr_info("Address spaces switched, " 369 pr_info("Address spaces switched, "
370 "mvcos not available\n"); 370 "mvcos not available\n");
371 } 371 }
372#ifdef CONFIG_TRACE_IRQFLAGS
373 sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
374 io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
375#endif
376} 372}
377 373
378static void __init 374static void __init