Commit 6dc56113 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: make signal frame construction more resemble x86

From: Bodo Stroesser <bstroesser@fujitsu-siemens.com>

This makes the UML signal frame construction interface somewhat more similar
to x86 than before.  Also, some small code cleanup, and checking for errors
before changing the signal mask in the SA_NODEFER case.
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b0baa0f5
......@@ -10,13 +10,11 @@
#include "sysdep/frame_kern.h"
extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
unsigned long handler,
void (*restorer)(void),
struct k_sigaction *ka,
struct pt_regs *regs,
sigset_t *mask);
extern int setup_signal_stack_si(unsigned long stack_top, int sig,
unsigned long handler,
void (*restorer)(void),
struct k_sigaction *ka,
struct pt_regs *regs, siginfo_t *info,
sigset_t *mask);
......
......@@ -56,11 +56,11 @@ static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
}
int setup_signal_stack_si(unsigned long stack_top, int sig,
unsigned long handler, void (*restorer)(void),
struct pt_regs *regs, siginfo_t *info,
sigset_t *mask)
struct k_sigaction *ka, struct pt_regs *regs,
siginfo_t *info, sigset_t *mask)
{
unsigned long start;
void *restorer;
void *sip, *ucp, *fp;
start = stack_top - signal_frame_si.common.len;
......@@ -68,6 +68,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
ucp = (void *) (start + signal_frame_si.uc_index);
fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
restorer = NULL;
if(ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
if(restorer == NULL)
panic("setup_signal_stack_si - no restorer");
......@@ -85,21 +89,26 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
signal_frame_si.common.sr_relative))
return(1);
PT_REGS_IP(regs) = handler;
PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
return(0);
}
int setup_signal_stack_sc(unsigned long stack_top, int sig,
unsigned long handler, void (*restorer)(void),
struct pt_regs *regs, sigset_t *mask)
struct k_sigaction *ka, struct pt_regs *regs,
sigset_t *mask)
{
struct frame_common *frame = &signal_frame_sc_sr.common;
void *restorer;
void *user_sc;
int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
unsigned long sigs, sr;
unsigned long start = stack_top - frame->len - sig_size;
restorer = NULL;
if(ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
if(restorer == NULL){
frame = &signal_frame_sc.common;
......@@ -121,7 +130,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
return(1);
PT_REGS_IP(regs) = handler;
PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
PT_REGS_SP(regs) = start + frame->sp_index;
return(0);
......
......@@ -42,7 +42,6 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset)
{
void (*restorer)(void);
unsigned long sp;
int err;
......@@ -75,20 +74,12 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
else restorer = NULL;
if(ka->sa.sa_flags & SA_SIGINFO)
err = setup_signal_stack_si(sp, signr,
(unsigned long) ka->sa.sa_handler,
restorer, regs, info, oldset);
err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
else
err = setup_signal_stack_sc(sp, signr,
(unsigned long) ka->sa.sa_handler,
restorer, regs, oldset);
err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
if (!(ka->sa.sa_flags & SA_NODEFER)) {
if (!err && !(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked, &current->blocked,
&ka->sa.sa_mask);
......@@ -107,9 +98,6 @@ static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset)
siginfo_t info;
int sig;
if (!oldset)
oldset = &current->blocked;
sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL);
if(sig > 0){
/* Whee! Actually deliver the signal. */
......@@ -147,7 +135,7 @@ static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset)
int do_signal(void)
{
return(kern_do_signal(&current->thread.regs, NULL));
return(kern_do_signal(&current->thread.regs, &current->blocked));
}
/*
......
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