Commit 10b84dad authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/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
parents ad0500ca f67b1503
...@@ -1153,6 +1153,7 @@ static void setup_pebs_sample_data(struct perf_event *event, ...@@ -1153,6 +1153,7 @@ static void setup_pebs_sample_data(struct perf_event *event,
if (pebs == NULL) if (pebs == NULL)
return; return;
regs->flags &= ~PERF_EFLAGS_EXACT;
sample_type = event->attr.sample_type; sample_type = event->attr.sample_type;
dsrc = sample_type & PERF_SAMPLE_DATA_SRC; dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
...@@ -1197,7 +1198,6 @@ static void setup_pebs_sample_data(struct perf_event *event, ...@@ -1197,7 +1198,6 @@ static void setup_pebs_sample_data(struct perf_event *event,
*/ */
*regs = *iregs; *regs = *iregs;
regs->flags = pebs->flags; regs->flags = pebs->flags;
set_linear_ip(regs, pebs->ip);
if (sample_type & PERF_SAMPLE_REGS_INTR) { if (sample_type & PERF_SAMPLE_REGS_INTR) {
regs->ax = pebs->ax; regs->ax = pebs->ax;
...@@ -1233,13 +1233,22 @@ static void setup_pebs_sample_data(struct perf_event *event, ...@@ -1233,13 +1233,22 @@ static void setup_pebs_sample_data(struct perf_event *event,
#endif #endif
} }
if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) { if (event->attr.precise_ip > 1) {
regs->ip = pebs->real_ip; /* 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; regs->flags |= PERF_EFLAGS_EXACT;
} else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs)) } 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; regs->flags |= PERF_EFLAGS_EXACT;
else }
regs->flags &= ~PERF_EFLAGS_EXACT; } else
set_linear_ip(regs, pebs->ip);
if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) && if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) &&
x86_pmu.intel_cap.pebs_format >= 1) x86_pmu.intel_cap.pebs_format >= 1)
......
...@@ -427,16 +427,9 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); ...@@ -427,16 +427,9 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
* modify_user_hw_breakpoint - modify a user-space hardware breakpoint * modify_user_hw_breakpoint - modify a user-space hardware breakpoint
* @bp: the breakpoint structure to modify * @bp: the breakpoint structure to modify
* @attr: new breakpoint attributes * @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) 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 * 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. * will not be possible to raise IPIs that invoke __perf_event_disable.
...@@ -451,27 +444,18 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att ...@@ -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_addr = attr->bp_addr;
bp->attr.bp_type = attr->bp_type; bp->attr.bp_type = attr->bp_type;
bp->attr.bp_len = attr->bp_len; bp->attr.bp_len = attr->bp_len;
bp->attr.disabled = 1;
if (attr->disabled) if (!attr->disabled) {
goto end; int err = validate_hw_breakpoint(bp);
err = validate_hw_breakpoint(bp); if (err)
if (!err) return err;
perf_event_enable(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); perf_event_enable(bp);
bp->attr.disabled = 0;
return err;
} }
end:
bp->attr.disabled = attr->disabled;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint); EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment