[PATCH] drivers/perf: arm_spe: Use perf_allow_kernel() for permissions
James Clark
james.clark at linaro.org
Wed Aug 7 10:54:41 UTC 2024
For other PMUs, PERF_SAMPLE_PHYS_ADDR requires perf_allow_kernel()
rather than just perfmon_capable(). Because PMSCR_EL1_PA is another form
of physical address, make it consistent and use perf_allow_kernel() for
SPE as well. PMSCR_EL1_PCT and PMSCR_EL1_CX also get the same change.
This improves consistency and indirectly fixes the following error
message which is misleading because perf_event_paranoid is not taken
into account by perfmon_capable():
$ perf record -e arm_spe/pa_enable/
Error:
Access to performance monitoring and observability operations is
limited. Consider adjusting /proc/sys/kernel/perf_event_paranoid
setting ...
Suggested-by: Al Grant <al.grant at arm.com>
Signed-off-by: James Clark <james.clark at linaro.org>
---
drivers/perf/arm_spe_pmu.c | 9 ++++-----
kernel/events/core.c | 1 +
security/security.c | 1 +
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index 9100d82bfabc..3569050f9cf3 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -41,7 +41,7 @@
/*
* Cache if the event is allowed to trace Context information.
- * This allows us to perform the check, i.e, perfmon_capable(),
+ * This allows us to perform the check, i.e, perf_allow_kernel(),
* in the context of the event owner, once, during the event_init().
*/
#define SPE_PMU_HW_FLAGS_CX 0x00001
@@ -50,7 +50,7 @@ static_assert((PERF_EVENT_FLAG_ARCH & SPE_PMU_HW_FLAGS_CX) == SPE_PMU_HW_FLAGS_C
static void set_spe_event_has_cx(struct perf_event *event)
{
- if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
+ if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && !perf_allow_kernel(&event->attr))
event->hw.flags |= SPE_PMU_HW_FLAGS_CX;
}
@@ -745,9 +745,8 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
set_spe_event_has_cx(event);
reg = arm_spe_event_to_pmscr(event);
- if (!perfmon_capable() &&
- (reg & (PMSCR_EL1_PA | PMSCR_EL1_PCT)))
- return -EACCES;
+ if (reg & (PMSCR_EL1_PA | PMSCR_EL1_PCT))
+ return perf_allow_kernel(&event->attr);
return 0;
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index aa3450bdc227..4a69583e329a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -417,6 +417,7 @@ static struct kmem_cache *perf_event_cache;
* 2 - disallow kernel profiling for unpriv
*/
int sysctl_perf_event_paranoid __read_mostly = 2;
+EXPORT_SYMBOL_GPL(sysctl_perf_event_paranoid);
/* Minimum for 512 kiB + 1 user control page */
int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */
diff --git a/security/security.c b/security/security.c
index 8cee5b6c6e6d..70cc9206e902 100644
--- a/security/security.c
+++ b/security/security.c
@@ -5610,6 +5610,7 @@ int security_perf_event_open(struct perf_event_attr *attr, int type)
{
return call_int_hook(perf_event_open, attr, type);
}
+EXPORT_SYMBOL_GPL(security_perf_event_open);
/**
* security_perf_event_alloc() - Allocate a perf event LSM blob
--
2.34.1
More information about the Linux-security-module-archive
mailing list