Patch "perf/core: Fix crash in perf_event_read()" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
perf/core: Fix crash in perf_event_read()
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
perf-core-fix-crash-in-perf_event_read.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
451d24d1e5f40bad000fa9abe36ddb16fc9928cbMon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Tue, 31 Jan 2017 11:27:10 +0100
Subject: perf/core: Fix crash in perf_event_read()
From: Peter Zijlstra <[email protected]>
commit 451d24d1e5f40bad000fa9abe36ddb16fc9928cb upstream.
Alexei had his box explode because doing read() on a package (rapl/uncore) event that isn't currently scheduled in ends up doing an out-of-bounds load.
Rework the code to more explicitly deal with event->oncpu being -1.
--- kernel/events/core.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
kernel/events/core.c +15 -10
@@ -3461,14 +3461,15 @@ struct perf_read_data {int ret; }; -static int find_cpu_to_read (struct perf_event *event,int local_cpu) +static int __perf_event_read_cpu (struct perf_event *event,int event_cpu) { -int event_cpu = event->oncpu;u16 local_pkg, event_pkg;if (event->group_caps &PERF_EV_CAP_READ_ACTIVE_PKG ) { - event_pkg =topology_physical_package_id (event_cpu); - local_pkg =topology_physical_package_id (local_cpu); +int local_cpu =smp_processor_id (); + + event_pkg =topology_physical_package_id (event_cpu); + local_pkg =topology_physical_package_id (local_cpu);if (event_pkg == local_pkg)return local_cpu;
@@ -3598,7 +3599,7 @@ u64 perf_event_read_local(struct perf_evstatic int perf_event_read (struct perf_event *event,bool group) { -int ret =0 , cpu_to_read, local_cpu; +int event_cpu, ret =0 ;/* * If event is enabled and currently active on a CPU, update the
@@ -3611,21 +3612,25 @@ static int perf_event_read(struct perf_e .ret = 0, }; - local_cpu =get_cpu (); - cpu_to_read =find_cpu_to_read (event, local_cpu); -put_cpu (); + event_cpu =READ_ONCE (event->oncpu); +if ((unsigned )event_cpu >= nr_cpu_ids) +return 0 ; + +preempt_disable (); + event_cpu =__perf_event_read_cpu (event, event_cpu);/* * Purposely ignore the smp_call_function_single() return * value. * -* If event->oncpu isn't a valid CPU it means the event got +* If event_cpu isn't a valid CPU it means the event got * scheduled out and that will have updated the event count. * * Therefore, either way, we'll have an up-to-date event count * after this. */ - (void )smp_call_function_single (cpu_to_read, __perf_event_read, &data,1 ); + (void )smp_call_function_single (event_cpu, __perf_event_read, &data,1 ); +preempt_enable (); ret = data.ret; }else if (event->state ==PERF_EVENT_STATE_INACTIVE ) {struct perf_event_context *ctx = event->ctx;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/x86-cpu-amd-fix-zen-smt-topology.patch queue-4.9/stacktrace-lockdep-fix-address-newline-ugliness.patch queue-4.9/perf-core-fix-crash-in-perf_event_read.patch queue-4.9/x86-cpu-amd-bring-back-compute-unit-id.patch