Skip to content

Commit 7a310c6

Browse files
lrq-maxIngo Molnar
authored andcommitted
perf/x86/intel/bts: Check if bts_ctx is allocated when calling BTS functions
bts_ctx might not be allocated, for example if the CPU has X86_FEATURE_PTI, but intel_bts_disable/enable_local() and intel_bts_interrupt() are called unconditionally from intel_pmu_handle_irq() and crash on bts_ctx. So check if bts_ctx is allocated when calling BTS functions. Fixes: 3acfcef ("perf/x86/intel/bts: Allocate bts_ctx only if necessary") Reported-by: Jiri Olsa <[email protected]> Tested-by: Jiri Olsa <[email protected]> Suggested-by: Adrian Hunter <[email protected]> Suggested-by: Dave Hansen <[email protected]> Signed-off-by: Li RongQing <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent fa6192a commit 7a310c6

File tree

1 file changed

+20
-5
lines changed
  • arch/x86/events/intel

1 file changed

+20
-5
lines changed

arch/x86/events/intel/bts.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,14 @@ static void bts_event_stop(struct perf_event *event, int flags)
338338

339339
void intel_bts_enable_local(void)
340340
{
341-
struct bts_ctx *bts = this_cpu_ptr(bts_ctx);
342-
int state = READ_ONCE(bts->state);
341+
struct bts_ctx *bts;
342+
int state;
343343

344+
if (!bts_ctx)
345+
return;
346+
347+
bts = this_cpu_ptr(bts_ctx);
348+
state = READ_ONCE(bts->state);
344349
/*
345350
* Here we transition from INACTIVE to ACTIVE;
346351
* if we instead are STOPPED from the interrupt handler,
@@ -358,7 +363,12 @@ void intel_bts_enable_local(void)
358363

359364
void intel_bts_disable_local(void)
360365
{
361-
struct bts_ctx *bts = this_cpu_ptr(bts_ctx);
366+
struct bts_ctx *bts;
367+
368+
if (!bts_ctx)
369+
return;
370+
371+
bts = this_cpu_ptr(bts_ctx);
362372

363373
/*
364374
* Here we transition from ACTIVE to INACTIVE;
@@ -450,12 +460,17 @@ bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle)
450460
int intel_bts_interrupt(void)
451461
{
452462
struct debug_store *ds = this_cpu_ptr(&cpu_hw_events)->ds;
453-
struct bts_ctx *bts = this_cpu_ptr(bts_ctx);
454-
struct perf_event *event = bts->handle.event;
463+
struct bts_ctx *bts;
464+
struct perf_event *event;
455465
struct bts_buffer *buf;
456466
s64 old_head;
457467
int err = -ENOSPC, handled = 0;
458468

469+
if (!bts_ctx)
470+
return 0;
471+
472+
bts = this_cpu_ptr(bts_ctx);
473+
event = bts->handle.event;
459474
/*
460475
* The only surefire way of knowing if this NMI is ours is by checking
461476
* the write ptr against the PMI threshold.

0 commit comments

Comments
 (0)