Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b84c69b authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds
Browse files

[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: 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 19bdf040
Loading
Loading
Loading
Loading
+0 −27
Original line number Diff line number Diff line
/*
 * Copyright (C) 2004 PathScale, Inc
 * Licensed under the GPL
 */

#ifndef __I386_SIGNAL_H_
#define __I386_SIGNAL_H_

#include <signal.h>

#define ARCH_SIGHDLR_PARAM int sig

#define ARCH_GET_SIGCONTEXT(sc, sig) \
	do sc = (struct sigcontext *) (&sig + 1); while(0)

#endif

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
+0 −29
Original line number Diff line number Diff line
/*
 * Copyright (C) 2004 PathScale, Inc
 * Licensed under the GPL
 */

#ifndef __X86_64_SIGNAL_H_
#define __X86_64_SIGNAL_H_

#define ARCH_SIGHDLR_PARAM int sig

#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
	do { \
		struct ucontext *__uc; \
		asm("movq %%rdx, %0" : "=r" (__uc)); \
		sc = (struct sigcontext *) &__uc->uc_mcontext; \
	} while(0)

#endif

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
+1 −1
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ void os_set_pollfd(int i, int fd)

void os_set_ioignore(void)
{
	set_handler(SIGIO, SIG_IGN, 0, -1);
	signal(SIGIO, SIG_IGN);
}

void init_irq_signals(int on_sigstack)
+28 −6
Original line number Diff line number Diff line
@@ -67,13 +67,32 @@ static __init void do_uml_initcalls(void)

static void last_ditch_exit(int sig)
{
	signal(SIGINT, SIG_DFL);
	signal(SIGTERM, SIG_DFL);
	signal(SIGHUP, SIG_DFL);
	uml_cleanup();
	exit(1);
}

static void install_fatal_handler(int sig)
{
	struct sigaction action;

	/* All signals are enabled in this handler ... */
	sigemptyset(&action.sa_mask);

	/* ... including the signal being handled, plus we want the
	 * handler reset to the default behavior, so that if an exit
	 * handler is hanging for some reason, the UML will just die
	 * after this signal is sent a second time.
	 */
	action.sa_flags = SA_RESETHAND | SA_NODEFER;
	action.sa_restorer = NULL;
	action.sa_handler = last_ditch_exit;
	if(sigaction(sig, &action, NULL) < 0){
		printf("failed to install handler for signal %d - errno = %d\n",
		       errno);
		exit(1);
	}
}

#define UML_LIB_PATH	":/usr/lib/uml"

static void setup_env_path(void)
@@ -158,9 +177,12 @@ int main(int argc, char **argv, char **envp)
	}
	new_argv[argc] = NULL;

	set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
	set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
	set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
	/* Allow these signals to bring down a UML if all other
	 * methods of control fail.
	 */
	install_fatal_handler(SIGINT);
	install_fatal_handler(SIGTERM);
	install_fatal_handler(SIGHUP);

	scan_elf_aux( envp);

+11 −1
Original line number Diff line number Diff line
@@ -246,7 +246,17 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
		set_sigstack(sig_stack, pages * page_size());
		flags = SA_ONSTACK;
	}
	if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
	if(usr1_handler){
		struct sigaction sa;

		sa.sa_handler = usr1_handler;
		sigemptyset(&sa.sa_mask);
		sa.sa_flags = flags;
		sa.sa_restorer = NULL;
		if(sigaction(SIGUSR1, &sa, NULL) < 0)
			panic("init_new_thread_stack - sigaction failed - "
			      "errno = %d\n", errno);
	}
}

void init_new_thread_signals(void)
Loading