patch-2.3.13 linux/arch/sparc64/kernel/signal.c
Next file: linux/arch/sparc64/kernel/signal32.c
Previous file: linux/arch/sparc64/kernel/setup.c
Back to the patch index
Back to the overall index
- Lines: 339
- Date:
Fri Aug 6 11:58:00 1999
- Orig file:
v2.3.12/linux/arch/sparc64/kernel/signal.c
- Orig date:
Wed Jul 28 14:47:42 1999
diff -u --recursive --new-file v2.3.12/linux/arch/sparc64/kernel/signal.c linux/arch/sparc64/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.41 1999/06/14 05:23:58 davem Exp $
+/* $Id: signal.c,v 1.44 1999/08/04 07:04:13 jj Exp $
* arch/sparc64/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -46,7 +46,7 @@
asmlinkage void sparc64_set_context(struct pt_regs *regs)
{
struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0];
- struct thread_struct *tp = ¤t->tss;
+ struct thread_struct *tp = ¤t->thread;
mc_gregset_t *grp;
unsigned long pc, npc, tstate;
unsigned long fp, i7;
@@ -123,9 +123,9 @@
err |= copy_from_user(fpregs+16,
((unsigned long *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16,
(sizeof(unsigned int) * 32));
- err |= __get_user(current->tss.xfsr[0],
+ err |= __get_user(current->thread.xfsr[0],
&(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
- err |= __get_user(current->tss.gsr[0],
+ err |= __get_user(current->thread.gsr[0],
&(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
regs->tstate &= ~TSTATE_PEF;
}
@@ -141,7 +141,7 @@
asmlinkage void sparc64_get_context(struct pt_regs *regs)
{
struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0];
- struct thread_struct *tp = ¤t->tss;
+ struct thread_struct *tp = ¤t->thread;
mc_gregset_t *grp;
mcontext_t *mcp;
unsigned long fp, i7;
@@ -155,7 +155,7 @@
#if 1
fenab = 0; /* IMO get_context is like any other system call, thus modifies FPU state -jj */
#else
- fenab = (current->tss.fpsaved[0] & FPRS_FEF);
+ fenab = (current->thread.fpsaved[0] & FPRS_FEF);
#endif
mcp = &ucp->uc_mcontext;
@@ -205,7 +205,7 @@
unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
unsigned long fprs;
- fprs = current->tss.fpsaved[0];
+ fprs = current->thread.fpsaved[0];
if (fprs & FPRS_DL)
err |= copy_to_user(&(mcp->mc_fpregs.mcfpu_fregs), fpregs,
(sizeof(unsigned int) * 32));
@@ -213,8 +213,8 @@
err |= copy_to_user(
((unsigned long *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
(sizeof(unsigned int) * 32));
- err |= __put_user(current->tss.xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
- err |= __put_user(current->tss.gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
+ err |= __put_user(current->thread.xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
+ err |= __put_user(current->thread.gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
err |= __put_user(fprs, &(mcp->mc_fpregs.mcfpu_fprs));
}
if (err)
@@ -226,34 +226,17 @@
do_exit(SIGSEGV);
}
-/*
- * The new signal frame, intended to be used for Linux applications only
- * (we have enough in there to work with clone).
- * All the interesting bits are in the info field.
- */
-
-struct new_signal_frame {
- struct sparc_stackf ss;
- __siginfo_t info;
- __siginfo_fpu_t * fpu_save;
- unsigned int insns [2];
- unsigned long extramask[_NSIG_WORDS-1];
- __siginfo_fpu_t fpu_state;
-};
-
struct rt_signal_frame {
struct sparc_stackf ss;
- siginfo_t info;
+ siginfo_t info;
struct pt_regs regs;
- sigset_t mask;
__siginfo_fpu_t * fpu_save;
- unsigned int insns [2];
stack_t stack;
+ sigset_t mask;
__siginfo_fpu_t fpu_state;
};
/* Align macros */
-#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
/*
@@ -265,7 +248,7 @@
sigset_t saveset;
#ifdef CONFIG_SPARC32_COMPAT
- if (current->tss.flags & SPARC_FLAG_32BIT) {
+ if (current->thread.flags & SPARC_FLAG_32BIT) {
extern asmlinkage void _sigpause32_common(old_sigset_t32,
struct pt_regs *);
_sigpause32_common(set, regs);
@@ -372,65 +355,12 @@
if (fprs & FPRS_DU)
err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
(sizeof(unsigned int) * 32));
- err |= __get_user(current->tss.xfsr[0], &fpu->si_fsr);
- err |= __get_user(current->tss.gsr[0], &fpu->si_gsr);
- current->tss.fpsaved[0] |= fprs;
+ err |= __get_user(current->thread.xfsr[0], &fpu->si_fsr);
+ err |= __get_user(current->thread.gsr[0], &fpu->si_gsr);
+ current->thread.fpsaved[0] |= fprs;
return err;
}
-void do_sigreturn(struct pt_regs *regs)
-{
- struct new_signal_frame *sf;
- unsigned long tpc, tnpc, tstate;
- __siginfo_fpu_t *fpu_save;
- sigset_t set;
- int err;
-
- synchronize_user_stack ();
- sf = (struct new_signal_frame *)
- (regs->u_regs [UREG_FP] + STACK_BIAS);
-
- /* 1. Make sure we are not getting garbage from the user */
- if (((unsigned long) sf) & 3)
- goto segv;
-
- err = get_user(tpc, &sf->info.si_regs.tpc);
- err |= __get_user(tnpc, &sf->info.si_regs.tnpc);
- err |= ((tpc | tnpc) & 3);
-
- /* 2. Restore the state */
- err |= __get_user(regs->y, &sf->info.si_regs.y);
- err |= __get_user(tstate, &sf->info.si_regs.tstate);
- err |= copy_from_user(regs->u_regs, sf->info.si_regs.u_regs, sizeof(regs->u_regs));
-
- /* User can only change condition codes in %tstate. */
- regs->tstate &= ~(TSTATE_ICC);
- regs->tstate |= (tstate & TSTATE_ICC);
-
- err |= __get_user(fpu_save, &sf->fpu_save);
- if (fpu_save)
- err |= restore_fpu_state(regs, &sf->fpu_state);
-
- err |= __get_user(set.sig[0], &sf->info.si_mask);
- if (_NSIG_WORDS > 1)
- err |= __copy_from_user(&set.sig[1], &sf->extramask, sizeof(sf->extramask));
-
- if (err)
- goto segv;
-
- regs->tpc = tpc;
- regs->tnpc = tnpc;
-
- sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(¤t->sigmask_lock);
- current->blocked = set;
- recalc_sigpending(current);
- spin_unlock_irq(¤t->sigmask_lock);
- return;
-segv:
- send_sig(SIGSEGV, current, 1);
-}
-
void do_rt_sigreturn(struct pt_regs *regs)
{
struct rt_signal_frame *sf;
@@ -503,15 +433,15 @@
unsigned long fprs;
int err = 0;
- fprs = current->tss.fpsaved[0];
+ fprs = current->thread.fpsaved[0];
if (fprs & FPRS_DL)
err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
(sizeof(unsigned int) * 32));
if (fprs & FPRS_DU)
err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
(sizeof(unsigned int) * 32));
- err |= __put_user(current->tss.xfsr[0], &fpu->si_fsr);
- err |= __put_user(current->tss.gsr[0], &fpu->si_gsr);
+ err |= __put_user(current->thread.xfsr[0], &fpu->si_fsr);
+ err |= __put_user(current->thread.gsr[0], &fpu->si_gsr);
err |= __put_user(fprs, &fpu->si_fprs);
return err;
@@ -533,77 +463,6 @@
}
static inline void
-new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
- int signo, sigset_t *oldset)
-{
- struct new_signal_frame *sf;
- int sigframe_size, err;
-
- /* 1. Make sure everything is clean */
- synchronize_user_stack();
- save_and_clear_fpu();
-
- sigframe_size = NF_ALIGNEDSZ;
-
- if (!(current->tss.fpsaved[0] & FPRS_FEF))
- sigframe_size -= sizeof(__siginfo_fpu_t);
-
- sf = (struct new_signal_frame *)get_sigframe(ka, regs, sigframe_size);
-
- if (invalid_frame_pointer (sf, sigframe_size))
- goto sigill;
-
- if (current->tss.w_saved != 0) {
-#ifdef DEBUG_SIGNALS
- printk ("%s[%d]: Invalid user stack frame for "
- "signal delivery.\n", current->comm, current->pid);
-#endif
- goto sigill;
- }
-
- /* 2. Save the current process state */
- err = copy_to_user(&sf->info.si_regs, regs, sizeof (*regs));
-
- if (current->tss.fpsaved[0] & FPRS_FEF) {
- err |= save_fpu_state(regs, &sf->fpu_state);
- err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
- } else {
- err |= __put_user(0, &sf->fpu_save);
- }
-
- err |= __put_user(oldset->sig[0], &sf->info.si_mask);
- if (_NSIG_WORDS > 1)
- err |= __copy_to_user(sf->extramask, &oldset->sig[1],
- sizeof(sf->extramask));
-
- err |= copy_in_user((u64 *)sf,
- (u64 *)(regs->u_regs[UREG_FP]+STACK_BIAS),
- sizeof(struct reg_window));
- if (err)
- goto sigsegv;
-
- /* 3. signal handler back-trampoline and parameters */
- regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS;
- regs->u_regs[UREG_I0] = signo;
- regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
-
- /* 5. signal handler */
- regs->tpc = (unsigned long) ka->sa.sa_handler;
- regs->tnpc = (regs->tpc + 4);
-
- /* 4. return to kernel instructions */
- regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
- return;
-
-sigill:
- lock_kernel();
- do_exit(SIGILL);
-sigsegv:
- lock_kernel();
- do_exit(SIGSEGV);
-}
-
-static inline void
setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset, siginfo_t *info)
{
@@ -615,7 +474,7 @@
save_and_clear_fpu();
sigframe_size = RT_ALIGNEDSZ;
- if (!(current->tss.fpsaved[0] & FPRS_FEF))
+ if (!(current->thread.fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t);
sf = (struct rt_signal_frame *)get_sigframe(ka, regs, sigframe_size);
@@ -623,7 +482,7 @@
if (invalid_frame_pointer (sf, sigframe_size))
goto sigill;
- if (current->tss.w_saved != 0) {
+ if (current->thread.w_saved != 0) {
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
@@ -634,7 +493,7 @@
/* 2. Save the current process state */
err = copy_to_user(&sf->regs, regs, sizeof (*regs));
- if (current->tss.fpsaved[0] & FPRS_FEF) {
+ if (current->thread.fpsaved[0] & FPRS_FEF) {
err |= save_fpu_state(regs, &sf->fpu_state);
err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
} else {
@@ -652,7 +511,12 @@
(u64 *)(regs->u_regs[UREG_FP]+STACK_BIAS),
sizeof(struct reg_window));
- err |= copy_to_user(&sf->info, info, sizeof(siginfo_t));
+ if (info)
+ err |= copy_to_user(&sf->info, info, sizeof(siginfo_t));
+ else {
+ err |= __put_user(signo, &sf->info.si_signo);
+ err |= __put_user(SI_NOINFO, &sf->info.si_code);
+ }
if (err)
goto sigsegv;
@@ -681,10 +545,7 @@
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
- if(ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame(ka, regs, signr, oldset, info);
- else
- new_setup_frame(ka, regs, signr, oldset);
+ setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
if(ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if(!(ka->sa.sa_flags & SA_NOMASK)) {
@@ -785,7 +646,7 @@
oldset = ¤t->blocked;
#ifdef CONFIG_SPARC32_COMPAT
- if (current->tss.flags & SPARC_FLAG_32BIT) {
+ if (current->thread.flags & SPARC_FLAG_32BIT) {
extern asmlinkage int do_signal32(sigset_t *, struct pt_regs *,
unsigned long, int);
return do_signal32(oldset, regs, orig_i0, restart_syscall);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)