diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2010-05-17 04:00:01 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-05-17 04:00:15 -0400 |
commit | 43d399d2ab7e96cb8d952d0ba4e9131587b7c8b9 (patch) | |
tree | 3b5c651e8cc1cdbde50a846ace4500aebcfe5ea2 /arch/s390/kernel/entry.S | |
parent | 94038a99119c171aea27608f81c7ba359de98c4e (diff) |
[S390] cleanup sysc_work and io_work code
Cleanup the #ifdef mess at io_work in entry[64].S and streamline the
TIF work code of the system call and io exit path.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 75 |
1 files changed, 28 insertions, 47 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 6af7045280a8..ffebfb64b913 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -301,31 +301,29 @@ sysc_restore_trace_psw: | |||
301 | #endif | 301 | #endif |
302 | 302 | ||
303 | # | 303 | # |
304 | # recheck if there is more work to do | 304 | # There is work to do, but first we need to check if we return to userspace. |
305 | # | ||
306 | sysc_work_loop: | ||
307 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | ||
308 | bz BASED(sysc_restore) # there is no work to do | ||
309 | # | ||
310 | # One of the work bits is on. Find out which one. | ||
311 | # | 305 | # |
312 | sysc_work: | 306 | sysc_work: |
313 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 307 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
314 | bno BASED(sysc_restore) | 308 | bno BASED(sysc_restore) |
309 | |||
310 | # | ||
311 | # One of the work bits is on. Find out which one. | ||
312 | # | ||
313 | sysc_work_loop: | ||
315 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 314 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING |
316 | bo BASED(sysc_mcck_pending) | 315 | bo BASED(sysc_mcck_pending) |
317 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 316 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
318 | bo BASED(sysc_reschedule) | 317 | bo BASED(sysc_reschedule) |
319 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 318 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
320 | bnz BASED(sysc_sigpending) | 319 | bo BASED(sysc_sigpending) |
321 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | 320 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME |
322 | bnz BASED(sysc_notify_resume) | 321 | bo BASED(sysc_notify_resume) |
323 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC | 322 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC |
324 | bo BASED(sysc_restart) | 323 | bo BASED(sysc_restart) |
325 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 324 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP |
326 | bo BASED(sysc_singlestep) | 325 | bo BASED(sysc_singlestep) |
327 | b BASED(sysc_restore) | 326 | b BASED(sysc_return) # beware of critical section cleanup |
328 | sysc_work_done: | ||
329 | 327 | ||
330 | # | 328 | # |
331 | # _TIF_NEED_RESCHED is set, call schedule | 329 | # _TIF_NEED_RESCHED is set, call schedule |
@@ -386,7 +384,7 @@ sysc_singlestep: | |||
386 | mvi SP_SVCNR+1(%r15),0xff | 384 | mvi SP_SVCNR+1(%r15),0xff |
387 | la %r2,SP_PTREGS(%r15) # address of register-save area | 385 | la %r2,SP_PTREGS(%r15) # address of register-save area |
388 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 386 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
389 | la %r14,BASED(sysc_return) # load adr. of system return | 387 | la %r14,BASED(sysc_work_loop) # load adr. of system return |
390 | br %r1 # branch to do_single_step | 388 | br %r1 # branch to do_single_step |
391 | 389 | ||
392 | # | 390 | # |
@@ -636,30 +634,36 @@ io_restore_trace_psw: | |||
636 | #endif | 634 | #endif |
637 | 635 | ||
638 | # | 636 | # |
639 | # switch to kernel stack, then check the TIF bits | 637 | # 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 | ||
639 | # 2) if we return to kernel code and preemptive scheduling is enabled check | ||
640 | # the preemption counter and if it is zero call preempt_schedule_irq | ||
641 | # Before any work can be done, a switch to the kernel stack is required. | ||
640 | # | 642 | # |
641 | io_work: | 643 | io_work: |
642 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 644 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
643 | #ifndef CONFIG_PREEMPT | 645 | bo BASED(io_work_user) # yes -> do resched & signal |
644 | bno BASED(io_restore) # no-> skip resched & signal | 646 | #ifdef CONFIG_PREEMPT |
645 | #else | ||
646 | bnz BASED(io_work_user) # no -> check for preemptive scheduling | ||
647 | # check for preemptive scheduling | 647 | # check for preemptive scheduling |
648 | icm %r0,15,__TI_precount(%r9) | 648 | icm %r0,15,__TI_precount(%r9) |
649 | bnz BASED(io_restore) # preemption disabled | 649 | bnz BASED(io_restore) # preemption disabled |
650 | # switch to kernel stack | ||
650 | l %r1,SP_R15(%r15) | 651 | l %r1,SP_R15(%r15) |
651 | s %r1,BASED(.Lc_spsize) | 652 | s %r1,BASED(.Lc_spsize) |
652 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 653 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
653 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 654 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
654 | lr %r15,%r1 | 655 | lr %r15,%r1 |
655 | io_resume_loop: | 656 | io_resume_loop: |
656 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | ||
657 | bno BASED(io_restore) | ||
658 | l %r1,BASED(.Lpreempt_schedule_irq) | 657 | l %r1,BASED(.Lpreempt_schedule_irq) |
659 | la %r14,BASED(io_resume_loop) | 658 | la %r14,BASED(io_resume_loop) |
660 | br %r1 # call schedule | 659 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
660 | bor %r1 # call preempt_schedule_irq | ||
661 | #endif | 661 | #endif |
662 | b BASED(io_restore) | ||
662 | 663 | ||
664 | # | ||
665 | # Need to do work before returning to userspace, switch to kernel stack | ||
666 | # | ||
663 | io_work_user: | 667 | io_work_user: |
664 | l %r1,__LC_KERNEL_STACK | 668 | l %r1,__LC_KERNEL_STACK |
665 | s %r1,BASED(.Lc_spsize) | 669 | s %r1,BASED(.Lc_spsize) |
@@ -668,7 +672,7 @@ io_work_user: | |||
668 | lr %r15,%r1 | 672 | lr %r15,%r1 |
669 | # | 673 | # |
670 | # One of the work bits is on. Find out which one. | 674 | # One of the work bits is on. Find out which one. |
671 | # Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED | 675 | # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED |
672 | # and _TIF_MCCK_PENDING | 676 | # and _TIF_MCCK_PENDING |
673 | # | 677 | # |
674 | io_work_loop: | 678 | io_work_loop: |
@@ -677,11 +681,10 @@ io_work_loop: | |||
677 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 681 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
678 | bo BASED(io_reschedule) | 682 | bo BASED(io_reschedule) |
679 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 683 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
680 | bnz BASED(io_sigpending) | 684 | bo BASED(io_sigpending) |
681 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | 685 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME |
682 | bnz BASED(io_notify_resume) | 686 | bo BASED(io_notify_resume) |
683 | b BASED(io_restore) | 687 | b BASED(io_return) # beware of critical section cleanup |
684 | io_work_done: | ||
685 | 688 | ||
686 | # | 689 | # |
687 | # _TIF_MCCK_PENDING is set, call handler | 690 | # _TIF_MCCK_PENDING is set, call handler |
@@ -701,8 +704,6 @@ io_reschedule: | |||
701 | basr %r14,%r1 # call scheduler | 704 | basr %r14,%r1 # call scheduler |
702 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 705 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
703 | TRACE_IRQS_OFF | 706 | TRACE_IRQS_OFF |
704 | tm __TI_flags+3(%r9),_TIF_WORK_INT | ||
705 | bz BASED(io_restore) # there is no work to do | ||
706 | b BASED(io_work_loop) | 707 | b BASED(io_work_loop) |
707 | 708 | ||
708 | # | 709 | # |
@@ -921,14 +922,10 @@ cleanup_table_sysc_return: | |||
921 | .long sysc_return + 0x80000000, sysc_leave + 0x80000000 | 922 | .long sysc_return + 0x80000000, sysc_leave + 0x80000000 |
922 | cleanup_table_sysc_leave: | 923 | cleanup_table_sysc_leave: |
923 | .long sysc_leave + 0x80000000, sysc_done + 0x80000000 | 924 | .long sysc_leave + 0x80000000, sysc_done + 0x80000000 |
924 | cleanup_table_sysc_work_loop: | ||
925 | .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000 | ||
926 | cleanup_table_io_return: | 925 | cleanup_table_io_return: |
927 | .long io_return + 0x80000000, io_leave + 0x80000000 | 926 | .long io_return + 0x80000000, io_leave + 0x80000000 |
928 | cleanup_table_io_leave: | 927 | cleanup_table_io_leave: |
929 | .long io_leave + 0x80000000, io_done + 0x80000000 | 928 | .long io_leave + 0x80000000, io_done + 0x80000000 |
930 | cleanup_table_io_work_loop: | ||
931 | .long io_work_loop + 0x80000000, io_work_done + 0x80000000 | ||
932 | 929 | ||
933 | cleanup_critical: | 930 | cleanup_critical: |
934 | clc 4(4,%r12),BASED(cleanup_table_system_call) | 931 | clc 4(4,%r12),BASED(cleanup_table_system_call) |
@@ -946,11 +943,6 @@ cleanup_critical: | |||
946 | clc 4(4,%r12),BASED(cleanup_table_sysc_leave+4) | 943 | clc 4(4,%r12),BASED(cleanup_table_sysc_leave+4) |
947 | bl BASED(cleanup_sysc_leave) | 944 | bl BASED(cleanup_sysc_leave) |
948 | 0: | 945 | 0: |
949 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop) | ||
950 | bl BASED(0f) | ||
951 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) | ||
952 | bl BASED(cleanup_sysc_return) | ||
953 | 0: | ||
954 | clc 4(4,%r12),BASED(cleanup_table_io_return) | 946 | clc 4(4,%r12),BASED(cleanup_table_io_return) |
955 | bl BASED(0f) | 947 | bl BASED(0f) |
956 | clc 4(4,%r12),BASED(cleanup_table_io_return+4) | 948 | clc 4(4,%r12),BASED(cleanup_table_io_return+4) |
@@ -961,11 +953,6 @@ cleanup_critical: | |||
961 | clc 4(4,%r12),BASED(cleanup_table_io_leave+4) | 953 | clc 4(4,%r12),BASED(cleanup_table_io_leave+4) |
962 | bl BASED(cleanup_io_leave) | 954 | bl BASED(cleanup_io_leave) |
963 | 0: | 955 | 0: |
964 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop) | ||
965 | bl BASED(0f) | ||
966 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4) | ||
967 | bl BASED(cleanup_io_work_loop) | ||
968 | 0: | ||
969 | br %r14 | 956 | br %r14 |
970 | 957 | ||
971 | cleanup_system_call: | 958 | cleanup_system_call: |
@@ -1043,12 +1030,6 @@ cleanup_io_return: | |||
1043 | la %r12,__LC_RETURN_PSW | 1030 | la %r12,__LC_RETURN_PSW |
1044 | br %r14 | 1031 | br %r14 |
1045 | 1032 | ||
1046 | cleanup_io_work_loop: | ||
1047 | mvc __LC_RETURN_PSW(4),0(%r12) | ||
1048 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) | ||
1049 | la %r12,__LC_RETURN_PSW | ||
1050 | br %r14 | ||
1051 | |||
1052 | cleanup_io_leave: | 1033 | cleanup_io_leave: |
1053 | clc 4(4,%r12),BASED(cleanup_io_leave_insn) | 1034 | clc 4(4,%r12),BASED(cleanup_io_leave_insn) |
1054 | be BASED(2f) | 1035 | be BASED(2f) |