From nobody Mon Apr 29 07:27:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1558551653; cv=none; d=zoho.com; s=zohoarc; b=VMP03GzMkX/W3uK/ebLaBm5A8UisSp4w5MtFaO8lt6lwvmXsMc2gWRAp2AQrEEMAeUrquD9c9qTfQeM5O2bc9BT2HHkyNUYfiG7vtfNmh3BdAYGmmlac4VOdei55tYzW2fxKeVEVIg5vwrQbYESd09EXM6nuWrhUEMKIPyygabg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558551653; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=1E4rpd8McjbGhDkPcnggxuk1nqo2LuYy41OtRa6UoIU=; b=RpZHGLygPaj1AUf4ePgKYLKaHT9hFhHXrzoMiIJw9Ws13XZPAYrk25jnXfditpJ+7pkrMqdlcTNczlczdzhPPN3nsriCst2m5JI6bGju4gpa2oeJNVtYl9hr+rVYTrFLoXSy6bsnv1WWklNqRyNYIC2xvY4tD4KOLdr7QTbstMo= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155855165335840.81027719239728; Wed, 22 May 2019 12:00:53 -0700 (PDT) Received: from localhost ([127.0.0.1]:49689 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWTo-00047H-Bb for importer@patchew.org; Wed, 22 May 2019 15:00:48 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34795) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWOY-00086e-If for qemu-devel@nongnu.org; Wed, 22 May 2019 14:55:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hTWHS-0002MI-Fc for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:03 -0400 Received: from mx2.rt-rk.com ([89.216.37.149]:47800 helo=mail.rt-rk.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hTWHS-0001mm-96 for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:02 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.rt-rk.com (Postfix) with ESMTP id 0C1E61A4516; Wed, 22 May 2019 20:46:58 +0200 (CEST) Received: from rtrkw774-lin.domain.local (rtrkw774-lin.domain.local [10.10.13.43]) by mail.rt-rk.com (Postfix) with ESMTPSA id E759D1A2238; Wed, 22 May 2019 20:46:57 +0200 (CEST) X-Virus-Scanned: amavisd-new at rt-rk.com From: Aleksandar Markovic To: qemu-devel@nongnu.org Date: Wed, 22 May 2019 20:46:21 +0200 Message-Id: <1558550785-20098-2-git-send-email-aleksandar.markovic@rt-rk.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> References: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 89.216.37.149 Subject: [Qemu-devel] [PATCH 1/5] linux-user: Fix sigismember() check X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, =?UTF-8?q?Milo=C5=A1=20Stojanovi=C4=87?= , amarkovic@wavecomp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Milo=C5=A1 Stojanovi=C4=87 Fix copying between the host and target signal sets for the case when the target set is larger than the host set. sigismember() returns 1 if the specified signal number is a member of the specified signal set, but it can also return -1 if an error occurs (e.g. an out of range signal number is specified). All non-zero values would cause the signal to be added, so a comparison with 1 is added to assure that only the signals which are really in the set get added to the other set. Signed-off-by: Milo=C5=A1 Stojanovi=C4=87 Signed-off-by: Aleksandar Markovic --- linux-user/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index 44b2d3b..c08a7fe 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -116,7 +116,7 @@ void host_to_target_sigset_internal(target_sigset_t *d, int i; target_sigemptyset(d); for (i =3D 1; i <=3D TARGET_NSIG; i++) { - if (sigismember(s, i)) { + if (sigismember(s, i) =3D=3D 1) { target_sigaddset(d, host_to_target_signal(i)); } } --=20 2.7.4 From nobody Mon Apr 29 07:27:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1558551469; cv=none; d=zoho.com; s=zohoarc; b=KTyMJOut8Si0q2zp0ZuMBZBdwUfLhxRrmrEvLhHrtXAi61NRte+f9PegdOLMMWUzSeu0EAFbnfHWrmF3ylOCDKqkYsDJ8+3cZYjmnvsvXZmmtBmH0lp5M/taZdbfj589OCuaBGgh63HjDPoJuwXbMdddkKz0DuPwKcWiUAlW8Zk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558551469; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=qVzzTHY4+ivFtCM+CZPgcQWiIIiiyuCVdM+UDxEG3Hw=; b=ex+ybpoG3EqLfKOCiA6+gk6VSElXaxUJCOXrYPJt7co346umgKA3xa83gLDs5sHITs3O2TeT0RoWqqHGrBKEkQW6UzauN0LYJ7LQ2itBcAw2q8EsdSJLdABnVAVsorKyp3OtuaLRQEid+JsfSfAXaO+BGW6eIXIsl3BDrB75G6c= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558551469254449.46279177204997; Wed, 22 May 2019 11:57:49 -0700 (PDT) Received: from localhost ([127.0.0.1]:49647 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWQj-0001Ve-53 for importer@patchew.org; Wed, 22 May 2019 14:57:37 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34793) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWOX-00086d-Lt for qemu-devel@nongnu.org; Wed, 22 May 2019 14:55:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hTWHc-0002Re-A3 for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:13 -0400 Received: from mx2.rt-rk.com ([89.216.37.149]:47878 helo=mail.rt-rk.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hTWHc-0001t5-3U for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:12 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.rt-rk.com (Postfix) with ESMTP id 044B51A452D; Wed, 22 May 2019 20:47:09 +0200 (CEST) Received: from rtrkw774-lin.domain.local (rtrkw774-lin.domain.local [10.10.13.43]) by mail.rt-rk.com (Postfix) with ESMTPSA id DF8DC1A2238; Wed, 22 May 2019 20:47:08 +0200 (CEST) X-Virus-Scanned: amavisd-new at rt-rk.com From: Aleksandar Markovic To: qemu-devel@nongnu.org Date: Wed, 22 May 2019 20:46:22 +0200 Message-Id: <1558550785-20098-3-git-send-email-aleksandar.markovic@rt-rk.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> References: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 89.216.37.149 Subject: [Qemu-devel] [PATCH 2/5] linux-user: Add support for tracking the target signal mask X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, =?UTF-8?q?Milo=C5=A1=20Stojanovi=C4=87?= , amarkovic@wavecomp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Milo=C5=A1 Stojanovi=C4=87 If TRACK_TARGET_SIGMASK is defined, add fields in the TaskState structure which will hold the target signal and suspend mask and add support for initialization and forking. No functional changes are being introduced in this commit. The TRACK_TARGET_SIGMASK will be defined in a later commit where the target signal masks will be needed in order to implement multiplexing of real-time target signals which are out of the host range. Currently, QEMU has a copy of the host signal and suspend masks and that is usually enough, since most of the time the signal mask of the target architecture is either the same length or narrower. If however the signal mask is wider, then part of it won't be tracked. This commit enables adding support for separately tracking the target signal masks in the following commits. Signed-off-by: Milo=C5=A1 Stojanovi=C4=87 Signed-off-by: Aleksandar Markovic --- linux-user/qemu.h | 5 +++++ linux-user/signal.c | 3 +++ linux-user/syscall.c | 3 +++ 3 files changed, 11 insertions(+) diff --git a/linux-user/qemu.h b/linux-user/qemu.h index ef400cb..9f70996 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -141,6 +141,11 @@ typedef struct TaskState { * currently in the middle of such a syscall */ sigset_t sigsuspend_mask; +#ifdef TRACK_TARGET_SIGMASK + /* Track the target signal and suspend masks. */ + target_sigset_t target_signal_mask; + target_sigset_t target_sigsuspend_mask; +#endif /* Nonzero if we're leaving a sigsuspend and sigsuspend_mask is valid.= */ int in_sigsuspend; =20 diff --git a/linux-user/signal.c b/linux-user/signal.c index c08a7fe..954aef8 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -499,6 +499,9 @@ void signal_init(void) =20 /* Set the signal mask from the host mask. */ sigprocmask(0, 0, &ts->signal_mask); +#ifdef TRACK_TARGET_SIGMASK + host_to_target_sigset_internal(&ts->target_signal_mask, &ts->signal_ma= sk); +#endif =20 /* set all host signal handlers. ALL signals are blocked during the handlers to serialize them. */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index efa3ec2..115ab13 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5540,6 +5540,9 @@ static int do_fork(CPUArchState *env, unsigned int fl= ags, abi_ulong newsp, ts->bprm =3D parent_ts->bprm; ts->info =3D parent_ts->info; ts->signal_mask =3D parent_ts->signal_mask; +#ifdef TRACK_TARGET_SIGMASK + ts->target_signal_mask =3D parent_ts->target_signal_mask; +#endif =20 if (flags & CLONE_CHILD_CLEARTID) { ts->child_tidptr =3D child_tidptr; --=20 2.7.4 From nobody Mon Apr 29 07:27:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1558551887; cv=none; d=zoho.com; s=zohoarc; b=SkvoX75qJNESyvaFwlIbncK+oITzoUfW9nvEuuo/yheEe1wawZFz+6uIBlOvbdoQjBEgd3uP/m5LYXazhS86B2Ka7tL3l8gReMA6IdckgrvRUdB8eBaYHkIsQgxEj27y9hd1Q9reO+z5QJsG081MKq3HpQEaYbj6m7qPQBTXtSw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558551887; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=ey4X7xBq0EXMKowHelS1zowcorrsFbGz8j3ZcMXtJOE=; b=djpm6fq3VZkYTVsDBk/PDi7kNS+k/z7bBDlZPjnaqErJ8Y9zB8ovse9kAIFrD9Sexk00/ZYwlI37IPmJsn1nZef69WeHp/HaMRBHOJ0B8FtN4Pyijk57fYZ+NZ/dB5+UBbXHX1Mrj6Gkv79jMzwOTqqtTixyubD7E1eKaifJyO8= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558551887442454.0003194188108; Wed, 22 May 2019 12:04:47 -0700 (PDT) Received: from localhost ([127.0.0.1]:49746 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWXU-00008p-AB for importer@patchew.org; Wed, 22 May 2019 15:04:36 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34796) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWOX-00086f-Gk for qemu-devel@nongnu.org; Wed, 22 May 2019 14:55:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hTWHi-0002X7-MT for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:21 -0400 Received: from mx2.rt-rk.com ([89.216.37.149]:47937 helo=mail.rt-rk.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hTWHi-0001xk-Ak for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:18 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.rt-rk.com (Postfix) with ESMTP id 587261A4531; Wed, 22 May 2019 20:47:15 +0200 (CEST) Received: from rtrkw774-lin.domain.local (rtrkw774-lin.domain.local [10.10.13.43]) by mail.rt-rk.com (Postfix) with ESMTPSA id 379261A2238; Wed, 22 May 2019 20:47:15 +0200 (CEST) X-Virus-Scanned: amavisd-new at rt-rk.com From: Aleksandar Markovic To: qemu-devel@nongnu.org Date: Wed, 22 May 2019 20:46:23 +0200 Message-Id: <1558550785-20098-4-git-send-email-aleksandar.markovic@rt-rk.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> References: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 89.216.37.149 Subject: [Qemu-devel] [PATCH 3/5] linux-user: Add functionality for tracking target signal mask X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, =?UTF-8?q?Milo=C5=A1=20Stojanovi=C4=87?= , amarkovic@wavecomp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Milo=C5=A1 Stojanovi=C4=87 Add two inline functions that work with the signal set of the target. target_sigdelset() removes a signal from target_sigset_t. target_sigorset() creates a union of two target_sigset_t. These functions will be used for introducing support for tracking the target signal set. Functions for emptying and adding into a target signal set already exist so this commit will serve as a supplement. Add functions tswapal_target_sigset(), target_to_abi_ulong_old_sigset() and abi_ulong_to_target_old_sigset(). The tswapal_target_sigset() function transforms target signal sets from target to host endianness. This is helpful for tracking and working with the target signal masks in the host endianness rather then keeping it in the target endianness. The target_to_abi_ulong_old_sigset() and abi_ulong_to_target_old_sigset() functions are used for translating the signal set between the old way of storing it in abi_ulong and the new target_sigset_t structure. They can be used for expanding old implementations of certain system calls to include the tracking of the target signal masks. Add support for tracking the larger target signal mask in system calls sigprocmask()/rt_sigprocmask(), sigsuspend()/rt_sigsuspend(), sgetmask()/ssetmask() and in functions do_sigreturn(), do_rt_sigreturn(), handle_pending_signal(), process_pending_signals(). Add a new function do_target_sigprocmask() which is based on do_sigprocmask() and extends its functionallity. It can happen that the host machine has a smaller range of signals compared to the target machine that it's emulating. Currently the signals that are in the target range but out of the host range are treated like faulty signals and can't be used. In this patch, support is added for tracking the target signal mask, alongside and in the same manner as the host signal mask. Signed-off-by: Milo=C5=A1 Stojanovi=C4=87 Signed-off-by: Aleksandar Markovic --- linux-user/mips/signal.c | 16 +++++ linux-user/qemu.h | 6 ++ linux-user/signal-common.h | 5 ++ linux-user/signal.c | 158 +++++++++++++++++++++++++++++++++++++++++= +++- linux-user/syscall.c | 94 +++++++++++++++++++++++++++ linux-user/syscall_defs.h | 4 ++ 6 files changed, 282 insertions(+), 1 deletion(-) diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c index 6aa303e..37922d9 100644 --- a/linux-user/mips/signal.c +++ b/linux-user/mips/signal.c @@ -253,6 +253,9 @@ long do_sigreturn(CPUMIPSState *regs) abi_ulong frame_addr; sigset_t blocked; target_sigset_t target_set; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t target_blocked; +#endif int i; =20 frame_addr =3D regs->active_tc.gpr[29]; @@ -265,7 +268,12 @@ long do_sigreturn(CPUMIPSState *regs) } =20 target_to_host_sigset_internal(&blocked, &target_set); +#ifdef TRACK_TARGET_SIGMASK + tswapal_target_sigset(&target_blocked, &target_set); + target_set_sigmask(&blocked, &target_blocked); +#else set_sigmask(&blocked); +#endif =20 restore_sigcontext(regs, &frame->sf_sc); =20 @@ -358,6 +366,9 @@ long do_rt_sigreturn(CPUMIPSState *env) struct target_rt_sigframe *frame; abi_ulong frame_addr; sigset_t blocked; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t target_blocked; +#endif =20 frame_addr =3D env->active_tc.gpr[29]; trace_user_do_rt_sigreturn(env, frame_addr); @@ -366,7 +377,12 @@ long do_rt_sigreturn(CPUMIPSState *env) } =20 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask); +#ifdef TRACK_TARGET_SIGMASK + tswapal_target_sigset(&target_blocked, &frame->rs_uc.tuc_sigmask); + target_set_sigmask(&blocked, &target_blocked); +#else set_sigmask(&blocked); +#endif =20 restore_sigcontext(env, &frame->rs_uc.tuc_mcontext); =20 diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 9f70996..75ba2a5 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -401,12 +401,18 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, = const siginfo_t *info); void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo= ); int target_to_host_signal(int sig); int host_to_target_signal(int sig); +void tswapal_target_sigset(target_sigset_t *d, const target_sigset_t *s); long do_sigreturn(CPUArchState *env); long do_rt_sigreturn(CPUArchState *env); abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong= sp); int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset); abi_long do_swapcontext(CPUArchState *env, abi_ulong uold_ctx, abi_ulong unew_ctx, abi_long ctx_size); +#ifdef TRACK_TARGET_SIGMASK +int do_target_sigprocmask(int how, const target_sigset_t *target_set, + target_sigset_t *target_oldset, + const sigset_t *set, sigset_t *oldset); +#endif /** * block_signals: block all signals while handling this guest syscall * diff --git a/linux-user/signal-common.h b/linux-user/signal-common.h index 51030a9..6332931 100644 --- a/linux-user/signal-common.h +++ b/linux-user/signal-common.h @@ -37,7 +37,12 @@ void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s); void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info); +#ifndef TRACK_TARGET_SIGMASK void set_sigmask(const sigset_t *set); +#else +void target_set_sigmask(const sigset_t *set, + const target_sigset_t *target_set); +#endif void force_sig(int sig); void force_sigsegv(int oldsig); #if defined(TARGET_ARCH_HAS_SETUP_FRAME) diff --git a/linux-user/signal.c b/linux-user/signal.c index 954aef8..9a73bfa 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -103,6 +103,12 @@ static inline void target_sigaddset(target_sigset_t *s= et, int signum) set->sig[signum / TARGET_NSIG_BPW] |=3D mask; } =20 +static inline void target_sigdelset(target_sigset_t *set, int signum) +{ + abi_ulong mask =3D (abi_ulong)1 << (--signum % TARGET_NSIG_BPW); + set->sig[signum / TARGET_NSIG_BPW] &=3D ~mask; +} + static inline int target_sigismember(const target_sigset_t *set, int signu= m) { signum--; @@ -110,6 +116,16 @@ static inline int target_sigismember(const target_sigs= et_t *set, int signum) return ((set->sig[signum / TARGET_NSIG_BPW] & mask) !=3D 0); } =20 +static inline void target_sigorset(target_sigset_t *set, + const target_sigset_t *left, + const target_sigset_t *right) +{ + int i; + for (i =3D 0; i < TARGET_NSIG_WORDS; i++) { + set->sig[i] =3D left->sig[i] | right->sig[i]; + } +} + void host_to_target_sigset_internal(target_sigset_t *d, const sigset_t *s) { @@ -174,6 +190,33 @@ void target_to_host_old_sigset(sigset_t *sigset, target_to_host_sigset(sigset, &d); } =20 +void target_to_abi_ulong_old_sigset(abi_ulong *old_sigset, + const target_sigset_t *target_sigset) +{ + target_sigset_t d; + tswapal_target_sigset(&d, target_sigset); + + memcpy(old_sigset, &d.sig, sizeof(target_sigset_t)); +} + +void abi_ulong_to_target_old_sigset(target_sigset_t *target_sigset, + const abi_ulong *old_sigset) +{ + target_sigset_t d; + + memcpy(&d.sig, old_sigset, sizeof(target_sigset_t)); + tswapal_target_sigset(target_sigset, &d); +} + +void tswapal_target_sigset(target_sigset_t *d, const target_sigset_t *s) +{ + int i; + + for (i =3D 0; i < TARGET_NSIG_WORDS; i++) { + d->sig[i] =3D tswapal(s->sig[i]); + } +} + int block_signals(void) { TaskState *ts =3D (TaskState *)thread_cpu->opaque; @@ -236,16 +279,84 @@ int do_sigprocmask(int how, const sigset_t *set, sigs= et_t *oldset) return 0; } =20 +#ifdef TRACK_TARGET_SIGMASK +int do_target_sigprocmask(int how, const target_sigset_t *target_set, + target_sigset_t *target_oldset, + const sigset_t *set, sigset_t *oldset) +{ + TaskState *ts =3D (TaskState *)thread_cpu->opaque; + + if (target_oldset) { + *target_oldset =3D ts->target_signal_mask; + } + if (oldset) { + *oldset =3D ts->signal_mask; + } + + if (target_set && set) { + int i; + + if (block_signals()) { + return -TARGET_ERESTARTSYS; + } + + switch (how) { + case SIG_BLOCK: + target_sigorset(&ts->target_signal_mask, &ts->target_signal_ma= sk, + target_set); + sigorset(&ts->signal_mask, &ts->signal_mask, set); + break; + case SIG_UNBLOCK: + for (i =3D 1; i <=3D TARGET_NSIG; ++i) { + if (target_sigismember(target_set, i) =3D=3D 1) { + target_sigdelset(&ts->target_signal_mask, i); + } + } + for (i =3D 1; i <=3D NSIG; ++i) { + if (sigismember(set, i) =3D=3D 1) { + sigdelset(&ts->signal_mask, i); + } + } + break; + case SIG_SETMASK: + ts->target_signal_mask =3D *target_set; + ts->signal_mask =3D *set; + break; + default: + g_assert_not_reached(); + } + + /* Silently ignore attempts to change blocking status of KILL or S= TOP */ + target_sigdelset(&ts->target_signal_mask, SIGKILL); + target_sigdelset(&ts->target_signal_mask, SIGSTOP); + sigdelset(&ts->signal_mask, SIGKILL); + sigdelset(&ts->signal_mask, SIGSTOP); + } + return 0; +} +#endif + #if !defined(TARGET_NIOS2) /* Just set the guest's signal mask to the specified value; the * caller is assumed to have called block_signals() already. */ +#ifndef TRACK_TARGET_SIGMASK void set_sigmask(const sigset_t *set) { TaskState *ts =3D (TaskState *)thread_cpu->opaque; =20 ts->signal_mask =3D *set; } +#else +void target_set_sigmask(const sigset_t *set, + const target_sigset_t *target_set) +{ + TaskState *ts =3D (TaskState *)thread_cpu->opaque; + + ts->signal_mask =3D *set; + ts->target_signal_mask =3D *target_set; +} +#endif #endif =20 /* sigaltstack management */ @@ -849,6 +960,9 @@ static void handle_pending_signal(CPUArchState *cpu_env= , int sig, abi_ulong handler; sigset_t set; target_sigset_t target_old_set; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t target_set; +#endif struct target_sigaction *sa; TaskState *ts =3D cpu->opaque; =20 @@ -886,21 +1000,39 @@ static void handle_pending_signal(CPUArchState *cpu_= env, int sig, } else { /* compute the blocked signals during the handler execution */ sigset_t *blocked_set; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t *target_blocked_set; =20 + tswapal_target_sigset(&target_set, &sa->sa_mask); +#endif target_to_host_sigset(&set, &sa->sa_mask); /* SA_NODEFER indicates that the current signal should not be blocked during the handler */ - if (!(sa->sa_flags & TARGET_SA_NODEFER)) + if (!(sa->sa_flags & TARGET_SA_NODEFER)) { +#ifdef TRACK_TARGET_SIGMASK + target_sigaddset(&target_set, sig); +#endif sigaddset(&set, target_to_host_signal(sig)); + } =20 /* save the previous blocked signal state to restore it at the end of the signal execution (see do_sigreturn) */ +#ifdef TRACK_TARGET_SIGMASK + target_old_set =3D ts->target_signal_mask; +#else host_to_target_sigset_internal(&target_old_set, &ts->signal_mask); +#endif =20 /* block signals in the handler */ blocked_set =3D ts->in_sigsuspend ? &ts->sigsuspend_mask : &ts->signal_mask; sigorset(&ts->signal_mask, blocked_set, &set); +#ifdef TRACK_TARGET_SIGMASK + target_blocked_set =3D ts->in_sigsuspend ? + &ts->target_sigsuspend_mask : &ts->target_signal_mask; + target_sigorset(&ts->target_signal_mask, target_blocked_set, + &target_set); +#endif ts->in_sigsuspend =3D 0; =20 /* if the CPU is in VM86 mode, we restore the 32 bit values */ @@ -934,7 +1066,11 @@ void process_pending_signals(CPUArchState *cpu_env) int sig; TaskState *ts =3D cpu->opaque; sigset_t set; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t *target_blocked_set; +#else sigset_t *blocked_set; +#endif =20 while (atomic_read(&ts->signal_pending)) { /* FIXME: This is not threadsafe. */ @@ -952,22 +1088,42 @@ void process_pending_signals(CPUArchState *cpu_env) * to block a synchronous signal since it could then just end = up * looping round and round indefinitely. */ +#ifdef TRACK_TARGET_SIGMASK + if (sigismember(&ts->signal_mask, target_to_host_signal(sig)) = =3D=3D 1 + || target_sigismember(&ts->target_signal_mask, sig) =3D=3D= 1 + || sigact_table[sig - 1]._sa_handler =3D=3D TARGET_SIG_IGN= ) { + sigdelset(&ts->signal_mask, target_to_host_signal(sig)); + target_sigdelset(&ts->target_signal_mask, sig); + sigact_table[sig - 1]._sa_handler =3D TARGET_SIG_DFL; + } +#else if (sigismember(&ts->signal_mask, target_to_host_signal_table[= sig]) || sigact_table[sig - 1]._sa_handler =3D=3D TARGET_SIG_IGN= ) { sigdelset(&ts->signal_mask, target_to_host_signal_table[si= g]); sigact_table[sig - 1]._sa_handler =3D TARGET_SIG_DFL; } +#endif =20 handle_pending_signal(cpu_env, sig, &ts->sync_signal); } =20 for (sig =3D 1; sig <=3D TARGET_NSIG; sig++) { +#ifdef TRACK_TARGET_SIGMASK + target_blocked_set =3D ts->in_sigsuspend ? + &ts->target_sigsuspend_mask : &ts->target_signal_mask; +#else blocked_set =3D ts->in_sigsuspend ? &ts->sigsuspend_mask : &ts->signal_mask; +#endif =20 +#ifdef TRACK_TARGET_SIGMASK + if (ts->sigtab[sig - 1].pending && + (!target_sigismember(target_blocked_set, sig))) { +#else if (ts->sigtab[sig - 1].pending && (!sigismember(blocked_set, target_to_host_signal_table[sig]))) { +#endif handle_pending_signal(cpu_env, sig, &ts->sigtab[sig - 1]); /* Restart scan from the beginning, as handle_pending_sign= al * might have resulted in a new synchronous signal (eg SIG= SEGV). diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 115ab13..dede443 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7871,6 +7871,17 @@ static abi_long do_syscall1(void *cpu_env, int num, = abi_long arg1, #ifdef TARGET_NR_sgetmask /* not on alpha */ case TARGET_NR_sgetmask: { +#ifdef TRACK_TARGET_SIGMASK + sigset_t cur_set; + target_sigset_t target_set_mask; + abi_ulong target_set; + ret =3D do_target_sigprocmask(0, NULL, &target_set_mask, + NULL, &cur_set); + if (!ret) { + target_to_abi_ulong_old_sigset(&target_set, &target_set_ma= sk); + ret =3D target_set; + } +#else sigset_t cur_set; abi_ulong target_set; ret =3D do_sigprocmask(0, NULL, &cur_set); @@ -7878,12 +7889,26 @@ static abi_long do_syscall1(void *cpu_env, int num,= abi_long arg1, host_to_target_old_sigset(&target_set, &cur_set); ret =3D target_set; } +#endif } return ret; #endif #ifdef TARGET_NR_ssetmask /* not on alpha */ case TARGET_NR_ssetmask: { +#ifdef TRACK_TARGET_SIGMASK + sigset_t set, oset; + target_sigset_t target_set_mask, target_oset; + abi_ulong target_set =3D arg1; + target_to_host_old_sigset(&set, &target_set); + abi_ulong_to_target_old_sigset(&target_set_mask, &target_set); + ret =3D do_target_sigprocmask(SIG_SETMASK, &target_set_mask, + &target_oset, &set, &oset); + if (!ret) { + target_to_abi_ulong_old_sigset(&target_set, &target_oset); + ret =3D target_set; + } +#else sigset_t set, oset; abi_ulong target_set =3D arg1; target_to_host_old_sigset(&set, &target_set); @@ -7892,6 +7917,7 @@ static abi_long do_syscall1(void *cpu_env, int num, a= bi_long arg1, host_to_target_old_sigset(&target_set, &oset); ret =3D target_set; } +#endif } return ret; #endif @@ -7900,6 +7926,9 @@ static abi_long do_syscall1(void *cpu_env, int num, a= bi_long arg1, { #if defined(TARGET_ALPHA) sigset_t set, oldset; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t target_set, target_oldset; +#endif abi_ulong mask; int how; =20 @@ -7919,14 +7948,26 @@ static abi_long do_syscall1(void *cpu_env, int num,= abi_long arg1, mask =3D arg2; target_to_host_old_sigset(&set, &mask); =20 +#ifdef TRACK_TARGET_SIGMASK + abi_ulong_to_target_old_sigset(&target_set, &mask); + + ret =3D do_target_sigprocmask(how, &target_set, &target_oldset, + &set, &oldset); + if (!is_error(ret)) { + target_to_abi_ulong_old_sigset(&mask, &target_oldset); +#else ret =3D do_sigprocmask(how, &set, &oldset); if (!is_error(ret)) { host_to_target_old_sigset(&mask, &oldset); +#endif ret =3D mask; ((CPUAlphaState *)cpu_env)->ir[IR_V0] =3D 0; /* force no e= rror */ } #else sigset_t set, oldset, *set_ptr; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t target_set, target_oldset, *target_set_ptr; +#endif int how; =20 if (arg2) { @@ -7946,17 +7987,32 @@ static abi_long do_syscall1(void *cpu_env, int num,= abi_long arg1, if (!(p =3D lock_user(VERIFY_READ, arg2, sizeof(target_sig= set_t), 1))) return -TARGET_EFAULT; target_to_host_old_sigset(&set, p); +#ifdef TRACK_TARGET_SIGMASK + abi_ulong_to_target_old_sigset(&target_set, p); + target_set_ptr =3D &target_set; +#endif unlock_user(p, arg2, 0); set_ptr =3D &set; } else { how =3D 0; set_ptr =3D NULL; +#ifdef TRACK_TARGET_SIGMASK + target_set_ptr =3D NULL; + } + ret =3D do_target_sigprocmask(how, target_set_ptr, &target_old= set, + set_ptr, &oldset); +#else } ret =3D do_sigprocmask(how, set_ptr, &oldset); +#endif if (!is_error(ret) && arg3) { if (!(p =3D lock_user(VERIFY_WRITE, arg3, sizeof(target_si= gset_t), 0))) return -TARGET_EFAULT; +#ifdef TRACK_TARGET_SIGMASK + target_to_abi_ulong_old_sigset(p, &target_oldset); +#else host_to_target_old_sigset(p, &oldset); +#endif unlock_user(p, arg3, sizeof(target_sigset_t)); } #endif @@ -7967,6 +8023,9 @@ static abi_long do_syscall1(void *cpu_env, int num, a= bi_long arg1, { int how =3D arg1; sigset_t set, oldset, *set_ptr; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t target_set, target_oldset, *target_set_ptr; +#endif =20 if (arg4 !=3D sizeof(target_sigset_t)) { return -TARGET_EINVAL; @@ -7989,17 +8048,32 @@ static abi_long do_syscall1(void *cpu_env, int num,= abi_long arg1, if (!(p =3D lock_user(VERIFY_READ, arg2, sizeof(target_sig= set_t), 1))) return -TARGET_EFAULT; target_to_host_sigset(&set, p); +#ifdef TRACK_TARGET_SIGMASK + tswapal_target_sigset(&target_set, p); + target_set_ptr =3D &target_set; +#endif unlock_user(p, arg2, 0); set_ptr =3D &set; } else { how =3D 0; set_ptr =3D NULL; +#ifdef TRACK_TARGET_SIGMASK + target_set_ptr =3D NULL; + } + ret =3D do_target_sigprocmask(how, target_set_ptr, &target_old= set, + set_ptr, &oldset); +#else } ret =3D do_sigprocmask(how, set_ptr, &oldset); +#endif if (!is_error(ret) && arg3) { if (!(p =3D lock_user(VERIFY_WRITE, arg3, sizeof(target_si= gset_t), 0))) return -TARGET_EFAULT; +#ifdef TRACK_TARGET_SIGMASK + tswapal_target_sigset(p, &target_oldset); +#else host_to_target_sigset(p, &oldset); +#endif unlock_user(p, arg3, sizeof(target_sigset_t)); } } @@ -8047,10 +8121,16 @@ static abi_long do_syscall1(void *cpu_env, int num,= abi_long arg1, #if defined(TARGET_ALPHA) abi_ulong mask =3D arg1; target_to_host_old_sigset(&ts->sigsuspend_mask, &mask); +#ifdef TRACK_TARGET_SIGMASK + abi_ulong_to_target_old_sigset(&ts->target_sigsuspend_mask, &m= ask); +#endif #else if (!(p =3D lock_user(VERIFY_READ, arg1, sizeof(target_sigset_= t), 1))) return -TARGET_EFAULT; target_to_host_old_sigset(&ts->sigsuspend_mask, p); +#ifdef TRACK_TARGET_SIGMASK + abi_ulong_to_target_old_sigset(&ts->target_sigsuspend_mask, p); +#endif unlock_user(p, arg1, 0); #endif ret =3D get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask, @@ -8071,6 +8151,9 @@ static abi_long do_syscall1(void *cpu_env, int num, a= bi_long arg1, if (!(p =3D lock_user(VERIFY_READ, arg1, sizeof(target_sigset_= t), 1))) return -TARGET_EFAULT; target_to_host_sigset(&ts->sigsuspend_mask, p); +#ifdef TRACK_TARGET_SIGMASK + tswapal_target_sigset(&ts->target_sigsuspend_mask, p); +#endif unlock_user(p, arg1, 0); ret =3D get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask, SIGSET_T_SIZE)); @@ -10351,6 +10434,9 @@ static abi_long do_syscall1(void *cpu_env, int num,= abi_long arg1, abi_ulong mask; int how; sigset_t set, oldset; +#ifdef TRACK_TARGET_SIGMASK + target_sigset_t target_set, target_oldset; +#endif =20 switch(arg1) { case TARGET_SIG_BLOCK: @@ -10367,9 +10453,17 @@ static abi_long do_syscall1(void *cpu_env, int num= , abi_long arg1, } mask =3D arg2; target_to_host_old_sigset(&set, &mask); +#ifdef TRACK_TARGET_SIGMASK + abi_ulong_to_target_old_sigset(&target_set, &mask); + ret =3D do_target_sigprocmask(how, &target_set, &target_oldset, + &set, &oldset); + if (!ret) { + target_to_abi_ulong_old_sigset(&mask, &target_oldset); +#else ret =3D do_sigprocmask(how, &set, &oldset); if (!ret) { host_to_target_old_sigset(&mask, &oldset); +#endif ret =3D mask; } } diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 1f5b2d1..64edec2 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -419,6 +419,10 @@ void host_to_target_old_sigset(abi_ulong *old_sigset, const sigset_t *sigset); void target_to_host_old_sigset(sigset_t *sigset, const abi_ulong *old_sigset); +void target_to_abi_ulong_old_sigset(abi_ulong *old_sigset, + const target_sigset_t *target_sigset); +void abi_ulong_to_target_old_sigset(target_sigset_t *target_sigset, + const abi_ulong *old_sigset); struct target_sigaction; int do_sigaction(int sig, const struct target_sigaction *act, struct target_sigaction *oact); --=20 2.7.4 From nobody Mon Apr 29 07:27:53 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1558551472; cv=none; d=zoho.com; s=zohoarc; b=Wsf91a1woIaE1B0I6f4h/up7l0JEor2lFsy1vE7A/fL6zpLgsGYLOgykH+OwDoDAxLatHf6LWA8XBvSsMmy4XnxnXjNoS708GEZiyQWx+Kd6EgQN8hbgej6ugih+D/FRttKZtoJxeIVWtVxEs84FRcKnoksGu4FFCumgNmUYvU0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558551472; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=BZIXVl47GJ+6QaFfGDimLo+v77z4ROf3zefXfCPoLXA=; b=IYBjjHHwQnNIpiARu6hqd+U/9xiMhBT6PlFO9UILFn9bgIke9AjhPT9nyI7QeJcmmZRUTIWJjPFfZCeYSOLXa3/r6ybYwwjWVDKqbYmLOl8JILL0xeusM5GkpAgubKz0OsAo714iuz0RciYEV8XV8WM7SOKkE/xPd5uJ83QpK3E= ARC-Authentication-Results: i=1; mx.zoho.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558551472004651.1227095267146; Wed, 22 May 2019 11:57:52 -0700 (PDT) Received: from localhost ([127.0.0.1]:49645 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWQi-0001UM-A1 for importer@patchew.org; Wed, 22 May 2019 14:57:36 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34795) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWOX-00086e-6G for qemu-devel@nongnu.org; Wed, 22 May 2019 14:55:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hTWHn-0002Zc-8Z for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:24 -0400 Received: from mx2.rt-rk.com ([89.216.37.149]:47945 helo=mail.rt-rk.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hTWHm-00020j-UX for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:23 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.rt-rk.com (Postfix) with ESMTP id 33BEC1A4545; Wed, 22 May 2019 20:47:20 +0200 (CEST) Received: from rtrkw774-lin.domain.local (rtrkw774-lin.domain.local [10.10.13.43]) by mail.rt-rk.com (Postfix) with ESMTPSA id 1A2F01A2238; Wed, 22 May 2019 20:47:20 +0200 (CEST) X-Virus-Scanned: amavisd-new at rt-rk.com From: Aleksandar Markovic To: qemu-devel@nongnu.org Date: Wed, 22 May 2019 20:46:24 +0200 Message-Id: <1558550785-20098-5-git-send-email-aleksandar.markovic@rt-rk.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> References: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 89.216.37.149 Subject: [Qemu-devel] [PATCH 4/5] linux-user: Add support for multiplexing larger target signals X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, =?UTF-8?q?Milo=C5=A1=20Stojanovi=C4=87?= , amarkovic@wavecomp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Milo=C5=A1 Stojanovi=C4=87 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=C5=A1 Stojanovi=C4=87 Signed-off-by: Aleksandar Markovic --- 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 9a73bfa..601de3e 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -291,6 +291,15 @@ int do_target_sigprocmask(int how, const target_sigset= _t *target_set, } if (oldset) { *oldset =3D 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 ther= e. + */ + if (target_sigismember(&ts->target_signal_mask, MUX_SIG) =3D=3D 1)= { + sigaddset(oldset, MUX_SIG); + } +#endif } =20 if (target_set && set) { @@ -331,6 +340,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; } @@ -355,6 +373,10 @@ void target_set_sigmask(const sigset_t *set, =20 ts->signal_mask =3D *set; ts->target_signal_mask =3D *target_set; +#ifdef MUX_SIG + /* MUX_SIG can't be blocked on host */ + sigdelset(&ts->signal_mask, MUX_SIG); +#endif } #endif #endif @@ -929,6 +951,12 @@ int do_sigaction(int sig, const struct target_sigactio= n *act, =20 /* we update the host linux signal state */ host_sig =3D target_to_host_signal(sig); +#ifdef MUX_SIG + /* put the out of host range signal into the multiplex */ + if (sig >=3D _NSIG && sig < TARGET_NSIG) { + host_sig =3D MUX_SIG; + } +#endif if (host_sig !=3D SIGSEGV && host_sig !=3D SIGBUS) { sigfillset(&act1.sa_mask); act1.sa_flags =3D SA_SIGINFO; @@ -1141,6 +1169,10 @@ void process_pending_signals(CPUArchState *cpu_env) set =3D 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 =3D 0; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 64edec2..0c72509 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -387,6 +387,26 @@ struct target_dirent64 { #define TARGET_NSIG_BPW TARGET_ABI_BITS #define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW) =20 +#if _NSIG <=3D 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; --=20 2.7.4 From nobody Mon Apr 29 07:27:53 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1558551469; cv=none; d=zoho.com; s=zohoarc; b=BMjaP583OE4Hq8d0UkhRAS7fEI2ebAyWvNWTVOEu2pwoZOSNmgDmowo/6NMoB42Ko/Rawdvq15sfEJA9l5pKR6jSSP9N1C7lyopKAI2PTBd751KAwHKL/ByoowoI6H7nh4Exap1eAqmUNOKA9To37jGt+sqx/cqGCGjHogskBnE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1558551469; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=eRQ73jqHA+I0i4FyD7yCYlcV0melmpBTGWfxrrfcy6M=; b=Kds/t5BY8hq4EnxOre8N2ZmMO8DZa4MXB2zcwBuatHIFled3vOGKYEDPx5DSikCJC3WHONmRDsylKqoVTfSfDP0CxvDX4R63Du4bZ8C4r92Op6A1jlIUO1xIQm41lqgRVuT90K3Orq4Syogo5JJRhrlBQMavcDG6dUM9TaWMkAw= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1558551469237525.1732056417964; Wed, 22 May 2019 11:57:49 -0700 (PDT) Received: from localhost ([127.0.0.1]:49649 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWQl-0001Wh-3J for importer@patchew.org; Wed, 22 May 2019 14:57:39 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34793) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hTWOY-00086d-Rt for qemu-devel@nongnu.org; Wed, 22 May 2019 14:55:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hTWHO-0002KH-MQ for qemu-devel@nongnu.org; Wed, 22 May 2019 14:48:00 -0400 Received: from mx2.rt-rk.com ([89.216.37.149]:48035 helo=mail.rt-rk.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hTWHO-0002J4-C4 for qemu-devel@nongnu.org; Wed, 22 May 2019 14:47:58 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.rt-rk.com (Postfix) with ESMTP id B9A1A1A4547; Wed, 22 May 2019 20:47:21 +0200 (CEST) Received: from rtrkw774-lin.domain.local (rtrkw774-lin.domain.local [10.10.13.43]) by mail.rt-rk.com (Postfix) with ESMTPSA id 9F0E51A2238; Wed, 22 May 2019 20:47:21 +0200 (CEST) X-Virus-Scanned: amavisd-new at rt-rk.com From: Aleksandar Markovic To: qemu-devel@nongnu.org Date: Wed, 22 May 2019 20:46:25 +0200 Message-Id: <1558550785-20098-6-git-send-email-aleksandar.markovic@rt-rk.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> References: <1558550785-20098-1-git-send-email-aleksandar.markovic@rt-rk.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 89.216.37.149 Subject: [Qemu-devel] [PATCH 5/5] linux-user: Add support for multiplexing signals in more syscalls X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, =?UTF-8?q?Milo=C5=A1=20Stojanovi=C4=87?= , amarkovic@wavecomp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Milo=C5=A1 Stojanovi=C4=87 Add support for multiplexing in the host_signal_handler() function and in system calls rt_sigqueueinfo()/rt_tgsigqueueinfo(), tgkill(), kill() for the case when pid > 0. The rt_sigqueueinfo()/rt_tgsigqueueinfo() system calls multiplex target signals which are out of the host range by setting the si_errno value to the actual value of the signal and sending the signal to the MUX_SIG signal number. The host_signal_handler() will pull out the multiplexed signals and set their signal number to the correct value. That value should be in the si_errno field of the siginfo_t structure. The si_errno field is used here but this implementation can be replaced with any other unused field in the uinfo structure. The emulation of larger target signal range is done by spoofing the system call info, adding the signal number to the si_errno field, and sending it to the host multiplex queue via rt_sigqueueinfo()/rt_tgsigqueueinfo(). In order to send a signal using rt_sigqueueinfo()/rt_tgsigqueueinfo() with si_code SI_USER or SI_TKILL to another thread or process, we need to disguise it as some other signal from the kernel range because the host kernel doesn't allow direct impersonations of those signals. This is done with SIG_SPOOF which moves the si_code to the nearest unused kernel si_code value. After the signal is successfully sent the host_signal_handler() of the receiving thread/process will turn it back into the proper kill/tgkill signal, before it gets processed. The tkill() system call as well as kill() with the argument pid <=3D 0 couldn't be implemented simply using this method because it requires acquiring information about, and sending simultaneous signals to multiple threads or processes. These functionalities are out of the scope of rt_sigqueueinfo()/rt_tgsigqueueinfo(). Signed-off-by: Milo=C5=A1 Stojanovi=C4=87 Signed-off-by: Aleksandar Markovic --- linux-user/signal.c | 22 +++++++++++++ linux-user/syscall.c | 81 +++++++++++++++++++++++++++++++++++++++++++= ++++ linux-user/syscall_defs.h | 8 +++++ 3 files changed, 111 insertions(+) diff --git a/linux-user/signal.c b/linux-user/signal.c index 601de3e..885ceab 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -807,6 +807,28 @@ static void host_signal_handler(int host_signum, sigin= fo_t *info, sig =3D host_to_target_signal(host_signum); if (sig < 1 || sig > TARGET_NSIG) return; + +#ifdef MUX_SIG + if (sig =3D=3D MUX_SIG) { + /* return the spoofed kill/tgkill signals into standard form */ + if (info->si_code =3D=3D SIG_SPOOF(SI_USER)) { + info->si_code =3D SI_USER; + } else if (info->si_code =3D=3D SIG_SPOOF(SI_TKILL)) { + info->si_code =3D SI_TKILL; + } + + /* + * We assume that si_errno field will remain intact during signal + * processing on the host. If it changes, the signal will be sent = to + * the wrong number (most likely to MUX_SIG). + */ + /* get the actual target signal number */ + int target_sig =3D info->si_errno; + if (target_sig >=3D _NSIG && target_sig < TARGET_NSIG) { + sig =3D target_sig; + } + } +#endif trace_user_host_signal(env, host_signum, sig); =20 rewind_if_in_safe_syscall(puc); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index dede443..2e3c951 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6448,6 +6448,24 @@ static inline abi_long host_to_target_stat64(void *c= pu_env, } #endif =20 +#ifdef MUX_SIG +static inline int multiplex(abi_long *arg, siginfo_t *uinfo) +{ + if (*arg >=3D _NSIG && *arg < TARGET_NSIG) { + /* + * Using si_errno to transfer the signal number assumes that the f= ield + * doesn't change its value before it gets handled in the + * host_signal_handler(). + */ + uinfo->si_errno =3D *arg; + *arg =3D MUX_SIG; + uinfo->si_signo =3D MUX_SIG; + } + + return 0; +} +#endif + /* ??? Using host futex calls even when target atomic operations are not really atomic probably breaks things. However implementing futexes locally would make futexes shared between multiple processes @@ -7535,7 +7553,42 @@ static abi_long do_syscall1(void *cpu_env, int num, = abi_long arg1, return get_errno(syncfs(arg1)); #endif case TARGET_NR_kill: +#ifdef MUX_SIG + if (arg2 >=3D _NSIG && arg2 < TARGET_NSIG) { + siginfo_t info; + + info.si_errno =3D arg2; + info.si_signo =3D MUX_SIG; + info.si_code =3D SIG_SPOOF(SI_USER); + info.si_pid =3D getpid(); + info.si_uid =3D getuid(); + + /* pid > 0 */ + if (arg1 > 0) { + return get_errno(sys_rt_sigqueueinfo(arg1, MUX_SIG, &info)= ); + } else { + return -TARGET_EINVAL; + } + /* + * TODO: In order to implement kill with rt_tgsigqueueinfo() f= or + * cases where pid <=3D 0 one needs to get a list of all the r= elevant + * processes and simultaniously send the signal to them. + * Missing: + * (pid =3D 0): + * send to every process in the process group of + * the calling process + * (pid =3D -1): + * send to every process for which the calling process + * has permission to send signals, except for process 1 (i= nit) + * (pid < -1): + * send to every process in the process group whose ID is = -pid + */ + } else { + return get_errno(safe_kill(arg1, target_to_host_signal(arg2))); + } +#else return get_errno(safe_kill(arg1, target_to_host_signal(arg2))); +#endif #ifdef TARGET_NR_rename case TARGET_NR_rename: { @@ -8208,6 +8261,9 @@ static abi_long do_syscall1(void *cpu_env, int num, a= bi_long arg1, } target_to_host_siginfo(&uinfo, p); unlock_user(p, arg3, 0); +#ifdef MUX_SIG + multiplex(&arg2, &uinfo); +#endif ret =3D get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); } return ret; @@ -8221,6 +8277,9 @@ static abi_long do_syscall1(void *cpu_env, int num, a= bi_long arg1, } target_to_host_siginfo(&uinfo, p); unlock_user(p, arg4, 0); +#ifdef MUX_SIG + multiplex(&arg3, &uinfo); +#endif ret =3D get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, arg3, &uin= fo)); } return ret; @@ -11037,11 +11096,33 @@ static abi_long do_syscall1(void *cpu_env, int nu= m, abi_long arg1, #endif =20 case TARGET_NR_tkill: + /* + * TODO: In order to implement tkill with rt_sigqueueinfo() one ne= eds + * to get a list of all the threads with the specifiend tid and + * simultaniously send the signal to them. + */ return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)= )); =20 case TARGET_NR_tgkill: +#ifdef MUX_SIG + if (arg3 >=3D _NSIG && arg3 < TARGET_NSIG) { + siginfo_t info; + + info.si_errno =3D arg3; + info.si_signo =3D MUX_SIG; + info.si_code =3D SIG_SPOOF(SI_TKILL); + info.si_pid =3D getpid(); + info.si_uid =3D getuid(); + + return get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, MUX_SIG, &i= nfo)); + } else { + return get_errno(safe_tgkill((int)arg1, (int)arg2, + target_to_host_signal(arg3))); + } +#else return get_errno(safe_tgkill((int)arg1, (int)arg2, target_to_host_signal(arg3))); +#endif =20 #ifdef TARGET_NR_set_robust_list case TARGET_NR_set_robust_list: diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 0c72509..ca97f67 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -405,6 +405,14 @@ struct target_dirent64 { * the host signal masks. */ #define TRACK_TARGET_SIGMASK + +/* + * This macro is used to change a kill/tgkill signal so it can be sent thr= ough + * rt_sigqueueinfo()/rt_tgsigqueueinfo(), since the host kernel doesn't al= low + * direct impersonations of those signals. Subtracting 8 from the code mov= es + * it to the nearest unused kernel si_code value. + */ +#define SIG_SPOOF(code) ((code) - 8) #endif =20 typedef struct { --=20 2.7.4