patch-2.4.4 linux/arch/ia64/kernel/signal.c
Next file: linux/arch/ia64/kernel/smp.c
Previous file: linux/arch/ia64/kernel/setup.c
Back to the patch index
Back to the overall index
- Lines: 215
- Date:
Thu Apr 5 12:51:47 2001
- Orig file:
v2.4.3/linux/arch/ia64/kernel/signal.c
- Orig date:
Thu Jan 4 12:50:17 2001
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/signal.c linux/arch/ia64/kernel/signal.c
@@ -1,8 +1,8 @@
/*
* Architecture-specific signal handling support.
*
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
*
* Derived from i386 and Alpha versions.
*/
@@ -38,12 +38,8 @@
#endif
struct sigscratch {
-#ifdef CONFIG_IA64_NEW_UNWIND
unsigned long scratch_unat; /* ar.unat for the general registers saved in pt */
unsigned long pad;
-#else
- struct switch_stack sw;
-#endif
struct pt_regs pt;
};
@@ -52,7 +48,6 @@
struct sigcontext sc;
};
-extern long sys_wait4 (int, int *, int, struct rusage *);
extern long ia64_do_signal (sigset_t *, struct sigscratch *, long); /* forward decl */
long
@@ -141,11 +136,7 @@
ia64_psr(&scr->pt)->ri = ip & 0x3;
scr->pt.cr_ipsr = (scr->pt.cr_ipsr & ~IA64_PSR_UM) | (um & IA64_PSR_UM);
-#ifdef CONFIG_IA64_NEW_UNWIND
scr->scratch_unat = ia64_put_scratch_nat_bits(&scr->pt, nat);
-#else
- ia64_put_nat_bits(&scr->pt, &scr->sw, nat); /* restore the original scratch NaT bits */
-#endif
if ((flags & IA64_SC_FLAG_FPH_VALID) != 0) {
struct ia64_psr *psr = ia64_psr(&scr->pt);
@@ -162,7 +153,7 @@
int
copy_siginfo_to_user (siginfo_t *to, siginfo_t *from)
{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+ if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t)))
return -EFAULT;
if (from->si_code < 0)
return __copy_to_user(to, from, sizeof(siginfo_t));
@@ -190,6 +181,11 @@
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);
+ case __SI_PROF >> 16:
+ err |= __put_user(from->si_uid, &to->si_uid);
+ err |= __put_user(from->si_pid, &to->si_pid);
+ err |= __put_user(from->si_pfm_ovfl, &to->si_pfm_ovfl);
+ break;
default:
err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user(from->si_pid, &to->si_pid);
@@ -200,6 +196,43 @@
}
}
+int
+copy_siginfo_from_user (siginfo_t *to, siginfo_t *from)
+{
+ if (!access_ok(VERIFY_READ, from, sizeof(siginfo_t)))
+ return -EFAULT;
+ if (__copy_from_user(to, from, sizeof(siginfo_t)) != 0)
+ return -EFAULT;
+
+ if (SI_FROMUSER(to))
+ return 0;
+
+ to->si_code &= ~__SI_MASK;
+ if (to->si_code != 0) {
+ switch (to->si_signo) {
+ case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGTRAP:
+ to->si_code |= __SI_FAULT;
+ break;
+
+ case SIGCHLD:
+ to->si_code |= __SI_CHLD;
+ break;
+
+ case SIGPOLL:
+ to->si_code |= __SI_POLL;
+ break;
+
+ case SIGPROF:
+ to->si_code |= __SI_PROF;
+ break;
+
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
long
ia64_rt_sigreturn (struct sigscratch *scr)
{
@@ -212,19 +245,17 @@
sc = &((struct sigframe *) (scr->pt.r12 + 16))->sc;
/*
- * When we return to the previously executing context, r8 and
- * r10 have already been setup the way we want them. Indeed,
- * if the signal wasn't delivered while in a system call, we
- * must not touch r8 or r10 as otherwise user-level stat could
- * be corrupted.
+ * When we return to the previously executing context, r8 and r10 have already
+ * been setup the way we want them. Indeed, if the signal wasn't delivered while
+ * in a system call, we must not touch r8 or r10 as otherwise user-level state
+ * could be corrupted.
*/
retval = (long) &ia64_leave_kernel;
if (current->ptrace & PT_TRACESYS)
/*
- * strace expects to be notified after sigreturn
- * returns even though the context to which we return
- * may not be in the middle of a syscall. Thus, the
- * return-value that strace displays for sigreturn is
+ * strace expects to be notified after sigreturn returns even though the
+ * context to which we return may not be in the middle of a syscall.
+ * Thus, the return-value that strace displays for sigreturn is
* meaningless.
*/
retval = (long) &ia64_strace_leave_kernel;
@@ -301,11 +332,7 @@
* preserved registers (r4-r7) are never being looked at by
* the signal handler (registers r4-r7 are used instead).
*/
-#ifdef CONFIG_IA64_NEW_UNWIND
nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat);
-#else
- nat = ia64_get_nat_bits(&scr->pt, &scr->sw);
-#endif
err = __put_user(flags, &sc->sc_flags);
@@ -371,21 +398,11 @@
scr->pt.cr_iip = tramp_addr;
ia64_psr(&scr->pt)->ri = 0; /* start executing in first slot */
-#ifdef CONFIG_IA64_NEW_UNWIND
/*
* Note: this affects only the NaT bits of the scratch regs
* (the ones saved in pt_regs), which is exactly what we want.
*/
scr->scratch_unat = 0; /* ensure NaT bits of at least r2, r3, r12, and r15 are clear */
-#else
- /*
- * Note: this affects only the NaT bits of the scratch regs
- * (the ones saved in pt_regs), which is exactly what we want.
- * The NaT bits for the preserved regs (r4-r7) are in
- * sw->ar_unat iff this process is being PTRACED.
- */
- scr->sw.caller_unat = 0; /* ensure NaT bits of at least r2, r3, r12, and r15 are clear */
-#endif
#if DEBUG_SIG
printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%lx\n",
@@ -437,13 +454,8 @@
}
/*
- * Note that `init' is a special process: it doesn't get signals it
- * doesn't want to handle. Thus you cannot kill init even with a
- * SIGKILL even by mistake.
- *
- * Note that we go through the signals twice: once to check the
- * signals that the kernel can handle, and then we build all the
- * user-level signal handling stack-frames in one go after that.
+ * Note that `init' is a special process: it doesn't get signals it doesn't want to
+ * handle. Thus you cannot kill init even with a SIGKILL even by mistake.
*/
long
ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
@@ -454,9 +466,9 @@
long errno = scr->pt.r8;
/*
- * In the ia64_leave_kernel code path, we want the common case
- * to go fast, which is why we may in certain cases get here
- * from kernel mode. Just return without doing anything if so.
+ * In the ia64_leave_kernel code path, we want the common case to go fast, which
+ * is why we may in certain cases get here from kernel mode. Just return without
+ * doing anything if so.
*/
if (!user_mode(&scr->pt))
return 0;
@@ -476,11 +488,10 @@
#endif
if (scr->pt.r10 != -1) {
/*
- * A system calls has to be restarted only if one of
- * the error codes ERESTARTNOHAND, ERESTARTSYS, or
- * ERESTARTNOINTR is returned. If r10 isn't -1 then
- * r8 doesn't hold an error code and we don't need to
- * restart the syscall, so we set in_syscall to zero.
+ * A system calls has to be restarted only if one of the error codes
+ * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned. If r10
+ * isn't -1 then r8 doesn't hold an error code and we don't need to
+ * restart the syscall, so we can clear the "restart" flag here.
*/
restart = 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)