return -ENOENT;
}
+ /* Check online status of the CPU to which the event is pinned */
if (event->cpu >= nr_cpumask_bits ||
(event->cpu >= 0 && !cpu_online(event->cpu)))
return -ENODEV;
+ /* Force reset of idle/hv excludes regardless of what the
+ * user requested.
+ */
+ if (event->attr.exclude_hv)
+ event->attr.exclude_hv = 0;
+ if (event->attr.exclude_idle)
+ event->attr.exclude_idle = 0;
+
err = __hw_perf_event_init(event);
if (unlikely(err))
if (event->destroy)
cpuhw->flags &= ~PMU_F_ENABLED;
}
+/* perf_exclude_event() - Filter event
+ * @event: The perf event
+ * @regs: pt_regs structure
+ * @sde_regs: Sample-data-entry (sde) regs structure
+ *
+ * Filter perf events according to their exclude specification.
+ *
+ * Return non-zero if the event shall be excluded.
+ */
+static int perf_exclude_event(struct perf_event *event, struct pt_regs *regs,
+ struct perf_sf_sde_regs *sde_regs)
+{
+ if (event->attr.exclude_user && user_mode(regs))
+ return 1;
+ if (event->attr.exclude_kernel && !user_mode(regs))
+ return 1;
+ if (event->attr.exclude_guest && sde_regs->in_guest)
+ return 1;
+ if (event->attr.exclude_host && !sde_regs->in_guest)
+ return 1;
+ return 0;
+}
+
/* perf_push_sample() - Push samples to perf
* @event: The perf event
* @sample: Hardware sample data
sde_regs->in_guest = 1;
overflow = 0;
+ if (perf_exclude_event(event, ®s, sde_regs))
+ goto out;
if (perf_event_overflow(event, &data, ®s)) {
overflow = 1;
event->pmu->stop(event, 0);
}
perf_event_update_userpage(event);
-
+out:
return overflow;
}