Subject: [2.5 PATCH] signal handling

From: Vivien Chappelier <[email-masked]>
Date: Mon, 13 Jan 2003 11:06:35 +0100

Hello,

         This patch fixes various bugs in the 2.5 signal code (native and
mips64 32bit compatibility code):
         - revert changes to ucontext.h to match the arguments of
setup_sigcontext and restore_sigcontext (which need a sigcontext struct,
not mcontext struct)
         - fix swapped arguments in the call to do_signal in
do_notify_resume
         - cleanup and fix 32 bit compatibility code for mips64, 
including making sigset_t32 and sigset_t size match.

Vivien.
--- include/asm-mips/ucontext.h	2002-10-09 23:12:56.000000000 +0200
+++ include/asm-mips/ucontext.h	2003-01-10 23:36:16.000000000 +0100
@@ -10,33 +10,12 @@
 #ifndef _ASM_UCONTEXT_H
 #define _ASM_UCONTEXT_H
 
-typedef unsigned int greg_t;
-
-#define NGREG 36
-
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
-	union {
-		double		fp_dregs[16];
-		float		fp_fregs [32];
-		unsigned int	fp_regs[32];
-	} fp_r;
-	unsigned int fp_csr;
-	unsigned int fp_pad;
-} fpregset_t;
-
-typedef struct {
-	gregset_t gregs;
-	fpregset_t fpregs;
-} mcontext_t;
-
 struct ucontext {
-	unsigned long	uc_flags;
-	struct ucontext	*uc_link;
-	stack_t		uc_stack;
-	mcontext_t	uc_mcontext;
-	sigset_t	uc_sigmask;	/* mask last for extensibility */
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
 
 #endif /* _ASM_UCONTEXT_H */
--- include/asm-mips64/ucontext.h	2002-10-09 23:12:58.000000000 +0200
+++ include/asm-mips64/ucontext.h	2003-01-10 23:35:06.000000000 +0100
@@ -10,33 +10,12 @@
 #ifndef _ASM_UCONTEXT_H
 #define _ASM_UCONTEXT_H
 
-typedef unsigned int greg_t;
-
-#define NGREG 36
-
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
-	union {
-		double		fp_dregs[32];
-		float		fp_fregs [32];
-		unsigned long	fp_regs[32];
-	} fp_r;
-	unsigned int fp_csr;
-	unsigned int fp_pad;
-} fpregset_t;
-
-typedef struct {
-	gregset_t gregs;
-	fpregset_t fpregs;
-} mcontext_t;
-
 struct ucontext {
-	unsigned long	uc_flags;
-	struct ucontext	*uc_link;
-	stack_t		uc_stack;
-	mcontext_t	uc_mcontext;
-	sigset_t	uc_sigmask;	/* mask last for extensibility */
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
 
 #endif /* _ASM_UCONTEXT_H */
--- include/asm-mips64/signal.h	2002-11-09 16:16:54.000000000 +0100
+++ include/asm-mips64/signal.h	2003-01-11 00:57:26.000000000 +0100
@@ -11,25 +11,47 @@
 
 #include <linux/types.h>
 
-#define _NSIG		64
+#define _NSIG		128
 #define _NSIG_BPW	64
 #define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
 
 typedef struct {
-	long sig[_NSIG_WORDS];
+	unsigned long sig[_NSIG_WORDS];
 } sigset_t;
 
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+#ifdef __KERNEL__
+
 #define _NSIG32		128
 #define _NSIG_BPW32	32
 #define _NSIG_WORDS32	(_NSIG32 / _NSIG_BPW32)
 
 typedef struct {
-	long sig[_NSIG_WORDS32];
+	unsigned int sig[_NSIG_WORDS32];
 } sigset_t32;
 
-typedef unsigned long old_sigset_t;		/* at least 32 bits */
 typedef unsigned int old_sigset_t32;
 
+typedef unsigned int __sighandler_t32;
+
+struct sigaction32 {
+	unsigned int		sa_flags;
+	__sighandler_t32	sa_handler;
+	sigset_t32		sa_mask;
+	unsigned int		sa_restorer;
+	unsigned int		sa_resv[1];     /* reserved */
+};
+
+/* IRIX compatible stack_t  */
+typedef struct sigaltstack32 {
+	unsigned int ss_sp;
+	__kernel_size_t32 ss_size;
+	int ss_flags;
+} stack32_t;
+
+#endif /* __KERNEL__ */
+
 #define SIGHUP		 1	/* Hangup (POSIX).  */
 #define SIGINT		 2	/* Interrupt (ANSI).  */
 #define SIGQUIT		 3	/* Quit (POSIX).  */
--- arch/mips/kernel/signal.c	2002-11-09 16:10:08.000000000 +0100
+++ arch/mips/kernel/signal.c	2003-01-10 21:26:35.000000000 +0100
@@ -580,6 +580,6 @@
 			return;
 		}
 #endif
-		do_signal(regs,oldset);
+		do_signal(oldset, regs);
 	}
 }
--- arch/mips64/kernel/signal.c	2002-11-09 16:10:14.000000000 +0100
+++ arch/mips64/kernel/signal.c	2003-01-10 22:40:25.000000000 +0100
@@ -411,6 +411,6 @@
 			return;
 		}
 #endif
-		do_signal(regs,oldset);
+		do_signal(oldset, regs);
 	}
 }
--- arch/mips64/kernel/signal32.c	2002-11-09 16:10:14.000000000 +0100
+++ arch/mips64/kernel/signal32.c	2003-01-11 01:39:50.000000000 +0100
@@ -35,37 +35,10 @@
 
 extern asmlinkage void do_syscall_trace(void);
 
-/* 32-bit compatibility types */
-
-#define _NSIG32_BPW	32
-#define _NSIG32_WORDS	(_NSIG / _NSIG32_BPW)
-
-typedef struct {
-	unsigned int sig[_NSIG32_WORDS];
-} sigset32_t;
-
-typedef unsigned int __sighandler32_t;
-typedef void (*vfptr_t)(void);
-
-struct sigaction32 {
-	unsigned int		sa_flags;
-	__sighandler32_t	sa_handler;
-	sigset32_t		sa_mask;
-	unsigned int		sa_restorer;
-	int			sa_resv[1];     /* reserved */
-};
-
-/* IRIX compatible stack_t  */
-typedef struct sigaltstack32 {
-	s32 ss_sp;
-	__kernel_size_t32 ss_size;
-	int ss_flags;
-} stack32_t;
-
 extern void __put_sigset_unknown_nsig(void);
 extern void __get_sigset_unknown_nsig(void);
 
-static inline int put_sigset(const sigset_t *kbuf, sigset32_t *ubuf)
+static inline int put_sigset(const sigset_t *kbuf, sigset_t32 *ubuf)
 {
 	int err = 0;
 
@@ -86,7 +59,7 @@
 	return err;
 }
 
-static inline int get_sigset(sigset_t *kbuf, const sigset32_t *ubuf)
+static inline int get_sigset(sigset_t *kbuf, const sigset_t32 *ubuf)
 {
 	int err = 0;
 	unsigned long sig[4];
@@ -115,11 +88,11 @@
  */
 asmlinkage inline int sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs)
 {
-	sigset32_t *uset;
+	sigset_t32 *uset;
 	sigset_t newset, saveset;
 
 	save_static(&regs);
-	uset = (sigset32_t *) regs.regs[4];
+	uset = (sigset_t32 *) regs.regs[4];
 	if (get_sigset(&newset, uset))
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -142,17 +115,17 @@
 
 asmlinkage int sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs)
 {
-	sigset32_t *uset;
+	sigset_t32 *uset;
 	sigset_t newset, saveset;
         size_t sigsetsize;
 
 	save_static(&regs);
 	/* XXX Don't preclude handling different sized sigset_t's.  */
 	sigsetsize = regs.regs[5];
-	if (sigsetsize != sizeof(sigset32_t))
+	if (sigsetsize != sizeof(sigset_t32))
 		return -EINVAL;
 
-	uset = (sigset32_t *) regs.regs[4];
+	uset = (sigset_t32 *) regs.regs[4];
 	if (get_sigset(&newset, uset))
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -795,7 +768,7 @@
 asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
 				   size_t sigsetsize);
 
-asmlinkage int sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
+asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset,
 				    unsigned int sigsetsize)
 {
 	sigset_t old_set, new_set;
@@ -818,7 +791,7 @@
 
 asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
-asmlinkage int sys32_rt_sigpending(sigset32_t *uset, unsigned int sigsetsize)
+asmlinkage int sys32_rt_sigpending(sigset_t32 *uset, unsigned int sigsetsize)
 {
 	int ret;
 	sigset_t set;