All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Use compat code to translate siginfo_t for N32
@ 2006-07-27 23:44 Peter Watkins
  2006-07-28  1:44 ` Yoichi Yuasa
  0 siblings, 1 reply; 3+ messages in thread
From: Peter Watkins @ 2006-07-27 23:44 UTC (permalink / raw)
  To: linux-mips

[-- Attachment #1: Type: text/plain, Size: 242 bytes --]


This patch fixes incorrect data returned from waitid() for mips64el N32. 
It uses compat code to translate siginfo_t for N32, and factors out 
common O32 and N32 compat code for siginfo_t, to compat32.c. Tested on 
glibc suite and LTP.






[-- Attachment #2: patch-siginfo-2.6.18-rc1 --]
[-- Type: text/plain, Size: 11904 bytes --]

From: Peter Watkins <treestem@gmail.com>
Date: Thu, 27 Jul 2006 19:13:09 -0400
Subject: Use compat code to translate siginfo_t for N32.
Use compat code to translate siginfo_t for N32.
Factor out common O32 and N32 compat code for siginfo_t, to compat32.c.
---
 arch/mips/kernel/Makefile     |    4 +-
 arch/mips/kernel/compat32.c   |   88 +++++++++++++++++++++++++++++++++++++++++
 arch/mips/kernel/compat32.h   |   76 +++++++++++++++++++++++++++++++++++
 arch/mips/kernel/linux32.c    |   28 -------------
 arch/mips/kernel/signal32.c   |   52 ------------------------
 arch/mips/kernel/signal_n32.c |   37 ++++++++++++++++-
 6 files changed, 200 insertions(+), 85 deletions(-)

diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 881c467..108171a 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -56,8 +56,8 @@ obj-$(CONFIG_32BIT)		+= scall32-o32.o
 obj-$(CONFIG_64BIT)		+= scall64-64.o
 obj-$(CONFIG_BINFMT_IRIX)	+= binfmt_irix.o
 obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o signal32.o
-obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
-obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
+obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o compat32.o
+obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o compat32.o
 
 obj-$(CONFIG_KGDB)		+= gdb-low.o gdb-stub.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
diff --git a/arch/mips/kernel/compat32.c b/arch/mips/kernel/compat32.c
new file mode 100644
index 0000000..858f7db
--- /dev/null
+++ b/arch/mips/kernel/compat32.c
@@ -0,0 +1,88 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/cache.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/compat.h>
+#include <linux/suspend.h>
+#include <linux/compiler.h>
+
+#include <asm/abi.h>
+#include <asm/asm.h>
+#include <linux/bitops.h>
+#include <asm/sim.h>
+#include <asm/uaccess.h>
+#include <asm/ucontext.h>
+#include <asm/system.h>
+#include <asm/fpu.h>
+#include <asm/war.h>
+
+#include "compat32.h"
+
+
+int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
+{
+	int err;
+
+	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
+		return -EFAULT;
+
+	/* If you change siginfo_t structure, please be sure
+	   this code is fixed accordingly.
+	   It should never copy any pad contained in the structure
+	   to avoid security leaks, but must copy the generic
+	   3 ints plus the relevant union member.
+	   This routine must convert siginfo from 64bit to 32bit as well
+	   at the same time.  */
+	err = __put_user(from->si_signo, &to->si_signo);
+	err |= __put_user(from->si_errno, &to->si_errno);
+	err |= __put_user((short)from->si_code, &to->si_code);
+	if (from->si_code < 0)
+		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+	else {
+		switch (from->si_code >> 16) {
+		case __SI_TIMER >> 16:
+			err |= __put_user(from->si_tid, &to->si_tid);
+			err |= __put_user(from->si_overrun, &to->si_overrun);
+			err |= __put_user(from->si_int, &to->si_int);
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_pid, &to->si_pid);
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		case __SI_FAULT >> 16:
+			err |= __put_user((long)from->si_addr, &to->si_addr);
+			break;
+		case __SI_POLL >> 16:
+			err |= __put_user(from->si_band, &to->si_band);
+			err |= __put_user(from->si_fd, &to->si_fd);
+			break;
+		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
+		case __SI_MESGQ >> 16:
+			err |= __put_user(from->si_pid, &to->si_pid);
+			err |= __put_user(from->si_uid, &to->si_uid);
+			err |= __put_user(from->si_int, &to->si_int);
+			break;
+		}
+	}
+	return err;
+}
diff --git a/arch/mips/kernel/compat32.h b/arch/mips/kernel/compat32.h
new file mode 100644
index 0000000..e2bb23b
--- /dev/null
+++ b/arch/mips/kernel/compat32.h
@@ -0,0 +1,76 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+
+#define SI_PAD_SIZE32   ((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct compat_siginfo {
+	int si_signo;
+	int si_code;
+	int si_errno;
+
+	union {
+		int _pad[SI_PAD_SIZE32];
+
+		/* kill() */
+		struct {
+			compat_pid_t _pid;	/* sender's pid */
+			compat_uid_t _uid;	/* sender's uid */
+		} _kill;
+
+		/* SIGCHLD */
+		struct {
+			compat_pid_t _pid;	/* which child */
+			compat_uid_t _uid;	/* sender's uid */
+			int _status;		/* exit code */
+			compat_clock_t _utime;
+			compat_clock_t _stime;
+		} _sigchld;
+
+		/* IRIX SIGCHLD */
+		struct {
+			compat_pid_t _pid;	/* which child */
+			compat_clock_t _utime;
+			int _status;		/* exit code */
+			compat_clock_t _stime;
+		} _irix_sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			s32 _addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL, SIGXFSZ (To do ...)  */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+
+		/* POSIX.1b timers */
+		struct {
+			timer_t _tid;		/* timer id */
+			int _overrun;		/* overrun count */
+			compat_sigval_t _sigval;/* same as below */
+			int _sys_private;       /* not to be passed to user */
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			compat_pid_t _pid;	/* sender's pid */
+			compat_uid_t _uid;	/* sender's uid */
+			compat_sigval_t _sigval;
+		} _rt;
+
+	} _sifields;
+} compat_siginfo_t;
+
+
+
+int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from);
+
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 450ac59..dd71096 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -163,34 +163,6 @@ out:
 	return error;
 }
 
-asmlinkage long
-sysn32_waitid(int which, compat_pid_t pid,
-	      siginfo_t __user *uinfo, int options,
-	      struct compat_rusage __user *uru)
-{
-	struct rusage ru;
-	long ret;
-	mm_segment_t old_fs = get_fs();
-	int si_signo;
-
-	if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo)))
-		return -EFAULT;
-
-	set_fs (KERNEL_DS);
-	ret = sys_waitid(which, pid, uinfo, options,
-			 uru ? (struct rusage __user *) &ru : NULL);
-	set_fs (old_fs);
-
-	if (__get_user(si_signo, &uinfo->si_signo))
-		return -EFAULT;
-	if (ret < 0 || si_signo == 0)
-		return ret;
-
-	if (uru)
-		ret = put_compat_rusage(&ru, uru);
-	return ret;
-}
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index f32a229..2ba8c53 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -411,58 +411,6 @@ #if ICACHE_REFILLS_WORKAROUND_WAR
 #endif
 };
 
-int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
-{
-	int err;
-
-	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
-		return -EFAULT;
-
-	/* If you change siginfo_t structure, please be sure
-	   this code is fixed accordingly.
-	   It should never copy any pad contained in the structure
-	   to avoid security leaks, but must copy the generic
-	   3 ints plus the relevant union member.
-	   This routine must convert siginfo from 64bit to 32bit as well
-	   at the same time.  */
-	err = __put_user(from->si_signo, &to->si_signo);
-	err |= __put_user(from->si_errno, &to->si_errno);
-	err |= __put_user((short)from->si_code, &to->si_code);
-	if (from->si_code < 0)
-		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
-	else {
-		switch (from->si_code >> 16) {
-		case __SI_TIMER >> 16:
-			err |= __put_user(from->si_tid, &to->si_tid);
-			err |= __put_user(from->si_overrun, &to->si_overrun);
-			err |= __put_user(from->si_int, &to->si_int);
-			break;
-		case __SI_CHLD >> 16:
-			err |= __put_user(from->si_utime, &to->si_utime);
-			err |= __put_user(from->si_stime, &to->si_stime);
-			err |= __put_user(from->si_status, &to->si_status);
-		default:
-			err |= __put_user(from->si_pid, &to->si_pid);
-			err |= __put_user(from->si_uid, &to->si_uid);
-			break;
-		case __SI_FAULT >> 16:
-			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
-			break;
-		case __SI_POLL >> 16:
-			err |= __put_user(from->si_band, &to->si_band);
-			err |= __put_user(from->si_fd, &to->si_fd);
-			break;
-		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
-		case __SI_MESGQ >> 16:
-			err |= __put_user(from->si_pid, &to->si_pid);
-			err |= __put_user(from->si_uid, &to->si_uid);
-			err |= __put_user(from->si_int, &to->si_int);
-			break;
-		}
-	}
-	return err;
-}
-
 save_static_function(sys32_sigreturn);
 __attribute_used__ noinline static void
 _sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 477c533..f805bea 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -23,6 +23,7 @@ #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
+#include <linux/syscalls.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
@@ -41,6 +42,7 @@ #include <asm/cpu-features.h>
 #include <asm/war.h>
 
 #include "signal-common.h"
+#include "compat32.h"
 
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
@@ -74,7 +76,7 @@ #if ICACHE_REFILLS_WORKAROUND_WAR
 #else
 	u32 rs_code[2];			/* signal trampoline */
 #endif
-	struct siginfo rs_info;
+	compat_siginfo_t rs_info;
 	struct ucontextn32 rs_uc;
 #if ICACHE_REFILLS_WORKAROUND_WAR
 	u32 rs_code[8] ____cacheline_aligned;		/* signal trampoline */
@@ -180,7 +182,7 @@ int setup_rt_frame_n32(struct k_sigactio
 	install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
 
 	/* Create siginfo.  */
-	err |= copy_siginfo_to_user(&frame->rs_info, info);
+	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -215,7 +217,7 @@ int setup_rt_frame_n32(struct k_sigactio
 	regs->regs[31] = (unsigned long) frame->rs_code;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
 	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
 	       current->comm, current->pid,
 	       frame, regs->cp0_epc, regs->regs[31]);
@@ -226,3 +228,32 @@ give_sigsegv:
 	force_sigsegv(signr, current);
 	return -EFAULT;
 }
+
+
+
+asmlinkage long
+sysn32_waitid(int which, compat_pid_t pid,
+	      compat_siginfo_t __user *uinfo, int options,
+	      struct compat_rusage __user *uru)
+{
+	siginfo_t info;
+	struct rusage ru;
+	long ret;
+	mm_segment_t old_fs = get_fs();
+
+	info.si_signo = 0;
+	set_fs (KERNEL_DS);
+	ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
+			 uru ? (struct rusage __user *) &ru : NULL);
+	set_fs (old_fs);
+
+	if (ret < 0 || info.si_signo == 0)
+		return ret;
+
+	if (uru && (ret = put_compat_rusage(&ru, uru)))
+		return ret;
+
+	BUG_ON(info.si_code & __SI_MASK);
+	info.si_code |= __SI_CHLD;
+	return copy_siginfo_to_user32(uinfo, &info);
+}
-- 
1.4.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] Use compat code to translate siginfo_t for N32
  2006-07-27 23:44 [PATCH] Use compat code to translate siginfo_t for N32 Peter Watkins
@ 2006-07-28  1:44 ` Yoichi Yuasa
  2006-07-28 17:00   ` Peter Watkins
  0 siblings, 1 reply; 3+ messages in thread
From: Yoichi Yuasa @ 2006-07-28  1:44 UTC (permalink / raw)
  To: Peter Watkins; +Cc: linux-mips

Hi,

> diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
> index 881c467..108171a 100644
> --- a/arch/mips/kernel/Makefile
> +++ b/arch/mips/kernel/Makefile
> @@ -56,8 +56,8 @@ obj-$(CONFIG_32BIT)           += scall32-o32.o
>  obj-$(CONFIG_64BIT)            += scall64-64.o
>  obj-$(CONFIG_BINFMT_IRIX)      += binfmt_irix.o
>  obj-$(CONFIG_MIPS32_COMPAT)    += linux32.o signal32.o
> -obj-$(CONFIG_MIPS32_N32)       += binfmt_elfn32.o scall64-n32.o signal_n32.o
> -obj-$(CONFIG_MIPS32_O32)       += binfmt_elfo32.o scall64-o32.o ptrace32.o
> +obj-$(CONFIG_MIPS32_N32)       += binfmt_elfn32.o scall64-n32.o signal_n32.o compat32.o
> +obj-$(CONFIG_MIPS32_O32)       += binfmt_elfo32.o scall64-o32.o ptrace32.o compat32.o

Why do you separate comapt32.o ?

> diff --git a/arch/mips/kernel/compat32.c b/arch/mips/kernel/compat32.c
> new file mode 100644
> index 0000000..858f7db
> --- /dev/null
> +++ b/arch/mips/kernel/compat32.c

<snip>

> +int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)

see include/linux/compat.h .

int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from);


> diff --git a/arch/mips/kernel/compat32.h b/arch/mips/kernel/compat32.h
> new file mode 100644
> index 0000000..e2bb23b
> --- /dev/null
> +++ b/arch/mips/kernel/compat32.h
> @@ -0,0 +1,76 @@

<snip>

> +int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from);

It's already defined in include/linux/compat.h .

> diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
> index 477c533..f805bea 100644
> --- a/arch/mips/kernel/signal_n32.c
> +++ b/arch/mips/kernel/signal_n32.c

<snip>

> @@ -74,7 +76,7 @@ #if ICACHE_REFILLS_WORKAROUND_WAR
>  #else
>  	u32 rs_code[2];			/* signal trampoline */
>  #endif
> -	struct siginfo rs_info;
> +	compat_siginfo_t rs_info;

use struct compat_siginfo .

Yoichi

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Use compat code to translate siginfo_t for N32
  2006-07-28  1:44 ` Yoichi Yuasa
@ 2006-07-28 17:00   ` Peter Watkins
  0 siblings, 0 replies; 3+ messages in thread
From: Peter Watkins @ 2006-07-28 17:00 UTC (permalink / raw)
  To: Yoichi Yuasa; +Cc: linux-mips

[-- Attachment #1: Type: text/plain, Size: 759 bytes --]

Hello Yoichi,

The attached patch addresses your points, and ends up cleaner and
simpler. Except:

> > diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
> > index 477c533..f805bea 100644
> > --- a/arch/mips/kernel/signal_n32.c
> > +++ b/arch/mips/kernel/signal_n32.c
>
> <snip>
>
> > @@ -74,7 +76,7 @@ #if ICACHE_REFILLS_WORKAROUND_WAR
> >  #else
> >       u32 rs_code[2];                 /* signal trampoline */
> >  #endif
> > -     struct siginfo rs_info;
> > +     compat_siginfo_t rs_info;
>
> use struct compat_siginfo .
>

I did not change this as it's currently consistent with the form used
in signal32.c and signal_n32.c. If we want to change this, it seemed
preferable to have another patch for just that purpose.

- Peter

[-- Attachment #2: patch-siginfo-2.6.18-rc1.txt --]
[-- Type: text/plain, Size: 5468 bytes --]

From 214005a395dd08a209f2ec2d9c03cd00038ec783 Mon Sep 17 00:00:00 2001
From: Peter Watkins <treestem@gmail.com>
Date: Fri, 28 Jul 2006 12:15:52 -0400
Subject: [PATCH] Fix incorrect data returned from waitid() for mips64el N32.
Use compat code to translate siginfo_t for N32.
---
 arch/mips/kernel/linux32.c       |   28 ----------------
 arch/mips/kernel/signal-common.h |   65 ++++++++++++++++++++++++++++++++++++++
 arch/mips/kernel/signal_n32.c    |   36 +++++++++++++++++++--
 3 files changed, 98 insertions(+), 31 deletions(-)

diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 450ac59..dd71096 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -163,34 +163,6 @@ out:
 	return error;
 }
 
-asmlinkage long
-sysn32_waitid(int which, compat_pid_t pid,
-	      siginfo_t __user *uinfo, int options,
-	      struct compat_rusage __user *uru)
-{
-	struct rusage ru;
-	long ret;
-	mm_segment_t old_fs = get_fs();
-	int si_signo;
-
-	if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo)))
-		return -EFAULT;
-
-	set_fs (KERNEL_DS);
-	ret = sys_waitid(which, pid, uinfo, options,
-			 uru ? (struct rusage __user *) &ru : NULL);
-	set_fs (old_fs);
-
-	if (__get_user(si_signo, &uinfo->si_signo))
-		return -EFAULT;
-	if (ret < 0 || si_signo == 0)
-		return ret;
-
-	if (uru)
-		ret = put_compat_rusage(&ru, uru);
-	return ret;
-}
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index b1f09d5..d4a80e7 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -8,6 +8,7 @@
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 
+#include <linux/compat.h>
 
 static inline int
 setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
@@ -174,3 +175,67 @@ static inline int install_sigtramp(unsig
 
 	return err;
 }
+
+
+#define SI_PAD_SIZE32   ((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct compat_siginfo {
+	int si_signo;
+	int si_code;
+	int si_errno;
+
+	union {
+		int _pad[SI_PAD_SIZE32];
+
+		/* kill() */
+		struct {
+			compat_pid_t _pid;	/* sender's pid */
+			compat_uid_t _uid;	/* sender's uid */
+		} _kill;
+
+		/* SIGCHLD */
+		struct {
+			compat_pid_t _pid;	/* which child */
+			compat_uid_t _uid;	/* sender's uid */
+			int _status;		/* exit code */
+			compat_clock_t _utime;
+			compat_clock_t _stime;
+		} _sigchld;
+
+		/* IRIX SIGCHLD */
+		struct {
+			compat_pid_t _pid;	/* which child */
+			compat_clock_t _utime;
+			int _status;		/* exit code */
+			compat_clock_t _stime;
+		} _irix_sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			s32 _addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL, SIGXFSZ (To do ...)  */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+
+		/* POSIX.1b timers */
+		struct {
+			timer_t _tid;		/* timer id */
+			int _overrun;		/* overrun count */
+			compat_sigval_t _sigval;/* same as below */
+			int _sys_private;       /* not to be passed to user */
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			compat_pid_t _pid;	/* sender's pid */
+			compat_uid_t _uid;	/* sender's uid */
+			compat_sigval_t _sigval;
+		} _rt;
+
+	} _sifields;
+} compat_siginfo_t;
+
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 477c533..394d4c6 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -23,6 +23,7 @@ #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
+#include <linux/syscalls.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
@@ -74,7 +75,7 @@ #if ICACHE_REFILLS_WORKAROUND_WAR
 #else
 	u32 rs_code[2];			/* signal trampoline */
 #endif
-	struct siginfo rs_info;
+	compat_siginfo_t rs_info;
 	struct ucontextn32 rs_uc;
 #if ICACHE_REFILLS_WORKAROUND_WAR
 	u32 rs_code[8] ____cacheline_aligned;		/* signal trampoline */
@@ -180,7 +181,7 @@ int setup_rt_frame_n32(struct k_sigactio
 	install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
 
 	/* Create siginfo.  */
-	err |= copy_siginfo_to_user(&frame->rs_info, info);
+	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -215,7 +216,7 @@ int setup_rt_frame_n32(struct k_sigactio
 	regs->regs[31] = (unsigned long) frame->rs_code;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
 	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
 	       current->comm, current->pid,
 	       frame, regs->cp0_epc, regs->regs[31]);
@@ -226,3 +227,32 @@ give_sigsegv:
 	force_sigsegv(signr, current);
 	return -EFAULT;
 }
+
+
+
+asmlinkage long
+sysn32_waitid(int which, compat_pid_t pid,
+	      compat_siginfo_t __user *uinfo, int options,
+	      struct compat_rusage __user *uru)
+{
+	siginfo_t info;
+	struct rusage ru;
+	long ret;
+	mm_segment_t old_fs = get_fs();
+
+	info.si_signo = 0;
+	set_fs (KERNEL_DS);
+	ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
+			 uru ? (struct rusage __user *) &ru : NULL);
+	set_fs (old_fs);
+
+	if (ret < 0 || info.si_signo == 0)
+		return ret;
+
+	if (uru && (ret = put_compat_rusage(&ru, uru)))
+		return ret;
+
+	BUG_ON(info.si_code & __SI_MASK);
+	info.si_code |= __SI_CHLD;
+	return copy_siginfo_to_user32(uinfo, &info);
+}
-- 
1.4.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-07-28 17:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-27 23:44 [PATCH] Use compat code to translate siginfo_t for N32 Peter Watkins
2006-07-28  1:44 ` Yoichi Yuasa
2006-07-28 17:00   ` Peter Watkins

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.