lkml.org 
[lkml]   [2018]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] perf/x86/intel: Init early callchain for bts event
Date
Vince reported crash in bts flush code when touching the
callchain data, which was supposed to be initialized
as an 'early' callchain data.

BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
...
Call Trace:
<IRQ>
intel_pmu_drain_bts_buffer+0x151/0x220
? intel_get_event_constraints+0x219/0x360
? perf_assign_events+0xe2/0x2a0
? select_idle_sibling+0x22/0x3a0
? __update_load_avg_se+0x1ec/0x270
? enqueue_task_fair+0x377/0xdd0
? cpumask_next_and+0x19/0x20
? load_balance+0x134/0x950
? check_preempt_curr+0x7a/0x90
? ttwu_do_wakeup+0x19/0x140
x86_pmu_stop+0x3b/0x90
x86_pmu_del+0x57/0x160
event_sched_out.isra.106+0x81/0x170
group_sched_out.part.108+0x51/0xc0
__perf_event_disable+0x7f/0x160
event_function+0x8c/0xd0
remote_function+0x3c/0x50
flush_smp_call_function_queue+0x35/0xe0
smp_call_function_single_interrupt+0x3a/0xd0
call_function_single_interrupt+0xf/0x20
</IRQ>

It was triggered by fuzzer by can be easilt reproduced by:
# perf record -e cpu/branch-instructions/p -g -c 1

The problem is that bts drain code does not initialize sample's
early callchain data and calls perf_prepare_sample with NULL
sample->callchain, even if it's expected to exist via
__PERF_SAMPLE_CALLCHAIN_EARLY sample type bit.

The fix initializes the callchain data for this case with
empty callchain, because bts does not report callchains.

Cc: Vince Weaver <vincent.weaver@maine.edu>
Fixes: 6cbc304f2f36 ("perf/x86/intel: Fix unwind errors from PEBS entries (mk-II)")
Reported-by: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
arch/x86/events/intel/ds.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index b7b01d762d32..1049b547fdfe 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -577,6 +577,8 @@ void intel_pmu_disable_bts(void)
update_debugctlmsr(debugctlmsr);
}

+static struct perf_callchain_entry __empty_callchain = { .nr = 0, };
+
int intel_pmu_drain_bts_buffer(void)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
@@ -612,6 +614,9 @@ int intel_pmu_drain_bts_buffer(void)

perf_sample_data_init(&data, 0, event->hw.last_period);

+ if (event->attr.sample_type & __PERF_SAMPLE_CALLCHAIN_EARLY)
+ data.callchain = &__empty_callchain;
+
/*
* BTS leaks kernel addresses in branches across the cpl boundary,
* such as traps or system calls, so unless the user is asking for
--
2.17.2
\
 
 \ /
  Last update: 2018-11-11 19:17    [W:0.058 / U:1.528 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site