]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.18.3/perf-x86-intel-uncore-make-sure-only-uncore-events-are-collected.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 3.18.3 / perf-x86-intel-uncore-make-sure-only-uncore-events-are-collected.patch
CommitLineData
5bdb2afd
GKH
1From af91568e762d04931dcbdd6bef4655433d8b9418 Mon Sep 17 00:00:00 2001
2From: Jiri Olsa <jolsa@kernel.org>
3Date: Wed, 10 Dec 2014 21:23:50 +0100
4Subject: perf/x86/intel/uncore: Make sure only uncore events are collected
5
6From: Jiri Olsa <jolsa@kernel.org>
7
8commit af91568e762d04931dcbdd6bef4655433d8b9418 upstream.
9
10The uncore_collect_events functions assumes that event group
11might contain only uncore events which is wrong, because it
12might contain any type of events.
13
14This bug leads to uncore framework touching 'not' uncore events,
15which could end up all sorts of bugs.
16
17One was triggered by Vince's perf fuzzer, when the uncore code
18touched breakpoint event private event space as if it was uncore
19event and caused BUG:
20
21 BUG: unable to handle kernel paging request at ffffffff82822068
22 IP: [<ffffffff81020338>] uncore_assign_events+0x188/0x250
23 ...
24
25The code in uncore_assign_events() function was looking for
26event->hw.idx data while the event was initialized as a
27breakpoint with different members in event->hw union.
28
29This patch forces uncore_collect_events() to collect only uncore
30events.
31
32Reported-by: Vince Weaver <vince@deater.net>
33Signed-off-by: Jiri Olsa <jolsa@redhat.com>
34Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
35Cc: Frederic Weisbecker <fweisbec@gmail.com>
36Cc: Linus Torvalds <torvalds@linux-foundation.org>
37Cc: Peter Zijlstra <peterz@infradead.org>
38Cc: Stephane Eranian <eranian@google.com>
39Cc: Yan, Zheng <zheng.z.yan@intel.com>
40Link: http://lkml.kernel.org/r/1418243031-20367-2-git-send-email-jolsa@kernel.org
41Signed-off-by: Ingo Molnar <mingo@kernel.org>
42Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
43
44---
45 arch/x86/kernel/cpu/perf_event_intel_uncore.c | 22 +++++++++++++++++++---
46 1 file changed, 19 insertions(+), 3 deletions(-)
47
48--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
49+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
50@@ -276,6 +276,17 @@ static struct intel_uncore_box *uncore_a
51 return box;
52 }
53
54+/*
55+ * Using uncore_pmu_event_init pmu event_init callback
56+ * as a detection point for uncore events.
57+ */
58+static int uncore_pmu_event_init(struct perf_event *event);
59+
60+static bool is_uncore_event(struct perf_event *event)
61+{
62+ return event->pmu->event_init == uncore_pmu_event_init;
63+}
64+
65 static int
66 uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp)
67 {
68@@ -290,13 +301,18 @@ uncore_collect_events(struct intel_uncor
69 return -EINVAL;
70
71 n = box->n_events;
72- box->event_list[n] = leader;
73- n++;
74+
75+ if (is_uncore_event(leader)) {
76+ box->event_list[n] = leader;
77+ n++;
78+ }
79+
80 if (!dogrp)
81 return n;
82
83 list_for_each_entry(event, &leader->sibling_list, group_entry) {
84- if (event->state <= PERF_EVENT_STATE_OFF)
85+ if (!is_uncore_event(event) ||
86+ event->state <= PERF_EVENT_STATE_OFF)
87 continue;
88
89 if (n >= max_count)