Messages in this thread Patch in this message | | | From | Martin Schwidefsky <> | Subject | [PATCH] s390 (2/8): nanosleep restarting. | Date | Thu, 12 Dec 2002 19:06:46 +0100 |
| |
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(-)
diff -urN linux-2.5.51/arch/s390/kernel/entry.S linux-2.5.51-s390/arch/s390/kernel/entry.S --- linux-2.5.51/arch/s390/kernel/entry.S Tue Dec 10 03:45:45 2002 +++ linux-2.5.51-s390/arch/s390/kernel/entry.S Thu Dec 12 18:27:00 2002 @@ -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. diff -urN linux-2.5.51/arch/s390/kernel/signal.c linux-2.5.51-s390/arch/s390/kernel/signal.c --- linux-2.5.51/arch/s390/kernel/signal.c Tue Dec 10 03:46:15 2002 +++ linux-2.5.51-s390/arch/s390/kernel/signal.c Thu Dec 12 18:27:00 2002 @@ -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; } diff -urN linux-2.5.51/arch/s390x/kernel/entry.S linux-2.5.51-s390/arch/s390x/kernel/entry.S --- linux-2.5.51/arch/s390x/kernel/entry.S Tue Dec 10 03:45:51 2002 +++ linux-2.5.51-s390/arch/s390x/kernel/entry.S Thu Dec 12 18:27:00 2002 @@ -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. diff -urN linux-2.5.51/arch/s390x/kernel/signal.c linux-2.5.51-s390/arch/s390x/kernel/signal.c --- linux-2.5.51/arch/s390x/kernel/signal.c Tue Dec 10 03:46:11 2002 +++ linux-2.5.51-s390/arch/s390x/kernel/signal.c Thu Dec 12 18:27:08 2002 @@ -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; } diff -urN linux-2.5.51/include/asm-s390/current.h linux-2.5.51-s390/include/asm-s390/current.h --- linux-2.5.51/include/asm-s390/current.h Tue Dec 10 03:46:24 2002 +++ linux-2.5.51-s390/include/asm-s390/current.h Thu Dec 12 18:27:00 2002 @@ -13,7 +13,7 @@ #ifdef __KERNEL__ -#include <asm/thread_info.h> +#include <linux/thread_info.h> struct task_struct; diff -urN linux-2.5.51/include/asm-s390/thread_info.h linux-2.5.51-s390/include/asm-s390/thread_info.h --- linux-2.5.51/include/asm-s390/thread_info.h Tue Dec 10 03:46:13 2002 +++ linux-2.5.51-s390/include/asm-s390/thread_info.h Thu Dec 12 18:27:00 2002 @@ -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) diff -urN linux-2.5.51/include/asm-s390/unistd.h linux-2.5.51-s390/include/asm-s390/unistd.h --- linux-2.5.51/include/asm-s390/unistd.h Tue Dec 10 03:46:28 2002 +++ linux-2.5.51-s390/include/asm-s390/unistd.h Thu Dec 12 18:27:00 2002 @@ -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 diff -urN linux-2.5.51/include/asm-s390x/current.h linux-2.5.51-s390/include/asm-s390x/current.h --- linux-2.5.51/include/asm-s390x/current.h Tue Dec 10 03:46:26 2002 +++ linux-2.5.51-s390/include/asm-s390x/current.h Thu Dec 12 18:27:00 2002 @@ -13,7 +13,7 @@ #ifdef __KERNEL__ -#include <asm/thread_info.h> +#include <linux/thread_info.h> struct task_struct; diff -urN linux-2.5.51/include/asm-s390x/thread_info.h linux-2.5.51-s390/include/asm-s390x/thread_info.h --- linux-2.5.51/include/asm-s390x/thread_info.h Tue Dec 10 03:46:13 2002 +++ linux-2.5.51-s390/include/asm-s390x/thread_info.h Thu Dec 12 18:27:00 2002 @@ -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) diff -urN linux-2.5.51/include/asm-s390x/unistd.h linux-2.5.51-s390/include/asm-s390x/unistd.h --- linux-2.5.51/include/asm-s390x/unistd.h Tue Dec 10 03:46:13 2002 +++ linux-2.5.51-s390/include/asm-s390x/unistd.h Thu Dec 12 18:27:00 2002 @@ -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 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |