All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] s390 (2/8): nanosleep restarting.
@ 2002-12-12 18:06 Martin Schwidefsky
  0 siblings, 0 replies; only message in thread
From: Martin Schwidefsky @ 2002-12-12 18:06 UTC (permalink / raw)
  To: linux-kernel, torvalds

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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-12-12 18:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-12 18:06 [PATCH] s390 (2/8): nanosleep restarting Martin Schwidefsky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.