Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1374623 > unrolled thread
| Started by | Stas Sergeev <stsp@list.ru> |
|---|---|
| First post | 2016-04-09 14:50 +0200 |
| Last post | 2016-04-09 14:50 +0200 |
| Articles | 3 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH v6(RESEND) 0/4] make sigaltstack() compatible with swapcontext() Stas Sergeev <stsp@list.ru> - 2016-04-09 14:50 +0200
[PATCH 1/4] [Cleanup] x86: signal: unify the sigaltstack check with other arches Stas Sergeev <stsp@list.ru> - 2016-04-09 14:50 +0200
[PATCH 2/4] sigaltstack: preparations for adding new SS_xxx flags Stas Sergeev <stsp@list.ru> - 2016-04-09 14:50 +0200
| From | Stas Sergeev <stsp@list.ru> |
|---|---|
| Date | 2016-04-09 14:50 +0200 |
| Subject | [PATCH v6(RESEND) 0/4] make sigaltstack() compatible with swapcontext() |
| Message-ID | <rm0uR-52s-3@gated-at.bofh.it> |
It is absolutely unclear what happened with my patch series, but it is neither applied nor rejected. So here's the re-send. The following patches make it possible to use swapcontext() in a sighandler that works on sigaltstack. The approach is inspired by Andy Lutomirski's suggestion that sigaltstack should disarm itself after saving into uc_stack: https://lkml.org/lkml/2016/2/1/594 I add the SS_AUTODISARM flag that does exactly that. On sighandler exit, the sigaltstack is restored from uc_stack. Another possible name could be SS_ONESHOT, but, since it gets always re-enabled, I choose SS_AUTODISARM. Change since v5: - Fix description of patch 4/4 Change since v4: - Implement this Andy Lutomirski's suggestion: https://lkml.org/lkml/2016/3/6/158 that allows the run-time probing of the existence of the flags added in the future. [PATCH 1/4] [Cleanup] x86: signal: unify the sigaltstack check with A clean-up patch that unifies x86's sigaltstack handling with other arches. [PATCH 2/4] sigaltstack: preparations for adding new SS_xxx flags Andy's suggested changes [PATCH 3/4] sigaltstack: implement SS_AUTODISARM flag This patch implements SS_AUTODISARM flag [PATCH 4/4] selftests: Add test for This patch adds the selftest code for new functionality CC: linux-kernel@vger.kernel.org CC: linux-api@vger.kernel.org CC: Andy Lutomirski <luto@amacapital.net> CC: Oleg Nesterov <oleg@redhat.com> CC: Shuah Khan <shuahkh@osg.samsung.com> CC: Ingo Molnar <mingo@redhat.com> Diffstat: arch/x86/kernel/signal.c | 23 +-- include/linux/sched.h | 8 + include/linux/signal.h | 4 include/uapi/linux/signal.h | 7 + kernel/fork.c | 2 kernel/signal.c | 26 ++-- tools/testing/selftests/Makefile | 1 tools/testing/selftests/sigaltstack/Makefile | 8 + tools/testing/selftests/sigaltstack/sas.c | 156 +++++++++++++++++++++++++++ 9 files changed, 208 insertions(+), 27 deletions(-)
[toc] | [next] | [standalone]
| From | Stas Sergeev <stsp@list.ru> |
|---|---|
| Date | 2016-04-09 14:50 +0200 |
| Subject | [PATCH 1/4] [Cleanup] x86: signal: unify the sigaltstack check with other arches |
| Message-ID | <rm0uR-52s-7@gated-at.bofh.it> |
| In reply to | #1374623 |
Currently x86's get_sigframe() checks for "current->sas_ss_size"
to determine whether there is a need to switch to sigaltstack.
The common practice used by all other arches is to check for
sas_ss_flags(sp) == 0
This patch makes the code consistent with other arches.
The slight complexity of the patch is added by the optimization on
!sigstack check that was requested by Andy Lutomirski: sas_ss_flags(sp)==0
already implies that we are not on a sigstack, so the code is shuffled
to avoid the duplicate checking.
This patch have no any user-visible impact. It is purely a cleanup.
CC: linux-kernel@vger.kernel.org
CC: Andy Lutomirski <luto@amacapital.net>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ingo Molnar <mingo@redhat.com>
CC: "H. Peter Anvin" <hpa@zytor.com>
CC: x86@kernel.org
CC: Borislav Petkov <bp@suse.de>
CC: Brian Gerst <brgerst@gmail.com>
CC: Oleg Nesterov <oleg@redhat.com>
CC: Richard Weinberger <richard@nod.at>
Signed-off-by: Stas Sergeev <stsp@users.sourceforge.net>
---
arch/x86/kernel/signal.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index cb6282c..285183b 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -213,18 +213,17 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
if (config_enabled(CONFIG_X86_64))
sp -= 128;
- if (!onsigstack) {
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (current->sas_ss_size)
- sp = current->sas_ss_sp + current->sas_ss_size;
- } else if (config_enabled(CONFIG_X86_32) &&
- (regs->ss & 0xffff) != __USER_DS &&
- !(ka->sa.sa_flags & SA_RESTORER) &&
- ka->sa.sa_restorer) {
- /* This is the legacy signal stack switching. */
- sp = (unsigned long) ka->sa.sa_restorer;
- }
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (sas_ss_flags(sp) == 0)
+ sp = current->sas_ss_sp + current->sas_ss_size;
+ } else if (config_enabled(CONFIG_X86_32) &&
+ !onsigstack &&
+ (regs->ss & 0xffff) != __USER_DS &&
+ !(ka->sa.sa_flags & SA_RESTORER) &&
+ ka->sa.sa_restorer) {
+ /* This is the legacy signal stack switching. */
+ sp = (unsigned long) ka->sa.sa_restorer;
}
if (fpu->fpstate_active) {
--
2.7.2
[toc] | [prev] | [next] | [standalone]
| From | Stas Sergeev <stsp@list.ru> |
|---|---|
| Date | 2016-04-09 14:50 +0200 |
| Subject | [PATCH 2/4] sigaltstack: preparations for adding new SS_xxx flags |
| Message-ID | <rm0uR-52s-11@gated-at.bofh.it> |
| In reply to | #1374623 |
This patch adds SS_FLAG_BITS - the mask that splits sigaltstack
mode values and bit-flags. Since there is no bit-flags yet, the
mask is defined to 0. The flags are added by subsequent patches.
With every new flag, the mask should have the appropriate bit cleared.
This makes sure if some flag is tried on a kernel that doesn't
support it, the EINVAL error will be returned, because such a
flag will be treated as an invalid mode rather than the bit-flag.
That way the existence of the particular features can be probed
at run-time.
This change was suggested by Andy Lutomirski:
https://lkml.org/lkml/2016/3/6/158
Signed-off-by: Stas Sergeev <stsp@users.sourceforge.net>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Oleg Nesterov <oleg@redhat.com>
CC: "Peter Zijlstra (Intel)" <peterz@infradead.org>
CC: "Amanieu d'Antras" <amanieu@gmail.com>
CC: Michal Hocko <mhocko@suse.com>
CC: Richard Weinberger <richard@nod.at>
CC: Vladimir Davydov <vdavydov@parallels.com>
CC: Sasha Levin <sasha.levin@oracle.com>
CC: linux-kernel@vger.kernel.org
---
include/uapi/linux/signal.h | 3 +++
kernel/signal.c | 16 ++++++----------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/include/uapi/linux/signal.h b/include/uapi/linux/signal.h
index e1bd50c2..7c73165 100644
--- a/include/uapi/linux/signal.h
+++ b/include/uapi/linux/signal.h
@@ -7,4 +7,7 @@
#define SS_ONSTACK 1
#define SS_DISABLE 2
+/* mask for all SS_xxx flags */
+#define SS_FLAG_BITS 0
+
#endif /* _UAPI_LINUX_SIGNAL_H */
diff --git a/kernel/signal.c b/kernel/signal.c
index 0508544..9a24bc3 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3100,7 +3100,8 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s
if (uss) {
void __user *ss_sp;
size_t ss_size;
- int ss_flags;
+ unsigned ss_flags;
+ int ss_mode;
error = -EFAULT;
if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
@@ -3115,18 +3116,13 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s
if (on_sig_stack(sp))
goto out;
+ ss_mode = ss_flags & ~SS_FLAG_BITS;
error = -EINVAL;
- /*
- * Note - this code used to test ss_flags incorrectly:
- * old code may have been written using ss_flags==0
- * to mean ss_flags==SS_ONSTACK (as this was the only
- * way that worked) - this fix preserves that older
- * mechanism.
- */
- if (ss_flags != SS_DISABLE && ss_flags != SS_ONSTACK && ss_flags != 0)
+ if (ss_mode != SS_DISABLE && ss_mode != SS_ONSTACK &&
+ ss_mode != 0)
goto out;
- if (ss_flags == SS_DISABLE) {
+ if (ss_mode == SS_DISABLE) {
ss_size = 0;
ss_sp = NULL;
} else {
--
2.7.2
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web