Commit df313e15 authored by Richard Weinberger's avatar Richard Weinberger Committed by Luis Henriques

kernel/signal.c: unexport sigsuspend()

commit 9d8a7652 upstream.

sigsuspend() is nowhere used except in signal.c itself, so we can mark it
static do not pollute the global namespace.

But this patch is more than a boring cleanup patch, it fixes a real issue
on UserModeLinux.  UML has a special console driver to display ttys using
xterm, or other terminal emulators, on the host side.  Vegard reported
that sometimes UML is unable to spawn a xterm and he's facing the
following warning:

  WARNING: CPU: 0 PID: 908 at include/linux/thread_info.h:128 sigsuspend+0xab/0xc0()

It turned out that this warning makes absolutely no sense as the UML
xterm code calls sigsuspend() on the host side, at least it tries.  But
as the kernel itself offers a sigsuspend() symbol the linker choose this
one instead of the glibc wrapper.  Interestingly this code used to work
since ever but always blocked signals on the wrong side.  Some recent
kernel change made the WARN_ON() trigger and uncovered the bug.

It is a wonderful example of how much works by chance on computers. :-)

Fixes: 68f3f16d ("new helper: sigsuspend()")
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
Reported-by: default avatarVegard Nossum <vegard.nossum@oracle.com>
Tested-by: default avatarVegard Nossum <vegard.nossum@oracle.com>
Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 6063adde
...@@ -242,7 +242,6 @@ extern int sigprocmask(int, sigset_t *, sigset_t *); ...@@ -242,7 +242,6 @@ extern int sigprocmask(int, sigset_t *, sigset_t *);
extern void set_current_blocked(sigset_t *); extern void set_current_blocked(sigset_t *);
extern void __set_current_blocked(const sigset_t *); extern void __set_current_blocked(const sigset_t *);
extern int show_unhandled_signals; extern int show_unhandled_signals;
extern int sigsuspend(sigset_t *);
struct sigaction { struct sigaction {
#ifndef __ARCH_HAS_IRIX_SIGACTION #ifndef __ARCH_HAS_IRIX_SIGACTION
......
...@@ -3547,7 +3547,7 @@ SYSCALL_DEFINE0(pause) ...@@ -3547,7 +3547,7 @@ SYSCALL_DEFINE0(pause)
#endif #endif
int sigsuspend(sigset_t *set) static int sigsuspend(sigset_t *set)
{ {
current->saved_sigmask = current->blocked; current->saved_sigmask = current->blocked;
set_current_blocked(set); set_current_blocked(set);
......
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