aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S109
1 files changed, 76 insertions, 33 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 139ca153d5cc..764d56177cb5 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -69,13 +69,31 @@ STACK_SIZE = 1 << STACK_SHIFT
69 basr %r14,%r1 69 basr %r14,%r1
70 .endm 70 .endm
71 71
72 .macro LOCKDEP_SYS_EXIT 72 .macro TRACE_IRQS_CHECK
73 l %r1,BASED(.Llockdep_sys_exit) 73 tm SP_PSW(%r15),0x03 # irqs enabled?
74 jz 0f
75 l %r1,BASED(.Ltrace_irq_on)
74 basr %r14,%r1 76 basr %r14,%r1
77 j 1f
780: l %r1,BASED(.Ltrace_irq_off)
79 basr %r14,%r1
801:
75 .endm 81 .endm
76#else 82#else
77#define TRACE_IRQS_ON 83#define TRACE_IRQS_ON
78#define TRACE_IRQS_OFF 84#define TRACE_IRQS_OFF
85#define TRACE_IRQS_CHECK
86#endif
87
88#ifdef CONFIG_LOCKDEP
89 .macro LOCKDEP_SYS_EXIT
90 tm SP_PSW+1(%r15),0x01 # returning to user ?
91 jz 0f
92 l %r1,BASED(.Llockdep_sys_exit)
93 basr %r14,%r1
940:
95 .endm
96#else
79#define LOCKDEP_SYS_EXIT 97#define LOCKDEP_SYS_EXIT
80#endif 98#endif
81 99
@@ -234,8 +252,6 @@ sysc_saveall:
234 lh %r7,0x8a # get svc number from lowcore 252 lh %r7,0x8a # get svc number from lowcore
235#ifdef CONFIG_VIRT_CPU_ACCOUNTING 253#ifdef CONFIG_VIRT_CPU_ACCOUNTING
236sysc_vtime: 254sysc_vtime:
237 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
238 bz BASED(sysc_do_svc)
239 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 255 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
240sysc_stime: 256sysc_stime:
241 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 257 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -263,19 +279,34 @@ sysc_do_restart:
263 279
264sysc_return: 280sysc_return:
265 tm SP_PSW+1(%r15),0x01 # returning to user ? 281 tm SP_PSW+1(%r15),0x01 # returning to user ?
266 bno BASED(sysc_leave) 282 bno BASED(sysc_restore)
267 tm __TI_flags+3(%r9),_TIF_WORK_SVC 283 tm __TI_flags+3(%r9),_TIF_WORK_SVC
268 bnz BASED(sysc_work) # there is work to do (signals etc.) 284 bnz BASED(sysc_work) # there is work to do (signals etc.)
285sysc_restore:
286#ifdef CONFIG_TRACE_IRQFLAGS
287 la %r1,BASED(sysc_restore_trace_psw)
288 lpsw 0(%r1)
289sysc_restore_trace:
290 TRACE_IRQS_CHECK
269 LOCKDEP_SYS_EXIT 291 LOCKDEP_SYS_EXIT
292#endif
270sysc_leave: 293sysc_leave:
271 RESTORE_ALL __LC_RETURN_PSW,1 294 RESTORE_ALL __LC_RETURN_PSW,1
295sysc_done:
296
297#ifdef CONFIG_TRACE_IRQFLAGS
298 .align 8
299 .globl sysc_restore_trace_psw
300sysc_restore_trace_psw:
301 .long 0, sysc_restore_trace + 0x80000000
302#endif
272 303
273# 304#
274# recheck if there is more work to do 305# recheck if there is more work to do
275# 306#
276sysc_work_loop: 307sysc_work_loop:
277 tm __TI_flags+3(%r9),_TIF_WORK_SVC 308 tm __TI_flags+3(%r9),_TIF_WORK_SVC
278 bz BASED(sysc_leave) # there is no work to do 309 bz BASED(sysc_restore) # there is no work to do
279# 310#
280# One of the work bits is on. Find out which one. 311# One of the work bits is on. Find out which one.
281# 312#
@@ -290,8 +321,8 @@ sysc_work:
290 bo BASED(sysc_restart) 321 bo BASED(sysc_restart)
291 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP 322 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
292 bo BASED(sysc_singlestep) 323 bo BASED(sysc_singlestep)
293 LOCKDEP_SYS_EXIT 324 b BASED(sysc_restore)
294 b BASED(sysc_leave) 325sysc_work_done:
295 326
296# 327#
297# _TIF_NEED_RESCHED is set, call schedule 328# _TIF_NEED_RESCHED is set, call schedule
@@ -458,6 +489,7 @@ pgm_check_handler:
458pgm_no_vtime: 489pgm_no_vtime:
459#endif 490#endif
460 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 491 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
492 TRACE_IRQS_OFF
461 l %r3,__LC_PGM_ILC # load program interruption code 493 l %r3,__LC_PGM_ILC # load program interruption code
462 la %r8,0x7f 494 la %r8,0x7f
463 nr %r8,%r3 495 nr %r8,%r3
@@ -497,6 +529,7 @@ pgm_per_std:
497pgm_no_vtime2: 529pgm_no_vtime2:
498#endif 530#endif
499 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 531 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
532 TRACE_IRQS_OFF
500 l %r1,__TI_task(%r9) 533 l %r1,__TI_task(%r9)
501 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 534 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
502 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 535 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -517,15 +550,13 @@ pgm_svcper:
517 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 550 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
518 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 551 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
519#ifdef CONFIG_VIRT_CPU_ACCOUNTING 552#ifdef CONFIG_VIRT_CPU_ACCOUNTING
520 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
521 bz BASED(pgm_no_vtime3)
522 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 553 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
523 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 554 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
524 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 555 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
525pgm_no_vtime3:
526#endif 556#endif
527 lh %r7,0x8a # get svc number from lowcore 557 lh %r7,0x8a # get svc number from lowcore
528 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 558 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
559 TRACE_IRQS_OFF
529 l %r1,__TI_task(%r9) 560 l %r1,__TI_task(%r9)
530 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 561 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
531 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 562 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
@@ -542,7 +573,7 @@ kernel_per:
542 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check 573 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
543 la %r2,SP_PTREGS(%r15) # address of register-save area 574 la %r2,SP_PTREGS(%r15) # address of register-save area
544 l %r1,BASED(.Lhandle_per) # load adr. of per handler 575 l %r1,BASED(.Lhandle_per) # load adr. of per handler
545 la %r14,BASED(sysc_leave) # load adr. of system return 576 la %r14,BASED(sysc_restore)# load adr. of system return
546 br %r1 # branch to do_single_step 577 br %r1 # branch to do_single_step
547 578
548/* 579/*
@@ -569,26 +600,38 @@ io_no_vtime:
569 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 600 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
570 la %r2,SP_PTREGS(%r15) # address of register-save area 601 la %r2,SP_PTREGS(%r15) # address of register-save area
571 basr %r14,%r1 # branch to standard irq handler 602 basr %r14,%r1 # branch to standard irq handler
572 TRACE_IRQS_ON
573
574io_return: 603io_return:
575 tm SP_PSW+1(%r15),0x01 # returning to user ? 604 tm SP_PSW+1(%r15),0x01 # returning to user ?
576#ifdef CONFIG_PREEMPT 605#ifdef CONFIG_PREEMPT
577 bno BASED(io_preempt) # no -> check for preemptive scheduling 606 bno BASED(io_preempt) # no -> check for preemptive scheduling
578#else 607#else
579 bno BASED(io_leave) # no-> skip resched & signal 608 bno BASED(io_restore) # no-> skip resched & signal
580#endif 609#endif
581 tm __TI_flags+3(%r9),_TIF_WORK_INT 610 tm __TI_flags+3(%r9),_TIF_WORK_INT
582 bnz BASED(io_work) # there is work to do (signals etc.) 611 bnz BASED(io_work) # there is work to do (signals etc.)
612io_restore:
613#ifdef CONFIG_TRACE_IRQFLAGS
614 la %r1,BASED(io_restore_trace_psw)
615 lpsw 0(%r1)
616io_restore_trace:
617 TRACE_IRQS_CHECK
583 LOCKDEP_SYS_EXIT 618 LOCKDEP_SYS_EXIT
619#endif
584io_leave: 620io_leave:
585 RESTORE_ALL __LC_RETURN_PSW,0 621 RESTORE_ALL __LC_RETURN_PSW,0
586io_done: 622io_done:
587 623
624#ifdef CONFIG_TRACE_IRQFLAGS
625 .align 8
626 .globl io_restore_trace_psw
627io_restore_trace_psw:
628 .long 0, io_restore_trace + 0x80000000
629#endif
630
588#ifdef CONFIG_PREEMPT 631#ifdef CONFIG_PREEMPT
589io_preempt: 632io_preempt:
590 icm %r0,15,__TI_precount(%r9) 633 icm %r0,15,__TI_precount(%r9)
591 bnz BASED(io_leave) 634 bnz BASED(io_restore)
592 l %r1,SP_R15(%r15) 635 l %r1,SP_R15(%r15)
593 s %r1,BASED(.Lc_spsize) 636 s %r1,BASED(.Lc_spsize)
594 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 637 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -596,12 +639,14 @@ io_preempt:
596 lr %r15,%r1 639 lr %r15,%r1
597io_resume_loop: 640io_resume_loop:
598 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 641 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
599 bno BASED(io_leave) 642 bno BASED(io_restore)
600 mvc __TI_precount(4,%r9),BASED(.Lc_pactive) 643 mvc __TI_precount(4,%r9),BASED(.Lc_pactive)
644 TRACE_IRQS_ON
601 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 645 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
602 l %r1,BASED(.Lschedule) 646 l %r1,BASED(.Lschedule)
603 basr %r14,%r1 # call schedule 647 basr %r14,%r1 # call schedule
604 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 648 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
649 TRACE_IRQS_OFF
605 xc __TI_precount(4,%r9),__TI_precount(%r9) 650 xc __TI_precount(4,%r9),__TI_precount(%r9)
606 b BASED(io_resume_loop) 651 b BASED(io_resume_loop)
607#endif 652#endif
@@ -627,40 +672,42 @@ io_work_loop:
627 bo BASED(io_reschedule) 672 bo BASED(io_reschedule)
628 tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 673 tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
629 bnz BASED(io_sigpending) 674 bnz BASED(io_sigpending)
630 LOCKDEP_SYS_EXIT 675 b BASED(io_restore)
631 b BASED(io_leave) 676io_work_done:
632 677
633# 678#
634# _TIF_MCCK_PENDING is set, call handler 679# _TIF_MCCK_PENDING is set, call handler
635# 680#
636io_mcck_pending: 681io_mcck_pending:
637 TRACE_IRQS_OFF
638 l %r1,BASED(.Ls390_handle_mcck) 682 l %r1,BASED(.Ls390_handle_mcck)
639 basr %r14,%r1 # TIF bit will be cleared by handler 683 basr %r14,%r1 # TIF bit will be cleared by handler
640 TRACE_IRQS_ON
641 b BASED(io_work_loop) 684 b BASED(io_work_loop)
642 685
643# 686#
644# _TIF_NEED_RESCHED is set, call schedule 687# _TIF_NEED_RESCHED is set, call schedule
645# 688#
646io_reschedule: 689io_reschedule:
690 TRACE_IRQS_ON
647 l %r1,BASED(.Lschedule) 691 l %r1,BASED(.Lschedule)
648 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 692 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
649 basr %r14,%r1 # call scheduler 693 basr %r14,%r1 # call scheduler
650 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 694 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
695 TRACE_IRQS_OFF
651 tm __TI_flags+3(%r9),_TIF_WORK_INT 696 tm __TI_flags+3(%r9),_TIF_WORK_INT
652 bz BASED(io_leave) # there is no work to do 697 bz BASED(io_restore) # there is no work to do
653 b BASED(io_work_loop) 698 b BASED(io_work_loop)
654 699
655# 700#
656# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 701# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
657# 702#
658io_sigpending: 703io_sigpending:
704 TRACE_IRQS_ON
659 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 705 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
660 la %r2,SP_PTREGS(%r15) # load pt_regs 706 la %r2,SP_PTREGS(%r15) # load pt_regs
661 l %r1,BASED(.Ldo_signal) 707 l %r1,BASED(.Ldo_signal)
662 basr %r14,%r1 # call do_signal 708 basr %r14,%r1 # call do_signal
663 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 709 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
710 TRACE_IRQS_OFF
664 b BASED(io_work_loop) 711 b BASED(io_work_loop)
665 712
666/* 713/*
@@ -688,7 +735,6 @@ ext_no_vtime:
688 lh %r3,__LC_EXT_INT_CODE # get interruption code 735 lh %r3,__LC_EXT_INT_CODE # get interruption code
689 l %r1,BASED(.Ldo_extint) 736 l %r1,BASED(.Ldo_extint)
690 basr %r14,%r1 737 basr %r14,%r1
691 TRACE_IRQS_ON
692 b BASED(io_return) 738 b BASED(io_return)
693 739
694__critical_end: 740__critical_end:
@@ -853,15 +899,15 @@ cleanup_table_system_call:
853cleanup_table_sysc_return: 899cleanup_table_sysc_return:
854 .long sysc_return + 0x80000000, sysc_leave + 0x80000000 900 .long sysc_return + 0x80000000, sysc_leave + 0x80000000
855cleanup_table_sysc_leave: 901cleanup_table_sysc_leave:
856 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 902 .long sysc_leave + 0x80000000, sysc_done + 0x80000000
857cleanup_table_sysc_work_loop: 903cleanup_table_sysc_work_loop:
858 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 904 .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000
859cleanup_table_io_return: 905cleanup_table_io_return:
860 .long io_return + 0x80000000, io_leave + 0x80000000 906 .long io_return + 0x80000000, io_leave + 0x80000000
861cleanup_table_io_leave: 907cleanup_table_io_leave:
862 .long io_leave + 0x80000000, io_done + 0x80000000 908 .long io_leave + 0x80000000, io_done + 0x80000000
863cleanup_table_io_work_loop: 909cleanup_table_io_work_loop:
864 .long io_work_loop + 0x80000000, io_mcck_pending + 0x80000000 910 .long io_work_loop + 0x80000000, io_work_done + 0x80000000
865 911
866cleanup_critical: 912cleanup_critical:
867 clc 4(4,%r12),BASED(cleanup_table_system_call) 913 clc 4(4,%r12),BASED(cleanup_table_system_call)
@@ -930,8 +976,6 @@ cleanup_system_call:
930cleanup_vtime: 976cleanup_vtime:
931 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 977 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
932 bhe BASED(cleanup_stime) 978 bhe BASED(cleanup_stime)
933 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
934 bz BASED(cleanup_novtime)
935 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 979 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
936cleanup_stime: 980cleanup_stime:
937 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16) 981 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
@@ -939,7 +983,6 @@ cleanup_stime:
939 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 983 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
940cleanup_update: 984cleanup_update:
941 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 985 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
942cleanup_novtime:
943#endif 986#endif
944 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4) 987 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
945 la %r12,__LC_RETURN_PSW 988 la %r12,__LC_RETURN_PSW
@@ -978,10 +1021,10 @@ cleanup_sysc_leave:
9782: la %r12,__LC_RETURN_PSW 10212: la %r12,__LC_RETURN_PSW
979 br %r14 1022 br %r14
980cleanup_sysc_leave_insn: 1023cleanup_sysc_leave_insn:
1024 .long sysc_done - 4 + 0x80000000
981#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1025#ifdef CONFIG_VIRT_CPU_ACCOUNTING
982 .long sysc_leave + 14 + 0x80000000 1026 .long sysc_done - 8 + 0x80000000
983#endif 1027#endif
984 .long sysc_leave + 10 + 0x80000000
985 1028
986cleanup_io_return: 1029cleanup_io_return:
987 mvc __LC_RETURN_PSW(4),0(%r12) 1030 mvc __LC_RETURN_PSW(4),0(%r12)
@@ -1008,10 +1051,10 @@ cleanup_io_leave:
10082: la %r12,__LC_RETURN_PSW 10512: la %r12,__LC_RETURN_PSW
1009 br %r14 1052 br %r14
1010cleanup_io_leave_insn: 1053cleanup_io_leave_insn:
1054 .long io_done - 4 + 0x80000000
1011#ifdef CONFIG_VIRT_CPU_ACCOUNTING 1055#ifdef CONFIG_VIRT_CPU_ACCOUNTING
1012 .long io_leave + 18 + 0x80000000 1056 .long io_done - 8 + 0x80000000
1013#endif 1057#endif
1014 .long io_leave + 14 + 0x80000000
1015 1058
1016/* 1059/*
1017 * Integer constants 1060 * Integer constants