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/