[PATCH] powerpc/perf: add missing put_cpu_var in power_pmu_event_init

2015-03-24 Thread Jan Stancek
One path in power_pmu_event_init() calls get_cpu_var(), but is
missing matching call to put_cpu_var(), which causes preemption
imbalance and crash in user-space:

  Page fault in user mode with in_atomic() = 1 mm = c01fefa5a280
  NIP = 3fff9bf2cae0  MSR = 90014280f032
  Oops: Weird page fault, sig: 11 [#23]
  SMP NR_CPUS=2048 NUMA PowerNV
  Modules linked in: 
  CPU: 43 PID: 10285 Comm: a.out Tainted: G  D 4.0.0-rc5+ #1
  task: c01fe82c9200 ti: c01fe835c000 task.ti: c01fe835c000
  NIP: 3fff9bf2cae0 LR: 3fff9bee4898 CTR: 3fff9bf2cae0
  REGS: c01fe835fea0 TRAP: 0401   Tainted: G  D  (4.0.0-rc5+)
  MSR: 90014280f032   CR: 2228  
XER: 
  CFAR: 3fff9bee4894 SOFTE: 1
   GPR00: 3fff9bee494c 3fffe01c2ee0 3fff9c084410 10020068
   GPR04:  0002 0008 0001
   GPR08: 0001 3fff9c074a30 3fff9bf2cae0 3fff9bf2cd70
   GPR12: 5222 3fff9c10b700
  NIP [3fff9bf2cae0] 0x3fff9bf2cae0
  LR [3fff9bee4898] 0x3fff9bee4898
  Call Trace:
  ---[ end trace 5d3d952b5d4185d4 ]---

  BUG: sleeping function called from invalid context at 
kernel/locking/rwsem.c:41
  in_atomic(): 1, irqs_disabled(): 0, pid: 10285, name: a.out
  INFO: lockdep is turned off.
  CPU: 43 PID: 10285 Comm: a.out Tainted: G  D 4.0.0-rc5+ #1
  Call Trace:
  [c01fe835f990] [c089c014] .dump_stack+0x98/0xd4 (unreliable)
  [c01fe835fa10] [c00e4138] .___might_sleep+0x1d8/0x2e0
  [c01fe835faa0] [c0888da8] .down_read+0x38/0x110
  [c01fe835fb30] [c00bf2f4] .exit_signals+0x24/0x160
  [c01fe835fbc0] [c00abde0] .do_exit+0xd0/0xe70
  [c01fe835fcb0] [c001f4c4] .die+0x304/0x450
  [c01fe835fd60] [c088e1f4] .do_page_fault+0x2d4/0x900
  [c01fe835fe30] [c0008664] handle_page_fault+0x10/0x30
  note: a.out[10285] exited with preempt_count 1

Reproducer:
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 

  static struct perf_event_attr event = {
  .type = PERF_TYPE_RAW,
  .size = sizeof(struct perf_event_attr),
  .sample_type = PERF_SAMPLE_BRANCH_STACK,
  .branch_sample_type = PERF_SAMPLE_BRANCH_ANY_RETURN,
  };

  int main()
  {
  syscall(__NR_perf_event_open, , 0, -1, -1, 0);
  }

Signed-off-by: Jan Stancek 
---
 arch/powerpc/perf/core-book3s.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 7c4f669..b101c0b 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -1832,8 +1832,10 @@ static int power_pmu_event_init(struct perf_event *event)
cpuhw->bhrb_filter = ppmu->bhrb_filter_map(
event->attr.branch_sample_type);
 
-   if(cpuhw->bhrb_filter == -1)
+   if (cpuhw->bhrb_filter == -1) {
+   put_cpu_var(cpu_hw_events);
return -EOPNOTSUPP;
+   }
}
 
put_cpu_var(cpu_hw_events);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc/perf: add missing put_cpu_var in power_pmu_event_init

