2013-05-01 15:27:08

by Jiri Olsa

[permalink] [raw]
Subject: [PATCHv3 0/4] perf, signal x86: Fix breakpoint events overflow handling

hi,
sending v3 for initial patchset:
https://lkml.org/lkml/2013/3/1/324

basically just sending remaining (not pulled) patches,
with '*-by: *' tags updated.

v3 changes:
- perf test patches already pulled in
- added Oleg's Tested-by for signal related patches
- added Frederic's Reviewed-by for signal related patches
- added Peter's Reviewed-by for perf patch.

v2 changes:
- added patch to merge EFLAGS bit clearing into single statement

Also available at:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/linux.git
tip/perf/RF

thanks,
jirka

Signed-off-by: Jiri Olsa <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
---
Jiri Olsa (4):
signal x86: Propage RF EFLAGS bit throught the signal restore call
signal x86: Clear RF EFLAGS bit for signal handler
signal x86: Merge EFLAGS bit clearing into single statement
perf: Fix hw breakpoints overflow period sampling

arch/x86/ia32/ia32_signal.c | 2 --
arch/x86/include/asm/sighandling.h | 4 ++--
arch/x86/kernel/signal.c | 16 ++++++----------
include/linux/perf_event.h | 2 ++
kernel/events/core.c | 2 +-
kernel/events/hw_breakpoint.c | 5 +++++
6 files changed, 16 insertions(+), 15 deletions(-)


2013-05-01 15:26:42

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 3/4] signal x86: Merge EFLAGS bit clearing into single statement

Merging EFLAGS bit clearing into a single statement, to
ensure EFLAGS bits being cleared in single instruction.

Signed-off-by: Jiri Olsa <[email protected]>
Tested-by: Oleg Nesterov <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
---
arch/x86/kernel/signal.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index cb12fc9..cf91358 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));
}
--
1.7.11.7

2013-05-01 15:26:52

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 1/4] signal x86: Propage RF EFLAGS bit throught the signal restore call

Adding 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 <[email protected]>
Tested-by: Oleg Nesterov <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
---
arch/x86/ia32/ia32_signal.c | 2 --
arch/x86/include/asm/sighandling.h | 4 ++--
arch/x86/kernel/signal.c | 6 ------
3 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index cf1a471..bccfca6 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -34,8 +34,6 @@
#include <asm/sys_ia32.h>
#include <asm/smap.h>

-#define FIX_EFLAGS __FIX_EFLAGS
-
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
{
int err = 0;
diff --git a/arch/x86/include/asm/sighandling.h b/arch/x86/include/asm/sighandling.h
index beff97f..7a95816 100644
--- a/arch/x86/include/asm/sighandling.h
+++ b/arch/x86/include/asm/sighandling.h
@@ -7,10 +7,10 @@

#include <asm/processor-flags.h>

-#define __FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
+#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
- X86_EFLAGS_CF)
+ X86_EFLAGS_CF | X86_EFLAGS_RF)

void signal_fault(struct pt_regs *regs, void __user *frame, char *where);

diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 6956299..9df4c0b 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -43,12 +43,6 @@

#include <asm/sigframe.h>

-#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)
--
1.7.11.7

2013-05-01 15:27:16

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 2/4] signal x86: 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 <[email protected]>
Tested-by: Oleg Nesterov <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
---
arch/x86/kernel/signal.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 9df4c0b..cb12fc9 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -665,6 +665,12 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
*/
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
--
1.7.11.7

2013-05-01 15:28:01

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 4/4] perf: Fix hw breakpoints overflow period sampling

The hw breakpoint pmu 'add' function is missing the
period_left update needed for SW events.

The perf HW breakpoint events use SW events framework
for to process the overflow, so it needs to be properly
initialized during PMU 'add' method.

Signed-off-by: Jiri Olsa <[email protected]>
Reviewed-by: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
---
include/linux/perf_event.h | 2 ++
kernel/events/core.c | 2 +-
kernel/events/hw_breakpoint.c | 5 +++++
3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f463a46..fa38612 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -743,6 +743,7 @@ extern unsigned int perf_output_skip(struct perf_output_handle *handle,
unsigned int len);
extern int perf_swevent_get_recursion_context(void);
extern void perf_swevent_put_recursion_context(int rctx);
+extern u64 perf_swevent_set_period(struct perf_event *event);
extern void perf_event_enable(struct perf_event *event);
extern void perf_event_disable(struct perf_event *event);
extern int __perf_event_disable(void *info);
@@ -782,6 +783,7 @@ static inline void perf_event_fork(struct task_struct *tsk) { }
static inline void perf_event_init(void) { }
static inline int perf_swevent_get_recursion_context(void) { return -1; }
static inline void perf_swevent_put_recursion_context(int rctx) { }
+static inline u64 perf_swevent_set_period(struct perf_event *event) { return 0; }
static inline void perf_event_enable(struct perf_event *event) { }
static inline void perf_event_disable(struct perf_event *event) { }
static inline int __perf_event_disable(void *info) { return -1; }
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 82c01bf..f50d222 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5008,7 +5008,7 @@ static DEFINE_PER_CPU(struct swevent_htable, swevent_htable);
* sign as trigger.
*/

-static u64 perf_swevent_set_period(struct perf_event *event)
+u64 perf_swevent_set_period(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
u64 period = hwc->last_period;
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c
index a64f8ae..966a241 100644
--- a/kernel/events/hw_breakpoint.c
+++ b/kernel/events/hw_breakpoint.c
@@ -612,6 +612,11 @@ static int hw_breakpoint_add(struct perf_event *bp, int flags)
if (!(flags & PERF_EF_START))
bp->hw.state = PERF_HES_STOPPED;

+ if (is_sampling_event(bp)) {
+ bp->hw.last_period = bp->hw.sample_period;
+ perf_swevent_set_period(bp);
+ }
+
return arch_install_hw_breakpoint(bp);
}

--
1.7.11.7

2013-05-01 15:57:31

by Oleg Nesterov

[permalink] [raw]
Subject: Re: [PATCHv3 0/4] perf, signal x86: Fix breakpoint events overflow handling

On 05/01, Jiri Olsa wrote:
>
> - added Oleg's Tested-by for signal related patches

See the test-case below. Without 1/4 + 2/4 it fails, it can
miss the 2nd bp or report the 1st one twice.

Jan, FYI.

Oleg.

#define _GNU_SOURCE 1
#include <stdio.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/debugreg.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <assert.h>
#include <assert.h>
#include <stddef.h>

#define DR_GLOBAL_ENABLE 0x2
#define DR_LOCAL_ENABLE 0x1

unsigned long encode_dr7(int drnum, int enable, unsigned int type, unsigned int len)
{
unsigned long dr7;

dr7 = ((len | type) & 0xf)
<< (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
if (enable)
dr7 |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE));

return dr7;
}

int write_dr(int pid, int dr, unsigned long val)
{
return ptrace(PTRACE_POKEUSER, pid,
offsetof (struct user, u_debugreg[dr]),
val);
}

#define GET_REG(pid, reg) \
ptrace(PTRACE_PEEKUSER, (pid), \
offsetof(struct user, regs.reg), 0)

void *get_ip(int pid)
{
return (void*)GET_REG(pid, rip);
}


void func(void)
{
printf("bp_1 passed\n");
}

void sigh(int sig)
{
printf("bp_2 passed\n");
}

int main(void)
{
int pid, stat;
unsigned long dr7;

pid = fork();
if (!pid) {
assert(ptrace(PTRACE_TRACEME, 0,0,0) == 0);
kill(getpid(), SIGHUP);

signal(SIGINT, sigh);

func();

return 0x13;
}

assert(pid == waitpid(-1, &stat, 0));
assert(WSTOPSIG(stat) == SIGHUP);

assert(write_dr(pid, 0, (long)func) == 0);
assert(write_dr(pid, 1, (long)sigh) == 0);

dr7 = 0;
dr7 |= encode_dr7(0, 1, DR_RW_EXECUTE, DR_LEN_1);
dr7 |= encode_dr7(1, 1, DR_RW_EXECUTE, DR_LEN_1);

assert(write_dr(pid, 7, dr7) == 0);

assert(ptrace(PTRACE_CONT, pid, 0,0) == 0);
assert(pid == waitpid(-1, &stat, 0));
assert(WSTOPSIG(stat) == SIGTRAP);
assert(get_ip(pid) == func);

kill(pid, SIGINT);
assert(ptrace(PTRACE_CONT, pid, 0,0) == 0);
assert(pid == waitpid(-1, &stat, 0));
assert(WSTOPSIG(stat) == SIGINT);

assert(ptrace(PTRACE_CONT, pid, 0,SIGINT) == 0);
assert(pid == waitpid(-1, &stat, 0));
assert(WSTOPSIG(stat) == SIGTRAP);
assert(get_ip(pid) == sigh);

assert(ptrace(PTRACE_CONT, pid, 0,0) == 0);
assert(pid == waitpid(-1, &stat, 0));
assert(stat == 0x1300);

return 0;
}

