From 5e219b3c671b34b2d79468fe89c44c0460c0f02b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 1 May 2013 17:25:41 +0200 Subject: x86/signals: Propagate RF EFLAGS bit through the signal restore call While porting Vince's perf overflow tests I found perf event breakpoint overflow does not work properly. I found the x86 RF EFLAG bit not being set when returning from debug exception after triggering signal handler. Which is exactly what you get when you set perf breakpoint overflow SIGIO handler. This patch and the next two patches fix the underlying bugs. This patch adds the RF EFLAGS bit to be restored on return from signal from the original register context before the signal was entered. This will prevent the RF flag to disappear when returning from exception due to the signal handler being executed. Signed-off-by: Jiri Olsa Tested-by: Oleg Nesterov Reviewed-by: Frederic Weisbecker Originally-Reported-by: Vince Weaver Cc: H. Peter Anvin Cc: Andi Kleen Cc: Oleg Nesterov Cc: Arnaldo Carvalho de Melo Cc: Ingo Molnar Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Vince Weaver Cc: Stephane Eranian Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1367421944-19082-2-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/signal.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch/x86/kernel/signal.c') diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 69562992e45..9df4c0b5eca 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -43,12 +43,6 @@ #include -#ifdef CONFIG_X86_32 -# define FIX_EFLAGS (__FIX_EFLAGS | X86_EFLAGS_RF) -#else -# define FIX_EFLAGS __FIX_EFLAGS -#endif - #define COPY(x) do { \ get_user_ex(regs->x, &sc->x); \ } while (0) -- cgit v1.2.3-18-g5258 From 24cda10996f5420ab962f91cd03c15869a3a94b1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 1 May 2013 17:25:42 +0200 Subject: x86/signals: Clear RF EFLAGS bit for signal handler Clearing RF EFLAGS bit for signal handler. The reason is that this flag is set by debug exception code to prevent the recursive exception entry. Leaving it set for signal handler might prevent debug exception of the signal handler itself. Signed-off-by: Jiri Olsa Tested-by: Oleg Nesterov Reviewed-by: Frederic Weisbecker Originally-Reported-by: Vince Weaver Cc: H. Peter Anvin Cc: Andi Kleen Cc: Oleg Nesterov Cc: Arnaldo Carvalho de Melo Cc: Ingo Molnar Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Vince Weaver Cc: Stephane Eranian Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1367421944-19082-3-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/signal.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/x86/kernel/signal.c') diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 9df4c0b5eca..cb12fc9c064 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -664,6 +664,12 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) * Clear the direction flag as per the ABI for function entry. */ regs->flags &= ~X86_EFLAGS_DF; + /* + * Clear RF when entering the signal handler, because + * it might disable possible debug exception from the + * signal handler. + */ + regs->flags &= ~X86_EFLAGS_RF; /* * Clear TF when entering the signal handler, but * notify any tracer that was single-stepping it. -- cgit v1.2.3-18-g5258 From ddd40da4ccbabdd2e941837aa987e08dfa4396b4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 1 May 2013 17:25:43 +0200 Subject: x86/signals: Merge EFLAGS bit clearing into a single statement Merging EFLAGS bit clearing into a single statement, to ensure EFLAGS bits are being cleared in a single instruction. Signed-off-by: Jiri Olsa Tested-by: Oleg Nesterov Reviewed-by: Frederic Weisbecker Originally-Reported-by: Vince Weaver Cc: H. Peter Anvin Cc: Andi Kleen Cc: Oleg Nesterov Cc: Arnaldo Carvalho de Melo Cc: Ingo Molnar Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Vince Weaver Cc: Stephane Eranian Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1367421944-19082-4-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/signal.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'arch/x86/kernel/signal.c') diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index cb12fc9c064..cf913587d4d 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -662,21 +662,17 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) if (!failed) { /* * Clear the direction flag as per the ABI for function entry. - */ - regs->flags &= ~X86_EFLAGS_DF; - /* + * * Clear RF when entering the signal handler, because * it might disable possible debug exception from the * signal handler. - */ - regs->flags &= ~X86_EFLAGS_RF; - /* + * * Clear TF when entering the signal handler, but * notify any tracer that was single-stepping it. * The tracer may want to single-step inside the * handler too. */ - regs->flags &= ~X86_EFLAGS_TF; + regs->flags &= ~(X86_EFLAGS_DF|X86_EFLAGS_RF|X86_EFLAGS_TF); } signal_setup_done(failed, ksig, test_thread_flag(TIF_SINGLESTEP)); } -- cgit v1.2.3-18-g5258