Skip to content

Commit

Permalink
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
 "Two fixlets"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf/hwbp: Simplify the perf-hwbp code, fix documentation
  perf/x86/intel: Fix linear IP of PEBS real_ip on Haswell and later CPUs
  • Loading branch information
torvalds committed Mar 31, 2018
2 parents ad0500c + f67b150 commit 10b84da
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 31 deletions.
25 changes: 17 additions & 8 deletions arch/x86/events/intel/ds.c
Expand Up @@ -1153,6 +1153,7 @@ static void setup_pebs_sample_data(struct perf_event *event,
if (pebs == NULL)
return;

regs->flags &= ~PERF_EFLAGS_EXACT;
sample_type = event->attr.sample_type;
dsrc = sample_type & PERF_SAMPLE_DATA_SRC;

Expand Down Expand Up @@ -1197,7 +1198,6 @@ static void setup_pebs_sample_data(struct perf_event *event,
*/
*regs = *iregs;
regs->flags = pebs->flags;
set_linear_ip(regs, pebs->ip);

if (sample_type & PERF_SAMPLE_REGS_INTR) {
regs->ax = pebs->ax;
Expand Down Expand Up @@ -1233,13 +1233,22 @@ static void setup_pebs_sample_data(struct perf_event *event,
#endif
}

if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
regs->ip = pebs->real_ip;
regs->flags |= PERF_EFLAGS_EXACT;
} else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
regs->flags |= PERF_EFLAGS_EXACT;
else
regs->flags &= ~PERF_EFLAGS_EXACT;
if (event->attr.precise_ip > 1) {
/* Haswell and later have the eventing IP, so use it: */
if (x86_pmu.intel_cap.pebs_format >= 2) {
set_linear_ip(regs, pebs->real_ip);
regs->flags |= PERF_EFLAGS_EXACT;
} else {
/* Otherwise use PEBS off-by-1 IP: */
set_linear_ip(regs, pebs->ip);

/* ... and try to fix it up using the LBR entries: */
if (intel_pmu_pebs_fixup_ip(regs))
regs->flags |= PERF_EFLAGS_EXACT;
}
} else
set_linear_ip(regs, pebs->ip);


if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) &&
x86_pmu.intel_cap.pebs_format >= 1)
Expand Down
30 changes: 7 additions & 23 deletions kernel/events/hw_breakpoint.c
Expand Up @@ -427,16 +427,9 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
* modify_user_hw_breakpoint - modify a user-space hardware breakpoint
* @bp: the breakpoint structure to modify
* @attr: new breakpoint attributes
* @triggered: callback to trigger when we hit the breakpoint
* @tsk: pointer to 'task_struct' of the process to which the address belongs
*/
int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
{
u64 old_addr = bp->attr.bp_addr;
u64 old_len = bp->attr.bp_len;
int old_type = bp->attr.bp_type;
int err = 0;

/*
* modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it
* will not be possible to raise IPIs that invoke __perf_event_disable.
Expand All @@ -451,27 +444,18 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
bp->attr.bp_addr = attr->bp_addr;
bp->attr.bp_type = attr->bp_type;
bp->attr.bp_len = attr->bp_len;
bp->attr.disabled = 1;

if (attr->disabled)
goto end;

err = validate_hw_breakpoint(bp);
if (!err)
perf_event_enable(bp);
if (!attr->disabled) {
int err = validate_hw_breakpoint(bp);

if (err) {
bp->attr.bp_addr = old_addr;
bp->attr.bp_type = old_type;
bp->attr.bp_len = old_len;
if (!bp->attr.disabled)
perf_event_enable(bp);
if (err)
return err;

return err;
perf_event_enable(bp);
bp->attr.disabled = 0;
}

end:
bp->attr.disabled = attr->disabled;

return 0;
}
EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
Expand Down

0 comments on commit 10b84da

Please sign in to comment.