2013-05-07 12:45:50

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCHv3 0/4] perf, signal x86: Fix breakpoint events overflow handling

On Wed, May 01, 2013 at 05:25:40PM +0200, Jiri Olsa wrote:
> hi,
> sending v3 for initial patchset:
> https://lkml.org/lkml/2013/3/1/324
>
> basically just sending remaining (not pulled) patches,
> with '*-by: *' tags updated.
>
> v3 changes:
> - perf test patches already pulled in
> - added Oleg's Tested-by for signal related patches
> - added Frederic's Reviewed-by for signal related patches
> - added Peter's Reviewed-by for perf patch.

hi,

Thomas, Peter,
any chance you could pull this in?

Ingo,
could you please take the perf change (4/4)?
it's reviewed by PeterZ

thanks,
jirka

2013-05-15 15:06:32

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCHv3 0/4] perf, signal x86: Fix breakpoint events overflow handling

On Tue, May 07, 2013 at 02:29:48PM +0200, Jiri Olsa wrote:
> On Wed, May 01, 2013 at 05:25:40PM +0200, Jiri Olsa wrote:
> > hi,
> > sending v3 for initial patchset:
> > https://lkml.org/lkml/2013/3/1/324
> >
> > basically just sending remaining (not pulled) patches,
> > with '*-by: *' tags updated.
> >
> > v3 changes:
> > - perf test patches already pulled in
> > - added Oleg's Tested-by for signal related patches
> > - added Frederic's Reviewed-by for signal related patches
> > - added Peter's Reviewed-by for perf patch.
>
> hi,
>
> Thomas, Peter,
> any chance you could pull this in?
>
> Ingo,
> could you please take the perf change (4/4)?
> it's reviewed by PeterZ

ping

jirka

2013-05-15 15:44:10

by Frederic Weisbecker

[permalink] [raw]
Subject: Re: [PATCHv3 0/4] perf, signal x86: Fix breakpoint events overflow handling

2013/5/15 Jiri Olsa <[email protected]>:
> On Tue, May 07, 2013 at 02:29:48PM +0200, Jiri Olsa wrote:
>> On Wed, May 01, 2013 at 05:25:40PM +0200, Jiri Olsa wrote:
>> > hi,
>> > sending v3 for initial patchset:
>> > https://lkml.org/lkml/2013/3/1/324
>> >
>> > basically just sending remaining (not pulled) patches,
>> > with '*-by: *' tags updated.
>> >
>> > v3 changes:
>> > - perf test patches already pulled in
>> > - added Oleg's Tested-by for signal related patches
>> > - added Frederic's Reviewed-by for signal related patches
>> > - added Peter's Reviewed-by for perf patch.
>>
>> hi,
>>
>> Thomas, Peter,
>> any chance you could pull this in?
>>
>> Ingo,
>> could you please take the perf change (4/4)?
>> it's reviewed by PeterZ
>
> ping

May be you can set up a branch based on v3.10-rc1 with these patches
applied on top and send it as a pull request to Ingo (and LKML + other
people Cc'ed). Your branch is not pullable as is because it seems to
be based on tip:master (it's not targeted for mainline, just there for
testing) and moreover an old enough version of it.

Just suggesting that because clean pull requests based on sane
starting points usually get better and faster attention than
standalone patches because it's less maintainance noise. Also you have
all the necessary acks so it's all good.

Thanks!

2013-05-15 16:53:25

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCHv3 0/4] perf, signal x86: Fix breakpoint events overflow handling

On Wed, May 15, 2013 at 05:04:50PM +0200, Jiri Olsa wrote:
> On Tue, May 07, 2013 at 02:29:48PM +0200, Jiri Olsa wrote:
> > On Wed, May 01, 2013 at 05:25:40PM +0200, Jiri Olsa wrote:
> > > hi,
> > > sending v3 for initial patchset:
> > > https://lkml.org/lkml/2013/3/1/324
> > >
> > > basically just sending remaining (not pulled) patches,
> > > with '*-by: *' tags updated.
> > >
> > > v3 changes:
> > > - perf test patches already pulled in
> > > - added Oleg's Tested-by for signal related patches
> > > - added Frederic's Reviewed-by for signal related patches
> > > - added Peter's Reviewed-by for perf patch.
> >
> > hi,
> >
> > Thomas, Peter,
> > any chance you could pull this in?
> >
> > Ingo,
> > could you please take the perf change (4/4)?
> > it's reviewed by PeterZ

Queued them, will shove them Ingo-wards soonish.

2013-05-15 19:29:15

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCHv3 0/4] perf, signal x86: Fix breakpoint events overflow handling

On Wed, May 15, 2013 at 05:44:07PM +0200, Frederic Weisbecker wrote:
> 2013/5/15 Jiri Olsa <[email protected]>:
> > On Tue, May 07, 2013 at 02:29:48PM +0200, Jiri Olsa wrote:
> >> On Wed, May 01, 2013 at 05:25:40PM +0200, Jiri Olsa wrote:
> >> > hi,
> >> > sending v3 for initial patchset:
> >> > https://lkml.org/lkml/2013/3/1/324
> >> >
> >> > basically just sending remaining (not pulled) patches,
> >> > with '*-by: *' tags updated.
> >> >
> >> > v3 changes:
> >> > - perf test patches already pulled in
> >> > - added Oleg's Tested-by for signal related patches
> >> > - added Frederic's Reviewed-by for signal related patches
> >> > - added Peter's Reviewed-by for perf patch.
> >>
> >> hi,
> >>
> >> Thomas, Peter,
> >> any chance you could pull this in?
> >>
> >> Ingo,
> >> could you please take the perf change (4/4)?
> >> it's reviewed by PeterZ
> >
> > ping
>
> May be you can set up a branch based on v3.10-rc1 with these patches
> applied on top and send it as a pull request to Ingo (and LKML + other
> people Cc'ed). Your branch is not pullable as is because it seems to
> be based on tip:master (it's not targeted for mainline, just there for
> testing) and moreover an old enough version of it.

thanks for suggestion, will do this next time :)

jirka

2013-05-15 19:29:54

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCHv3 0/4] perf, signal x86: Fix breakpoint events overflow handling

On Wed, May 15, 2013 at 06:52:33PM +0200, Peter Zijlstra wrote:
> On Wed, May 15, 2013 at 05:04:50PM +0200, Jiri Olsa wrote:
> > On Tue, May 07, 2013 at 02:29:48PM +0200, Jiri Olsa wrote:
> > > On Wed, May 01, 2013 at 05:25:40PM +0200, Jiri Olsa wrote:
> > > > hi,
> > > > sending v3 for initial patchset:
> > > > https://lkml.org/lkml/2013/3/1/324
> > > >
> > > > basically just sending remaining (not pulled) patches,
> > > > with '*-by: *' tags updated.
> > > >
> > > > v3 changes:
> > > > - perf test patches already pulled in
> > > > - added Oleg's Tested-by for signal related patches
> > > > - added Frederic's Reviewed-by for signal related patches
> > > > - added Peter's Reviewed-by for perf patch.
> > >
> > > hi,
> > >
> > > Thomas, Peter,
> > > any chance you could pull this in?
> > >
> > > Ingo,
> > > could you please take the perf change (4/4)?
> > > it's reviewed by PeterZ
>
> Queued them, will shove them Ingo-wards soonish.
>

thanks,

jirka

Subject: [tip:perf/core] x86/signals: Propagate RF EFLAGS bit through the signal restore call

Commit-ID: 5e219b3c671b34b2d79468fe89c44c0460c0f02b
Gitweb: http://git.kernel.org/tip/5e219b3c671b34b2d79468fe89c44c0460c0f02b
Author: Jiri Olsa <[email protected]>
AuthorDate: Wed, 1 May 2013 17:25:41 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 28 May 2013 08:46:50 +0200

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 <[email protected]>
Tested-by: Oleg Nesterov <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
Originally-Reported-by: Vince Weaver <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/x86/ia32/ia32_signal.c | 2 --
arch/x86/include/asm/sighandling.h | 4 ++--
arch/x86/kernel/signal.c | 6 ------
3 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index cf1a471..bccfca6 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -34,8 +34,6 @@
#include <asm/sys_ia32.h>
#include <asm/smap.h>

-#define FIX_EFLAGS __FIX_EFLAGS
-
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
{
int err = 0;
diff --git a/arch/x86/include/asm/sighandling.h b/arch/x86/include/asm/sighandling.h
index beff97f..7a95816 100644
--- a/arch/x86/include/asm/sighandling.h
+++ b/arch/x86/include/asm/sighandling.h
@@ -7,10 +7,10 @@

#include <asm/processor-flags.h>

-#define __FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
+#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
- X86_EFLAGS_CF)
+ X86_EFLAGS_CF | X86_EFLAGS_RF)

