Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: perf: Add userspace counter access disable switch

Like x86, some users may want to disable userspace PMU counter
altogether. Add a sysctl 'perf_user_access' file to control userspace
counter access. The default is '0' which is disabled. Writing '1'
enables access.

Note that x86 supports globally enabling user access by writing '2' to
/sys/bus/event_source/devices/cpu/rdpmc. As there's not existing
userspace support to worry about, this shouldn't be necessary for Arm.
It could be added later if the need arises.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.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: Catalin Marinas <catalin.marinas@arm.com>
Cc: linux-perf-users@vger.kernel.org
Acked-by: Will Deacon <will@kernel.org>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20211208201124.310740-4-robh@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Rob Herring and committed by
Will Deacon
e2012600 82ff0c02

+28
+11
Documentation/admin-guide/sysctl/kernel.rst
··· 905 905 The default value is 8. 906 906 907 907 908 + perf_user_access (arm64 only) 909 + ================================= 910 + 911 + Controls user space access for reading perf event counters. When set to 1, 912 + user space can read performance monitor counter registers directly. 913 + 914 + The default value is 0 (access disabled). 915 + 916 + See Documentation/arm64/perf.rst for more information. 917 + 918 + 908 919 pid_max 909 920 ======= 910 921
+17
arch/arm64/kernel/perf_event.c
··· 286 286 PMU_FORMAT_ATTR(event, "config:0-15"); 287 287 PMU_FORMAT_ATTR(long, "config1:0"); 288 288 289 + static int sysctl_perf_user_access __read_mostly; 290 + 289 291 static inline bool armv8pmu_event_is_64bit(struct perf_event *event) 290 292 { 291 293 return event->attr.config1 & 0x1; ··· 1106 1104 return probe.present ? 0 : -ENODEV; 1107 1105 } 1108 1106 1107 + static struct ctl_table armv8_pmu_sysctl_table[] = { 1108 + { 1109 + .procname = "perf_user_access", 1110 + .data = &sysctl_perf_user_access, 1111 + .maxlen = sizeof(unsigned int), 1112 + .mode = 0644, 1113 + .proc_handler = proc_dointvec_minmax, 1114 + .extra1 = SYSCTL_ZERO, 1115 + .extra2 = SYSCTL_ONE, 1116 + }, 1117 + { } 1118 + }; 1119 + 1109 1120 static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name, 1110 1121 int (*map_event)(struct perf_event *event), 1111 1122 const struct attribute_group *events, ··· 1150 1135 format : &armv8_pmuv3_format_attr_group; 1151 1136 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = caps ? 1152 1137 caps : &armv8_pmuv3_caps_attr_group; 1138 + 1139 + register_sysctl("kernel", armv8_pmu_sysctl_table); 1153 1140 1154 1141 return 0; 1155 1142 }