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/