* [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb
@ 2012-02-08 0:56 Steven Rostedt
2012-02-08 0:56 ` [PATCH RT 1/2 v5] x86: Do not disable preemption in int3 on 32bit Steven Rostedt
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Steven Rostedt @ 2012-02-08 0:56 UTC (permalink / raw)
To: linux-kernel, linux-rt-users
Cc: Thomas Gleixner, Carsten Emde, John Kacur, Masami Hiramatsu,
Ingo Molnar, Andrew Morton, H. Peter Anvin,
Alexander van Heukelum, Andi Kleen, Oleg Nesterov, Clark Williams,
Luis Goncalves
OK, this patch set should be good to go.
Oleg, please take a look at the modifications I made to your patch,
and if you are fine with it, please ack it.
Thomas, this should be the final set (after I get an ack from Oleg)
and hopefully this one can go into -rt.
Thanks!
-- Steve
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH RT 1/2 v5] x86: Do not disable preemption in int3 on 32bit
2012-02-08 0:56 [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb Steven Rostedt
@ 2012-02-08 0:56 ` Steven Rostedt
2012-02-08 0:56 ` [PATCH RT 2/2 v5] signal/x86: Delay calling signals in atomic Steven Rostedt
2012-02-08 11:57 ` [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb Oleg Nesterov
2 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2012-02-08 0:56 UTC (permalink / raw)
To: linux-kernel, linux-rt-users
Cc: Thomas Gleixner, Carsten Emde, John Kacur, Masami Hiramatsu,
Ingo Molnar, Andrew Morton, H. Peter Anvin,
Alexander van Heukelum, Andi Kleen, Oleg Nesterov, Clark Williams,
Luis Goncalves, stable-rt
[-- Attachment #1: fix-rt-int3-x86_32-3.2-rt.patch --]
[-- Type: text/plain, Size: 3335 bytes --]
Preemption must be disabled before enabling interrupts in do_trap
on x86_64 because the stack in use for int3 and debug is a per CPU
stack set by th IST. But 32bit does not have an IST and the stack
still belongs to the current task and there is no problem in scheduling
out the task.
Keep preemption enabled on X86_32 when enabling interrupts for
do_trap().
The name of the function is changed from preempt_conditional_sti/cli()
to conditional_sti/cli_ist(), to annotate that this function is used
when the stack is on the IST.
Cc: stable-rt@vger.kernel.org
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Index: linux-rt.git/arch/x86/kernel/traps.c
===================================================================
--- linux-rt.git.orig/arch/x86/kernel/traps.c
+++ linux-rt.git/arch/x86/kernel/traps.c
@@ -87,9 +87,21 @@ static inline void conditional_sti(struc
local_irq_enable();
}
-static inline void preempt_conditional_sti(struct pt_regs *regs)
+static inline void conditional_sti_ist(struct pt_regs *regs)
{
+#ifdef CONFIG_X86_64
+ /*
+ * X86_64 uses a per CPU stack on the IST for certain traps
+ * like int3. The task can not be preempted when using one
+ * of these stacks, thus preemption must be disabled, otherwise
+ * the stack can be corrupted if the task is scheduled out,
+ * and another task comes in and uses this stack.
+ *
+ * On x86_32 the task keeps its own stack and it is OK if the
+ * task schedules out.
+ */
inc_preempt_count();
+#endif
if (regs->flags & X86_EFLAGS_IF)
local_irq_enable();
}
@@ -100,11 +112,13 @@ static inline void conditional_cli(struc
local_irq_disable();
}
-static inline void preempt_conditional_cli(struct pt_regs *regs)
+static inline void conditional_cli_ist(struct pt_regs *regs)
{
if (regs->flags & X86_EFLAGS_IF)
local_irq_disable();
+#ifdef CONFIG_X86_64
dec_preempt_count();
+#endif
}
static void __kprobes
@@ -222,9 +236,9 @@ dotraplinkage void do_stack_segment(stru
if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
12, SIGBUS) == NOTIFY_STOP)
return;
- preempt_conditional_sti(regs);
+ conditional_sti_ist(regs);
do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL);
- preempt_conditional_cli(regs);
+ conditional_cli_ist(regs);
}
dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
@@ -316,9 +330,9 @@ dotraplinkage void __kprobes do_int3(str
return;
#endif
- preempt_conditional_sti(regs);
+ conditional_sti_ist(regs);
do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
- preempt_conditional_cli(regs);
+ conditional_cli_ist(regs);
}
#ifdef CONFIG_X86_64
@@ -412,12 +426,12 @@ dotraplinkage void __kprobes do_debug(st
return;
/* It's safe to allow irq's after DR6 has been saved */
- preempt_conditional_sti(regs);
+ conditional_sti_ist(regs);
if (regs->flags & X86_VM_MASK) {
handle_vm86_trap((struct kernel_vm86_regs *) regs,
error_code, 1);
- preempt_conditional_cli(regs);
+ conditional_cli_ist(regs);
return;
}
@@ -436,7 +450,7 @@ dotraplinkage void __kprobes do_debug(st
si_code = get_si_code(tsk->thread.debugreg6);
if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
send_sigtrap(tsk, regs, error_code, si_code);
- preempt_conditional_cli(regs);
+ conditional_cli_ist(regs);
return;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH RT 2/2 v5] signal/x86: Delay calling signals in atomic
2012-02-08 0:56 [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb Steven Rostedt
2012-02-08 0:56 ` [PATCH RT 1/2 v5] x86: Do not disable preemption in int3 on 32bit Steven Rostedt
@ 2012-02-08 0:56 ` Steven Rostedt
2012-02-08 11:57 ` [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb Oleg Nesterov
2 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2012-02-08 0:56 UTC (permalink / raw)
To: linux-kernel, linux-rt-users
Cc: Thomas Gleixner, Carsten Emde, John Kacur, Masami Hiramatsu,
Ingo Molnar, Andrew Morton, H. Peter Anvin,
Alexander van Heukelum, Andi Kleen, Oleg Nesterov, Clark Williams,
Luis Goncalves, stable-rt
[-- Attachment #1: oleg-signal-rt-fix.patch --]
[-- Type: text/plain, Size: 5165 bytes --]
From: Oleg Nesterov <oleg@redhat.com>
On x86_64 we must disable preemption before we enable interrupts
for stack faults, int3 and debugging, because the current task is using
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
one of these is the spin lock used in signal handling.
Some of the debug code (int3) causes do_trap() to send a signal.
This function calls a spin lock that has been converted to a mutex
and has the possibility to sleep. If this happens, the above issues with
the corrupted stack is possible.
Instead of calling the signal right away, for PREEMPT_RT and x86_64,
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.
Cc: stable-rt@vger.kernel.org
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
[ Switched from #ifdef CONFIG_PREEMPT_RT_FULL to ARCH_RT_DELAYS_SIGNAL_SEND
and added comments to the code. ]
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
arch/x86/kernel/signal.c | 9 +++++++++
include/linux/sched.h | 4 ++++
kernel/signal.c | 31 +++++++++++++++++++++++++++++--
3 files changed, 42 insertions(+), 2 deletions(-)
Index: linux-rt.git/arch/x86/kernel/signal.c
===================================================================
--- linux-rt.git.orig/arch/x86/kernel/signal.c
+++ linux-rt.git/arch/x86/kernel/signal.c
@@ -820,6 +820,15 @@ do_notify_resume(struct pt_regs *regs, v
mce_notify_process();
#endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
+#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);
+ t->forced_info.si_signo = 0;
+ }
+#endif
+
/* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs);
Index: linux-rt.git/include/linux/sched.h
===================================================================
--- linux-rt.git.orig/include/linux/sched.h
+++ linux-rt.git/include/linux/sched.h
@@ -1405,6 +1405,10 @@ struct task_struct {
sigset_t blocked, real_blocked;
sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */
struct sigpending pending;
+#ifdef CONFIG_PREEMPT_RT_FULL
+ /* TODO: move me into ->restart_block ? */
+ struct siginfo forced_info;
+#endif
unsigned long sas_ss_sp;
size_t sas_ss_size;
Index: linux-rt.git/kernel/signal.c
===================================================================
--- linux-rt.git.orig/kernel/signal.c
+++ linux-rt.git/kernel/signal.c
@@ -1273,8 +1273,8 @@ int do_send_sig_info(int sig, struct sig
* 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 siginfo *info, struct task_struct *t)
+static int
+do_force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
{
unsigned long int flags;
int ret, blocked, ignored;
@@ -1299,6 +1299,39 @@ force_sig_info(int sig, struct siginfo *
return ret;
}
+int force_sig_info(int sig, struct 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.
+ */
+#ifdef ARCH_RT_DELAYS_SIGNAL_SEND
+ if (in_atomic()) {
+ if (WARN_ON_ONCE(t != current))
+ return 0;
+ 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_errno = 0;
+ t->forced_info.si_code = SI_KERNEL;
+ t->forced_info.si_pid = 0;
+ t->forced_info.si_uid = 0;
+ } else {
+ t->forced_info = *info;
+ }
+
+ set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
+ return 0;
+ }
+#endif
+ return do_force_sig_info(sig, info, t);
+}
+
/*
* Nuke all other threads in the group.
*/
Index: linux-rt.git/arch/x86/include/asm/signal.h
===================================================================
--- linux-rt.git.orig/arch/x86/include/asm/signal.h
+++ linux-rt.git/arch/x86/include/asm/signal.h
@@ -31,6 +31,19 @@ typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
+/*
+ * 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 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)
+#define ARCH_RT_DELAYS_SIGNAL_SEND
+#endif
+
#else
/* Here we must cater to libcs that poke about in kernel headers. */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb
2012-02-08 0:56 [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb Steven Rostedt
2012-02-08 0:56 ` [PATCH RT 1/2 v5] x86: Do not disable preemption in int3 on 32bit Steven Rostedt
2012-02-08 0:56 ` [PATCH RT 2/2 v5] signal/x86: Delay calling signals in atomic Steven Rostedt
@ 2012-02-08 11:57 ` Oleg Nesterov
2012-02-08 13:46 ` Steven Rostedt
2 siblings, 1 reply; 5+ messages in thread
From: Oleg Nesterov @ 2012-02-08 11:57 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, linux-rt-users, Thomas Gleixner, Carsten Emde,
John Kacur, Masami Hiramatsu, Ingo Molnar, Andrew Morton,
H. Peter Anvin, Alexander van Heukelum, Andi Kleen,
Clark Williams, Luis Goncalves
On 02/07, Steven Rostedt wrote:
>
> Oleg, please take a look at the modifications I made to your patch,
> and if you are fine with it, please ack it.
Yes, I believe the modifications are fine.
Thanks Steven!
Oleg.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb
2012-02-08 11:57 ` [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb Oleg Nesterov
@ 2012-02-08 13:46 ` Steven Rostedt
0 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2012-02-08 13:46 UTC (permalink / raw)
To: Oleg Nesterov
Cc: linux-kernel, linux-rt-users, Thomas Gleixner, Carsten Emde,
John Kacur, Masami Hiramatsu, Ingo Molnar, Andrew Morton,
H. Peter Anvin, Alexander van Heukelum, Andi Kleen,
Clark Williams, Luis Goncalves
On Wed, 2012-02-08 at 12:57 +0100, Oleg Nesterov wrote:
> On 02/07, Steven Rostedt wrote:
> >
> > Oleg, please take a look at the modifications I made to your patch,
> > and if you are fine with it, please ack it.
>
> Yes, I believe the modifications are fine.
Thanks Oleg,
Thomas, can you add these to the 3.2-rt series.
-- Steve
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-02-08 13:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-08 0:56 [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb Steven Rostedt
2012-02-08 0:56 ` [PATCH RT 1/2 v5] x86: Do not disable preemption in int3 on 32bit Steven Rostedt
2012-02-08 0:56 ` [PATCH RT 2/2 v5] signal/x86: Delay calling signals in atomic Steven Rostedt
2012-02-08 11:57 ` [PATCH RT 0/2 v5] preempt-rt/x86: Handle sending signals from do_trap() by gdb Oleg Nesterov
2012-02-08 13:46 ` Steven Rostedt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).