]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.1.7/revert-x86-sigcontext-cleanups.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.1.7 / revert-x86-sigcontext-cleanups.patch
CommitLineData
ea04701c
GKH
1From ed596cde9425509ec6ce88e19f03e9b13b6f518b Mon Sep 17 00:00:00 2001
2From: Linus Torvalds <torvalds@linux-foundation.org>
3Date: Thu, 13 Aug 2015 08:25:20 -0700
4Subject: Revert x86 sigcontext cleanups
5
6From: Linus Torvalds <torvalds@linux-foundation.org>
7
8commit ed596cde9425509ec6ce88e19f03e9b13b6f518b upstream.
9
10This reverts commits 9a036b93a344 ("x86/signal/64: Remove 'fs' and 'gs'
11from sigcontext") and c6f2062935c8 ("x86/signal/64: Fix SS handling for
12signals delivered to 64-bit programs").
13
14They were cleanups, but they break dosemu by changing the signal return
15behavior (and removing 'fs' and 'gs' from the sigcontext struct - while
16not actually changing any behavior - causes build problems).
17
18Reported-and-tested-by: Stas Sergeev <stsp@list.ru>
19Acked-by: Andy Lutomirski <luto@amacapital.net>
20Cc: Ingo Molnar <mingo@kernel.org>
21Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
22Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23
24---
25 arch/x86/include/asm/sigcontext.h | 6 +++---
26 arch/x86/include/uapi/asm/sigcontext.h | 21 +++------------------
27 arch/x86/kernel/signal.c | 26 +++++++++++---------------
28 3 files changed, 17 insertions(+), 36 deletions(-)
29
30--- a/arch/x86/include/asm/sigcontext.h
31+++ b/arch/x86/include/asm/sigcontext.h
32@@ -57,9 +57,9 @@ struct sigcontext {
33 unsigned long ip;
34 unsigned long flags;
35 unsigned short cs;
36- unsigned short __pad2; /* Was called gs, but was always zero. */
37- unsigned short __pad1; /* Was called fs, but was always zero. */
38- unsigned short ss;
39+ unsigned short gs;
40+ unsigned short fs;
41+ unsigned short __pad0;
42 unsigned long err;
43 unsigned long trapno;
44 unsigned long oldmask;
45--- a/arch/x86/include/uapi/asm/sigcontext.h
46+++ b/arch/x86/include/uapi/asm/sigcontext.h
47@@ -177,24 +177,9 @@ struct sigcontext {
48 __u64 rip;
49 __u64 eflags; /* RFLAGS */
50 __u16 cs;
51-
52- /*
53- * Prior to 2.5.64 ("[PATCH] x86-64 updates for 2.5.64-bk3"),
54- * Linux saved and restored fs and gs in these slots. This
55- * was counterproductive, as fsbase and gsbase were never
56- * saved, so arch_prctl was presumably unreliable.
57- *
58- * If these slots are ever needed for any other purpose, there
59- * is some risk that very old 64-bit binaries could get
60- * confused. I doubt that many such binaries still work,
61- * though, since the same patch in 2.5.64 also removed the
62- * 64-bit set_thread_area syscall, so it appears that there is
63- * no TLS API that works in both pre- and post-2.5.64 kernels.
64- */
65- __u16 __pad2; /* Was gs. */
66- __u16 __pad1; /* Was fs. */
67-
68- __u16 ss;
69+ __u16 gs;
70+ __u16 fs;
71+ __u16 __pad0;
72 __u64 err;
73 __u64 trapno;
74 __u64 oldmask;
75--- a/arch/x86/kernel/signal.c
76+++ b/arch/x86/kernel/signal.c
77@@ -93,8 +93,15 @@ int restore_sigcontext(struct pt_regs *r
78 COPY(r15);
79 #endif /* CONFIG_X86_64 */
80
81+#ifdef CONFIG_X86_32
82 COPY_SEG_CPL3(cs);
83 COPY_SEG_CPL3(ss);
84+#else /* !CONFIG_X86_32 */
85+ /* Kernel saves and restores only the CS segment register on signals,
86+ * which is the bare minimum needed to allow mixed 32/64-bit code.
87+ * App's signal handler can save/restore other segments if needed. */
88+ COPY_SEG_CPL3(cs);
89+#endif /* CONFIG_X86_32 */
90
91 get_user_ex(tmpflags, &sc->flags);
92 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
93@@ -154,9 +161,8 @@ int setup_sigcontext(struct sigcontext _
94 #else /* !CONFIG_X86_32 */
95 put_user_ex(regs->flags, &sc->flags);
96 put_user_ex(regs->cs, &sc->cs);
97- put_user_ex(0, &sc->__pad2);
98- put_user_ex(0, &sc->__pad1);
99- put_user_ex(regs->ss, &sc->ss);
100+ put_user_ex(0, &sc->gs);
101+ put_user_ex(0, &sc->fs);
102 #endif /* CONFIG_X86_32 */
103
104 put_user_ex(fpstate, &sc->fpstate);
105@@ -450,19 +456,9 @@ static int __setup_rt_frame(int sig, str
106
107 regs->sp = (unsigned long)frame;
108
109- /*
110- * Set up the CS and SS registers to run signal handlers in
111- * 64-bit mode, even if the handler happens to be interrupting
112- * 32-bit or 16-bit code.
113- *
114- * SS is subtle. In 64-bit mode, we don't need any particular
115- * SS descriptor, but we do need SS to be valid. It's possible
116- * that the old SS is entirely bogus -- this can happen if the
117- * signal we're trying to deliver is #GP or #SS caused by a bad
118- * SS value.
119- */
120+ /* Set up the CS register to run signal handlers in 64-bit mode,
121+ even if the handler happens to be interrupting 32-bit code. */
122 regs->cs = __USER_CS;
123- regs->ss = __USER_DS;
124
125 return 0;
126 }