void signal_fault(struct pt_regs *regs, void __user *frame, char *where);

diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 6956299..9df4c0b 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -43,12 +43,6 @@

#include <asm/sigframe.h>

-#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)

Subject: [tip:perf/core] x86/signals: Clear RF EFLAGS bit for signal handler

Commit-ID: 24cda10996f5420ab962f91cd03c15869a3a94b1
Gitweb: http://git.kernel.org/tip/24cda10996f5420ab962f91cd03c15869a3a94b1
Author: Jiri Olsa <[email protected]>
AuthorDate: Wed, 1 May 2013 17:25:42 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 28 May 2013 08:46:52 +0200

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 <[email protected]>
Tested-by: Oleg Nesterov <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
Originally-Reported-by: Vince Weaver <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/x86/kernel/signal.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 9df4c0b..cb12fc9 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -665,6 +665,12 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
*/
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

Subject: [tip:perf/core] x86/signals: Merge EFLAGS bit clearing into a single statement

Commit-ID: ddd40da4ccbabdd2e941837aa987e08dfa4396b4
Gitweb: http://git.kernel.org/tip/ddd40da4ccbabdd2e941837aa987e08dfa4396b4
Author: Jiri Olsa <[email protected]>
AuthorDate: Wed, 1 May 2013 17:25:43 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 28 May 2013 08:46:53 +0200

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 <[email protected]>
Tested-by: Oleg Nesterov <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
Originally-Reported-by: Vince Weaver <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/x86/kernel/signal.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index cb12fc9..cf91358 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));
}

Subject: [tip:perf/core] perf: Fix hw breakpoints overflow period sampling

Commit-ID: ab573844e3058eef2788803d373019f8bebead57
Gitweb: http://git.kernel.org/tip/ab573844e3058eef2788803d373019f8bebead57
Author: Jiri Olsa <[email protected]>
AuthorDate: Wed, 1 May 2013 17:25:44 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 28 May 2013 08:59:54 +0200

perf: Fix hw breakpoints overflow period sampling

The hw breakpoint pmu 'add' function is missing the
period_left update needed for SW events.

The perf HW breakpoint events use the SW events framework
to process the overflow, so it needs to be properly initialized
in the PMU 'add' method.

Signed-off-by: Jiri Olsa <[email protected]>
Reviewed-by: Peter Zijlstra <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
include/linux/perf_event.h | 2 ++
kernel/events/core.c | 2 +-
kernel/events/hw_breakpoint.c | 5 +++++
3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f463a46..fa38612 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -743,6 +743,7 @@ extern unsigned int perf_output_skip(struct perf_output_handle *handle,
unsigned int len);
extern int perf_swevent_get_recursion_context(void);
extern void perf_swevent_put_recursion_context(int rctx);
+extern u64 perf_swevent_set_period(struct perf_event *event);
extern void perf_event_enable(struct perf_event *event);
extern void perf_event_disable(struct perf_event *event);
extern int __perf_event_disable(void *info);
@@ -782,6 +783,7 @@ static inline void perf_event_fork(struct task_struct *tsk) { }
static inline void perf_event_init(void) { }
static inline int perf_swevent_get_recursion_context(void) { return -1; }
static inline void perf_swevent_put_recursion_context(int rctx) { }
+static inline u64 perf_swevent_set_period(struct perf_event *event) { return 0; }
static inline void perf_event_enable(struct perf_event *event) { }
static inline void perf_event_disable(struct perf_event *event) { }
static inline int __perf_event_disable(void *info) { return -1; }
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 9dc297f..e0dcced 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4961,7 +4961,7 @@ static DEFINE_PER_CPU(struct swevent_htable, swevent_htable);
* sign as trigger.
*/

-static u64 perf_swevent_set_period(struct perf_event *event)
+u64 perf_swevent_set_period(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
u64 period = hwc->last_period;
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c
index a64f8ae..966a241 100644
--- a/kernel/events/hw_breakpoint.c
+++ b/kernel/events/hw_breakpoint.c
@@ -612,6 +612,11 @@ static int hw_breakpoint_add(struct perf_event *bp, int flags)
if (!(flags & PERF_EF_START))
bp->hw.state = PERF_HES_STOPPED;

+ if (is_sampling_event(bp)) {
+ bp->hw.last_period = bp->hw.sample_period;
+ perf_swevent_set_period(bp);
+ }
+
return arch_install_hw_breakpoint(bp);
}