[PATCH] s390 (2/8): nanosleep restarting.

From: Martin Schwidefsky (schwidefsky@de.ibm.com)
Date: Thu Dec 12 2002 - 13:06:46 EST


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/



This archive was generated by hypermail 2b29 : Sun Dec 15 2002 - 22:00:25 EST