From 482db6df1746c4fa7d64a2441d4cb2610249c679 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 26 Oct 2010 14:21:13 -0700 Subject: um: fix global timer issue when using CONFIG_NO_HZ This fixes a issue which was introduced by fe2cc53e ("uml: track and make up lost ticks"). timeval_to_ns() returns long long and not int. Due to that UML's timer did not work properlt and caused timer freezes. Signed-off-by: Richard Weinberger Acked-by: Pekka Enberg Cc: Jeff Dike Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um/os-Linux') diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index dec5678fc17f..6e3359d6a839 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -60,7 +60,7 @@ static inline long long timeval_to_ns(const struct timeval *tv) long long disable_timer(void) { struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } }); - int remain, max = UM_NSEC_PER_SEC / UM_HZ; + long long remain, max = UM_NSEC_PER_SEC / UM_HZ; if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0) printk(UM_KERN_ERR "disable_timer - setitimer failed, " -- cgit v1.2.2 From b2db21997f43907f54500edaf063253ca2a186f9 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 17 May 2011 15:44:11 -0700 Subject: um: fix abort os_dump_core() uses abort() to terminate UML in case of an fatal error. glibc's abort() calls raise(SIGABRT) which makes use of tgkill(). tgkill() has no effect within UML's kernel threads because they are not pthreads. As fallback abort() executes an invalid instruction to terminate the process. Therefore UML gets killed by SIGSEGV and leaves a ugly log entry in the host's kernel ring buffer. To get rid of this we use our own abort routine. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/util.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'arch/um/os-Linux') diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 6ea77979531c..42827cafa6af 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -75,6 +76,26 @@ void setup_hostinfo(char *buf, int len) host.release, host.version, host.machine); } +/* + * We cannot use glibc's abort(). It makes use of tgkill() which + * has no effect within UML's kernel threads. + * After that glibc would execute an invalid instruction to kill + * the calling process and UML crashes with SIGSEGV. + */ +static inline void __attribute__ ((noreturn)) uml_abort(void) +{ + sigset_t sig; + + fflush(NULL); + + if (!sigemptyset(&sig) && !sigaddset(&sig, SIGABRT)) + sigprocmask(SIG_UNBLOCK, &sig, 0); + + for (;;) + if (kill(getpid(), SIGABRT) < 0) + exit(127); +} + void os_dump_core(void) { int pid; @@ -116,5 +137,5 @@ void os_dump_core(void) while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0) os_kill_ptraced_process(pid, 0); - abort(); + uml_abort(); } -- cgit v1.2.2 From 0ce451acb1872eab0fcf22753f93f51567e812fa Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 24 May 2011 17:13:00 -0700 Subject: um: fix UML_LIB_PATH UML_LIB_PATH is hardcoded to /usr/lib/uml/, on 64bit systems UML_LIB_PATH needs to be /usr/lib64/uml/. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um/os-Linux') diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index eee69b9f52c9..39613ea42196 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -78,7 +78,7 @@ static void install_fatal_handler(int sig) } } -#define UML_LIB_PATH ":/usr/lib/uml" +#define UML_LIB_PATH ":" OS_LIB_PATH "/uml" static void setup_env_path(void) { -- cgit v1.2.2 From 2525e70d492f8c7bbe1292db8fcd973607a56ac6 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 24 May 2011 17:13:00 -0700 Subject: um: remove SIGHUP handler The UML kernel ignores SIGHUP anyway. This handler is in vain. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/um/os-Linux') diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 39613ea42196..fb2a97a75fb1 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -142,7 +142,6 @@ int __init main(int argc, char **argv, char **envp) */ install_fatal_handler(SIGINT); install_fatal_handler(SIGTERM); - install_fatal_handler(SIGHUP); scan_elf_aux(envp); -- cgit v1.2.2 From d634f194d4e2e58d57927c812aca097e67a2287d Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 24 May 2011 17:13:01 -0700 Subject: um: add earlyprintk support User Mode Linux can also benefit from earlyprintk. UML's earlyprintk writes kernel messages directly to stdout. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/util.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/um/os-Linux') diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 42827cafa6af..5803b1887672 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -139,3 +139,8 @@ void os_dump_core(void) uml_abort(); } + +void um_early_printk(const char *s, unsigned int n) +{ + printf("%.*s", n, s); +} -- cgit v1.2.2 From db271cf03f5fe39feab8e1b1818c0880c7290c5c Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 24 May 2011 17:13:04 -0700 Subject: um: fix crash while os_dump_core() os_dump_core() emits SIGTERM to terminate all UML processes. Kernel threads have to exit on SIGTERM instead of calling last_ditch_exit(). Multiple calls to last_ditch_exit() can cause a crash. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/process.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/um/os-Linux') diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index e0477c3ee894..0c45dc8efb05 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -253,6 +253,7 @@ void init_new_thread_signals(void) SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); signal(SIGWINCH, SIG_IGN); + signal(SIGTERM, SIG_DFL); } int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr) -- cgit v1.2.2