* [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs
@ 2015-03-09 12:43 a
2015-03-09 12:43 ` [PATCH 1/3] arm/pmu: Reject groups spanning multiple hardware PMUs a
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: a @ 2015-03-09 12:43 UTC (permalink / raw)
To: will.deacon
Cc: a.p.zijlstra, linux, acme, linux-kernel, linux-arm-kernel,
punit.agrawal, pawel.moll, Suzuki K. Poulose
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
This is a collection of fixes which denies grouping hardware events
from different PMUs. They also fix crashes triggered by perf_fuzzer
on Linux-4.0-rc2.
Pawel,
Similar fix is required in ARM CCN PMU driver. I didn't find it
straight forward to fix it there. Could you please take a look
into it ?
Suzuki K. Poulose (3):
arm/pmu: Reject groups spanning multiple hardware PMUs
arm64/pmu: Reject groups spanning multiple HW PMUs
arm-cci: Reject groups spanning multiple HW PMUs
arch/arm/kernel/perf_event.c | 21 +++++++++++++++------
arch/arm64/kernel/perf_event.c | 21 +++++++++++++++------
drivers/bus/arm-cci.c | 19 ++++++++++++++-----
3 files changed, 44 insertions(+), 17 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] arm/pmu: Reject groups spanning multiple hardware PMUs
2015-03-09 12:43 [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs a
@ 2015-03-09 12:43 ` a
2015-03-09 12:43 ` [PATCH 2/3] arm64/pmu: Reject groups spanning multiple HW PMUs a
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: a @ 2015-03-09 12:43 UTC (permalink / raw)
To: will.deacon
Cc: a.p.zijlstra, linux, acme, linux-kernel, linux-arm-kernel,
punit.agrawal, pawel.moll, Suzuki K. Poulose, Mark Rutland
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
Don't allow grouping hardware events from different PMUs
(eg. CCI + CPU).
Fixes a crash triggered by perf_fuzzer on Linux-4.0-rc2,
with CCI PMU turned on. The validate_event(), after certain checks,
assumes that the given hardware pmu event belongs to armpmu,
which may not be true always, with other hardware PMUs
around (CCI, CCN).
---
CPU: 0 PID: 1527 Comm: perf_fuzzer Not tainted 4.0.0-rc2 #57
Hardware name: ARM-Versatile Express
task: bd8484c0 ti: be676000 task.ti: be676000
PC is at 0xbf1bbc90
LR is at validate_event+0x34/0x5c
pc : [<bf1bbc90>] lr : [<80016060>] psr: 00000013
...
[<80016060>] (validate_event) from [<80016198>] (validate_group+0x28/0x90)
[<80016198>] (validate_group) from [<80016398>] (armpmu_event_init+0x150/0x218)
[<80016398>] (armpmu_event_init) from [<800882e4>] (perf_try_init_event+0x30/0x48)
[<800882e4>] (perf_try_init_event) from [<8008f544>] (perf_init_event+0x5c/0xf4)
[<8008f544>] (perf_init_event) from [<8008f8a8>] (perf_event_alloc+0x2cc/0x35c)
[<8008f8a8>] (perf_event_alloc) from [<8009015c>] (SyS_perf_event_open+0x498/0xa70)
[<8009015c>] (SyS_perf_event_open) from [<8000e420>] (ret_fast_syscall+0x0/0x34)
Code: bf1be000 bf1bb380 802a2664 00000000 (00000002)
---[ end trace 01aff0ff00926a0a ]---
Also cleans up the code to use the arm_pmu only when we know that
we are dealing with an arm pmu event.
Cc: Will Deacon <will.deacon@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
---
arch/arm/kernel/perf_event.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 557e128..4a86a01 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -259,20 +259,29 @@ out:
}
static int
-validate_event(struct pmu_hw_events *hw_events,
- struct perf_event *event)
+validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events,
+ struct perf_event *event)
{
- struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct arm_pmu *armpmu;
if (is_software_event(event))
return 1;
+ /*
+ * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
+ * core perf code won't check that the pmu->ctx == leader->ctx
+ * until after pmu->event_init(event).
+ */
+ if (event->pmu != pmu)
+ return 0;
+
if (event->state < PERF_EVENT_STATE_OFF)
return 1;
if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
return 1;
+ armpmu = to_arm_pmu(event->pmu);
return armpmu->get_event_idx(hw_events, event) >= 0;
}
@@ -288,15 +297,15 @@ validate_group(struct perf_event *event)
*/
memset(&fake_pmu.used_mask, 0, sizeof(fake_pmu.used_mask));
- if (!validate_event(&fake_pmu, leader))
+ if (!validate_event(event->pmu, &fake_pmu, leader))
return -EINVAL;
list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
- if (!validate_event(&fake_pmu, sibling))
+ if (!validate_event(event->pmu, &fake_pmu, sibling))
return -EINVAL;
}
- if (!validate_event(&fake_pmu, event))
+ if (!validate_event(event->pmu, &fake_pmu, event))
return -EINVAL;
return 0;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] arm64/pmu: Reject groups spanning multiple HW PMUs
2015-03-09 12:43 [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs a
2015-03-09 12:43 ` [PATCH 1/3] arm/pmu: Reject groups spanning multiple hardware PMUs a
@ 2015-03-09 12:43 ` a
2015-03-09 12:43 ` [PATCH 3/3] arm-cci: " a
2015-03-09 12:44 ` [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs Suzuki K. Poulose
3 siblings, 0 replies; 6+ messages in thread
From: a @ 2015-03-09 12:43 UTC (permalink / raw)
To: will.deacon
Cc: a.p.zijlstra, linux, acme, linux-kernel, linux-arm-kernel,
punit.agrawal, pawel.moll, Suzuki K. Poulose, Mark Rutland
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
Don't allow grouping hardware events from different PMUs
(eg. CCI + CPU).
Fixes a crash triggered by perf_fuzzer on Linux-4.0-rc2,
with CCI PMU turned on. The validate_event(), after certain checks,
assumes that the given hardware pmu event belongs to armpmu,
which may not be true always, with other hardware PMUs
around (CCI, CCN).
Bad mode in Synchronous Abort handler detected, code 0x86000006 -- IABT (current EL)
CPU: 0 PID: 1371 Comm: perf_fuzzer Not tainted 3.19.0+ #249
Hardware name: V2F-1XV7 Cortex-A53x2 SMM (DT)
task: ffffffc07c73a280 ti: ffffffc07b0a0000 task.ti: ffffffc07b0a0000
PC is at 0x0
LR is at validate_event+0x90/0xa8
pc : [<0000000000000000>] lr : [<ffffffc000090228>] pstate: 00000145
sp : ffffffc07b0a3ba0
[< (null)>] (null)
[<ffffffc0000907d8>] armpmu_event_init+0x174/0x3cc
[<ffffffc00015d870>] perf_try_init_event+0x34/0x70
[<ffffffc000164094>] perf_init_event+0xe0/0x10c
[<ffffffc000164348>] perf_event_alloc+0x288/0x358
[<ffffffc000164c5c>] SyS_perf_event_open+0x464/0x98c
Code: bad PC value
Also cleans up the code to use the arm_pmu only when we know
that we are dealing with an arm pmu event.
Cc: Will Deacon <will.deacon@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
---
arch/arm64/kernel/perf_event.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 25a5308..68a7415 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -322,22 +322,31 @@ out:
}
static int
-validate_event(struct pmu_hw_events *hw_events,
- struct perf_event *event)
+validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events,
+ struct perf_event *event)
{
- struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct arm_pmu *armpmu;
struct hw_perf_event fake_event = event->hw;
struct pmu *leader_pmu = event->group_leader->pmu;
if (is_software_event(event))
return 1;
+ /*
+ * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
+ * core perf code won't check that the pmu->ctx == leader->ctx
+ * until after pmu->event_init(event).
+ */
+ if (event->pmu != pmu)
+ return 0;
+
if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
return 1;
if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
return 1;
+ armpmu = to_arm_pmu(event->pmu);
return armpmu->get_event_idx(hw_events, &fake_event) >= 0;
}
@@ -355,15 +364,15 @@ validate_group(struct perf_event *event)
memset(fake_used_mask, 0, sizeof(fake_used_mask));
fake_pmu.used_mask = fake_used_mask;
- if (!validate_event(&fake_pmu, leader))
+ if (!validate_event(event->pmu, &fake_pmu, leader))
return -EINVAL;
list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
- if (!validate_event(&fake_pmu, sibling))
+ if (!validate_event(event->pmu, &fake_pmu, sibling))
return -EINVAL;
}
- if (!validate_event(&fake_pmu, event))
+ if (!validate_event(event->pmu, &fake_pmu, event))
return -EINVAL;
return 0;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] arm-cci: Reject groups spanning multiple HW PMUs
2015-03-09 12:43 [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs a
2015-03-09 12:43 ` [PATCH 1/3] arm/pmu: Reject groups spanning multiple hardware PMUs a
2015-03-09 12:43 ` [PATCH 2/3] arm64/pmu: Reject groups spanning multiple HW PMUs a
@ 2015-03-09 12:43 ` a
2015-03-09 12:44 ` [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs Suzuki K. Poulose
3 siblings, 0 replies; 6+ messages in thread
From: a @ 2015-03-09 12:43 UTC (permalink / raw)
To: will.deacon
Cc: a.p.zijlstra, linux, acme, linux-kernel, linux-arm-kernel,
punit.agrawal, pawel.moll, Suzuki K. Poulose
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
Invalidate an event if the group has a hardware event from
a different PMU as we cannot schedule all of them in the same
context. The perf core code won't check the group consistency
until after pmu_event_init().
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
---
drivers/bus/arm-cci.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 84fd660..68ef6f2 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -660,12 +660,21 @@ static void cci_pmu_del(struct perf_event *event, int flags)
}
static int
-validate_event(struct cci_pmu_hw_events *hw_events,
- struct perf_event *event)
+validate_event(struct pmu *cci_pmu,
+ struct cci_pmu_hw_events *hw_events,
+ struct perf_event *event)
{
if (is_software_event(event))
return 1;
+ /*
+ * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
+ * core perf code won't check that the pmu->ctx == leader->ctx
+ * until after pmu->event_init(event).
+ */
+ if (event->pmu != cci_pmu)
+ return 0;
+
if (event->state < PERF_EVENT_STATE_OFF)
return 1;
@@ -687,15 +696,15 @@ validate_group(struct perf_event *event)
.used_mask = CPU_BITS_NONE,
};
- if (!validate_event(&fake_pmu, leader))
+ if (!validate_event(event->pmu, &fake_pmu, leader))
return -EINVAL;
list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
- if (!validate_event(&fake_pmu, sibling))
+ if (!validate_event(event->pmu, &fake_pmu, sibling))
return -EINVAL;
}
- if (!validate_event(&fake_pmu, event))
+ if (!validate_event(event->pmu, &fake_pmu, event))
return -EINVAL;
return 0;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs
2015-03-09 12:43 [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs a
` (2 preceding siblings ...)
2015-03-09 12:43 ` [PATCH 3/3] arm-cci: " a
@ 2015-03-09 12:44 ` Suzuki K. Poulose
3 siblings, 0 replies; 6+ messages in thread
From: Suzuki K. Poulose @ 2015-03-09 12:44 UTC (permalink / raw)
To: a, Will Deacon
Cc: a.p.zijlstra@chello.nl, linux@arm.linux.org.uk, acme@kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Punit Agrawal, Pawel Moll
On 09/03/15 12:43, a wrote:
> From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
>
> This is a collection of fixes which denies grouping hardware events
> from different PMUs. They also fix crashes triggered by perf_fuzzer
> on Linux-4.0-rc2.
>
> Pawel,
>
> Similar fix is required in ARM CCN PMU driver. I didn't find it
> straight forward to fix it there. Could you please take a look
> into it ?
>
>
Sorry, I messed up the git send-email inputs. This indeed was sent by
me. :(
Cheers
Suzuki
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs
@ 2015-03-09 12:46 Suzuki K. Poulose
0 siblings, 0 replies; 6+ messages in thread
From: Suzuki K. Poulose @ 2015-03-09 12:46 UTC (permalink / raw)
To: will.deacon
Cc: a.p.zijlstra, linux, acme, linux-kernel, linux-arm-kernel,
punit.agrawal, pawel.moll, Suzuki K. Poulose
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
This is a collection of fixes which denies grouping hardware events
from different PMUs. They also fix crashes triggered by perf_fuzzer
on Linux-4.0-rc2.
Pawel,
Similar fix is required in ARM CCN PMU driver. I didn't find it
straight forward to fix it there. Could you please take a look
into it ?
Suzuki K. Poulose (3):
arm/pmu: Reject groups spanning multiple hardware PMUs
arm64/pmu: Reject groups spanning multiple HW PMUs
arm-cci: Reject groups spanning multiple HW PMUs
arch/arm/kernel/perf_event.c | 21 +++++++++++++++------
arch/arm64/kernel/perf_event.c | 21 +++++++++++++++------
drivers/bus/arm-cci.c | 19 ++++++++++++++-----
3 files changed, 44 insertions(+), 17 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-03-09 12:46 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-09 12:43 [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs a
2015-03-09 12:43 ` [PATCH 1/3] arm/pmu: Reject groups spanning multiple hardware PMUs a
2015-03-09 12:43 ` [PATCH 2/3] arm64/pmu: Reject groups spanning multiple HW PMUs a
2015-03-09 12:43 ` [PATCH 3/3] arm-cci: " a
2015-03-09 12:44 ` [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs Suzuki K. Poulose
-- strict thread matches above, loose matches on Subject: below --
2015-03-09 12:46 Suzuki K. Poulose
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox