[PATCH] uml: Move signal handlers to arch code
Have most signals go through an arch-provided handler which recovers the sigcontext and then calls a generic handler. This replaces the ARCH_GET_SIGCONTEXT macro, which was somewhat fragile. On x86_64, recovering %rdx (which holds the sigcontext pointer) must be the first thing that happens. sig_handler duly invokes that first, but there is no guarantee that I can see that instructions won't be reordered such that %rdx is used before that. Having the arch provide the handler seems much more robust. Some signals in some parts of UML require their own handlers - these places don't call set_handler any more. They call sigaction or signal themselves. Signed-off-by: Jeff Dike <jdike@addtoit.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
committed by
Linus Torvalds
parent
19bdf0409f
commit
4b84c69b5f
@ -15,7 +15,6 @@
|
||||
#include "user.h"
|
||||
#include "signal_kern.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "sysdep/signal.h"
|
||||
#include "sigcontext.h"
|
||||
#include "mode.h"
|
||||
#include "os.h"
|
||||
@ -38,18 +37,10 @@
|
||||
static int signals_enabled = 1;
|
||||
static int pending = 0;
|
||||
|
||||
void sig_handler(ARCH_SIGHDLR_PARAM)
|
||||
void sig_handler(int sig, struct sigcontext *sc)
|
||||
{
|
||||
struct sigcontext *sc;
|
||||
int enabled;
|
||||
|
||||
/* Must be the first thing that this handler does - x86_64 stores
|
||||
* the sigcontext in %rdx, and we need to save it before it has a
|
||||
* chance to get trashed.
|
||||
*/
|
||||
|
||||
ARCH_GET_SIGCONTEXT(sc, sig);
|
||||
|
||||
enabled = signals_enabled;
|
||||
if(!enabled && (sig == SIGIO)){
|
||||
pending |= SIGIO_MASK;
|
||||
@ -84,13 +75,10 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
|
||||
|
||||
}
|
||||
|
||||
void alarm_handler(ARCH_SIGHDLR_PARAM)
|
||||
void alarm_handler(int sig, struct sigcontext *sc)
|
||||
{
|
||||
struct sigcontext *sc;
|
||||
int enabled;
|
||||
|
||||
ARCH_GET_SIGCONTEXT(sc, sig);
|
||||
|
||||
enabled = signals_enabled;
|
||||
if(!signals_enabled){
|
||||
if(sig == SIGVTALRM)
|
||||
@ -126,6 +114,10 @@ void remove_sigstack(void)
|
||||
panic("disabling signal stack failed, errno = %d\n", errno);
|
||||
}
|
||||
|
||||
void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
|
||||
|
||||
extern void hard_handler(int sig);
|
||||
|
||||
void set_handler(int sig, void (*handler)(int), int flags, ...)
|
||||
{
|
||||
struct sigaction action;
|
||||
@ -133,13 +125,16 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
|
||||
sigset_t sig_mask;
|
||||
int mask;
|
||||
|
||||
va_start(ap, flags);
|
||||
action.sa_handler = handler;
|
||||
handlers[sig] = (void (*)(int, struct sigcontext *)) handler;
|
||||
action.sa_handler = hard_handler;
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
while((mask = va_arg(ap, int)) != -1){
|
||||
|
||||
va_start(ap, flags);
|
||||
while((mask = va_arg(ap, int)) != -1)
|
||||
sigaddset(&action.sa_mask, mask);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
action.sa_flags = flags;
|
||||
action.sa_restorer = NULL;
|
||||
if(sigaction(sig, &action, NULL) < 0)
|
||||
|
Reference in New Issue
Block a user