lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Sun, 12 Aug 2012 11:50:21 -0500
From:	Heechul Yun <heechul@...inois.edu>
To:	Paul Mackerras <paulus@...ba.org>
Cc:	linux-kernel@...r.kernel.org, Heechul Yun <heechul@...inois.edu>
Subject: [PATCH] powerpc: perf: Do not reset a counter value on stop/start

A performance counter of e500mc processor core generates an overflow
interrupt when the counter value reaches to 0x80000000. In order to
set up a sampling counter, the kernel sets the counter value to
0x80000000 - <samples> to cause an interrupt right after <samples>
are incremented.

In the current code, the problem arises when the kernel stops and
re-starts the sampling counter (fsl_emb_pmu_stop() and
fsl_emb_pmu_start() are called repsectively). When fsl_emb_pmu_stop()
is called, called when a user adjusts the sampling period, it currently
re-writes the counter value to zero, which breaks working of the
sampling counter. Similarily fsl_emb_pmu_start() re-write the counter
value.

This patch fixes the bug by not re-writing the counter unnecessarily.
Also, it sets the counter freeze bit in fsl_emb_pmu_stop(), so that
the counter does not increase until fsl_emb_pmu_start() is called
again.

Signed-off-by: Heechul Yun <heechul@...inois.edu>
---
 arch/powerpc/perf/core-fsl-emb.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c
index 106c533..4cd4f12 100644
--- a/arch/powerpc/perf/core-fsl-emb.c
+++ b/arch/powerpc/perf/core-fsl-emb.c
@@ -365,7 +365,6 @@ static void fsl_emb_pmu_del(struct perf_event *event, int flags)
 static void fsl_emb_pmu_start(struct perf_event *event, int ef_flags)
 {
 	unsigned long flags;
-	s64 left;
 
 	if (event->hw.idx < 0 || !event->hw.sample_period)
 		return;
@@ -380,8 +379,9 @@ static void fsl_emb_pmu_start(struct perf_event *event, int ef_flags)
 	perf_pmu_disable(event->pmu);
 
 	event->hw.state = 0;
-	left = local64_read(&event->hw.period_left);
-	write_pmc(event->hw.idx, left);
+
+	/* start the counter. */
+	write_pmlca(event->hw.idx, event->hw.config_base);
 
 	perf_event_update_userpage(event);
 	perf_pmu_enable(event->pmu);
@@ -403,7 +403,9 @@ static void fsl_emb_pmu_stop(struct perf_event *event, int ef_flags)
 
 	fsl_emb_pmu_read(event);
 	event->hw.state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
-	write_pmc(event->hw.idx, 0);
+
+	/* freeze the counter. */
+	write_pmlca(event->hw.idx, event->hw.config_base | PMLCA_FC);
 
 	perf_event_update_userpage(event);
 	perf_pmu_enable(event->pmu);
@@ -575,7 +577,6 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
 	int record = 0;
 
 	if (event->hw.state & PERF_HES_STOPPED) {
-		write_pmc(event->hw.idx, 0);
 		return;
 	}
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