s390 (2/8): nanosleep restarting.
PATCH 1/1 s390 (2/8): nanosleep restarting.
sys_restart_syscall for nanosleep restarting.
diffstat:
arch/s390/kernel/entry.S | 32 ++++++++++++++++++++++++-------- arch/s390/kernel/signal.c | 9 +++++++++ arch/s390x/kernel/entry.S | 27 +++++++++++++++++++++------ arch/s390x/kernel/signal.c | 9 +++++++++ include/asm-s390/current.h | 2 +- include/asm-s390/thread_info.h | 14 ++++++++++---- include/asm-s390/unistd.h | 1 + include/asm-s390x/current.h | 2 +- include/asm-s390x/thread_info.h | 14 ++++++++++---- include/asm-s390x/unistd.h | 1 + 10 files changed, 87 insertions(+), 24 deletions(-)
arch/s390/kernel/entry.S +24 -8
@@ -47,7 +47,8 @@ SP_TRAP = (SP_ORIG_R2+GPR_SIZE) SP_SIZE = (SP_TRAP+4) -_TIF_WORK_MASK = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) +_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC) +_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) /* * Base Address of this Module --- saved in __LC_ENTRY_BASE
@@ -181,6 +182,7 @@ GET_THREAD_INFO # load pointer to task_struct to R9 sll %r7,2 stosm 24(%r15),0x03 # reenable interrupts +sysc_do_restart: l %r8,sys_call_table-entry_base(%r7,%r13) # get system call addr. tm __TI_flags+3(%r9),_TIF_SYSCALL_TRACE bo BASED(sysc_tracesys)
@@ -191,7 +193,7 @@ sysc_return: stnsm 24(%r15),0xfc # disable I/O and ext. interrupts - tm __TI_flags+3(%r9),_TIF_WORK_MASK + tm __TI_flags+3(%r9),_TIF_WORK_SVC bnz BASED(sysc_work) # there is work to do (signals etc.) sysc_leave: RESTORE_ALL 1
@@ -202,7 +204,7 @@ sysc_work_loop: stnsm 24(%r15),0xfc # disable I/O and ext. interrupts GET_THREAD_INFO # load pointer to task_struct to R9 - tm __TI_flags+3(%r9),_TIF_WORK_MASK + tm __TI_flags+3(%r9),_TIF_WORK_SVC bz BASED(sysc_leave) # there is no work to do # # One of the work bits is on. Find out which one.
@@ -213,6 +215,8 @@ bo BASED(sysc_reschedule) tm __TI_flags+3(%r9),_TIF_SIGPENDING bo BASED(sysc_sigpending) + tm __TI_flags+3(%r9),_TIF_RESTART_SVC + bo BASED(sysc_restart) b BASED(sysc_leave) #
@@ -237,14 +241,26 @@ b BASED(sysc_leave) # out of here, do NOT recheck # +# _TIF_RESTART_SVC is set, set up registers and restart svc +# +sysc_restart: + ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC + stosm 24(%r15),0x03 # reenable interrupts + l %r7,SP_R2(%r15) # load new svc number + sll %r7,2 + mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument + lm %r2,%r6,SP_R2(%r15) # load svc arguments + b BASED(sysc_do_restart) # restart svc + +# # call trace before and after sys_call # sysc_tracesys: l %r1,BASED(.Ltrace) srl %r7,2 - st %r7,SP_R2(4,%r15) + st %r7,SP_R2(%r15) basr %r14,%r1 - l %r7,SP_R2(4,%r15) # strace might have changed the + l %r7,SP_R2(%r15) # strace might have changed the n %r7,BASED(.Lc256) # system call sll %r7,2 l %r8,sys_call_table-entry_base(%r7,%r13)
@@ -354,7 +370,7 @@ .long sys_write .long sys_open /* 5 */ .long sys_close - .long sys_ni_syscall /* old waitpid syscall holder */ + .long sys_restart_syscall .long sys_creat .long sys_link .long sys_unlink /* 10 */
@@ -752,7 +768,7 @@ #else bno BASED(io_leave) # no-> skip resched & signal #endif - tm __TI_flags+3(%r9),_TIF_WORK_MASK + tm __TI_flags+3(%r9),_TIF_WORK_INT bnz BASED(io_work) # there is work to do (signals etc.) io_leave: RESTORE_ALL 0
@@ -788,7 +804,7 @@ io_work_loop: stnsm 24(%r15),0xfc # disable I/O and ext. interrupts GET_THREAD_INFO # load pointer to task_struct to R9 - tm __TI_flags+3(%r9),_TIF_WORK_MASK + tm __TI_flags+3(%r9),_TIF_WORK_INT bz BASED(io_leave) # there is no work to do # # One of the work bits is on. Find out which one.
arch/s390/kernel/signal.c +9 -0
@@ -397,6 +397,10 @@if (regs->trap == __LC_SVC_OLD_PSW) {/* If so, check system call restarting.. */ switch (regs->gprs[2 ]) { +case -ERESTART_RESTARTBLOCK : +current_thread_info ()->restart_block.fn = + do_no_restart_syscall; +clear_thread_flag (TIF_RESTART_SVC );case -ERESTARTNOHAND : regs->gprs[2 ] = -EINTR ;break ;
@@ -473,6 +477,11 @@ regs->gprs[2 ] = regs->orig_gpr2; regs->psw.addr -=2 ; } +/* Restart the system call with a new system call number */ +if (regs->gprs[2 ] == -ERESTART_RESTARTBLOCK ) { + regs->gprs[2 ] = __NR_restart_syscall; +set_thread_flag (TIF_RESTART_SVC ); + } }return 0 ; }
arch/s390x/kernel/entry.S +21 -6
@@ -47,7 +47,8 @@ SP_TRAP = (SP_ORIG_R2+GPR_SIZE) SP_SIZE = (SP_TRAP+4) -_TIF_WORK_MASK = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) +_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC) +_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) /* * Register usage in interrupt handlers:
@@ -161,6 +162,7 @@ llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore GET_THREAD_INFO # load pointer to task_struct to R9 stosm 48(%r15),0x03 # reenable interrupts +sysc_do_restart: larl %r10,sys_call_table sll %r7,3 tm SP_PSW+3(%r15),0x01 # are we running in 31 bit mode ?
@@ -177,7 +179,7 @@ sysc_return: stnsm 48(%r15),0xfc # disable I/O and ext. interrupts - tm __TI_flags+7(%r9),_TIF_WORK_MASK + tm __TI_flags+7(%r9),_TIF_WORK_SVC jnz sysc_work # there is work to do (signals etc.) sysc_leave: RESTORE_ALL 1
@@ -188,7 +190,7 @@ sysc_work_loop: stnsm 48(%r15),0xfc # disable I/O and ext. interrupts GET_THREAD_INFO # load pointer to task_struct to R9 - tm __TI_flags+7(%r9),_TIF_WORK_MASK + tm __TI_flags+7(%r9),_TIF_WORK_SVC jz sysc_leave # there is no work to do # # One of the work bits is on. Find out which one.
@@ -199,6 +201,8 @@ jo sysc_reschedule tm __TI_flags+7(%r9),_TIF_SIGPENDING jo sysc_sigpending + tm __TI_flags+7(%r9),_TIF_RESTART_SVC + jo sysc_restart j sysc_leave #
@@ -221,6 +225,17 @@ j sysc_leave # out of here, do NOT recheck # +# _TIF_RESTART_SVC is set, set up registers and restart svc +# +sysc_restart: + ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC + stosm 48(%r15),0x03 # reenable interrupts + lg %r7,SP_R2(%r15) # load new svc number + mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument + lmg %r2,%r6,SP_R2(%r15) # load svc arguments + j sysc_do_restart # restart svc + +# # call syscall_trace before and after system call # special linkage: %r12 contains the return address for trace_svc #
@@ -383,7 +398,7 @@ .long SYSCALL(sys_write,sys32_write_wrapper) .long SYSCALL(sys_open,sys32_open_wrapper) /* 5 */ .long SYSCALL(sys_close,sys32_close_wrapper) - .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old waitpid syscall */ + .long SYSCALL(sys_restart_syscall,sys_ni_syscall) .long SYSCALL(sys_creat,sys32_creat_wrapper) .long SYSCALL(sys_link,sys32_link_wrapper) .long SYSCALL(sys_unlink,sys32_unlink_wrapper) /* 10 */
@@ -777,7 +792,7 @@ #else jno io_leave # no-> skip resched & signal #endif - tm __TI_flags+7(%r9),_TIF_WORK_MASK + tm __TI_flags+7(%r9),_TIF_WORK_INT jnz io_work # there is work to do (signals etc.) io_leave: RESTORE_ALL 0
@@ -813,7 +828,7 @@ io_work_loop: stnsm 48(%r15),0xfc # disable I/O and ext. interrupts GET_THREAD_INFO # load pointer to task_struct to R9 - tm __TI_flags+7(%r9),_TIF_WORK_MASK + tm __TI_flags+7(%r9),_TIF_WORK_INT jz io_leave # there is no work to do # # One of the work bits is on. Find out which one.
arch/s390x/kernel/signal.c +9 -0
@@ -391,6 +391,10 @@if (regs->trap == __LC_SVC_OLD_PSW) {/* If so, check system call restarting.. */ switch (regs->gprs[2 ]) { +case -ERESTART_RESTARTBLOCK : +current_thread_info ()->restart_block.fn = + do_no_restart_syscall; +clear_thread_flag (TIF_RESTART_SVC );case -ERESTARTNOHAND : regs->gprs[2 ] = -EINTR ;break ;
@@ -473,6 +477,11 @@ regs->gprs[2 ] = regs->orig_gpr2; regs->psw.addr -=2 ; } +/* Restart the system call with a new system call number */ +if (regs->gprs[2 ] == -ERESTART_RESTARTBLOCK ) { + regs->gprs[2 ] = __NR_restart_syscall; +set_thread_flag (TIF_RESTART_SVC ); + } }return 0 ; }
include/asm-s390/current.h +1 -1
@@ -13,7 +13,7 @@#ifdef __KERNEL__ -#include <asm/thread_info.h> +#include <linux/thread_info.h> struct task_struct ;
include/asm-s390/thread_info.h +10 -4
@@ -26,6 +26,7 @@unsigned long flags;/* low level flags */ unsigned int cpu;/* current CPU */ unsigned int preempt_count;/* 0 => preemptable */ +struct restart_block restart_block; };/*
@@ -33,10 +34,13 @@*/ #define INIT_THREAD_INFO (tsk) \ { \ - task: &tsk, \ - exec_domain: &default_exec_domain, \ - flags: 0, \ - cpu: 0, \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ }#define init_thread_info (init_thread_union.thread_info)
@@ -69,6 +73,7 @@#define TIF_NOTIFY_RESUME 1/* resumption notification requested */ #define TIF_SIGPENDING 2/* signal pending */ #define TIF_NEED_RESCHED 3/* rescheduling necessary */ +#define TIF_RESTART_SVC 4/* restart svc with new svc number */ #define TIF_USEDFPU 16/* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17/* true if poll_idle() is polling TIF_NEED_RESCHED */
@@ -77,6 +82,7 @@#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)#define _TIF_USEDFPU (1<<TIF_USEDFPU)#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
include/asm-s390/unistd.h +1 -0
@@ -19,6 +19,7 @@#define __NR_write 4#define __NR_open 5#define __NR_close 6 +#define __NR_restart_syscall 7#define __NR_creat 8#define __NR_link 9#define __NR_unlink 10
include/asm-s390x/current.h +1 -1
@@ -13,7 +13,7 @@#ifdef __KERNEL__ -#include <asm/thread_info.h> +#include <linux/thread_info.h> struct task_struct ;
include/asm-s390x/thread_info.h +10 -4
@@ -26,6 +26,7 @@unsigned long flags;/* low level flags */ unsigned int cpu;/* current CPU */ unsigned int preempt_count;/* 0 => preemptable */ +struct restart_block restart_block; };/*
@@ -33,10 +34,13 @@*/ #define INIT_THREAD_INFO (tsk) \ { \ - task: &tsk, \ - exec_domain: &default_exec_domain, \ - flags: 0, \ - cpu: 0, \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ }#define init_thread_info (init_thread_union.thread_info)
@@ -69,6 +73,7 @@#define TIF_NOTIFY_RESUME 1/* resumption notification requested */ #define TIF_SIGPENDING 2/* signal pending */ #define TIF_NEED_RESCHED 3/* rescheduling necessary */ +#define TIF_RESTART_SVC 4/* restart svc with new svc number */ #define TIF_USEDFPU 16/* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17/* true if poll_idle() is polling TIF_NEED_RESCHED */
@@ -77,6 +82,7 @@#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)#define _TIF_USEDFPU (1<<TIF_USEDFPU)#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
include/asm-s390x/unistd.h +1 -0
@@ -19,6 +19,7 @@#define __NR_write 4#define __NR_open 5#define __NR_close 6 +#define __NR_restart_syscall 7#define __NR_creat 8#define __NR_link 9#define __NR_unlink 10