2015-03-24 Thread Jan Stancek
One path in power_pmu_event_init() calls get_cpu_var(), but is
missing matching call to put_cpu_var(), which causes preemption
imbalance and crash in user-space:

  Page fault in user mode with in_atomic() = 1 mm = c01fefa5a280
  NIP = 3fff9bf2cae0  MSR = 90014280f032
  Oops: Weird page fault, sig: 11 [#23]
  SMP NR_CPUS=2048 NUMA PowerNV
  Modules linked in: snip
  CPU: 43 PID: 10285 Comm: a.out Tainted: G  D 4.0.0-rc5+ #1
  task: c01fe82c9200 ti: c01fe835c000 task.ti: c01fe835c000
  NIP: 3fff9bf2cae0 LR: 3fff9bee4898 CTR: 3fff9bf2cae0
  REGS: c01fe835fea0 TRAP: 0401   Tainted: G  D  (4.0.0-rc5+)
  MSR: 90014280f032 SF,HV,VEC,VSX,EE,PR,FP,ME,IR,DR,RI  CR: 2228  
XER: 
  CFAR: 3fff9bee4894 SOFTE: 1
   GPR00: 3fff9bee494c 3fffe01c2ee0 3fff9c084410 10020068
   GPR04:  0002 0008 0001
   GPR08: 0001 3fff9c074a30 3fff9bf2cae0 3fff9bf2cd70
   GPR12: 5222 3fff9c10b700
  NIP [3fff9bf2cae0] 0x3fff9bf2cae0
  LR [3fff9bee4898] 0x3fff9bee4898
  Call Trace:
  ---[ end trace 5d3d952b5d4185d4 ]---

  BUG: sleeping function called from invalid context at 
kernel/locking/rwsem.c:41
  in_atomic(): 1, irqs_disabled(): 0, pid: 10285, name: a.out
  INFO: lockdep is turned off.
  CPU: 43 PID: 10285 Comm: a.out Tainted: G  D 4.0.0-rc5+ #1
  Call Trace:
  [c01fe835f990] [c089c014] .dump_stack+0x98/0xd4 (unreliable)
  [c01fe835fa10] [c00e4138] .___might_sleep+0x1d8/0x2e0
  [c01fe835faa0] [c0888da8] .down_read+0x38/0x110
  [c01fe835fb30] [c00bf2f4] .exit_signals+0x24/0x160
  [c01fe835fbc0] [c00abde0] .do_exit+0xd0/0xe70
  [c01fe835fcb0] [c001f4c4] .die+0x304/0x450
  [c01fe835fd60] [c088e1f4] .do_page_fault+0x2d4/0x900
  [c01fe835fe30] [c0008664] handle_page_fault+0x10/0x30
  note: a.out[10285] exited with preempt_count 1

Reproducer:
  #include stdio.h
  #include unistd.h
  #include syscall.h
  #include sys/types.h
  #include sys/stat.h
  #include linux/perf_event.h
  #include linux/hw_breakpoint.h

  static struct perf_event_attr event = {
  .type = PERF_TYPE_RAW,
  .size = sizeof(struct perf_event_attr),
  .sample_type = PERF_SAMPLE_BRANCH_STACK,
  .branch_sample_type = PERF_SAMPLE_BRANCH_ANY_RETURN,
  };

  int main()
  {
  syscall(__NR_perf_event_open, event, 0, -1, -1, 0);
  }

Signed-off-by: Jan Stancek jstan...@redhat.com
---
 arch/powerpc/perf/core-book3s.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 7c4f669..b101c0b 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -1832,8 +1832,10 @@ static int power_pmu_event_init(struct perf_event *event)
cpuhw-bhrb_filter = ppmu-bhrb_filter_map(
event-attr.branch_sample_type);
 
-   if(cpuhw-bhrb_filter == -1)
+   if (cpuhw-bhrb_filter == -1) {
+   put_cpu_var(cpu_hw_events);
return -EOPNOTSUPP;
+   }
}
 
put_cpu_var(cpu_hw_events);
-- 
1.7.1

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/