Commit 8c8efbbb authored by Yoshinori Sato's avatar Yoshinori Sato Committed by Linus Torvalds

[PATCH] H8/300: signal handling update

Signed-off-by: default avatarYoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 9d175c89
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/suspend.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -47,7 +48,7 @@ ...@@ -47,7 +48,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
/* /*
* Atomically swap in the new signal mask, and wait for a signal. * Atomically swap in the new signal mask, and wait for a signal.
...@@ -68,7 +69,7 @@ asmlinkage int do_sigsuspend(struct pt_regs *regs) ...@@ -68,7 +69,7 @@ asmlinkage int do_sigsuspend(struct pt_regs *regs)
while (1) { while (1) {
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
if (do_signal(&saveset, regs)) if (do_signal(regs, &saveset))
return -EINTR; return -EINTR;
} }
} }
...@@ -98,7 +99,7 @@ do_rt_sigsuspend(struct pt_regs *regs) ...@@ -98,7 +99,7 @@ do_rt_sigsuspend(struct pt_regs *regs)
while (1) { while (1) {
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
if (do_signal(&saveset, regs)) if (do_signal(regs, &saveset))
return -EINTR; return -EINTR;
} }
} }
...@@ -161,6 +162,7 @@ struct sigframe ...@@ -161,6 +162,7 @@ struct sigframe
unsigned char retcode[8]; unsigned char retcode[8];
unsigned long extramask[_NSIG_WORDS-1]; unsigned long extramask[_NSIG_WORDS-1];
struct sigcontext sc; struct sigcontext sc;
int sig;
} __attribute__((aligned(2),packed)); } __attribute__((aligned(2),packed));
struct rt_sigframe struct rt_sigframe
...@@ -172,73 +174,44 @@ struct rt_sigframe ...@@ -172,73 +174,44 @@ struct rt_sigframe
#endif #endif
long dummy_pc; long dummy_pc;
char *pretcode; char *pretcode;
struct siginfo *pinfo;
void *puc;
unsigned char retcode[8]; unsigned char retcode[8];
struct siginfo info; struct siginfo info;
struct ucontext uc; struct ucontext uc;
int sig;
} __attribute__((aligned(2),packed)); } __attribute__((aligned(2),packed));
static inline int static inline int
restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc,
int *pd0) int *pd0)
{ {
struct sigcontext context;
int err = 0; int err = 0;
unsigned int ccr;
/* get previous context */ unsigned int usp;
if (copy_from_user(&context, usc, sizeof(context))) unsigned int er0;
goto badframe;
/* Always make any pending restarted system calls return -EINTR */
/* restore passed registers */ current_thread_info()->restart_block.fn = do_no_restart_syscall;
regs->er1 = context.sc_er1;
regs->er2 = context.sc_er2; #define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */
regs->er3 = context.sc_er3; COPY(er1);
regs->er5 = context.sc_er5; COPY(er2);
regs->ccr = (regs->ccr & 0x10)|(context.sc_ccr & 0xef); COPY(er3);
regs->pc = context.sc_pc; COPY(er5);
COPY(pc);
ccr = regs->ccr & 0x10;
COPY(ccr);
#undef COPY
regs->ccr &= 0xef;
regs->ccr |= ccr;
regs->orig_er0 = -1; /* disable syscall checks */ regs->orig_er0 = -1; /* disable syscall checks */
wrusp(context.sc_usp); err |= __get_user(usp, &usc->sc_usp);
*pd0 = context.sc_er0;
return err;
badframe:
return 1;
}
static inline int
rt_restore_ucontext(struct pt_regs *regs, struct ucontext *uc, int *pd0)
{
int temp;
greg_t *gregs = uc->uc_mcontext.gregs;
unsigned long usp;
int err;
err = __get_user(temp, &uc->uc_mcontext.version);
if (temp != MCONTEXT_VERSION)
goto badframe;
/* restore passed registers */
err |= __get_user(regs->er0, &gregs[0]);
err |= __get_user(regs->er1, &gregs[1]);
err |= __get_user(regs->er2, &gregs[2]);
err |= __get_user(regs->er3, &gregs[3]);
err |= __get_user(regs->er4, &gregs[4]);
err |= __get_user(regs->er5, &gregs[5]);
err |= __get_user(regs->er6, &gregs[6]);
err |= __get_user(usp, &gregs[7]);
wrusp(usp); wrusp(usp);
err |= __get_user(regs->pc, &gregs[8]);
err |= __get_user(temp, &gregs[9]);
regs->ccr = (regs->ccr & 0x10) | (temp & 0xef);
regs->orig_er0 = -1; /* disable syscall checks */
if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) err |= __get_user(er0, &usc->sc_er0);
goto badframe; *pd0 = er0;
*pd0 = regs->er0;
return err; return err;
badframe:
return 1;
} }
asmlinkage int do_sigreturn(unsigned long __unused,...) asmlinkage int do_sigreturn(unsigned long __unused,...)
...@@ -263,7 +236,7 @@ asmlinkage int do_sigreturn(unsigned long __unused,...) ...@@ -263,7 +236,7 @@ asmlinkage int do_sigreturn(unsigned long __unused,...)
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
if (restore_sigcontext(regs, &frame->sc, frame + 1, &er0)) if (restore_sigcontext(regs, &frame->sc, &er0))
goto badframe; goto badframe;
return er0; return er0;
...@@ -291,8 +264,12 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused,...) ...@@ -291,8 +264,12 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
recalc_sigpending(); recalc_sigpending();
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
if (rt_restore_ucontext(regs, &frame->uc, &er0)) if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0))
goto badframe;
if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
goto badframe; goto badframe;
return er0; return er0;
badframe: badframe:
...@@ -300,36 +277,23 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused,...) ...@@ -300,36 +277,23 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
return 0; return 0;
} }
static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
unsigned long mask) unsigned long mask)
{ {
sc->sc_mask = mask;
sc->sc_usp = rdusp();
sc->sc_er0 = regs->er0;
sc->sc_er1 = regs->er1;
sc->sc_er2 = regs->er2;
sc->sc_er3 = regs->er3;
sc->sc_er5 = regs->er5;
sc->sc_ccr = regs->ccr;
sc->sc_pc = regs->pc;
}
static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
{
greg_t *gregs = uc->uc_mcontext.gregs;
int err = 0; int err = 0;
err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); err |= __put_user(regs->er0, &sc->sc_er0);
err |= __put_user(regs->er0, &gregs[0]); err |= __put_user(regs->er1, &sc->sc_er1);
err |= __put_user(regs->er1, &gregs[1]); err |= __put_user(regs->er2, &sc->sc_er2);
err |= __put_user(regs->er2, &gregs[2]); err |= __put_user(regs->er3, &sc->sc_er3);
err |= __put_user(regs->er3, &gregs[3]); err |= __put_user(regs->er4, &sc->sc_er4);
err |= __put_user(regs->er4, &gregs[4]); err |= __put_user(regs->er5, &sc->sc_er5);
err |= __put_user(regs->er5, &gregs[5]); err |= __put_user(regs->er6, &sc->sc_er6);
err |= __put_user(regs->er6, &gregs[6]); err |= __put_user(rdusp(), &sc->sc_usp);
err |= __put_user(rdusp(), &gregs[7]); err |= __put_user(regs->pc, &sc->sc_pc);
err |= __put_user(regs->pc, &gregs[8]); err |= __put_user(regs->ccr, &sc->sc_ccr);
err |= __put_user(regs->ccr, &gregs[9]); err |= __put_user(mask, &sc->sc_mask);
return err; return err;
} }
...@@ -353,26 +317,48 @@ static void setup_frame (int sig, struct k_sigaction *ka, ...@@ -353,26 +317,48 @@ static void setup_frame (int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs *regs) sigset_t *set, struct pt_regs *regs)
{ {
struct sigframe *frame; struct sigframe *frame;
struct sigcontext context;
int err = 0; int err = 0;
int usig;
unsigned char *ret;
frame = get_sigframe(ka, regs, sizeof(*frame)); frame = get_sigframe(ka, regs, sizeof(*frame));
if (_NSIG_WORDS > 1) if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
err |= copy_to_user(frame->extramask, &set->sig[1], goto give_sigsegv;
sizeof(frame->extramask));
setup_sigcontext(&context, regs, set->sig[0]); usig = current_thread_info()->exec_domain
err |= copy_to_user (&frame->sc, &context, sizeof(context)); && current_thread_info()->exec_domain->signal_invmap
&& sig < 32
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
/* Set up to return from userspace. */ err |= __put_user(usig, &frame->sig);
err |= __put_user(frame->retcode, &frame->pretcode); if (err)
goto give_sigsegv;
err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
if (err)
goto give_sigsegv;
if (_NSIG_WORDS > 1) {
err |= copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask));
if (err)
goto give_sigsegv;
}
ret = frame->retcode;
if (ka->sa.sa_flags & SA_RESTORER)
ret = (unsigned char *)(ka->sa.sa_restorer);
else {
/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
(unsigned long *)(frame->retcode + 0)); (unsigned long *)(frame->retcode + 0));
err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
}
/* Set up to return from userspace. */
err |= __put_user(ret, &frame->pretcode);
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
...@@ -399,10 +385,29 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -399,10 +385,29 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
{ {
struct rt_sigframe *frame; struct rt_sigframe *frame;
int err = 0; int err = 0;
int usig;
unsigned char *ret;
frame = get_sigframe(ka, regs, sizeof(*frame)); frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
usig = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
&& sig < 32
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
err |= __put_user(usig, &frame->sig);
if (err)
goto give_sigsegv;
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
err |= copy_siginfo_to_user(&frame->info, info); err |= copy_siginfo_to_user(&frame->info, info);
if (err)
goto give_sigsegv;
/* Create the ucontext. */ /* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags); err |= __put_user(0, &frame->uc.uc_flags);
...@@ -412,16 +417,22 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -412,16 +417,22 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(sas_ss_flags(rdusp()), err |= __put_user(sas_ss_flags(rdusp()),
&frame->uc.uc_stack.ss_flags); &frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= rt_setup_ucontext(&frame->uc, regs); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
goto give_sigsegv;
/* Set up to return from userspace. */ /* Set up to return from userspace. */
err |= __put_user(frame->retcode, &frame->pretcode); ret = frame->retcode;
if (ka->sa.sa_flags & SA_RESTORER)
/* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */ ret = (unsigned char *)(ka->sa.sa_restorer);
err != __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff), else {
(long *)(frame->retcode + 0)); /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
err |= __put_user(0x5700, (short *)(frame->retcode + 4)); err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
(unsigned long *)(frame->retcode + 0));
err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
}
err |= __put_user(ret, &frame->pretcode);
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
...@@ -444,41 +455,32 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -444,41 +455,32 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
force_sigsegv(sig, current); force_sigsegv(sig, current);
} }
static inline void /*
handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) * OK, we're invoking a handler
*/
static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
sigset_t *oldset, struct pt_regs * regs)
{ {
/* are we from a system call? */
if (regs->orig_er0 >= 0) {
switch (regs->er0) { switch (regs->er0) {
case -ERESTART_RESTARTBLOCK:
case -ERESTARTNOHAND: case -ERESTARTNOHAND:
if (!has_handler)
goto do_restart;
regs->er0 = -EINTR; regs->er0 = -EINTR;
break; break;
case -ERESTARTSYS: case -ERESTARTSYS:
if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { if (!(ka->sa.sa_flags & SA_RESTART)) {
regs->er0 = -EINTR; regs->er0 = -EINTR;
break; break;
} }
/* fallthrough */ /* fallthrough */
case -ERESTARTNOINTR: case -ERESTARTNOINTR:
do_restart:
regs->er0 = regs->orig_er0; regs->er0 = regs->orig_er0;
regs->pc -= 2; regs->pc -= 2;
break;
} }
} }
/*
* OK, we're invoking a handler
*/
static void
handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
/* are we from a system call? */
if (regs->orig_er0 >= 0)
/* If so, check system call restarting.. */
handle_restart(regs, ka, 1);
/* set up the stack frame */ /* set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO) if (ka->sa.sa_flags & SA_SIGINFO)
...@@ -486,9 +488,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -486,9 +488,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
else else
setup_frame(sig, ka, oldset, regs); setup_frame(sig, ka, oldset, regs);
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NODEFER)) { if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
...@@ -502,137 +501,52 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -502,137 +501,52 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
* Note that 'init' is a special process: it doesn't get signals it doesn't * 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 * want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake. * 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.
*/ */
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
{ {
siginfo_t info; siginfo_t info;
struct k_sigaction *ka;
current->thread.esp0 = (unsigned long) regs;
if (!oldset)
oldset = &current->blocked;
for (;;) {
int signr; int signr;
struct k_sigaction ka;
signr = get_signal_to_deliver(&info, regs, NULL); /*
* We want the common case to go fast, which
if (!signr) * is why we may in certain cases get here from
break; * kernel mode. Just return without doing anything
* if so.
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { */
current->exit_code = signr; if ((regs->ccr & 0x10))
current->state = TASK_STOPPED; return 1;
/* Did we come from a system call? */
if (regs->orig_er0 >= 0) {
/* Restart the system call the same way as
if the process were not traced. */
struct k_sigaction *ka =
&current->sighand->action[signr-1];
int has_handler =
(ka->sa.sa_handler != SIG_IGN &&
ka->sa.sa_handler != SIG_DFL);
handle_restart(regs, ka, has_handler);
}
notify_parent(current, SIGCHLD);
schedule();
/* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code)) {
discard_frame:
continue;
}
current->exit_code = 0;
/* The debugger continued. Ignore SIGSTOP. */
if (signr == SIGSTOP)
goto discard_frame;
/* Update the siginfo structure. Is this good? */
if (signr != info.si_signo) {
info.si_signo = signr;
info.si_errno = 0;
info.si_code = SI_USER;
info.si_pid = current->parent->pid;
info.si_uid = current->parent->uid;
}
/* If the (new) signal is now blocked, requeue it. */
if (sigismember(&current->blocked, signr)) {
send_sig_info(signr, &info, current);
continue;
}
}
ka = &current->sighand->action[signr-1];
if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
/* Check for SIGCHLD: it's special. */
while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
/* nothing */;
continue;
}
if (ka->sa.sa_handler == SIG_DFL) { if (current->flags & PF_FREEZE) {
int exit_code = signr; refrigerator(0);
goto no_signal;
if (current->pid == 1)
continue;
switch (signr) {
case SIGCONT: case SIGCHLD:
case SIGWINCH: case SIGURG:
continue;
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(process_group(current)))
continue;
/* FALLTHRU */
case SIGSTOP: {
struct sighand_struct *sig;
current->state = TASK_STOPPED;
current->exit_code = signr;
sig = current->parent->sighand;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags
& SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
continue;
} }
case SIGQUIT: case SIGILL: case SIGTRAP: current->thread.esp0 = (unsigned long) regs;
case SIGIOT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, exit_code, regs))
exit_code |= 0x80;
/* FALLTHRU */
default: if (!oldset)
sigaddset(&current->pending.signal, signr); oldset = &current->blocked;
recalc_sigpending();
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOTREACHED */
}
}
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
handle_signal(signr, ka, &info, oldset, regs); handle_signal(signr, &info, &ka, oldset, regs);
return 1; return 1;
} }
no_signal:
/* Did we come from a system call? */ /* Did we come from a system call? */
if (regs->orig_er0 >= 0) if (regs->orig_er0 >= 0) {
/* Restart the system call - no handlers present */ /* Restart the system call - no handlers present */
handle_restart(regs, NULL, 0); if (regs->er0 == -ERESTARTNOHAND ||
regs->er0 == -ERESTARTSYS ||
regs->er0 == -ERESTARTNOINTR) {
regs->er0 = regs->orig_er0;
regs->pc -= 2;
}
if (regs->er0 == -ERESTART_RESTARTBLOCK){
regs->er0 = __NR_restart_syscall;
regs->pc -= 2;
}
}
return 0; return 0;
} }
...@@ -247,9 +247,9 @@ SYMBOL_NAME_LABEL(ret_from_interrupt) ...@@ -247,9 +247,9 @@ SYMBOL_NAME_LABEL(ret_from_interrupt)
mov.l @(TI_FLAGS:16,er4),er1 mov.l @(TI_FLAGS:16,er4),er1
btst #TIF_NEED_RESCHED,r1l btst #TIF_NEED_RESCHED,r1l
bne SYMBOL_NAME(reschedule):16 bne SYMBOL_NAME(reschedule):16
mov.l sp,er1 mov.l sp,er0
subs #4,er1 /* adjust retpc */ subs #4,er0 /* adjust retpc */
mov.l er2,er0 mov.l er2,er1
jsr @SYMBOL_NAME(do_signal) jsr @SYMBOL_NAME(do_signal)
#if defined(CONFIG_PREEMPT) #if defined(CONFIG_PREEMPT)
bra done:8 /* userspace thoru */ bra done:8 /* userspace thoru */
......
...@@ -244,9 +244,9 @@ SYMBOL_NAME_LABEL(ret_from_interrupt) ...@@ -244,9 +244,9 @@ SYMBOL_NAME_LABEL(ret_from_interrupt)
mov.l @(TI_FLAGS:16,er4),er1 mov.l @(TI_FLAGS:16,er4),er1
btst #TIF_NEED_RESCHED,r1l btst #TIF_NEED_RESCHED,r1l
bne SYMBOL_NAME(reschedule):16 bne SYMBOL_NAME(reschedule):16
mov.l sp,er1 mov.l sp,er0
subs #4,er1 /* adjust retpc */ subs #4,er0 /* adjust retpc */
mov.l er2,er0 mov.l er2,er1
jsr @SYMBOL_NAME(do_signal) jsr @SYMBOL_NAME(do_signal)
#if defined(CONFIG_PREEMPT) #if defined(CONFIG_PREEMPT)
bra done:8 /* userspace thoru */ bra done:8 /* userspace thoru */
......
...@@ -8,7 +8,9 @@ struct sigcontext { ...@@ -8,7 +8,9 @@ struct sigcontext {
unsigned long sc_er1; unsigned long sc_er1;
unsigned long sc_er2; unsigned long sc_er2;
unsigned long sc_er3; unsigned long sc_er3;
unsigned long sc_er4;
unsigned long sc_er5; unsigned long sc_er5;
unsigned long sc_er6;
unsigned short sc_ccr; unsigned short sc_ccr;
unsigned long sc_pc; unsigned long sc_pc;
}; };
......
...@@ -96,6 +96,8 @@ typedef unsigned long sigset_t; ...@@ -96,6 +96,8 @@ typedef unsigned long sigset_t;
#define SA_ONESHOT SA_RESETHAND #define SA_ONESHOT SA_RESETHAND
#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ #define SA_INTERRUPT 0x20000000 /* dummy -- ignored */
#define SA_RESTORER 0x04000000
/* /*
* sigaltstack controls * sigaltstack controls
*/ */
......
#ifndef _H8300_UCONTEXT_H #ifndef _H8300_UCONTEXT_H
#define _H8300_UCONTEXT_H #define _H8300_UCONTEXT_H
typedef int greg_t;
#define NGREG 10
typedef greg_t gregset_t[NGREG];
struct mcontext {
int version;
gregset_t gregs;
};
#define MCONTEXT_VERSION 1
struct ucontext { struct ucontext {
unsigned long uc_flags; unsigned long uc_flags;
struct ucontext *uc_link; struct ucontext *uc_link;
stack_t uc_stack; stack_t uc_stack;
struct mcontext uc_mcontext; struct sigcontext uc_mcontext;
sigset_t uc_sigmask; /* mask last for extensibility */ sigset_t uc_sigmask; /* mask last for extensibility */
}; };
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* This file contains the system call numbers. * This file contains the system call numbers.
*/ */
#define __NR_restart_syscall 0
#define __NR_exit 1 #define __NR_exit 1
#define __NR_fork 2 #define __NR_fork 2
#define __NR_read 3 #define __NR_read 3
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment