mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tvrtko Ursulin <tursulin@ursulin.net>
To: linux-kernel@vger.kernel.org
Cc: tursulin@ursulin.net, tvrtko.ursulin@linux.intel.com,
	Tvrtko Ursulin <tvrtko.ursulin@intel.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@kernel.org>,
	Madhavan Srinivasan <maddy@linux.vnet.ibm.com>,
	Andi Kleen <ak@linux.intel.com>,
	Alexey Budankov <alexey.budankov@linux.intel.com>,
	x86@kernel.org
Subject: [RFC 5/5] tools/perf: Add support for per-PMU access control
Date: Wed, 19 Sep 2018 13:27:51 +0100	[thread overview]
Message-ID: <20180919122751.12439-6-tvrtko.ursulin@linux.intel.com> (raw)
In-Reply-To: <20180919122751.12439-1-tvrtko.ursulin@linux.intel.com>

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Now that the perf core supports per-PMU paranoid settings we need to
extend the tool to support that.

We handle the per-PMU setting in the platform support code where
applicable and also notify the user of the new facility on failures to
open the event.

Thanks to Jiri Olsa for contributing most of the "meat" for this patch and
suggestion to improve the error banner as well.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Alexey Budankov <alexey.budankov@linux.intel.com>
Cc: linux-kernel@vger.kernel.org
Cc: x86@kernel.org
---
 tools/perf/arch/arm/util/cs-etm.c    |  2 +-
 tools/perf/arch/arm64/util/arm-spe.c |  2 +-
 tools/perf/arch/x86/util/intel-bts.c |  2 +-
 tools/perf/arch/x86/util/intel-pt.c  |  2 +-
 tools/perf/util/evsel.c              | 41 ++++++++++++++++++++++++++--
 tools/perf/util/pmu.c                | 17 ++++++++++++
 tools/perf/util/pmu.h                |  1 +
 7 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 2f595cd73da6..a5437f100ab9 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -69,7 +69,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
 	struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
 	struct perf_evsel *evsel, *cs_etm_evsel = NULL;
 	const struct cpu_map *cpus = evlist->cpus;
-	bool privileged = (geteuid() == 0 || perf_event_paranoid() < 0);
+	bool privileged = (geteuid() == 0 || cs_etm_pmu->paranoid < 0);
 
 	ptr->evlist = evlist;
 	ptr->snapshot_mode = opts->auxtrace_snapshot_mode;
diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 5ccfce87e693..e7e8154757fa 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -65,7 +65,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
 			container_of(itr, struct arm_spe_recording, itr);
 	struct perf_pmu *arm_spe_pmu = sper->arm_spe_pmu;
 	struct perf_evsel *evsel, *arm_spe_evsel = NULL;
-	bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
+	bool privileged = geteuid() == 0 || arm_spe_pmu->paranoid < 0;
 	struct perf_evsel *tracking_evsel;
 	int err;
 
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index 781df40b2966..c97e6556c8e7 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -116,7 +116,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr,
 	struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu;
 	struct perf_evsel *evsel, *intel_bts_evsel = NULL;
 	const struct cpu_map *cpus = evlist->cpus;
-	bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
+	bool privileged = geteuid() == 0 || intel_bts_pmu->paranoid < 0;
 
 	btsr->evlist = evlist;
 	btsr->snapshot_mode = opts->auxtrace_snapshot_mode;
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index db0ba8caf5a2..ffbe5f7f1c57 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -555,7 +555,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 	bool have_timing_info, need_immediate = false;
 	struct perf_evsel *evsel, *intel_pt_evsel = NULL;
 	const struct cpu_map *cpus = evlist->cpus;
-	bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
+	bool privileged = geteuid() == 0 || intel_pt_pmu->paranoid < 0;
 	u64 tsc_bit;
 	int err;
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1a61628a1c12..fbebce0593f4 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -9,6 +9,7 @@
 
 #include <byteswap.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <inttypes.h>
 #include <linux/bitops.h>
 #include <api/fs/fs.h>
@@ -20,6 +21,7 @@
 #include <linux/err.h>
 #include <sys/ioctl.h>
 #include <sys/resource.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include "asm/bug.h"
@@ -2843,10 +2845,37 @@ static bool find_process(const char *name)
 	return ret ? false : true;
 }
 
+static int __pmu_paranoid_value(const char *name, char *buf, int bufsz)
+{
+	char path[PATH_MAX];
+	int fd, ret;
+
+	ret = snprintf(path, sizeof(path),
+		       "%s/bus/event_source/devices/%s/perf_event_paranoid",
+			sysfs__mountpoint(), name);
+	if (ret < 0 || ret == sizeof(path))
+		return -1;
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	ret = read(fd, buf, bufsz - 1);
+	if (ret <= 0)
+		return -1;
+
+	if (buf[ret - 1] == '\n')
+		buf[ret - 1] = 0;
+	else
+		buf[ret] = 0;
+
+	return 0;
+}
+
 int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
 			      int err, char *msg, size_t size)
 {
-	char sbuf[STRERR_BUFSIZE];
+	char sbuf[STRERR_BUFSIZE], buf[4];
 	int printed = 0;
 
 	switch (err) {
@@ -2870,9 +2899,15 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
 		 ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n"
 		 ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN\n\n"
 		 "To make this setting permanent, edit /etc/sysctl.conf too, e.g.:\n\n"
-		 "	kernel.perf_event_paranoid = -1\n" ,
+		 "	kernel.perf_event_paranoid = -1\n\n"
+		 "Alternatively an identical per PMU setting can be found and adjusted at\n"
+		 "/sys/bus/event_source/devices/%s/perf_event_paranoid for fine-grained\n"
+		 "access control. The current value is '%s'.\n",
 				 target->system_wide ? "system-wide " : "",
-				 perf_event_paranoid());
+				 perf_event_paranoid(),
+				 evsel->pmu_name,
+				 __pmu_paranoid_value(evsel->pmu_name, buf,
+						      sizeof(buf)) ? "-" : buf);
 	case ENOENT:
 		return scnprintf(msg, size, "The %s event is not supported.",
 				 perf_evsel__name(evsel));
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index afd68524ffa9..5ecead4969af 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -545,6 +545,22 @@ static int pmu_type(const char *name, __u32 *type)
 	return ret;
 }
 
+static int pmu_paranoid(const char *name)
+{
+	char path[PATH_MAX];
+	int ret, paranoid;
+
+	ret = snprintf(path, sizeof(path),
+		       EVENT_SOURCE_DEVICE_PATH "%s/perf_event_paranoid",
+		       name);
+
+	if (ret > 0 && ret < (int)sizeof(path) &&
+	    !sysfs__read_int(path, &paranoid))
+		return paranoid;
+
+	return perf_event_paranoid();
+}
+
 /* Add all pmus in sysfs to pmu list: */
 static void pmu_read_sysfs(void)
 {
@@ -825,6 +841,7 @@ static struct perf_pmu *pmu_lookup(const char *name)
 	pmu->name = strdup(name);
 	pmu->type = type;
 	pmu->is_uncore = pmu_is_uncore(name);
+	pmu->paranoid = pmu_paranoid(name);
 	pmu_add_cpu_aliases(&aliases, pmu);
 
 	INIT_LIST_HEAD(&pmu->format);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 76fecec7b3f9..1f00c8bbdb90 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -30,6 +30,7 @@ struct perf_pmu {
 	struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */
 	struct list_head list;    /* ELEM */
 	int (*set_drv_config)	(struct perf_evsel_config_term *term);
+	int paranoid;
 };
 
 struct perf_pmu_info {
-- 
2.17.1


  parent reply	other threads:[~2018-09-19 12:28 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-19 12:27 [RFC 0/5] perf: Per PMU access controls (paranoid setting) Tvrtko Ursulin
2018-09-19 12:27 ` [RFC 1/5] perf: Move some access checks later in perf_event_open Tvrtko Ursulin
2018-09-19 12:27 ` [RFC 2/5] perf: Pass pmu pointer to perf_paranoid_* helpers Tvrtko Ursulin
2018-09-19 12:27 ` [RFC 3/5] perf: Allow per PMU access control Tvrtko Ursulin
2018-09-27 20:15   ` Andi Kleen
2018-09-28  8:57     ` Tvrtko Ursulin
2018-09-19 12:27 ` [RFC 4/5] perf Documentation: Document the per PMU perf_event_paranoid interface Tvrtko Ursulin
2018-09-19 12:27 ` Tvrtko Ursulin [this message]
2018-09-28 10:26 ` [RFC 0/5] perf: Per PMU access controls (paranoid setting) Thomas Gleixner
2018-09-28 13:22   ` Tvrtko Ursulin
2018-09-28 14:02     ` Thomas Gleixner
2018-09-28 14:56       ` Tvrtko Ursulin
2018-09-28 15:23         ` Thomas Gleixner
2018-09-28 15:45       ` Alexey Budankov
2018-09-28 18:20         ` Thomas Gleixner
2018-09-28 20:45           ` Andi Kleen
2018-09-29  6:19             ` Thomas Gleixner
2018-10-01  6:25           ` Alexey Budankov
2018-09-28 15:12     ` Jann Horn
2018-09-28 22:02       ` Jann Horn
2018-10-01  6:27         ` Alexey Budankov
2018-09-28 16:41   ` Mark Rutland
2018-09-28 17:23     ` Andi Kleen
2018-09-28 17:40       ` Mark Rutland
2018-09-28 20:49         ` Andi Kleen
2018-09-28 20:54           ` Jann Horn
2018-09-28 20:59             ` Andi Kleen
2018-09-28 21:22               ` Jann Horn
2018-09-28 21:27                 ` Andi Kleen
2018-10-01  6:25                   ` Alexey Budankov
2018-10-01 16:11                     ` Thomas Gleixner
2018-10-01 16:15                       ` Jann Horn
2018-10-01 20:51                       ` Alexey Budankov
2018-10-02  6:40                         ` Thomas Gleixner
2018-10-02 11:44                           ` Alexey Budankov
2018-10-03 17:01                         ` Jann Horn
2018-10-04 17:11                           ` Alexey Budankov
2018-09-29  6:30               ` Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180919122751.12439-6-tvrtko.ursulin@linux.intel.com \
    --to=tursulin@ursulin.net \
    --cc=acme@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=alexey.budankov@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maddy@linux.vnet.ibm.com \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=tvrtko.ursulin@intel.com \
    --cc=tvrtko.ursulin@linux.intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome