Consistent with the kernel.perf_event_paranoid sysctl option that can allow non-root users to access system wide cpu metrics, this can optionally allow non-root users to access system wide OA counter metrics from Gen graphics hardware. Signed-off-by: Robert Bragg <robert@xxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_oa_perf.c | 40 ++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1e65dc2..7bc7243 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1831,6 +1831,8 @@ struct drm_i915_private { struct hrtimer timer; struct pt_regs dummy_regs; + struct ctl_table_header *sysctl_header; + struct perf_event *exclusive_event; struct intel_context *specific_ctx; bool event_active; diff --git a/drivers/gpu/drm/i915/i915_oa_perf.c b/drivers/gpu/drm/i915/i915_oa_perf.c index d0e144c..c3e5059 100644 --- a/drivers/gpu/drm/i915/i915_oa_perf.c +++ b/drivers/gpu/drm/i915/i915_oa_perf.c @@ -11,6 +11,8 @@ #define FREQUENCY 200 #define PERIOD max_t(u64, 10000, NSEC_PER_SEC / FREQUENCY) +static u32 i915_oa_event_paranoid = true; + static int hsw_perf_format_sizes[] = { 64, /* A13_HSW */ 128, /* A29_HSW */ @@ -548,7 +550,8 @@ static int i915_oa_event_init(struct perf_event *event) } } - if (!dev_priv->oa_pmu.specific_ctx && !capable(CAP_SYS_ADMIN)) + if (!dev_priv->oa_pmu.specific_ctx && + i915_oa_event_paranoid && !capable(CAP_SYS_ADMIN)) return -EACCES; mutex_lock(&dev_priv->dev->struct_mutex); @@ -795,6 +798,37 @@ void i915_oa_context_unpin_notify(struct drm_i915_private *dev_priv, spin_unlock_irqrestore(&dev_priv->oa_pmu.lock, flags); } +static struct ctl_table oa_table[] = { + { + .procname = "oa_event_paranoid", + .data = &i915_oa_event_paranoid, + .maxlen = sizeof(i915_oa_event_paranoid), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + {} +}; + +static struct ctl_table i915_root[] = { + { + .procname = "i915", + .maxlen = 0, + .mode = 0555, + .child = oa_table, + }, + {} +}; + +static struct ctl_table dev_root[] = { + { + .procname = "dev", + .maxlen = 0, + .mode = 0555, + .child = i915_root, + }, + {} +}; + void i915_oa_pmu_register(struct drm_device *dev) { struct drm_i915_private *i915 = to_i915(dev); @@ -802,6 +836,8 @@ void i915_oa_pmu_register(struct drm_device *dev) if (!IS_HASWELL(dev)) return; + i915->oa_pmu.sysctl_header = register_sysctl_table(dev_root); + /* We need to be careful about forwarding cpu metrics to * userspace considering that PERF_PMU_CAP_IS_DEVICE bypasses * the events/core security check that stops an unprivileged @@ -841,6 +877,8 @@ void i915_oa_pmu_unregister(struct drm_device *dev) if (i915->oa_pmu.pmu.event_init == NULL) return; + unregister_sysctl_table(i915->oa_pmu.sysctl_header); + perf_pmu_unregister(&i915->oa_pmu.pmu); i915->oa_pmu.pmu.event_init = NULL; } -- 2.3.2 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel