On Tue, Jun 26, 2018 at 04:36:38PM +0100, Tvrtko Ursulin wrote: > From: Tvrtko Ursulin <tvrtko.ursu...@intel.com> > > For situations where sysadmins might want to allow different level of > access control for different PMUs, we start creating per-PMU > perf_event_paranoid controls in sysfs. > > These work in equivalent fashion as the existing perf_event_paranoid > sysctl, which now becomes the parent control for each PMU. > > On PMU registration the global/parent value will be inherited by each PMU, > as it will be propagated to all registered PMUs when the sysctl is > updated. > > At any later point individual PMU access controls, located in > <sysfs>/device/<pmu-name>/perf_event_paranoid, can be adjusted to achieve > fine grained access control. > > Discussion from previous posting: > https://lkml.org/lkml/2018/5/21/156 > > Cc: Thomas Gleixner <t...@linutronix.de> > Cc: Peter Zijlstra <pet...@infradead.org> > Cc: Ingo Molnar <mi...@redhat.com> > Cc: "H. Peter Anvin" <h...@zytor.com> > Cc: Arnaldo Carvalho de Melo <a...@kernel.org> > Cc: Alexander Shishkin <alexander.shish...@linux.intel.com> > Cc: Jiri Olsa <jo...@redhat.com> > Cc: Namhyung Kim <namhy...@kernel.org> > Cc: Madhavan Srinivasan <ma...@linux.vnet.ibm.com> > Cc: Andi Kleen <a...@linux.intel.com> > Cc: Alexey Budankov <alexey.budan...@linux.intel.com> > Cc: linux-kernel@vger.kernel.org > Cc: x...@kernel.org > > Tvrtko Ursulin (4): > perf: Move some access checks later in perf_event_open > perf: Pass pmu pointer to perf_paranoid_* helpers > perf: Allow per PMU access control > perf Documentation: Document the per PMU perf_event_paranoid interface
I think we'll need some perf tool changes for this apart from the hint/docs, that checks/display paranoid value, I think we need some changes in arch related code like below (untested) jirka --- 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 1120e39c1b00..89d3d27ed8be 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/pmu.c b/tools/perf/util/pmu.c index d2fb597c9a8c..f2a91305a8b6 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -450,6 +450,20 @@ static int pmu_type(const char *name, __u32 *type) return ret; } +static int pmu_paranoid(const char *name) +{ + char path[PATH_MAX]; + int paranoid; + + snprintf(path, PATH_MAX, + EVENT_SOURCE_DEVICE_PATH "%s/perf_event_paranoid", name); + + if (!sysfs__read_int(EVENT_SOURCE_DEVICE_PATH, ¶noid)) + return paranoid; + + return perf_event_paranoid(); +} + /* Add all pmus in sysfs to pmu list: */ static void pmu_read_sysfs(void) { @@ -736,6 +750,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 {