[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 15/16] [RFC] linux-user: add support for multiplexin
From: |
Miloš Stojanović |
Subject: |
[Qemu-devel] [PATCH 15/16] [RFC] linux-user: add support for multiplexing larger target signals |
Date: |
Fri, 12 May 2017 13:02:23 +0200 |
Add MUX_SIG as a multiplex signal number for all target signals which are
out of the host range. Add support for multiplexing in do_sigaction(),
process_pending_signals(), target_set_sigmask() and do_target_sigprocmask().
This patch solves the problem of unusable target signals which are out of
the host range. This is done by enabling the usage of one of the host
signals (MUX_SIG) as a multiplex for all the target signals that are out
of range. In order to have the target signal masks available
TRACK_TARGET_MASK is defined which enables the tracking of the target
signals masks.
The table of signal handlers already supports the whole range of target
signals. In the do_sigaction() function the signal number of signals which
are out of range are replaced by MUX_SIG which bypasses the error from the
host system and doesn't interfere with signal handling on the target.
Since the MUX_SIG is used as a multiplex, it must never be blocked on host,
so support for emulating the blocking of this signal is added. This is done
by only blocking MUX_SIG in the target mask and retrieving its status from
there when it's needed.
Signed-off-by: Miloš Stojanović <address@hidden>
---
linux-user/signal.c | 32 ++++++++++++++++++++++++++++++++
linux-user/syscall_defs.h | 20 ++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9d4ad43..3d51424 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -308,6 +308,15 @@ int do_target_sigprocmask(int how, const target_sigset_t
*target_set,
}
if (oldset) {
*oldset = ts->signal_mask;
+#ifdef MUX_SIG
+ /*
+ * The emulation of MUX_SIG being blocked is done using the
+ * target_signal_mask, so the status of MUX_SIG is taken from there.
+ */
+ if (target_sigismember(&ts->target_signal_mask, MUX_SIG) == 1) {
+ sigaddset(oldset, MUX_SIG);
+ }
+#endif
}
if (target_set && set) {
@@ -348,6 +357,15 @@ int do_target_sigprocmask(int how, const target_sigset_t
*target_set,
target_sigdelset(&ts->target_signal_mask, SIGSTOP);
sigdelset(&ts->signal_mask, SIGKILL);
sigdelset(&ts->signal_mask, SIGSTOP);
+#ifdef MUX_SIG
+ /*
+ * Since MUX_SIG is used for all the target signals out of the host
+ * range it must never be blocked on host. The emulation of MUX_SIG
+ * being blocked is done using the target_signal_mask. The status
+ * of MUX_SIG is taken form the target_signal_mask.
+ */
+ sigdelset(&ts->signal_mask, MUX_SIG);
+#endif
}
return 0;
}
@@ -373,6 +391,10 @@ static void target_set_sigmask(const sigset_t *set,
ts->signal_mask = *set;
ts->target_signal_mask = *target_set;
+#ifdef MUX_SIG
+ /* MUX_SIG can't be blocked on host */
+ sigdelset(&ts->signal_mask, MUX_SIG);
+#endif
}
#endif
#endif
@@ -909,6 +931,12 @@ int do_sigaction(int sig, const struct target_sigaction
*act,
/* we update the host linux signal state */
host_sig = target_to_host_signal(sig);
+#ifdef MUX_SIG
+ /* put the out of host range signal into the multiplex */
+ if (sig >= _NSIG && sig < TARGET_NSIG) {
+ host_sig = MUX_SIG;
+ }
+#endif
if (host_sig != SIGSEGV && host_sig != SIGBUS) {
sigfillset(&act1.sa_mask);
act1.sa_flags = SA_SIGINFO;
@@ -6841,6 +6869,10 @@ void process_pending_signals(CPUArchState *cpu_env)
set = ts->signal_mask;
sigdelset(&set, SIGSEGV);
sigdelset(&set, SIGBUS);
+#ifdef MUX_SIG
+ /* MUX_SIG can't be blocked on host */
+ sigdelset(&ts->signal_mask, MUX_SIG);
+#endif
sigprocmask(SIG_SETMASK, &set, 0);
}
ts->in_sigsuspend = 0;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 7eec420..42089fc 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -394,6 +394,26 @@ struct target_dirent64 {
#define TARGET_NSIG_BPW TARGET_ABI_BITS
#define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW)
+#if _NSIG <= TARGET_NSIG
+/*
+ * MUX_SIG is used as a multiplex signal number - signals that are
+ * out of the host range and in the target range are sent through it.
+ * It is defined as the maximal available real-time signal in order to
+ * comply with the rule that low-numbered signals have highest priority.
+ * (signals using it will have the same priority but it will be smaller
+ * than all the other real-time signals)
+ * SIGRMTAX is avoided so it doesn't interfere with the hack of reversing
+ * __SIGRTMIN and __SIGRTMAX in the host_to_target_signal_table.
+ */
+#define MUX_SIG (SIGRTMAX - 1)
+
+/*
+ * The target signal masks must be tracked since they are larger than
+ * the host signal masks.
+ */
+#define TRACK_TARGET_SIGMASK
+#endif
+
typedef struct {
abi_ulong sig[TARGET_NSIG_WORDS];
} target_sigset_t;
--
1.9.1
- [Qemu-devel] [PATCH 03/16] linux-user: fix ssetmask() system call, (continued)
- [Qemu-devel] [PATCH 03/16] linux-user: fix ssetmask() system call, Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 08/16] linux-user: fix inconsistent spaces in print_siginfo() output, Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 12/16] [RFC] linux-user: fix sigismember() check, Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 01/16] linux-user: add strace for getuid(), gettid(), getppid(), geteuid(), Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 10/16] [RFC] linux-user: add support for tracking the target signal mask, Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 05/16] linux-user: fix argument type declaration of rt_sigqueinfo() syscall, Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 02/16] linux-user: add tkill(), tgkill() and rt_sigqueueinfo() strace, Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 11/16] [RFC] linux-user: add target_sigdelset() and target_sigorset(), Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 06/16] linux-user: add support for rt_tgsigqueueinfo() system call, Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 04/16] linux-user: fix mismatch of lock/unlock_user() invocations in rt_sigqueinfo() syscall, Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 15/16] [RFC] linux-user: add support for multiplexing larger target signals,
Miloš Stojanović <=
- [Qemu-devel] [PATCH 09/16] linux-user: add strace support for uinfo structure of rt_sigqueueinfo() and rt_tgsigqueueinfo(), Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 16/16] [RFC] linux-user: add support for multiplexing signals in rt_sigqueueinfo(), rt_tgsigqueueinfo(), kill() and tgkill() syscalls., Miloš Stojanović, 2017/05/12
- [Qemu-devel] [PATCH 14/16] [RFC] linux-user: add functionality for tracking target signal mask, Miloš Stojanović, 2017/05/12
- Re: [Qemu-devel] [PATCH 00/16] Augment support for signal handling, no-reply, 2017/05/12