summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/oleg-signal-rt-fix.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/oleg-signal-rt-fix.patch')
-rw-r--r--debian/patches-rt/oleg-signal-rt-fix.patch70
1 files changed, 28 insertions, 42 deletions
diff --git a/debian/patches-rt/oleg-signal-rt-fix.patch b/debian/patches-rt/oleg-signal-rt-fix.patch
index 0c62e304d..48fb89176 100644
--- a/debian/patches-rt/oleg-signal-rt-fix.patch
+++ b/debian/patches-rt/oleg-signal-rt-fix.patch
@@ -1,7 +1,7 @@
From: Oleg Nesterov <oleg@redhat.com>
Date: Tue, 14 Jul 2015 14:26:34 +0200
Subject: signal/x86: Delay calling signals in atomic
-Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.2/older/patches-5.2.17-rt9.tar.xz
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patches-5.4.3-rt1.tar.xz
On x86_64 we must disable preemption before we enable interrupts
for stack faults, int3 and debugging, because the current task is using
@@ -9,7 +9,7 @@ a per CPU debug stack defined by the IST. If we schedule out, another task
can come in and use the same stack and cause the stack to be corrupted
and crash the kernel on return.
-When CONFIG_PREEMPT_RT_FULL is enabled, spin_locks become mutexes, and
+When CONFIG_PREEMPT_RT is enabled, spin_locks become mutexes, and
one of these is the spin lock used in signal handling.
Some of the debug code (int3) causes do_trap() to send a signal.
@@ -22,31 +22,33 @@ the signal information is stored on the stacks task_struct and
TIF_NOTIFY_RESUME is set. Then on exit of the trap, the signal resume
code will send the signal when preemption is enabled.
-[ rostedt: Switched from #ifdef CONFIG_PREEMPT_RT_FULL to
+[ rostedt: Switched from #ifdef CONFIG_PREEMPT_RT to
ARCH_RT_DELAYS_SIGNAL_SEND and added comments to the code. ]
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+[bigeasy: also needed on 32bit as per Yang Shi <yang.shi@linaro.org>]
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
arch/x86/entry/common.c | 7 +++++++
arch/x86/include/asm/signal.h | 13 +++++++++++++
include/linux/sched.h | 4 ++++
- kernel/signal.c | 37 +++++++++++++++++++++++++++++++++++--
- 4 files changed, 59 insertions(+), 2 deletions(-)
+ kernel/signal.c | 28 ++++++++++++++++++++++++++++
+ 4 files changed, 52 insertions(+)
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
-@@ -153,6 +153,13 @@ static void exit_to_usermode_loop(struct
+@@ -148,6 +148,13 @@ static void exit_to_usermode_loop(struct
if (cached_flags & _TIF_NEED_RESCHED)
schedule();
+#ifdef ARCH_RT_DELAYS_SIGNAL_SEND
+ if (unlikely(current->forced_info.si_signo)) {
+ struct task_struct *t = current;
-+ force_sig_info(t->forced_info.si_signo, &t->forced_info, t);
++ force_sig_info(&t->forced_info);
+ t->forced_info.si_signo = 0;
+ }
+#endif
@@ -63,12 +65,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ * Because some traps use the IST stack, we must keep preemption
+ * disabled while calling do_trap(), but do_trap() may call
+ * force_sig_info() which will grab the signal spin_locks for the
-+ * task, which in PREEMPT_RT_FULL are mutexes. By defining
++ * task, which in PREEMPT_RT are mutexes. By defining
+ * ARCH_RT_DELAYS_SIGNAL_SEND the force_sig_info() will set
+ * TIF_NOTIFY_RESUME and set up the signal to be sent on exit of the
+ * trap.
+ */
-+#if defined(CONFIG_PREEMPT_RT_FULL) && defined(CONFIG_X86_64)
++#if defined(CONFIG_PREEMPT_RT)
+#define ARCH_RT_DELAYS_SIGNAL_SEND
+#endif
+
@@ -77,11 +79,11 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#endif
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
-@@ -875,6 +875,10 @@ struct task_struct {
+@@ -918,6 +918,10 @@ struct task_struct {
/* Restored if set_restore_sigmask() was used: */
sigset_t saved_sigmask;
struct sigpending pending;
-+#ifdef CONFIG_PREEMPT_RT_FULL
++#ifdef CONFIG_PREEMPT_RT
+ /* TODO: move me into ->restart_block ? */
+ struct kernel_siginfo forced_info;
+#endif
@@ -90,39 +92,26 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
unsigned int sas_ss_flags;
--- a/kernel/signal.c
+++ b/kernel/signal.c
-@@ -1287,8 +1287,8 @@ int do_send_sig_info(int sig, struct ker
- * We don't want to have recursive SIGSEGV's etc, for example,
- * that is why we also clear SIGNAL_UNKILLABLE.
- */
--int
--force_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *t)
-+static int
-+do_force_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *t)
- {
- unsigned long int flags;
- int ret, blocked, ignored;
-@@ -1317,6 +1317,39 @@ force_sig_info(int sig, struct kernel_si
- return ret;
- }
+@@ -1308,6 +1308,34 @@ force_sig_info_to_task(struct kernel_sig
+ struct k_sigaction *action;
+ int sig = info->si_signo;
-+int force_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *t)
-+{
-+/*
-+ * On some archs, PREEMPT_RT has to delay sending a signal from a trap
-+ * since it can not enable preemption, and the signal code's spin_locks
-+ * turn into mutexes. Instead, it must set TIF_NOTIFY_RESUME which will
-+ * send the signal on exit of the trap.
-+ */
++ /*
++ * On some archs, PREEMPT_RT has to delay sending a signal from a trap
++ * since it can not enable preemption, and the signal code's spin_locks
++ * turn into mutexes. Instead, it must set TIF_NOTIFY_RESUME which will
++ * send the signal on exit of the trap.
++ */
+#ifdef ARCH_RT_DELAYS_SIGNAL_SEND
+ if (in_atomic()) {
-+ if (WARN_ON_ONCE(t != current))
-+ return 0;
++ struct task_struct *t = current;
++
+ if (WARN_ON_ONCE(t->forced_info.si_signo))
+ return 0;
+
+ if (is_si_special(info)) {
+ WARN_ON_ONCE(info != SEND_SIG_PRIV);
-+ t->forced_info.si_signo = sig;
++ t->forced_info.si_signo = info->si_signo;
+ t->forced_info.si_errno = 0;
+ t->forced_info.si_code = SI_KERNEL;
+ t->forced_info.si_pid = 0;
@@ -135,9 +124,6 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ return 0;
+ }
+#endif
-+ return do_force_sig_info(sig, info, t);
-+}
-+
- /*
- * Nuke all other threads in the group.
- */
+ spin_lock_irqsave(&t->sighand->siglock, flags);
+ action = &t->sighand->action[sig-1];
+ ignored = action->sa.sa_handler == SIG_IGN;