17f5a08c7SBeau Belgrave // SPDX-License-Identifier: GPL-2.0-only
27f5a08c7SBeau Belgrave /*
37f5a08c7SBeau Belgrave * Copyright (c) 2021, Microsoft Corporation.
47f5a08c7SBeau Belgrave *
57f5a08c7SBeau Belgrave * Authors:
67f5a08c7SBeau Belgrave * Beau Belgrave <beaub@linux.microsoft.com>
77f5a08c7SBeau Belgrave */
87f5a08c7SBeau Belgrave
97f5a08c7SBeau Belgrave #include <linux/bitmap.h>
107f5a08c7SBeau Belgrave #include <linux/cdev.h>
117f5a08c7SBeau Belgrave #include <linux/hashtable.h>
127f5a08c7SBeau Belgrave #include <linux/list.h>
137f5a08c7SBeau Belgrave #include <linux/io.h>
147f5a08c7SBeau Belgrave #include <linux/uio.h>
157f5a08c7SBeau Belgrave #include <linux/ioctl.h>
167f5a08c7SBeau Belgrave #include <linux/jhash.h>
17d401b724SBeau Belgrave #include <linux/refcount.h>
187f5a08c7SBeau Belgrave #include <linux/trace_events.h>
197f5a08c7SBeau Belgrave #include <linux/tracefs.h>
207f5a08c7SBeau Belgrave #include <linux/types.h>
217f5a08c7SBeau Belgrave #include <linux/uaccess.h>
2272357590SBeau Belgrave #include <linux/highmem.h>
23ce58e96eSBeau Belgrave #include <linux/init.h>
245cfff569SSteven Rostedt (Google) #include <linux/user_events.h>
257f5a08c7SBeau Belgrave #include "trace_dynevent.h"
264bec284cSSteven Rostedt (Google) #include "trace_output.h"
274bec284cSSteven Rostedt (Google) #include "trace.h"
287f5a08c7SBeau Belgrave
297f5a08c7SBeau Belgrave #define USER_EVENTS_PREFIX_LEN (sizeof(USER_EVENTS_PREFIX)-1)
307f5a08c7SBeau Belgrave
317f5a08c7SBeau Belgrave #define FIELD_DEPTH_TYPE 0
327f5a08c7SBeau Belgrave #define FIELD_DEPTH_NAME 1
337f5a08c7SBeau Belgrave #define FIELD_DEPTH_SIZE 2
347f5a08c7SBeau Belgrave
357f5a08c7SBeau Belgrave /* Limit how long of an event name plus args within the subsystem. */
367f5a08c7SBeau Belgrave #define MAX_EVENT_DESC 512
3764805e40SBeau Belgrave #define EVENT_NAME(user_event) ((user_event)->reg_name)
3864805e40SBeau Belgrave #define EVENT_TP_NAME(user_event) ((user_event)->tracepoint.name)
397f5a08c7SBeau Belgrave #define MAX_FIELD_ARRAY_SIZE 1024
407f5a08c7SBeau Belgrave
4139d6d08bSBeau Belgrave /*
4239d6d08bSBeau Belgrave * Internal bits (kernel side only) to keep track of connected probes:
4339d6d08bSBeau Belgrave * These are used when status is requested in text form about an event. These
4439d6d08bSBeau Belgrave * bits are compared against an internal byte on the event to determine which
4539d6d08bSBeau Belgrave * probes to print out to the user.
4639d6d08bSBeau Belgrave *
4739d6d08bSBeau Belgrave * These do not reflect the mapped bytes between the user and kernel space.
4839d6d08bSBeau Belgrave */
4939d6d08bSBeau Belgrave #define EVENT_STATUS_FTRACE BIT(0)
5039d6d08bSBeau Belgrave #define EVENT_STATUS_PERF BIT(1)
5139d6d08bSBeau Belgrave #define EVENT_STATUS_OTHER BIT(7)
5239d6d08bSBeau Belgrave
53e5d27181SBeau Belgrave /*
5472357590SBeau Belgrave * Stores the system name, tables, and locks for a group of events. This
5572357590SBeau Belgrave * allows isolation for events by various means.
56e5d27181SBeau Belgrave */
57e5d27181SBeau Belgrave struct user_event_group {
58e5d27181SBeau Belgrave char *system_name;
5964805e40SBeau Belgrave char *system_multi_name;
60e5d27181SBeau Belgrave struct hlist_node node;
61e5d27181SBeau Belgrave struct mutex reg_mutex;
62e5d27181SBeau Belgrave DECLARE_HASHTABLE(register_table, 8);
6364805e40SBeau Belgrave /* ID that moves forward within the group for multi-event names */
6464805e40SBeau Belgrave u64 multi_id;
65e5d27181SBeau Belgrave };
667f5a08c7SBeau Belgrave
67e5d27181SBeau Belgrave /* Group for init_user_ns mapping, top-most group */
68e5d27181SBeau Belgrave static struct user_event_group *init_group;
697f5a08c7SBeau Belgrave
70ce58e96eSBeau Belgrave /* Max allowed events for the whole system */
71ce58e96eSBeau Belgrave static unsigned int max_user_events = 32768;
72ce58e96eSBeau Belgrave
73ce58e96eSBeau Belgrave /* Current number of events on the whole system */
74ce58e96eSBeau Belgrave static unsigned int current_user_events;
75ce58e96eSBeau Belgrave
767f5a08c7SBeau Belgrave /*
777f5a08c7SBeau Belgrave * Stores per-event properties, as users register events
787f5a08c7SBeau Belgrave * within a file a user_event might be created if it does not
797f5a08c7SBeau Belgrave * already exist. These are globally used and their lifetime
807f5a08c7SBeau Belgrave * is tied to the refcnt member. These cannot go away until the
81d401b724SBeau Belgrave * refcnt reaches one.
827f5a08c7SBeau Belgrave */
837f5a08c7SBeau Belgrave struct user_event {
84e5d27181SBeau Belgrave struct user_event_group *group;
8564805e40SBeau Belgrave char *reg_name;
867f5a08c7SBeau Belgrave struct tracepoint tracepoint;
877f5a08c7SBeau Belgrave struct trace_event_call call;
887f5a08c7SBeau Belgrave struct trace_event_class class;
897f5a08c7SBeau Belgrave struct dyn_event devent;
907f5a08c7SBeau Belgrave struct hlist_node node;
917f5a08c7SBeau Belgrave struct list_head fields;
922467cda1SBeau Belgrave struct list_head validators;
93a65442edSBeau Belgrave struct work_struct put_work;
94d401b724SBeau Belgrave refcount_t refcnt;
952467cda1SBeau Belgrave int min_size;
96b08d7258SBeau Belgrave int reg_flags;
9739d6d08bSBeau Belgrave char status;
987f5a08c7SBeau Belgrave };
997f5a08c7SBeau Belgrave
1007f5a08c7SBeau Belgrave /*
10172357590SBeau Belgrave * Stores per-mm/event properties that enable an address to be
10272357590SBeau Belgrave * updated properly for each task. As tasks are forked, we use
10372357590SBeau Belgrave * these to track enablement sites that are tied to an event.
10472357590SBeau Belgrave */
10572357590SBeau Belgrave struct user_event_enabler {
106dcbd1ac2SBeau Belgrave struct list_head mm_enablers_link;
10772357590SBeau Belgrave struct user_event *event;
10872357590SBeau Belgrave unsigned long addr;
10972357590SBeau Belgrave
11072357590SBeau Belgrave /* Track enable bit, flags, etc. Aligned for bitops. */
111ee7751b5SBeau Belgrave unsigned long values;
11272357590SBeau Belgrave };
11372357590SBeau Belgrave
11472357590SBeau Belgrave /* Bits 0-5 are for the bit to update upon enable/disable (0-63 allowed) */
11572357590SBeau Belgrave #define ENABLE_VAL_BIT_MASK 0x3F
11672357590SBeau Belgrave
11781f8fb65SBeau Belgrave /* Bit 6 is for faulting status of enablement */
11881f8fb65SBeau Belgrave #define ENABLE_VAL_FAULTING_BIT 6
11981f8fb65SBeau Belgrave
120dcb8177cSBeau Belgrave /* Bit 7 is for freeing status of enablement */
121dcb8177cSBeau Belgrave #define ENABLE_VAL_FREEING_BIT 7
122dcb8177cSBeau Belgrave
1232de9ee94SBeau Belgrave /* Bit 8 is for marking 32-bit on 64-bit */
1242de9ee94SBeau Belgrave #define ENABLE_VAL_32_ON_64_BIT 8
1252de9ee94SBeau Belgrave
1262de9ee94SBeau Belgrave #define ENABLE_VAL_COMPAT_MASK (1 << ENABLE_VAL_32_ON_64_BIT)
1272de9ee94SBeau Belgrave
1282de9ee94SBeau Belgrave /* Only duplicate the bit and compat values */
1292de9ee94SBeau Belgrave #define ENABLE_VAL_DUP_MASK (ENABLE_VAL_BIT_MASK | ENABLE_VAL_COMPAT_MASK)
13072357590SBeau Belgrave
131ee7751b5SBeau Belgrave #define ENABLE_BITOPS(e) (&(e)->values)
132ee7751b5SBeau Belgrave
133ee7751b5SBeau Belgrave #define ENABLE_BIT(e) ((int)((e)->values & ENABLE_VAL_BIT_MASK))
13481f8fb65SBeau Belgrave
13564805e40SBeau Belgrave #define EVENT_MULTI_FORMAT(f) ((f) & USER_EVENT_REG_MULTI_FORMAT)
13664805e40SBeau Belgrave
13781f8fb65SBeau Belgrave /* Used for asynchronous faulting in of pages */
13881f8fb65SBeau Belgrave struct user_event_enabler_fault {
13981f8fb65SBeau Belgrave struct work_struct work;
14081f8fb65SBeau Belgrave struct user_event_mm *mm;
14181f8fb65SBeau Belgrave struct user_event_enabler *enabler;
14241d8fba1SBeau Belgrave int attempt;
14381f8fb65SBeau Belgrave };
14481f8fb65SBeau Belgrave
14581f8fb65SBeau Belgrave static struct kmem_cache *fault_cache;
14681f8fb65SBeau Belgrave
14772357590SBeau Belgrave /* Global list of memory descriptors using user_events */
14872357590SBeau Belgrave static LIST_HEAD(user_event_mms);
14972357590SBeau Belgrave static DEFINE_SPINLOCK(user_event_mms_lock);
15072357590SBeau Belgrave
15172357590SBeau Belgrave /*
1527f5a08c7SBeau Belgrave * Stores per-file events references, as users register events
1537f5a08c7SBeau Belgrave * within a file this structure is modified and freed via RCU.
1547f5a08c7SBeau Belgrave * The lifetime of this struct is tied to the lifetime of the file.
1557f5a08c7SBeau Belgrave * These are not shared and only accessible by the file that created it.
1567f5a08c7SBeau Belgrave */
1577f5a08c7SBeau Belgrave struct user_event_refs {
1587f5a08c7SBeau Belgrave struct rcu_head rcu;
1597f5a08c7SBeau Belgrave int count;
1607f5a08c7SBeau Belgrave struct user_event *events[];
1617f5a08c7SBeau Belgrave };
1627f5a08c7SBeau Belgrave
163e5d27181SBeau Belgrave struct user_event_file_info {
164e5d27181SBeau Belgrave struct user_event_group *group;
165e5d27181SBeau Belgrave struct user_event_refs *refs;
166e5d27181SBeau Belgrave };
167e5d27181SBeau Belgrave
1682467cda1SBeau Belgrave #define VALIDATOR_ENSURE_NULL (1 << 0)
1692467cda1SBeau Belgrave #define VALIDATOR_REL (1 << 1)
1702467cda1SBeau Belgrave
1712467cda1SBeau Belgrave struct user_event_validator {
172dcbd1ac2SBeau Belgrave struct list_head user_event_link;
1732467cda1SBeau Belgrave int offset;
1742467cda1SBeau Belgrave int flags;
1752467cda1SBeau Belgrave };
1762467cda1SBeau Belgrave
align_addr_bit(unsigned long * addr,int * bit,unsigned long * flags)1772de9ee94SBeau Belgrave static inline void align_addr_bit(unsigned long *addr, int *bit,
1782de9ee94SBeau Belgrave unsigned long *flags)
1792de9ee94SBeau Belgrave {
1802de9ee94SBeau Belgrave if (IS_ALIGNED(*addr, sizeof(long))) {
1812de9ee94SBeau Belgrave #ifdef __BIG_ENDIAN
1822de9ee94SBeau Belgrave /* 32 bit on BE 64 bit requires a 32 bit offset when aligned. */
1832de9ee94SBeau Belgrave if (test_bit(ENABLE_VAL_32_ON_64_BIT, flags))
1842de9ee94SBeau Belgrave *bit += 32;
1852de9ee94SBeau Belgrave #endif
1862de9ee94SBeau Belgrave return;
1872de9ee94SBeau Belgrave }
1882de9ee94SBeau Belgrave
1892de9ee94SBeau Belgrave *addr = ALIGN_DOWN(*addr, sizeof(long));
1902de9ee94SBeau Belgrave
1912de9ee94SBeau Belgrave /*
1922de9ee94SBeau Belgrave * We only support 32 and 64 bit values. The only time we need
1932de9ee94SBeau Belgrave * to align is a 32 bit value on a 64 bit kernel, which on LE
1942de9ee94SBeau Belgrave * is always 32 bits, and on BE requires no change when unaligned.
1952de9ee94SBeau Belgrave */
1962de9ee94SBeau Belgrave #ifdef __LITTLE_ENDIAN
1972de9ee94SBeau Belgrave *bit += 32;
1982de9ee94SBeau Belgrave #endif
1992de9ee94SBeau Belgrave }
2002de9ee94SBeau Belgrave
2010279400aSBeau Belgrave typedef void (*user_event_func_t) (struct user_event *user, struct iov_iter *i,
2022467cda1SBeau Belgrave void *tpdata, bool *faulted);
2037f5a08c7SBeau Belgrave
204e5d27181SBeau Belgrave static int user_event_parse(struct user_event_group *group, char *name,
205e5d27181SBeau Belgrave char *args, char *flags,
206b08d7258SBeau Belgrave struct user_event **newuser, int reg_flags);
2077f5a08c7SBeau Belgrave
20872357590SBeau Belgrave static struct user_event_mm *user_event_mm_get(struct user_event_mm *mm);
20972357590SBeau Belgrave static struct user_event_mm *user_event_mm_get_all(struct user_event *user);
21072357590SBeau Belgrave static void user_event_mm_put(struct user_event_mm *mm);
211a65442edSBeau Belgrave static int destroy_user_event(struct user_event *user);
2121e953de9SBeau Belgrave static bool user_fields_match(struct user_event *user, int argc,
2131e953de9SBeau Belgrave const char **argv);
21472357590SBeau Belgrave
user_event_key(char * name)2157f5a08c7SBeau Belgrave static u32 user_event_key(char *name)
2167f5a08c7SBeau Belgrave {
2177f5a08c7SBeau Belgrave return jhash(name, strlen(name), 0);
2187f5a08c7SBeau Belgrave }
2197f5a08c7SBeau Belgrave
user_event_capable(u16 reg_flags)2205dbd04edSBeau Belgrave static bool user_event_capable(u16 reg_flags)
2215dbd04edSBeau Belgrave {
2225dbd04edSBeau Belgrave /* Persistent events require CAP_PERFMON / CAP_SYS_ADMIN */
2235dbd04edSBeau Belgrave if (reg_flags & USER_EVENT_REG_PERSIST) {
2245dbd04edSBeau Belgrave if (!perfmon_capable())
2255dbd04edSBeau Belgrave return false;
2265dbd04edSBeau Belgrave }
2275dbd04edSBeau Belgrave
2285dbd04edSBeau Belgrave return true;
2295dbd04edSBeau Belgrave }
2305dbd04edSBeau Belgrave
user_event_get(struct user_event * user)231f0dbf6fdSBeau Belgrave static struct user_event *user_event_get(struct user_event *user)
232f0dbf6fdSBeau Belgrave {
233f0dbf6fdSBeau Belgrave refcount_inc(&user->refcnt);
234f0dbf6fdSBeau Belgrave
235f0dbf6fdSBeau Belgrave return user;
236f0dbf6fdSBeau Belgrave }
237f0dbf6fdSBeau Belgrave
delayed_destroy_user_event(struct work_struct * work)238a65442edSBeau Belgrave static void delayed_destroy_user_event(struct work_struct *work)
239a65442edSBeau Belgrave {
240a65442edSBeau Belgrave struct user_event *user = container_of(
241a65442edSBeau Belgrave work, struct user_event, put_work);
242a65442edSBeau Belgrave
243a65442edSBeau Belgrave mutex_lock(&event_mutex);
244a65442edSBeau Belgrave
245a65442edSBeau Belgrave if (!refcount_dec_and_test(&user->refcnt))
246a65442edSBeau Belgrave goto out;
247a65442edSBeau Belgrave
248a65442edSBeau Belgrave if (destroy_user_event(user)) {
249a65442edSBeau Belgrave /*
250a65442edSBeau Belgrave * The only reason this would fail here is if we cannot
251a65442edSBeau Belgrave * update the visibility of the event. In this case the
252a65442edSBeau Belgrave * event stays in the hashtable, waiting for someone to
253a65442edSBeau Belgrave * attempt to delete it later.
254a65442edSBeau Belgrave */
255a65442edSBeau Belgrave pr_warn("user_events: Unable to delete event\n");
256a65442edSBeau Belgrave refcount_set(&user->refcnt, 1);
257a65442edSBeau Belgrave }
258a65442edSBeau Belgrave out:
259a65442edSBeau Belgrave mutex_unlock(&event_mutex);
260a65442edSBeau Belgrave }
261a65442edSBeau Belgrave
user_event_put(struct user_event * user,bool locked)262f0dbf6fdSBeau Belgrave static void user_event_put(struct user_event *user, bool locked)
263f0dbf6fdSBeau Belgrave {
264a65442edSBeau Belgrave bool delete;
265f0dbf6fdSBeau Belgrave
266f0dbf6fdSBeau Belgrave if (unlikely(!user))
267f0dbf6fdSBeau Belgrave return;
268f0dbf6fdSBeau Belgrave
269a65442edSBeau Belgrave /*
270a65442edSBeau Belgrave * When the event is not enabled for auto-delete there will always
271a65442edSBeau Belgrave * be at least 1 reference to the event. During the event creation
272a65442edSBeau Belgrave * we initially set the refcnt to 2 to achieve this. In those cases
273a65442edSBeau Belgrave * the caller must acquire event_mutex and after decrement check if
274a65442edSBeau Belgrave * the refcnt is 1, meaning this is the last reference. When auto
275a65442edSBeau Belgrave * delete is enabled, there will only be 1 ref, IE: refcnt will be
276a65442edSBeau Belgrave * only set to 1 during creation to allow the below checks to go
277a65442edSBeau Belgrave * through upon the last put. The last put must always be done with
278a65442edSBeau Belgrave * the event mutex held.
279a65442edSBeau Belgrave */
280a65442edSBeau Belgrave if (!locked) {
281a65442edSBeau Belgrave lockdep_assert_not_held(&event_mutex);
282a65442edSBeau Belgrave delete = refcount_dec_and_mutex_lock(&user->refcnt, &event_mutex);
283a65442edSBeau Belgrave } else {
284a65442edSBeau Belgrave lockdep_assert_held(&event_mutex);
285a65442edSBeau Belgrave delete = refcount_dec_and_test(&user->refcnt);
286a65442edSBeau Belgrave }
287a65442edSBeau Belgrave
288a65442edSBeau Belgrave if (!delete)
289a65442edSBeau Belgrave return;
290a65442edSBeau Belgrave
291a65442edSBeau Belgrave /*
292a65442edSBeau Belgrave * We now have the event_mutex in all cases, which ensures that
293a65442edSBeau Belgrave * no new references will be taken until event_mutex is released.
294a65442edSBeau Belgrave * New references come through find_user_event(), which requires
295a65442edSBeau Belgrave * the event_mutex to be held.
296a65442edSBeau Belgrave */
297a65442edSBeau Belgrave
298a65442edSBeau Belgrave if (user->reg_flags & USER_EVENT_REG_PERSIST) {
299a65442edSBeau Belgrave /* We should not get here when persist flag is set */
300a65442edSBeau Belgrave pr_alert("BUG: Auto-delete engaged on persistent event\n");
301a65442edSBeau Belgrave goto out;
302a65442edSBeau Belgrave }
303a65442edSBeau Belgrave
304a65442edSBeau Belgrave /*
305a65442edSBeau Belgrave * Unfortunately we have to attempt the actual destroy in a work
306a65442edSBeau Belgrave * queue. This is because not all cases handle a trace_event_call
307a65442edSBeau Belgrave * being removed within the class->reg() operation for unregister.
308a65442edSBeau Belgrave */
309a65442edSBeau Belgrave INIT_WORK(&user->put_work, delayed_destroy_user_event);
310a65442edSBeau Belgrave
311a65442edSBeau Belgrave /*
312a65442edSBeau Belgrave * Since the event is still in the hashtable, we have to re-inc
313a65442edSBeau Belgrave * the ref count to 1. This count will be decremented and checked
314a65442edSBeau Belgrave * in the work queue to ensure it's still the last ref. This is
315a65442edSBeau Belgrave * needed because a user-process could register the same event in
316a65442edSBeau Belgrave * between the time of event_mutex release and the work queue
317a65442edSBeau Belgrave * running the delayed destroy. If we removed the item now from
318a65442edSBeau Belgrave * the hashtable, this would result in a timing window where a
319a65442edSBeau Belgrave * user process would fail a register because the trace_event_call
320a65442edSBeau Belgrave * register would fail in the tracing layers.
321a65442edSBeau Belgrave */
322a65442edSBeau Belgrave refcount_set(&user->refcnt, 1);
323a65442edSBeau Belgrave
324a65442edSBeau Belgrave if (WARN_ON_ONCE(!schedule_work(&user->put_work))) {
325a65442edSBeau Belgrave /*
326a65442edSBeau Belgrave * If we fail we must wait for an admin to attempt delete or
327a65442edSBeau Belgrave * another register/close of the event, whichever is first.
328a65442edSBeau Belgrave */
329a65442edSBeau Belgrave pr_warn("user_events: Unable to queue delayed destroy\n");
330a65442edSBeau Belgrave }
331a65442edSBeau Belgrave out:
332a65442edSBeau Belgrave /* Ensure if we didn't have event_mutex before we unlock it */
333a65442edSBeau Belgrave if (!locked)
334a65442edSBeau Belgrave mutex_unlock(&event_mutex);
335f0dbf6fdSBeau Belgrave }
336f0dbf6fdSBeau Belgrave
user_event_group_destroy(struct user_event_group * group)337e5d27181SBeau Belgrave static void user_event_group_destroy(struct user_event_group *group)
338e5d27181SBeau Belgrave {
339e5d27181SBeau Belgrave kfree(group->system_name);
34064805e40SBeau Belgrave kfree(group->system_multi_name);
341e5d27181SBeau Belgrave kfree(group);
342e5d27181SBeau Belgrave }
343e5d27181SBeau Belgrave
user_event_group_system_name(void)344ed0e0ae0SBeau Belgrave static char *user_event_group_system_name(void)
345e5d27181SBeau Belgrave {
346e5d27181SBeau Belgrave char *system_name;
347e5d27181SBeau Belgrave int len = sizeof(USER_EVENTS_SYSTEM) + 1;
348e5d27181SBeau Belgrave
349e5d27181SBeau Belgrave system_name = kmalloc(len, GFP_KERNEL);
350e5d27181SBeau Belgrave
351e5d27181SBeau Belgrave if (!system_name)
352e5d27181SBeau Belgrave return NULL;
353e5d27181SBeau Belgrave
354e5d27181SBeau Belgrave snprintf(system_name, len, "%s", USER_EVENTS_SYSTEM);
355e5d27181SBeau Belgrave
356e5d27181SBeau Belgrave return system_name;
357e5d27181SBeau Belgrave }
358e5d27181SBeau Belgrave
user_event_group_system_multi_name(void)35964805e40SBeau Belgrave static char *user_event_group_system_multi_name(void)
36064805e40SBeau Belgrave {
36164805e40SBeau Belgrave return kstrdup(USER_EVENTS_MULTI_SYSTEM, GFP_KERNEL);
36264805e40SBeau Belgrave }
36364805e40SBeau Belgrave
current_user_event_group(void)364e5d27181SBeau Belgrave static struct user_event_group *current_user_event_group(void)
365e5d27181SBeau Belgrave {
366ed0e0ae0SBeau Belgrave return init_group;
367e5d27181SBeau Belgrave }
368e5d27181SBeau Belgrave
user_event_group_create(void)369ed0e0ae0SBeau Belgrave static struct user_event_group *user_event_group_create(void)
370e5d27181SBeau Belgrave {
371e5d27181SBeau Belgrave struct user_event_group *group;
372e5d27181SBeau Belgrave
373e5d27181SBeau Belgrave group = kzalloc(sizeof(*group), GFP_KERNEL);
374e5d27181SBeau Belgrave
375e5d27181SBeau Belgrave if (!group)
376e5d27181SBeau Belgrave return NULL;
377e5d27181SBeau Belgrave
378ed0e0ae0SBeau Belgrave group->system_name = user_event_group_system_name();
379e5d27181SBeau Belgrave
380e5d27181SBeau Belgrave if (!group->system_name)
381e5d27181SBeau Belgrave goto error;
382e5d27181SBeau Belgrave
38364805e40SBeau Belgrave group->system_multi_name = user_event_group_system_multi_name();
38464805e40SBeau Belgrave
38564805e40SBeau Belgrave if (!group->system_multi_name)
38664805e40SBeau Belgrave goto error;
38764805e40SBeau Belgrave
388e5d27181SBeau Belgrave mutex_init(&group->reg_mutex);
389e5d27181SBeau Belgrave hash_init(group->register_table);
390e5d27181SBeau Belgrave
391e5d27181SBeau Belgrave return group;
392e5d27181SBeau Belgrave error:
393e5d27181SBeau Belgrave if (group)
394e5d27181SBeau Belgrave user_event_group_destroy(group);
395e5d27181SBeau Belgrave
396e5d27181SBeau Belgrave return NULL;
397e5d27181SBeau Belgrave };
398e5d27181SBeau Belgrave
user_event_enabler_destroy(struct user_event_enabler * enabler,bool locked)399f0dbf6fdSBeau Belgrave static void user_event_enabler_destroy(struct user_event_enabler *enabler,
400f0dbf6fdSBeau Belgrave bool locked)
40139d6d08bSBeau Belgrave {
402dcbd1ac2SBeau Belgrave list_del_rcu(&enabler->mm_enablers_link);
40339d6d08bSBeau Belgrave
40472357590SBeau Belgrave /* No longer tracking the event via the enabler */
405f0dbf6fdSBeau Belgrave user_event_put(enabler->event, locked);
40672357590SBeau Belgrave
40772357590SBeau Belgrave kfree(enabler);
40839d6d08bSBeau Belgrave }
40939d6d08bSBeau Belgrave
user_event_mm_fault_in(struct user_event_mm * mm,unsigned long uaddr,int attempt)41041d8fba1SBeau Belgrave static int user_event_mm_fault_in(struct user_event_mm *mm, unsigned long uaddr,
41141d8fba1SBeau Belgrave int attempt)
41239d6d08bSBeau Belgrave {
41372357590SBeau Belgrave bool unlocked;
41472357590SBeau Belgrave int ret;
41539d6d08bSBeau Belgrave
41641d8fba1SBeau Belgrave /*
41741d8fba1SBeau Belgrave * Normally this is low, ensure that it cannot be taken advantage of by
41841d8fba1SBeau Belgrave * bad user processes to cause excessive looping.
41941d8fba1SBeau Belgrave */
42041d8fba1SBeau Belgrave if (attempt > 10)
42141d8fba1SBeau Belgrave return -EFAULT;
42241d8fba1SBeau Belgrave
42372357590SBeau Belgrave mmap_read_lock(mm->mm);
42472357590SBeau Belgrave
42572357590SBeau Belgrave /* Ensure MM has tasks, cannot use after exit_mm() */
42672357590SBeau Belgrave if (refcount_read(&mm->tasks) == 0) {
42772357590SBeau Belgrave ret = -ENOENT;
42872357590SBeau Belgrave goto out;
42972357590SBeau Belgrave }
43072357590SBeau Belgrave
43172357590SBeau Belgrave ret = fixup_user_fault(mm->mm, uaddr, FAULT_FLAG_WRITE | FAULT_FLAG_REMOTE,
43272357590SBeau Belgrave &unlocked);
43372357590SBeau Belgrave out:
43472357590SBeau Belgrave mmap_read_unlock(mm->mm);
43572357590SBeau Belgrave
43672357590SBeau Belgrave return ret;
43772357590SBeau Belgrave }
43872357590SBeau Belgrave
43972357590SBeau Belgrave static int user_event_enabler_write(struct user_event_mm *mm,
44081f8fb65SBeau Belgrave struct user_event_enabler *enabler,
44141d8fba1SBeau Belgrave bool fixup_fault, int *attempt);
44281f8fb65SBeau Belgrave
user_event_enabler_fault_fixup(struct work_struct * work)44381f8fb65SBeau Belgrave static void user_event_enabler_fault_fixup(struct work_struct *work)
44481f8fb65SBeau Belgrave {
44581f8fb65SBeau Belgrave struct user_event_enabler_fault *fault = container_of(
44681f8fb65SBeau Belgrave work, struct user_event_enabler_fault, work);
44781f8fb65SBeau Belgrave struct user_event_enabler *enabler = fault->enabler;
44881f8fb65SBeau Belgrave struct user_event_mm *mm = fault->mm;
44981f8fb65SBeau Belgrave unsigned long uaddr = enabler->addr;
45041d8fba1SBeau Belgrave int attempt = fault->attempt;
45181f8fb65SBeau Belgrave int ret;
45281f8fb65SBeau Belgrave
45341d8fba1SBeau Belgrave ret = user_event_mm_fault_in(mm, uaddr, attempt);
45481f8fb65SBeau Belgrave
45581f8fb65SBeau Belgrave if (ret && ret != -ENOENT) {
45681f8fb65SBeau Belgrave struct user_event *user = enabler->event;
45781f8fb65SBeau Belgrave
45881f8fb65SBeau Belgrave pr_warn("user_events: Fault for mm: 0x%pK @ 0x%llx event: %s\n",
45981f8fb65SBeau Belgrave mm->mm, (unsigned long long)uaddr, EVENT_NAME(user));
46081f8fb65SBeau Belgrave }
46181f8fb65SBeau Belgrave
46281f8fb65SBeau Belgrave /* Prevent state changes from racing */
46381f8fb65SBeau Belgrave mutex_lock(&event_mutex);
46481f8fb65SBeau Belgrave
465dcb8177cSBeau Belgrave /* User asked for enabler to be removed during fault */
466dcb8177cSBeau Belgrave if (test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler))) {
467f0dbf6fdSBeau Belgrave user_event_enabler_destroy(enabler, true);
468dcb8177cSBeau Belgrave goto out;
469dcb8177cSBeau Belgrave }
470dcb8177cSBeau Belgrave
47181f8fb65SBeau Belgrave /*
47281f8fb65SBeau Belgrave * If we managed to get the page, re-issue the write. We do not
47381f8fb65SBeau Belgrave * want to get into a possible infinite loop, which is why we only
47481f8fb65SBeau Belgrave * attempt again directly if the page came in. If we couldn't get
47581f8fb65SBeau Belgrave * the page here, then we will try again the next time the event is
47681f8fb65SBeau Belgrave * enabled/disabled.
47781f8fb65SBeau Belgrave */
47881f8fb65SBeau Belgrave clear_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler));
47981f8fb65SBeau Belgrave
48081f8fb65SBeau Belgrave if (!ret) {
48181f8fb65SBeau Belgrave mmap_read_lock(mm->mm);
48241d8fba1SBeau Belgrave user_event_enabler_write(mm, enabler, true, &attempt);
48381f8fb65SBeau Belgrave mmap_read_unlock(mm->mm);
48481f8fb65SBeau Belgrave }
485dcb8177cSBeau Belgrave out:
48681f8fb65SBeau Belgrave mutex_unlock(&event_mutex);
48781f8fb65SBeau Belgrave
48881f8fb65SBeau Belgrave /* In all cases we no longer need the mm or fault */
48981f8fb65SBeau Belgrave user_event_mm_put(mm);
49081f8fb65SBeau Belgrave kmem_cache_free(fault_cache, fault);
49181f8fb65SBeau Belgrave }
49281f8fb65SBeau Belgrave
user_event_enabler_queue_fault(struct user_event_mm * mm,struct user_event_enabler * enabler,int attempt)49381f8fb65SBeau Belgrave static bool user_event_enabler_queue_fault(struct user_event_mm *mm,
49441d8fba1SBeau Belgrave struct user_event_enabler *enabler,
49541d8fba1SBeau Belgrave int attempt)
49672357590SBeau Belgrave {
49781f8fb65SBeau Belgrave struct user_event_enabler_fault *fault;
49881f8fb65SBeau Belgrave
49981f8fb65SBeau Belgrave fault = kmem_cache_zalloc(fault_cache, GFP_NOWAIT | __GFP_NOWARN);
50081f8fb65SBeau Belgrave
50181f8fb65SBeau Belgrave if (!fault)
50281f8fb65SBeau Belgrave return false;
50381f8fb65SBeau Belgrave
50481f8fb65SBeau Belgrave INIT_WORK(&fault->work, user_event_enabler_fault_fixup);
50581f8fb65SBeau Belgrave fault->mm = user_event_mm_get(mm);
50681f8fb65SBeau Belgrave fault->enabler = enabler;
50741d8fba1SBeau Belgrave fault->attempt = attempt;
50881f8fb65SBeau Belgrave
50981f8fb65SBeau Belgrave /* Don't try to queue in again while we have a pending fault */
51081f8fb65SBeau Belgrave set_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler));
51181f8fb65SBeau Belgrave
51281f8fb65SBeau Belgrave if (!schedule_work(&fault->work)) {
51381f8fb65SBeau Belgrave /* Allow another attempt later */
51481f8fb65SBeau Belgrave clear_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler));
51581f8fb65SBeau Belgrave
51681f8fb65SBeau Belgrave user_event_mm_put(mm);
51781f8fb65SBeau Belgrave kmem_cache_free(fault_cache, fault);
51881f8fb65SBeau Belgrave
51981f8fb65SBeau Belgrave return false;
52081f8fb65SBeau Belgrave }
52181f8fb65SBeau Belgrave
52281f8fb65SBeau Belgrave return true;
52381f8fb65SBeau Belgrave }
52481f8fb65SBeau Belgrave
user_event_enabler_write(struct user_event_mm * mm,struct user_event_enabler * enabler,bool fixup_fault,int * attempt)52581f8fb65SBeau Belgrave static int user_event_enabler_write(struct user_event_mm *mm,
52681f8fb65SBeau Belgrave struct user_event_enabler *enabler,
52741d8fba1SBeau Belgrave bool fixup_fault, int *attempt)
52881f8fb65SBeau Belgrave {
52972357590SBeau Belgrave unsigned long uaddr = enabler->addr;
53072357590SBeau Belgrave unsigned long *ptr;
53172357590SBeau Belgrave struct page *page;
53272357590SBeau Belgrave void *kaddr;
5332de9ee94SBeau Belgrave int bit = ENABLE_BIT(enabler);
53472357590SBeau Belgrave int ret;
53572357590SBeau Belgrave
53672357590SBeau Belgrave lockdep_assert_held(&event_mutex);
53772357590SBeau Belgrave mmap_assert_locked(mm->mm);
53872357590SBeau Belgrave
53941d8fba1SBeau Belgrave *attempt += 1;
54041d8fba1SBeau Belgrave
54172357590SBeau Belgrave /* Ensure MM has tasks, cannot use after exit_mm() */
54272357590SBeau Belgrave if (refcount_read(&mm->tasks) == 0)
54372357590SBeau Belgrave return -ENOENT;
54472357590SBeau Belgrave
545dcb8177cSBeau Belgrave if (unlikely(test_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler)) ||
546dcb8177cSBeau Belgrave test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler))))
54781f8fb65SBeau Belgrave return -EBUSY;
54881f8fb65SBeau Belgrave
5492de9ee94SBeau Belgrave align_addr_bit(&uaddr, &bit, ENABLE_BITOPS(enabler));
5502de9ee94SBeau Belgrave
55172357590SBeau Belgrave ret = pin_user_pages_remote(mm->mm, uaddr, 1, FOLL_WRITE | FOLL_NOFAULT,
5520b295316SLorenzo Stoakes &page, NULL);
55372357590SBeau Belgrave
55481f8fb65SBeau Belgrave if (unlikely(ret <= 0)) {
55581f8fb65SBeau Belgrave if (!fixup_fault)
55681f8fb65SBeau Belgrave return -EFAULT;
55781f8fb65SBeau Belgrave
55841d8fba1SBeau Belgrave if (!user_event_enabler_queue_fault(mm, enabler, *attempt))
55981f8fb65SBeau Belgrave pr_warn("user_events: Unable to queue fault handler\n");
56081f8fb65SBeau Belgrave
56172357590SBeau Belgrave return -EFAULT;
56272357590SBeau Belgrave }
56372357590SBeau Belgrave
56472357590SBeau Belgrave kaddr = kmap_local_page(page);
56572357590SBeau Belgrave ptr = kaddr + (uaddr & ~PAGE_MASK);
56672357590SBeau Belgrave
56772357590SBeau Belgrave /* Update bit atomically, user tracers must be atomic as well */
56872357590SBeau Belgrave if (enabler->event && enabler->event->status)
5692de9ee94SBeau Belgrave set_bit(bit, ptr);
57072357590SBeau Belgrave else
5712de9ee94SBeau Belgrave clear_bit(bit, ptr);
57272357590SBeau Belgrave
57372357590SBeau Belgrave kunmap_local(kaddr);
57472357590SBeau Belgrave unpin_user_pages_dirty_lock(&page, 1, true);
57572357590SBeau Belgrave
57672357590SBeau Belgrave return 0;
57772357590SBeau Belgrave }
57872357590SBeau Belgrave
user_event_enabler_exists(struct user_event_mm * mm,unsigned long uaddr,unsigned char bit)57997bbce89SBeau Belgrave static bool user_event_enabler_exists(struct user_event_mm *mm,
58097bbce89SBeau Belgrave unsigned long uaddr, unsigned char bit)
58197bbce89SBeau Belgrave {
58297bbce89SBeau Belgrave struct user_event_enabler *enabler;
58397bbce89SBeau Belgrave
584dcbd1ac2SBeau Belgrave list_for_each_entry(enabler, &mm->enablers, mm_enablers_link) {
585ee7751b5SBeau Belgrave if (enabler->addr == uaddr && ENABLE_BIT(enabler) == bit)
58697bbce89SBeau Belgrave return true;
58797bbce89SBeau Belgrave }
58897bbce89SBeau Belgrave
58997bbce89SBeau Belgrave return false;
59097bbce89SBeau Belgrave }
59197bbce89SBeau Belgrave
user_event_enabler_update(struct user_event * user)59272357590SBeau Belgrave static void user_event_enabler_update(struct user_event *user)
59372357590SBeau Belgrave {
59472357590SBeau Belgrave struct user_event_enabler *enabler;
59572357590SBeau Belgrave struct user_event_mm *next;
596ff9e1632SBeau Belgrave struct user_event_mm *mm;
59741d8fba1SBeau Belgrave int attempt;
59872357590SBeau Belgrave
599aaecdaf9SLinus Torvalds lockdep_assert_held(&event_mutex);
600aaecdaf9SLinus Torvalds
601ff9e1632SBeau Belgrave /*
602ff9e1632SBeau Belgrave * We need to build a one-shot list of all the mms that have an
603ff9e1632SBeau Belgrave * enabler for the user_event passed in. This list is only valid
604ff9e1632SBeau Belgrave * while holding the event_mutex. The only reason for this is due
605ff9e1632SBeau Belgrave * to the global mm list being RCU protected and we use methods
606ff9e1632SBeau Belgrave * which can wait (mmap_read_lock and pin_user_pages_remote).
607ff9e1632SBeau Belgrave *
608ff9e1632SBeau Belgrave * NOTE: user_event_mm_get_all() increments the ref count of each
609ff9e1632SBeau Belgrave * mm that is added to the list to prevent removal timing windows.
610ff9e1632SBeau Belgrave * We must always put each mm after they are used, which may wait.
611ff9e1632SBeau Belgrave */
612ff9e1632SBeau Belgrave mm = user_event_mm_get_all(user);
613ff9e1632SBeau Belgrave
61472357590SBeau Belgrave while (mm) {
61572357590SBeau Belgrave next = mm->next;
61672357590SBeau Belgrave mmap_read_lock(mm->mm);
61772357590SBeau Belgrave
618dcbd1ac2SBeau Belgrave list_for_each_entry(enabler, &mm->enablers, mm_enablers_link) {
61941d8fba1SBeau Belgrave if (enabler->event == user) {
62041d8fba1SBeau Belgrave attempt = 0;
62141d8fba1SBeau Belgrave user_event_enabler_write(mm, enabler, true, &attempt);
62241d8fba1SBeau Belgrave }
62341d8fba1SBeau Belgrave }
62472357590SBeau Belgrave
62572357590SBeau Belgrave mmap_read_unlock(mm->mm);
62672357590SBeau Belgrave user_event_mm_put(mm);
62772357590SBeau Belgrave mm = next;
62872357590SBeau Belgrave }
62972357590SBeau Belgrave }
63072357590SBeau Belgrave
user_event_enabler_dup(struct user_event_enabler * orig,struct user_event_mm * mm)63172357590SBeau Belgrave static bool user_event_enabler_dup(struct user_event_enabler *orig,
63272357590SBeau Belgrave struct user_event_mm *mm)
63372357590SBeau Belgrave {
63472357590SBeau Belgrave struct user_event_enabler *enabler;
63572357590SBeau Belgrave
636dcb8177cSBeau Belgrave /* Skip pending frees */
637dcb8177cSBeau Belgrave if (unlikely(test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(orig))))
638dcb8177cSBeau Belgrave return true;
639dcb8177cSBeau Belgrave
640f9cce238SBeau Belgrave enabler = kzalloc(sizeof(*enabler), GFP_NOWAIT | __GFP_ACCOUNT);
64172357590SBeau Belgrave
64272357590SBeau Belgrave if (!enabler)
64372357590SBeau Belgrave return false;
64472357590SBeau Belgrave
645f0dbf6fdSBeau Belgrave enabler->event = user_event_get(orig->event);
64672357590SBeau Belgrave enabler->addr = orig->addr;
64772357590SBeau Belgrave
64872357590SBeau Belgrave /* Only dup part of value (ignore future flags, etc) */
64972357590SBeau Belgrave enabler->values = orig->values & ENABLE_VAL_DUP_MASK;
65072357590SBeau Belgrave
651aaecdaf9SLinus Torvalds /* Enablers not exposed yet, RCU not required */
652dcbd1ac2SBeau Belgrave list_add(&enabler->mm_enablers_link, &mm->enablers);
65372357590SBeau Belgrave
65472357590SBeau Belgrave return true;
65572357590SBeau Belgrave }
65672357590SBeau Belgrave
user_event_mm_get(struct user_event_mm * mm)65772357590SBeau Belgrave static struct user_event_mm *user_event_mm_get(struct user_event_mm *mm)
65872357590SBeau Belgrave {
65972357590SBeau Belgrave refcount_inc(&mm->refcnt);
66072357590SBeau Belgrave
66172357590SBeau Belgrave return mm;
66272357590SBeau Belgrave }
66372357590SBeau Belgrave
user_event_mm_get_all(struct user_event * user)66472357590SBeau Belgrave static struct user_event_mm *user_event_mm_get_all(struct user_event *user)
66572357590SBeau Belgrave {
66672357590SBeau Belgrave struct user_event_mm *found = NULL;
66772357590SBeau Belgrave struct user_event_enabler *enabler;
66872357590SBeau Belgrave struct user_event_mm *mm;
66972357590SBeau Belgrave
67072357590SBeau Belgrave /*
671ff9e1632SBeau Belgrave * We use the mm->next field to build a one-shot list from the global
672ff9e1632SBeau Belgrave * RCU protected list. To build this list the event_mutex must be held.
673ff9e1632SBeau Belgrave * This lets us build a list without requiring allocs that could fail
674ff9e1632SBeau Belgrave * when user based events are most wanted for diagnostics.
675ff9e1632SBeau Belgrave */
676ff9e1632SBeau Belgrave lockdep_assert_held(&event_mutex);
677ff9e1632SBeau Belgrave
678ff9e1632SBeau Belgrave /*
67972357590SBeau Belgrave * We do not want to block fork/exec while enablements are being
68072357590SBeau Belgrave * updated, so we use RCU to walk the current tasks that have used
68172357590SBeau Belgrave * user_events ABI for 1 or more events. Each enabler found in each
68272357590SBeau Belgrave * task that matches the event being updated has a write to reflect
68372357590SBeau Belgrave * the kernel state back into the process. Waits/faults must not occur
68472357590SBeau Belgrave * during this. So we scan the list under RCU for all the mm that have
68572357590SBeau Belgrave * the event within it. This is needed because mm_read_lock() can wait.
68672357590SBeau Belgrave * Each user mm returned has a ref inc to handle remove RCU races.
68772357590SBeau Belgrave */
68872357590SBeau Belgrave rcu_read_lock();
68972357590SBeau Belgrave
690dcbd1ac2SBeau Belgrave list_for_each_entry_rcu(mm, &user_event_mms, mms_link) {
691dcbd1ac2SBeau Belgrave list_for_each_entry_rcu(enabler, &mm->enablers, mm_enablers_link) {
69272357590SBeau Belgrave if (enabler->event == user) {
69372357590SBeau Belgrave mm->next = found;
69472357590SBeau Belgrave found = user_event_mm_get(mm);
69572357590SBeau Belgrave break;
69672357590SBeau Belgrave }
697dcbd1ac2SBeau Belgrave }
698dcbd1ac2SBeau Belgrave }
69972357590SBeau Belgrave
70072357590SBeau Belgrave rcu_read_unlock();
70172357590SBeau Belgrave
70272357590SBeau Belgrave return found;
70372357590SBeau Belgrave }
70472357590SBeau Belgrave
user_event_mm_alloc(struct task_struct * t)7053e0fea09SLinus Torvalds static struct user_event_mm *user_event_mm_alloc(struct task_struct *t)
70672357590SBeau Belgrave {
70772357590SBeau Belgrave struct user_event_mm *user_mm;
70872357590SBeau Belgrave
709f9cce238SBeau Belgrave user_mm = kzalloc(sizeof(*user_mm), GFP_KERNEL_ACCOUNT);
71072357590SBeau Belgrave
71172357590SBeau Belgrave if (!user_mm)
71272357590SBeau Belgrave return NULL;
71372357590SBeau Belgrave
71472357590SBeau Belgrave user_mm->mm = t->mm;
71572357590SBeau Belgrave INIT_LIST_HEAD(&user_mm->enablers);
71672357590SBeau Belgrave refcount_set(&user_mm->refcnt, 1);
71772357590SBeau Belgrave refcount_set(&user_mm->tasks, 1);
71872357590SBeau Belgrave
71972357590SBeau Belgrave /*
72072357590SBeau Belgrave * The lifetime of the memory descriptor can slightly outlast
72172357590SBeau Belgrave * the task lifetime if a ref to the user_event_mm is taken
72272357590SBeau Belgrave * between list_del_rcu() and call_rcu(). Therefore we need
72372357590SBeau Belgrave * to take a reference to it to ensure it can live this long
72472357590SBeau Belgrave * under this corner case. This can also occur in clones that
72572357590SBeau Belgrave * outlast the parent.
72672357590SBeau Belgrave */
72772357590SBeau Belgrave mmgrab(user_mm->mm);
72872357590SBeau Belgrave
72972357590SBeau Belgrave return user_mm;
73072357590SBeau Belgrave }
73172357590SBeau Belgrave
user_event_mm_attach(struct user_event_mm * user_mm,struct task_struct * t)7323e0fea09SLinus Torvalds static void user_event_mm_attach(struct user_event_mm *user_mm, struct task_struct *t)
7333e0fea09SLinus Torvalds {
7343e0fea09SLinus Torvalds unsigned long flags;
7353e0fea09SLinus Torvalds
7363e0fea09SLinus Torvalds spin_lock_irqsave(&user_event_mms_lock, flags);
737dcbd1ac2SBeau Belgrave list_add_rcu(&user_mm->mms_link, &user_event_mms);
7383e0fea09SLinus Torvalds spin_unlock_irqrestore(&user_event_mms_lock, flags);
7393e0fea09SLinus Torvalds
7403e0fea09SLinus Torvalds t->user_event_mm = user_mm;
7413e0fea09SLinus Torvalds }
7423e0fea09SLinus Torvalds
current_user_event_mm(void)74372357590SBeau Belgrave static struct user_event_mm *current_user_event_mm(void)
74472357590SBeau Belgrave {
74572357590SBeau Belgrave struct user_event_mm *user_mm = current->user_event_mm;
74672357590SBeau Belgrave
74772357590SBeau Belgrave if (user_mm)
74872357590SBeau Belgrave goto inc;
74972357590SBeau Belgrave
7503e0fea09SLinus Torvalds user_mm = user_event_mm_alloc(current);
75172357590SBeau Belgrave
75272357590SBeau Belgrave if (!user_mm)
75372357590SBeau Belgrave goto error;
7543e0fea09SLinus Torvalds
7553e0fea09SLinus Torvalds user_event_mm_attach(user_mm, current);
75672357590SBeau Belgrave inc:
75772357590SBeau Belgrave refcount_inc(&user_mm->refcnt);
75872357590SBeau Belgrave error:
75972357590SBeau Belgrave return user_mm;
76072357590SBeau Belgrave }
76172357590SBeau Belgrave
user_event_mm_destroy(struct user_event_mm * mm)76272357590SBeau Belgrave static void user_event_mm_destroy(struct user_event_mm *mm)
76372357590SBeau Belgrave {
76472357590SBeau Belgrave struct user_event_enabler *enabler, *next;
76572357590SBeau Belgrave
766dcbd1ac2SBeau Belgrave list_for_each_entry_safe(enabler, next, &mm->enablers, mm_enablers_link)
767f0dbf6fdSBeau Belgrave user_event_enabler_destroy(enabler, false);
76872357590SBeau Belgrave
76972357590SBeau Belgrave mmdrop(mm->mm);
77072357590SBeau Belgrave kfree(mm);
77172357590SBeau Belgrave }
77272357590SBeau Belgrave
user_event_mm_put(struct user_event_mm * mm)77372357590SBeau Belgrave static void user_event_mm_put(struct user_event_mm *mm)
77472357590SBeau Belgrave {
77572357590SBeau Belgrave if (mm && refcount_dec_and_test(&mm->refcnt))
77672357590SBeau Belgrave user_event_mm_destroy(mm);
77772357590SBeau Belgrave }
77872357590SBeau Belgrave
delayed_user_event_mm_put(struct work_struct * work)77972357590SBeau Belgrave static void delayed_user_event_mm_put(struct work_struct *work)
78072357590SBeau Belgrave {
78172357590SBeau Belgrave struct user_event_mm *mm;
78272357590SBeau Belgrave
78372357590SBeau Belgrave mm = container_of(to_rcu_work(work), struct user_event_mm, put_rwork);
78472357590SBeau Belgrave user_event_mm_put(mm);
78572357590SBeau Belgrave }
78672357590SBeau Belgrave
user_event_mm_remove(struct task_struct * t)78772357590SBeau Belgrave void user_event_mm_remove(struct task_struct *t)
78872357590SBeau Belgrave {
78972357590SBeau Belgrave struct user_event_mm *mm;
79072357590SBeau Belgrave unsigned long flags;
79172357590SBeau Belgrave
79272357590SBeau Belgrave might_sleep();
79372357590SBeau Belgrave
79472357590SBeau Belgrave mm = t->user_event_mm;
79572357590SBeau Belgrave t->user_event_mm = NULL;
79672357590SBeau Belgrave
79772357590SBeau Belgrave /* Clone will increment the tasks, only remove if last clone */
79872357590SBeau Belgrave if (!refcount_dec_and_test(&mm->tasks))
79972357590SBeau Belgrave return;
80072357590SBeau Belgrave
80172357590SBeau Belgrave /* Remove the mm from the list, so it can no longer be enabled */
80272357590SBeau Belgrave spin_lock_irqsave(&user_event_mms_lock, flags);
803dcbd1ac2SBeau Belgrave list_del_rcu(&mm->mms_link);
80472357590SBeau Belgrave spin_unlock_irqrestore(&user_event_mms_lock, flags);
80572357590SBeau Belgrave
80672357590SBeau Belgrave /*
80772357590SBeau Belgrave * We need to wait for currently occurring writes to stop within
80872357590SBeau Belgrave * the mm. This is required since exit_mm() snaps the current rss
80972357590SBeau Belgrave * stats and clears them. On the final mmdrop(), check_mm() will
81072357590SBeau Belgrave * report a bug if these increment.
81172357590SBeau Belgrave *
81272357590SBeau Belgrave * All writes/pins are done under mmap_read lock, take the write
81372357590SBeau Belgrave * lock to ensure in-progress faults have completed. Faults that
81472357590SBeau Belgrave * are pending but yet to run will check the task count and skip
81572357590SBeau Belgrave * the fault since the mm is going away.
81672357590SBeau Belgrave */
81772357590SBeau Belgrave mmap_write_lock(mm->mm);
81872357590SBeau Belgrave mmap_write_unlock(mm->mm);
81972357590SBeau Belgrave
82072357590SBeau Belgrave /*
82172357590SBeau Belgrave * Put for mm must be done after RCU delay to handle new refs in
82272357590SBeau Belgrave * between the list_del_rcu() and now. This ensures any get refs
82372357590SBeau Belgrave * during rcu_read_lock() are accounted for during list removal.
82472357590SBeau Belgrave *
82572357590SBeau Belgrave * CPU A | CPU B
82672357590SBeau Belgrave * ---------------------------------------------------------------
82772357590SBeau Belgrave * user_event_mm_remove() | rcu_read_lock();
82872357590SBeau Belgrave * list_del_rcu() | list_for_each_entry_rcu();
82972357590SBeau Belgrave * call_rcu() | refcount_inc();
83072357590SBeau Belgrave * . | rcu_read_unlock();
83172357590SBeau Belgrave * schedule_work() | .
83272357590SBeau Belgrave * user_event_mm_put() | .
83372357590SBeau Belgrave *
83472357590SBeau Belgrave * mmdrop() cannot be called in the softirq context of call_rcu()
83572357590SBeau Belgrave * so we use a work queue after call_rcu() to run within.
83672357590SBeau Belgrave */
83772357590SBeau Belgrave INIT_RCU_WORK(&mm->put_rwork, delayed_user_event_mm_put);
83872357590SBeau Belgrave queue_rcu_work(system_wq, &mm->put_rwork);
83972357590SBeau Belgrave }
84072357590SBeau Belgrave
user_event_mm_dup(struct task_struct * t,struct user_event_mm * old_mm)84172357590SBeau Belgrave void user_event_mm_dup(struct task_struct *t, struct user_event_mm *old_mm)
84272357590SBeau Belgrave {
8433e0fea09SLinus Torvalds struct user_event_mm *mm = user_event_mm_alloc(t);
84472357590SBeau Belgrave struct user_event_enabler *enabler;
84572357590SBeau Belgrave
84672357590SBeau Belgrave if (!mm)
84772357590SBeau Belgrave return;
84872357590SBeau Belgrave
84972357590SBeau Belgrave rcu_read_lock();
85072357590SBeau Belgrave
851dcbd1ac2SBeau Belgrave list_for_each_entry_rcu(enabler, &old_mm->enablers, mm_enablers_link) {
85272357590SBeau Belgrave if (!user_event_enabler_dup(enabler, mm))
85372357590SBeau Belgrave goto error;
854dcbd1ac2SBeau Belgrave }
85572357590SBeau Belgrave
85672357590SBeau Belgrave rcu_read_unlock();
85772357590SBeau Belgrave
8583e0fea09SLinus Torvalds user_event_mm_attach(mm, t);
85972357590SBeau Belgrave return;
86072357590SBeau Belgrave error:
86172357590SBeau Belgrave rcu_read_unlock();
8623e0fea09SLinus Torvalds user_event_mm_destroy(mm);
86372357590SBeau Belgrave }
86472357590SBeau Belgrave
current_user_event_enabler_exists(unsigned long uaddr,unsigned char bit)86597bbce89SBeau Belgrave static bool current_user_event_enabler_exists(unsigned long uaddr,
86697bbce89SBeau Belgrave unsigned char bit)
86797bbce89SBeau Belgrave {
86897bbce89SBeau Belgrave struct user_event_mm *user_mm = current_user_event_mm();
86997bbce89SBeau Belgrave bool exists;
87097bbce89SBeau Belgrave
87197bbce89SBeau Belgrave if (!user_mm)
87297bbce89SBeau Belgrave return false;
87397bbce89SBeau Belgrave
87497bbce89SBeau Belgrave exists = user_event_enabler_exists(user_mm, uaddr, bit);
87597bbce89SBeau Belgrave
87697bbce89SBeau Belgrave user_event_mm_put(user_mm);
87797bbce89SBeau Belgrave
87897bbce89SBeau Belgrave return exists;
87997bbce89SBeau Belgrave }
88097bbce89SBeau Belgrave
88172357590SBeau Belgrave static struct user_event_enabler
user_event_enabler_create(struct user_reg * reg,struct user_event * user,int * write_result)88272357590SBeau Belgrave *user_event_enabler_create(struct user_reg *reg, struct user_event *user,
88372357590SBeau Belgrave int *write_result)
88472357590SBeau Belgrave {
88572357590SBeau Belgrave struct user_event_enabler *enabler;
88672357590SBeau Belgrave struct user_event_mm *user_mm;
88772357590SBeau Belgrave unsigned long uaddr = (unsigned long)reg->enable_addr;
88841d8fba1SBeau Belgrave int attempt = 0;
88972357590SBeau Belgrave
89072357590SBeau Belgrave user_mm = current_user_event_mm();
89172357590SBeau Belgrave
89272357590SBeau Belgrave if (!user_mm)
89372357590SBeau Belgrave return NULL;
89472357590SBeau Belgrave
895f9cce238SBeau Belgrave enabler = kzalloc(sizeof(*enabler), GFP_KERNEL_ACCOUNT);
89672357590SBeau Belgrave
89772357590SBeau Belgrave if (!enabler)
89872357590SBeau Belgrave goto out;
89972357590SBeau Belgrave
90072357590SBeau Belgrave enabler->event = user;
90172357590SBeau Belgrave enabler->addr = uaddr;
90272357590SBeau Belgrave enabler->values = reg->enable_bit;
9032de9ee94SBeau Belgrave
9042de9ee94SBeau Belgrave #if BITS_PER_LONG >= 64
9052de9ee94SBeau Belgrave if (reg->enable_size == 4)
9062de9ee94SBeau Belgrave set_bit(ENABLE_VAL_32_ON_64_BIT, ENABLE_BITOPS(enabler));
9072de9ee94SBeau Belgrave #endif
9082de9ee94SBeau Belgrave
90972357590SBeau Belgrave retry:
91072357590SBeau Belgrave /* Prevents state changes from racing with new enablers */
91172357590SBeau Belgrave mutex_lock(&event_mutex);
91272357590SBeau Belgrave
91372357590SBeau Belgrave /* Attempt to reflect the current state within the process */
91472357590SBeau Belgrave mmap_read_lock(user_mm->mm);
91541d8fba1SBeau Belgrave *write_result = user_event_enabler_write(user_mm, enabler, false,
91641d8fba1SBeau Belgrave &attempt);
91772357590SBeau Belgrave mmap_read_unlock(user_mm->mm);
91872357590SBeau Belgrave
91972357590SBeau Belgrave /*
92072357590SBeau Belgrave * If the write works, then we will track the enabler. A ref to the
92172357590SBeau Belgrave * underlying user_event is held by the enabler to prevent it going
92272357590SBeau Belgrave * away while the enabler is still in use by a process. The ref is
92372357590SBeau Belgrave * removed when the enabler is destroyed. This means a event cannot
92472357590SBeau Belgrave * be forcefully deleted from the system until all tasks using it
92572357590SBeau Belgrave * exit or run exec(), which includes forks and clones.
92672357590SBeau Belgrave */
92772357590SBeau Belgrave if (!*write_result) {
928f0dbf6fdSBeau Belgrave user_event_get(user);
929dcbd1ac2SBeau Belgrave list_add_rcu(&enabler->mm_enablers_link, &user_mm->enablers);
93072357590SBeau Belgrave }
93172357590SBeau Belgrave
93272357590SBeau Belgrave mutex_unlock(&event_mutex);
93372357590SBeau Belgrave
93472357590SBeau Belgrave if (*write_result) {
93572357590SBeau Belgrave /* Attempt to fault-in and retry if it worked */
93641d8fba1SBeau Belgrave if (!user_event_mm_fault_in(user_mm, uaddr, attempt))
93772357590SBeau Belgrave goto retry;
93872357590SBeau Belgrave
93972357590SBeau Belgrave kfree(enabler);
94072357590SBeau Belgrave enabler = NULL;
94172357590SBeau Belgrave }
94272357590SBeau Belgrave out:
94372357590SBeau Belgrave user_event_mm_put(user_mm);
94472357590SBeau Belgrave
94572357590SBeau Belgrave return enabler;
94639d6d08bSBeau Belgrave }
94739d6d08bSBeau Belgrave
9480279400aSBeau Belgrave static __always_inline __must_check
user_event_last_ref(struct user_event * user)949d401b724SBeau Belgrave bool user_event_last_ref(struct user_event *user)
950d401b724SBeau Belgrave {
951a65442edSBeau Belgrave int last = 0;
952a65442edSBeau Belgrave
953a65442edSBeau Belgrave if (user->reg_flags & USER_EVENT_REG_PERSIST)
954a65442edSBeau Belgrave last = 1;
955a65442edSBeau Belgrave
956a65442edSBeau Belgrave return refcount_read(&user->refcnt) == last;
957d401b724SBeau Belgrave }
958d401b724SBeau Belgrave
959d401b724SBeau Belgrave static __always_inline __must_check
copy_nofault(void * addr,size_t bytes,struct iov_iter * i)9600279400aSBeau Belgrave size_t copy_nofault(void *addr, size_t bytes, struct iov_iter *i)
9610279400aSBeau Belgrave {
9620279400aSBeau Belgrave size_t ret;
9630279400aSBeau Belgrave
9640279400aSBeau Belgrave pagefault_disable();
9650279400aSBeau Belgrave
9660279400aSBeau Belgrave ret = copy_from_iter_nocache(addr, bytes, i);
9670279400aSBeau Belgrave
9680279400aSBeau Belgrave pagefault_enable();
9690279400aSBeau Belgrave
9700279400aSBeau Belgrave return ret;
9710279400aSBeau Belgrave }
9720279400aSBeau Belgrave
user_event_get_fields(struct trace_event_call * call)9737f5a08c7SBeau Belgrave static struct list_head *user_event_get_fields(struct trace_event_call *call)
9747f5a08c7SBeau Belgrave {
9757f5a08c7SBeau Belgrave struct user_event *user = (struct user_event *)call->data;
9767f5a08c7SBeau Belgrave
9777f5a08c7SBeau Belgrave return &user->fields;
9787f5a08c7SBeau Belgrave }
9797f5a08c7SBeau Belgrave
9807f5a08c7SBeau Belgrave /*
9817f5a08c7SBeau Belgrave * Parses a register command for user_events
9827f5a08c7SBeau Belgrave * Format: event_name[:FLAG1[,FLAG2...]] [field1[;field2...]]
9837f5a08c7SBeau Belgrave *
9847f5a08c7SBeau Belgrave * Example event named 'test' with a 20 char 'msg' field with an unsigned int
9857f5a08c7SBeau Belgrave * 'id' field after:
9867f5a08c7SBeau Belgrave * test char[20] msg;unsigned int id
9877f5a08c7SBeau Belgrave *
9887f5a08c7SBeau Belgrave * NOTE: Offsets are from the user data perspective, they are not from the
9897f5a08c7SBeau Belgrave * trace_entry/buffer perspective. We automatically add the common properties
9907f5a08c7SBeau Belgrave * sizes to the offset for the user.
9917e348b32SBeau Belgrave *
9927e348b32SBeau Belgrave * Upon success user_event has its ref count increased by 1.
9937f5a08c7SBeau Belgrave */
user_event_parse_cmd(struct user_event_group * group,char * raw_command,struct user_event ** newuser,int reg_flags)994e5d27181SBeau Belgrave static int user_event_parse_cmd(struct user_event_group *group,
995b08d7258SBeau Belgrave char *raw_command, struct user_event **newuser,
996b08d7258SBeau Belgrave int reg_flags)
9977f5a08c7SBeau Belgrave {
9987f5a08c7SBeau Belgrave char *name = raw_command;
9997f5a08c7SBeau Belgrave char *args = strpbrk(name, " ");
10007f5a08c7SBeau Belgrave char *flags;
10017f5a08c7SBeau Belgrave
10027f5a08c7SBeau Belgrave if (args)
10037f5a08c7SBeau Belgrave *args++ = '\0';
10047f5a08c7SBeau Belgrave
10057f5a08c7SBeau Belgrave flags = strpbrk(name, ":");
10067f5a08c7SBeau Belgrave
10077f5a08c7SBeau Belgrave if (flags)
10087f5a08c7SBeau Belgrave *flags++ = '\0';
10097f5a08c7SBeau Belgrave
1010b08d7258SBeau Belgrave return user_event_parse(group, name, args, flags, newuser, reg_flags);
10117f5a08c7SBeau Belgrave }
10127f5a08c7SBeau Belgrave
user_field_array_size(const char * type)10137f5a08c7SBeau Belgrave static int user_field_array_size(const char *type)
10147f5a08c7SBeau Belgrave {
10157f5a08c7SBeau Belgrave const char *start = strchr(type, '[');
10167f5a08c7SBeau Belgrave char val[8];
10177f5a08c7SBeau Belgrave char *bracket;
10187f5a08c7SBeau Belgrave int size = 0;
10197f5a08c7SBeau Belgrave
10207f5a08c7SBeau Belgrave if (start == NULL)
10217f5a08c7SBeau Belgrave return -EINVAL;
10227f5a08c7SBeau Belgrave
10237f5a08c7SBeau Belgrave if (strscpy(val, start + 1, sizeof(val)) <= 0)
10247f5a08c7SBeau Belgrave return -EINVAL;
10257f5a08c7SBeau Belgrave
10267f5a08c7SBeau Belgrave bracket = strchr(val, ']');
10277f5a08c7SBeau Belgrave
10287f5a08c7SBeau Belgrave if (!bracket)
10297f5a08c7SBeau Belgrave return -EINVAL;
10307f5a08c7SBeau Belgrave
10317f5a08c7SBeau Belgrave *bracket = '\0';
10327f5a08c7SBeau Belgrave
10337f5a08c7SBeau Belgrave if (kstrtouint(val, 0, &size))
10347f5a08c7SBeau Belgrave return -EINVAL;
10357f5a08c7SBeau Belgrave
10367f5a08c7SBeau Belgrave if (size > MAX_FIELD_ARRAY_SIZE)
10377f5a08c7SBeau Belgrave return -EINVAL;
10387f5a08c7SBeau Belgrave
10397f5a08c7SBeau Belgrave return size;
10407f5a08c7SBeau Belgrave }
10417f5a08c7SBeau Belgrave
user_field_size(const char * type)10427f5a08c7SBeau Belgrave static int user_field_size(const char *type)
10437f5a08c7SBeau Belgrave {
10447f5a08c7SBeau Belgrave /* long is not allowed from a user, since it's ambigious in size */
10457f5a08c7SBeau Belgrave if (strcmp(type, "s64") == 0)
10467f5a08c7SBeau Belgrave return sizeof(s64);
10477f5a08c7SBeau Belgrave if (strcmp(type, "u64") == 0)
10487f5a08c7SBeau Belgrave return sizeof(u64);
10497f5a08c7SBeau Belgrave if (strcmp(type, "s32") == 0)
10507f5a08c7SBeau Belgrave return sizeof(s32);
10517f5a08c7SBeau Belgrave if (strcmp(type, "u32") == 0)
10527f5a08c7SBeau Belgrave return sizeof(u32);
10537f5a08c7SBeau Belgrave if (strcmp(type, "int") == 0)
10547f5a08c7SBeau Belgrave return sizeof(int);
10557f5a08c7SBeau Belgrave if (strcmp(type, "unsigned int") == 0)
10567f5a08c7SBeau Belgrave return sizeof(unsigned int);
10577f5a08c7SBeau Belgrave if (strcmp(type, "s16") == 0)
10587f5a08c7SBeau Belgrave return sizeof(s16);
10597f5a08c7SBeau Belgrave if (strcmp(type, "u16") == 0)
10607f5a08c7SBeau Belgrave return sizeof(u16);
10617f5a08c7SBeau Belgrave if (strcmp(type, "short") == 0)
10627f5a08c7SBeau Belgrave return sizeof(short);
10637f5a08c7SBeau Belgrave if (strcmp(type, "unsigned short") == 0)
10647f5a08c7SBeau Belgrave return sizeof(unsigned short);
10657f5a08c7SBeau Belgrave if (strcmp(type, "s8") == 0)
10667f5a08c7SBeau Belgrave return sizeof(s8);
10677f5a08c7SBeau Belgrave if (strcmp(type, "u8") == 0)
10687f5a08c7SBeau Belgrave return sizeof(u8);
10697f5a08c7SBeau Belgrave if (strcmp(type, "char") == 0)
10707f5a08c7SBeau Belgrave return sizeof(char);
10717f5a08c7SBeau Belgrave if (strcmp(type, "unsigned char") == 0)
10727f5a08c7SBeau Belgrave return sizeof(unsigned char);
10737f5a08c7SBeau Belgrave if (str_has_prefix(type, "char["))
10747f5a08c7SBeau Belgrave return user_field_array_size(type);
10757f5a08c7SBeau Belgrave if (str_has_prefix(type, "unsigned char["))
10767f5a08c7SBeau Belgrave return user_field_array_size(type);
10777f5a08c7SBeau Belgrave if (str_has_prefix(type, "__data_loc "))
10787f5a08c7SBeau Belgrave return sizeof(u32);
10797f5a08c7SBeau Belgrave if (str_has_prefix(type, "__rel_loc "))
10807f5a08c7SBeau Belgrave return sizeof(u32);
10817f5a08c7SBeau Belgrave
10827f5a08c7SBeau Belgrave /* Uknown basic type, error */
10837f5a08c7SBeau Belgrave return -EINVAL;
10847f5a08c7SBeau Belgrave }
10857f5a08c7SBeau Belgrave
user_event_destroy_validators(struct user_event * user)10862467cda1SBeau Belgrave static void user_event_destroy_validators(struct user_event *user)
10872467cda1SBeau Belgrave {
10882467cda1SBeau Belgrave struct user_event_validator *validator, *next;
10892467cda1SBeau Belgrave struct list_head *head = &user->validators;
10902467cda1SBeau Belgrave
1091dcbd1ac2SBeau Belgrave list_for_each_entry_safe(validator, next, head, user_event_link) {
1092dcbd1ac2SBeau Belgrave list_del(&validator->user_event_link);
10932467cda1SBeau Belgrave kfree(validator);
10942467cda1SBeau Belgrave }
10952467cda1SBeau Belgrave }
10962467cda1SBeau Belgrave
user_event_destroy_fields(struct user_event * user)10977f5a08c7SBeau Belgrave static void user_event_destroy_fields(struct user_event *user)
10987f5a08c7SBeau Belgrave {
10997f5a08c7SBeau Belgrave struct ftrace_event_field *field, *next;
11007f5a08c7SBeau Belgrave struct list_head *head = &user->fields;
11017f5a08c7SBeau Belgrave
11027f5a08c7SBeau Belgrave list_for_each_entry_safe(field, next, head, link) {
11037f5a08c7SBeau Belgrave list_del(&field->link);
11047f5a08c7SBeau Belgrave kfree(field);
11057f5a08c7SBeau Belgrave }
11067f5a08c7SBeau Belgrave }
11077f5a08c7SBeau Belgrave
user_event_add_field(struct user_event * user,const char * type,const char * name,int offset,int size,int is_signed,int filter_type)11087f5a08c7SBeau Belgrave static int user_event_add_field(struct user_event *user, const char *type,
11097f5a08c7SBeau Belgrave const char *name, int offset, int size,
11107f5a08c7SBeau Belgrave int is_signed, int filter_type)
11117f5a08c7SBeau Belgrave {
11122467cda1SBeau Belgrave struct user_event_validator *validator;
11137f5a08c7SBeau Belgrave struct ftrace_event_field *field;
11142467cda1SBeau Belgrave int validator_flags = 0;
11157f5a08c7SBeau Belgrave
1116f9cce238SBeau Belgrave field = kmalloc(sizeof(*field), GFP_KERNEL_ACCOUNT);
11177f5a08c7SBeau Belgrave
11187f5a08c7SBeau Belgrave if (!field)
11197f5a08c7SBeau Belgrave return -ENOMEM;
11207f5a08c7SBeau Belgrave
11212467cda1SBeau Belgrave if (str_has_prefix(type, "__data_loc "))
11222467cda1SBeau Belgrave goto add_validator;
11232467cda1SBeau Belgrave
11242467cda1SBeau Belgrave if (str_has_prefix(type, "__rel_loc ")) {
11252467cda1SBeau Belgrave validator_flags |= VALIDATOR_REL;
11262467cda1SBeau Belgrave goto add_validator;
11272467cda1SBeau Belgrave }
11282467cda1SBeau Belgrave
11292467cda1SBeau Belgrave goto add_field;
11302467cda1SBeau Belgrave
11312467cda1SBeau Belgrave add_validator:
11329cbf1234SBeau Belgrave if (strstr(type, "char") != NULL)
11332467cda1SBeau Belgrave validator_flags |= VALIDATOR_ENSURE_NULL;
11342467cda1SBeau Belgrave
1135f9cce238SBeau Belgrave validator = kmalloc(sizeof(*validator), GFP_KERNEL_ACCOUNT);
11362467cda1SBeau Belgrave
11372467cda1SBeau Belgrave if (!validator) {
11382467cda1SBeau Belgrave kfree(field);
11392467cda1SBeau Belgrave return -ENOMEM;
11402467cda1SBeau Belgrave }
11412467cda1SBeau Belgrave
11422467cda1SBeau Belgrave validator->flags = validator_flags;
11432467cda1SBeau Belgrave validator->offset = offset;
11442467cda1SBeau Belgrave
11452467cda1SBeau Belgrave /* Want sequential access when validating */
1146dcbd1ac2SBeau Belgrave list_add_tail(&validator->user_event_link, &user->validators);
11472467cda1SBeau Belgrave
11482467cda1SBeau Belgrave add_field:
11497f5a08c7SBeau Belgrave field->type = type;
11507f5a08c7SBeau Belgrave field->name = name;
11517f5a08c7SBeau Belgrave field->offset = offset;
11527f5a08c7SBeau Belgrave field->size = size;
11537f5a08c7SBeau Belgrave field->is_signed = is_signed;
11547f5a08c7SBeau Belgrave field->filter_type = filter_type;
11557f5a08c7SBeau Belgrave
11569872c07bSBeau Belgrave if (filter_type == FILTER_OTHER)
11579872c07bSBeau Belgrave field->filter_type = filter_assign_type(type);
11589872c07bSBeau Belgrave
11597f5a08c7SBeau Belgrave list_add(&field->link, &user->fields);
11607f5a08c7SBeau Belgrave
11612467cda1SBeau Belgrave /*
11622467cda1SBeau Belgrave * Min size from user writes that are required, this does not include
11632467cda1SBeau Belgrave * the size of trace_entry (common fields).
11642467cda1SBeau Belgrave */
11652467cda1SBeau Belgrave user->min_size = (offset + size) - sizeof(struct trace_entry);
11662467cda1SBeau Belgrave
11677f5a08c7SBeau Belgrave return 0;
11687f5a08c7SBeau Belgrave }
11697f5a08c7SBeau Belgrave
11707f5a08c7SBeau Belgrave /*
11717f5a08c7SBeau Belgrave * Parses the values of a field within the description
11727f5a08c7SBeau Belgrave * Format: type name [size]
11737f5a08c7SBeau Belgrave */
user_event_parse_field(char * field,struct user_event * user,u32 * offset)11747f5a08c7SBeau Belgrave static int user_event_parse_field(char *field, struct user_event *user,
11757f5a08c7SBeau Belgrave u32 *offset)
11767f5a08c7SBeau Belgrave {
11777f5a08c7SBeau Belgrave char *part, *type, *name;
11787f5a08c7SBeau Belgrave u32 depth = 0, saved_offset = *offset;
11797f5a08c7SBeau Belgrave int len, size = -EINVAL;
11807f5a08c7SBeau Belgrave bool is_struct = false;
11817f5a08c7SBeau Belgrave
11827f5a08c7SBeau Belgrave field = skip_spaces(field);
11837f5a08c7SBeau Belgrave
11847f5a08c7SBeau Belgrave if (*field == '\0')
11857f5a08c7SBeau Belgrave return 0;
11867f5a08c7SBeau Belgrave
11877f5a08c7SBeau Belgrave /* Handle types that have a space within */
11887f5a08c7SBeau Belgrave len = str_has_prefix(field, "unsigned ");
11897f5a08c7SBeau Belgrave if (len)
11907f5a08c7SBeau Belgrave goto skip_next;
11917f5a08c7SBeau Belgrave
11927f5a08c7SBeau Belgrave len = str_has_prefix(field, "struct ");
11937f5a08c7SBeau Belgrave if (len) {
11947f5a08c7SBeau Belgrave is_struct = true;
11957f5a08c7SBeau Belgrave goto skip_next;
11967f5a08c7SBeau Belgrave }
11977f5a08c7SBeau Belgrave
11987f5a08c7SBeau Belgrave len = str_has_prefix(field, "__data_loc unsigned ");
11997f5a08c7SBeau Belgrave if (len)
12007f5a08c7SBeau Belgrave goto skip_next;
12017f5a08c7SBeau Belgrave
12027f5a08c7SBeau Belgrave len = str_has_prefix(field, "__data_loc ");
12037f5a08c7SBeau Belgrave if (len)
12047f5a08c7SBeau Belgrave goto skip_next;
12057f5a08c7SBeau Belgrave
12067f5a08c7SBeau Belgrave len = str_has_prefix(field, "__rel_loc unsigned ");
12077f5a08c7SBeau Belgrave if (len)
12087f5a08c7SBeau Belgrave goto skip_next;
12097f5a08c7SBeau Belgrave
12107f5a08c7SBeau Belgrave len = str_has_prefix(field, "__rel_loc ");
12117f5a08c7SBeau Belgrave if (len)
12127f5a08c7SBeau Belgrave goto skip_next;
12137f5a08c7SBeau Belgrave
12147f5a08c7SBeau Belgrave goto parse;
12157f5a08c7SBeau Belgrave skip_next:
12167f5a08c7SBeau Belgrave type = field;
12177f5a08c7SBeau Belgrave field = strpbrk(field + len, " ");
12187f5a08c7SBeau Belgrave
12197f5a08c7SBeau Belgrave if (field == NULL)
12207f5a08c7SBeau Belgrave return -EINVAL;
12217f5a08c7SBeau Belgrave
12227f5a08c7SBeau Belgrave *field++ = '\0';
12237f5a08c7SBeau Belgrave depth++;
12247f5a08c7SBeau Belgrave parse:
1225173c2049SBeau Belgrave name = NULL;
1226173c2049SBeau Belgrave
12277f5a08c7SBeau Belgrave while ((part = strsep(&field, " ")) != NULL) {
12287f5a08c7SBeau Belgrave switch (depth++) {
12297f5a08c7SBeau Belgrave case FIELD_DEPTH_TYPE:
12307f5a08c7SBeau Belgrave type = part;
12317f5a08c7SBeau Belgrave break;
12327f5a08c7SBeau Belgrave case FIELD_DEPTH_NAME:
12337f5a08c7SBeau Belgrave name = part;
12347f5a08c7SBeau Belgrave break;
12357f5a08c7SBeau Belgrave case FIELD_DEPTH_SIZE:
12367f5a08c7SBeau Belgrave if (!is_struct)
12377f5a08c7SBeau Belgrave return -EINVAL;
12387f5a08c7SBeau Belgrave
12397f5a08c7SBeau Belgrave if (kstrtou32(part, 10, &size))
12407f5a08c7SBeau Belgrave return -EINVAL;
12417f5a08c7SBeau Belgrave break;
12427f5a08c7SBeau Belgrave default:
12437f5a08c7SBeau Belgrave return -EINVAL;
12447f5a08c7SBeau Belgrave }
12457f5a08c7SBeau Belgrave }
12467f5a08c7SBeau Belgrave
1247173c2049SBeau Belgrave if (depth < FIELD_DEPTH_SIZE || !name)
12487f5a08c7SBeau Belgrave return -EINVAL;
12497f5a08c7SBeau Belgrave
12507f5a08c7SBeau Belgrave if (depth == FIELD_DEPTH_SIZE)
12517f5a08c7SBeau Belgrave size = user_field_size(type);
12527f5a08c7SBeau Belgrave
12537f5a08c7SBeau Belgrave if (size == 0)
12547f5a08c7SBeau Belgrave return -EINVAL;
12557f5a08c7SBeau Belgrave
12567f5a08c7SBeau Belgrave if (size < 0)
12577f5a08c7SBeau Belgrave return size;
12587f5a08c7SBeau Belgrave
12597f5a08c7SBeau Belgrave *offset = saved_offset + size;
12607f5a08c7SBeau Belgrave
12617f5a08c7SBeau Belgrave return user_event_add_field(user, type, name, saved_offset, size,
12627f5a08c7SBeau Belgrave type[0] != 'u', FILTER_OTHER);
12637f5a08c7SBeau Belgrave }
12647f5a08c7SBeau Belgrave
user_event_parse_fields(struct user_event * user,char * args)12657f5a08c7SBeau Belgrave static int user_event_parse_fields(struct user_event *user, char *args)
12667f5a08c7SBeau Belgrave {
12677f5a08c7SBeau Belgrave char *field;
12687f5a08c7SBeau Belgrave u32 offset = sizeof(struct trace_entry);
12697f5a08c7SBeau Belgrave int ret = -EINVAL;
12707f5a08c7SBeau Belgrave
12717f5a08c7SBeau Belgrave if (args == NULL)
12727f5a08c7SBeau Belgrave return 0;
12737f5a08c7SBeau Belgrave
12747f5a08c7SBeau Belgrave while ((field = strsep(&args, ";")) != NULL) {
12757f5a08c7SBeau Belgrave ret = user_event_parse_field(field, user, &offset);
12767f5a08c7SBeau Belgrave
12777f5a08c7SBeau Belgrave if (ret)
12787f5a08c7SBeau Belgrave break;
12797f5a08c7SBeau Belgrave }
12807f5a08c7SBeau Belgrave
12817f5a08c7SBeau Belgrave return ret;
12827f5a08c7SBeau Belgrave }
12837f5a08c7SBeau Belgrave
12847f5a08c7SBeau Belgrave static struct trace_event_fields user_event_fields_array[1];
12857f5a08c7SBeau Belgrave
user_field_format(const char * type)1286aa3b2b4cSBeau Belgrave static const char *user_field_format(const char *type)
1287aa3b2b4cSBeau Belgrave {
1288aa3b2b4cSBeau Belgrave if (strcmp(type, "s64") == 0)
1289aa3b2b4cSBeau Belgrave return "%lld";
1290aa3b2b4cSBeau Belgrave if (strcmp(type, "u64") == 0)
1291aa3b2b4cSBeau Belgrave return "%llu";
1292aa3b2b4cSBeau Belgrave if (strcmp(type, "s32") == 0)
1293aa3b2b4cSBeau Belgrave return "%d";
1294aa3b2b4cSBeau Belgrave if (strcmp(type, "u32") == 0)
1295aa3b2b4cSBeau Belgrave return "%u";
1296aa3b2b4cSBeau Belgrave if (strcmp(type, "int") == 0)
1297aa3b2b4cSBeau Belgrave return "%d";
1298aa3b2b4cSBeau Belgrave if (strcmp(type, "unsigned int") == 0)
1299aa3b2b4cSBeau Belgrave return "%u";
1300aa3b2b4cSBeau Belgrave if (strcmp(type, "s16") == 0)
1301aa3b2b4cSBeau Belgrave return "%d";
1302aa3b2b4cSBeau Belgrave if (strcmp(type, "u16") == 0)
1303aa3b2b4cSBeau Belgrave return "%u";
1304aa3b2b4cSBeau Belgrave if (strcmp(type, "short") == 0)
1305aa3b2b4cSBeau Belgrave return "%d";
1306aa3b2b4cSBeau Belgrave if (strcmp(type, "unsigned short") == 0)
1307aa3b2b4cSBeau Belgrave return "%u";
1308aa3b2b4cSBeau Belgrave if (strcmp(type, "s8") == 0)
1309aa3b2b4cSBeau Belgrave return "%d";
1310aa3b2b4cSBeau Belgrave if (strcmp(type, "u8") == 0)
1311aa3b2b4cSBeau Belgrave return "%u";
1312aa3b2b4cSBeau Belgrave if (strcmp(type, "char") == 0)
1313aa3b2b4cSBeau Belgrave return "%d";
1314aa3b2b4cSBeau Belgrave if (strcmp(type, "unsigned char") == 0)
1315aa3b2b4cSBeau Belgrave return "%u";
13169cbf1234SBeau Belgrave if (strstr(type, "char[") != NULL)
1317aa3b2b4cSBeau Belgrave return "%s";
1318aa3b2b4cSBeau Belgrave
1319aa3b2b4cSBeau Belgrave /* Unknown, likely struct, allowed treat as 64-bit */
1320aa3b2b4cSBeau Belgrave return "%llu";
1321aa3b2b4cSBeau Belgrave }
1322aa3b2b4cSBeau Belgrave
user_field_is_dyn_string(const char * type,const char ** str_func)1323aa3b2b4cSBeau Belgrave static bool user_field_is_dyn_string(const char *type, const char **str_func)
1324aa3b2b4cSBeau Belgrave {
1325aa3b2b4cSBeau Belgrave if (str_has_prefix(type, "__data_loc ")) {
1326aa3b2b4cSBeau Belgrave *str_func = "__get_str";
1327aa3b2b4cSBeau Belgrave goto check;
1328aa3b2b4cSBeau Belgrave }
1329aa3b2b4cSBeau Belgrave
1330aa3b2b4cSBeau Belgrave if (str_has_prefix(type, "__rel_loc ")) {
1331aa3b2b4cSBeau Belgrave *str_func = "__get_rel_str";
1332aa3b2b4cSBeau Belgrave goto check;
1333aa3b2b4cSBeau Belgrave }
1334aa3b2b4cSBeau Belgrave
1335aa3b2b4cSBeau Belgrave return false;
1336aa3b2b4cSBeau Belgrave check:
13379cbf1234SBeau Belgrave return strstr(type, "char") != NULL;
1338aa3b2b4cSBeau Belgrave }
1339aa3b2b4cSBeau Belgrave
1340aa3b2b4cSBeau Belgrave #define LEN_OR_ZERO (len ? len - pos : 0)
user_dyn_field_set_string(int argc,const char ** argv,int * iout,char * buf,int len,bool * colon)1341e6f89a14SBeau Belgrave static int user_dyn_field_set_string(int argc, const char **argv, int *iout,
1342e6f89a14SBeau Belgrave char *buf, int len, bool *colon)
1343e6f89a14SBeau Belgrave {
1344e6f89a14SBeau Belgrave int pos = 0, i = *iout;
1345e6f89a14SBeau Belgrave
1346e6f89a14SBeau Belgrave *colon = false;
1347e6f89a14SBeau Belgrave
1348e6f89a14SBeau Belgrave for (; i < argc; ++i) {
1349e6f89a14SBeau Belgrave if (i != *iout)
1350e6f89a14SBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, " ");
1351e6f89a14SBeau Belgrave
1352e6f89a14SBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, "%s", argv[i]);
1353e6f89a14SBeau Belgrave
1354e6f89a14SBeau Belgrave if (strchr(argv[i], ';')) {
1355e6f89a14SBeau Belgrave ++i;
1356e6f89a14SBeau Belgrave *colon = true;
1357e6f89a14SBeau Belgrave break;
1358e6f89a14SBeau Belgrave }
1359e6f89a14SBeau Belgrave }
1360e6f89a14SBeau Belgrave
1361e6f89a14SBeau Belgrave /* Actual set, advance i */
1362e6f89a14SBeau Belgrave if (len != 0)
1363e6f89a14SBeau Belgrave *iout = i;
1364e6f89a14SBeau Belgrave
1365e6f89a14SBeau Belgrave return pos + 1;
1366e6f89a14SBeau Belgrave }
1367e6f89a14SBeau Belgrave
user_field_set_string(struct ftrace_event_field * field,char * buf,int len,bool colon)1368e6f89a14SBeau Belgrave static int user_field_set_string(struct ftrace_event_field *field,
1369e6f89a14SBeau Belgrave char *buf, int len, bool colon)
1370e6f89a14SBeau Belgrave {
1371e6f89a14SBeau Belgrave int pos = 0;
1372e6f89a14SBeau Belgrave
1373e6f89a14SBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, "%s", field->type);
1374e6f89a14SBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, " ");
1375e6f89a14SBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, "%s", field->name);
1376e6f89a14SBeau Belgrave
1377d0a3022fSBeau Belgrave if (str_has_prefix(field->type, "struct "))
1378d0a3022fSBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, " %d", field->size);
1379d0a3022fSBeau Belgrave
1380e6f89a14SBeau Belgrave if (colon)
1381e6f89a14SBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, ";");
1382e6f89a14SBeau Belgrave
1383e6f89a14SBeau Belgrave return pos + 1;
1384e6f89a14SBeau Belgrave }
1385e6f89a14SBeau Belgrave
user_event_set_print_fmt(struct user_event * user,char * buf,int len)1386aa3b2b4cSBeau Belgrave static int user_event_set_print_fmt(struct user_event *user, char *buf, int len)
1387aa3b2b4cSBeau Belgrave {
1388a943188dSEric Vaughn struct ftrace_event_field *field;
1389aa3b2b4cSBeau Belgrave struct list_head *head = &user->fields;
1390aa3b2b4cSBeau Belgrave int pos = 0, depth = 0;
1391aa3b2b4cSBeau Belgrave const char *str_func;
1392aa3b2b4cSBeau Belgrave
1393aa3b2b4cSBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
1394aa3b2b4cSBeau Belgrave
1395a943188dSEric Vaughn list_for_each_entry_reverse(field, head, link) {
1396aa3b2b4cSBeau Belgrave if (depth != 0)
1397aa3b2b4cSBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, " ");
1398aa3b2b4cSBeau Belgrave
1399aa3b2b4cSBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, "%s=%s",
1400aa3b2b4cSBeau Belgrave field->name, user_field_format(field->type));
1401aa3b2b4cSBeau Belgrave
1402aa3b2b4cSBeau Belgrave depth++;
1403aa3b2b4cSBeau Belgrave }
1404aa3b2b4cSBeau Belgrave
1405aa3b2b4cSBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
1406aa3b2b4cSBeau Belgrave
1407a943188dSEric Vaughn list_for_each_entry_reverse(field, head, link) {
1408aa3b2b4cSBeau Belgrave if (user_field_is_dyn_string(field->type, &str_func))
1409aa3b2b4cSBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO,
1410aa3b2b4cSBeau Belgrave ", %s(%s)", str_func, field->name);
1411aa3b2b4cSBeau Belgrave else
1412aa3b2b4cSBeau Belgrave pos += snprintf(buf + pos, LEN_OR_ZERO,
1413aa3b2b4cSBeau Belgrave ", REC->%s", field->name);
1414aa3b2b4cSBeau Belgrave }
1415aa3b2b4cSBeau Belgrave
1416aa3b2b4cSBeau Belgrave return pos + 1;
1417aa3b2b4cSBeau Belgrave }
1418aa3b2b4cSBeau Belgrave #undef LEN_OR_ZERO
1419aa3b2b4cSBeau Belgrave
user_event_create_print_fmt(struct user_event * user)1420aa3b2b4cSBeau Belgrave static int user_event_create_print_fmt(struct user_event *user)
1421aa3b2b4cSBeau Belgrave {
1422aa3b2b4cSBeau Belgrave char *print_fmt;
1423aa3b2b4cSBeau Belgrave int len;
1424aa3b2b4cSBeau Belgrave
1425aa3b2b4cSBeau Belgrave len = user_event_set_print_fmt(user, NULL, 0);
1426aa3b2b4cSBeau Belgrave
1427f9cce238SBeau Belgrave print_fmt = kmalloc(len, GFP_KERNEL_ACCOUNT);
1428aa3b2b4cSBeau Belgrave
1429aa3b2b4cSBeau Belgrave if (!print_fmt)
1430aa3b2b4cSBeau Belgrave return -ENOMEM;
1431aa3b2b4cSBeau Belgrave
1432aa3b2b4cSBeau Belgrave user_event_set_print_fmt(user, print_fmt, len);
1433aa3b2b4cSBeau Belgrave
1434aa3b2b4cSBeau Belgrave user->call.print_fmt = print_fmt;
1435aa3b2b4cSBeau Belgrave
1436aa3b2b4cSBeau Belgrave return 0;
1437aa3b2b4cSBeau Belgrave }
1438aa3b2b4cSBeau Belgrave
user_event_print_trace(struct trace_iterator * iter,int flags,struct trace_event * event)14397f5a08c7SBeau Belgrave static enum print_line_t user_event_print_trace(struct trace_iterator *iter,
14407f5a08c7SBeau Belgrave int flags,
14417f5a08c7SBeau Belgrave struct trace_event *event)
14427f5a08c7SBeau Belgrave {
14434bec284cSSteven Rostedt (Google) return print_event_fields(iter, event);
14447f5a08c7SBeau Belgrave }
14457f5a08c7SBeau Belgrave
14467f5a08c7SBeau Belgrave static struct trace_event_functions user_event_funcs = {
14477f5a08c7SBeau Belgrave .trace = user_event_print_trace,
14487f5a08c7SBeau Belgrave };
14497f5a08c7SBeau Belgrave
user_event_set_call_visible(struct user_event * user,bool visible)1450089331d4SBeau Belgrave static int user_event_set_call_visible(struct user_event *user, bool visible)
1451089331d4SBeau Belgrave {
1452089331d4SBeau Belgrave int ret;
1453089331d4SBeau Belgrave const struct cred *old_cred;
1454089331d4SBeau Belgrave struct cred *cred;
1455089331d4SBeau Belgrave
1456089331d4SBeau Belgrave cred = prepare_creds();
1457089331d4SBeau Belgrave
1458089331d4SBeau Belgrave if (!cred)
1459089331d4SBeau Belgrave return -ENOMEM;
1460089331d4SBeau Belgrave
1461089331d4SBeau Belgrave /*
1462089331d4SBeau Belgrave * While by default tracefs is locked down, systems can be configured
1463089331d4SBeau Belgrave * to allow user_event files to be less locked down. The extreme case
1464089331d4SBeau Belgrave * being "other" has read/write access to user_events_data/status.
1465089331d4SBeau Belgrave *
146694c255acSXiang wangx * When not locked down, processes may not have permissions to
1467089331d4SBeau Belgrave * add/remove calls themselves to tracefs. We need to temporarily
1468089331d4SBeau Belgrave * switch to root file permission to allow for this scenario.
1469089331d4SBeau Belgrave */
1470089331d4SBeau Belgrave cred->fsuid = GLOBAL_ROOT_UID;
1471089331d4SBeau Belgrave
1472089331d4SBeau Belgrave old_cred = override_creds(cred);
1473089331d4SBeau Belgrave
1474089331d4SBeau Belgrave if (visible)
1475089331d4SBeau Belgrave ret = trace_add_event_call(&user->call);
1476089331d4SBeau Belgrave else
1477089331d4SBeau Belgrave ret = trace_remove_event_call(&user->call);
1478089331d4SBeau Belgrave
1479089331d4SBeau Belgrave revert_creds(old_cred);
1480089331d4SBeau Belgrave put_cred(cred);
1481089331d4SBeau Belgrave
1482089331d4SBeau Belgrave return ret;
1483089331d4SBeau Belgrave }
1484089331d4SBeau Belgrave
destroy_user_event(struct user_event * user)14857f5a08c7SBeau Belgrave static int destroy_user_event(struct user_event *user)
14867f5a08c7SBeau Belgrave {
14877f5a08c7SBeau Belgrave int ret = 0;
14887f5a08c7SBeau Belgrave
1489ce58e96eSBeau Belgrave lockdep_assert_held(&event_mutex);
1490ce58e96eSBeau Belgrave
14917f5a08c7SBeau Belgrave /* Must destroy fields before call removal */
14927f5a08c7SBeau Belgrave user_event_destroy_fields(user);
14937f5a08c7SBeau Belgrave
1494089331d4SBeau Belgrave ret = user_event_set_call_visible(user, false);
14957f5a08c7SBeau Belgrave
14967f5a08c7SBeau Belgrave if (ret)
14977f5a08c7SBeau Belgrave return ret;
14987f5a08c7SBeau Belgrave
14997f5a08c7SBeau Belgrave dyn_event_remove(&user->devent);
15007f5a08c7SBeau Belgrave hash_del(&user->node);
15017f5a08c7SBeau Belgrave
15022467cda1SBeau Belgrave user_event_destroy_validators(user);
150364805e40SBeau Belgrave
150464805e40SBeau Belgrave /* If we have different names, both must be freed */
150564805e40SBeau Belgrave if (EVENT_NAME(user) != EVENT_TP_NAME(user))
150664805e40SBeau Belgrave kfree(EVENT_TP_NAME(user));
150764805e40SBeau Belgrave
1508aa3b2b4cSBeau Belgrave kfree(user->call.print_fmt);
15097f5a08c7SBeau Belgrave kfree(EVENT_NAME(user));
15107f5a08c7SBeau Belgrave kfree(user);
15117f5a08c7SBeau Belgrave
1512ce58e96eSBeau Belgrave if (current_user_events > 0)
1513ce58e96eSBeau Belgrave current_user_events--;
1514ce58e96eSBeau Belgrave else
1515ce58e96eSBeau Belgrave pr_alert("BUG: Bad current_user_events\n");
1516ce58e96eSBeau Belgrave
15177f5a08c7SBeau Belgrave return ret;
15187f5a08c7SBeau Belgrave }
15197f5a08c7SBeau Belgrave
find_user_event(struct user_event_group * group,char * name,int argc,const char ** argv,u32 flags,u32 * outkey)1520e5d27181SBeau Belgrave static struct user_event *find_user_event(struct user_event_group *group,
15211e953de9SBeau Belgrave char *name, int argc, const char **argv,
15221e953de9SBeau Belgrave u32 flags, u32 *outkey)
15237f5a08c7SBeau Belgrave {
15247f5a08c7SBeau Belgrave struct user_event *user;
15257f5a08c7SBeau Belgrave u32 key = user_event_key(name);
15267f5a08c7SBeau Belgrave
15277f5a08c7SBeau Belgrave *outkey = key;
15287f5a08c7SBeau Belgrave
15291e953de9SBeau Belgrave hash_for_each_possible(group->register_table, user, node, key) {
153064805e40SBeau Belgrave /*
153164805e40SBeau Belgrave * Single-format events shouldn't return multi-format
153264805e40SBeau Belgrave * events. Callers expect the underlying tracepoint to match
153364805e40SBeau Belgrave * the name exactly in these cases. Only check like-formats.
153464805e40SBeau Belgrave */
153564805e40SBeau Belgrave if (EVENT_MULTI_FORMAT(flags) != EVENT_MULTI_FORMAT(user->reg_flags))
153664805e40SBeau Belgrave continue;
153764805e40SBeau Belgrave
15381e953de9SBeau Belgrave if (strcmp(EVENT_NAME(user), name))
15391e953de9SBeau Belgrave continue;
15401e953de9SBeau Belgrave
15411e953de9SBeau Belgrave if (user_fields_match(user, argc, argv))
1542f0dbf6fdSBeau Belgrave return user_event_get(user);
15437f5a08c7SBeau Belgrave
154464805e40SBeau Belgrave /* Scan others if this is a multi-format event */
154564805e40SBeau Belgrave if (EVENT_MULTI_FORMAT(flags))
154664805e40SBeau Belgrave continue;
154764805e40SBeau Belgrave
15481e953de9SBeau Belgrave return ERR_PTR(-EADDRINUSE);
15491e953de9SBeau Belgrave }
15501e953de9SBeau Belgrave
15517f5a08c7SBeau Belgrave return NULL;
15527f5a08c7SBeau Belgrave }
15537f5a08c7SBeau Belgrave
user_event_validate(struct user_event * user,void * data,int len)15542467cda1SBeau Belgrave static int user_event_validate(struct user_event *user, void *data, int len)
15552467cda1SBeau Belgrave {
15562467cda1SBeau Belgrave struct list_head *head = &user->validators;
15572467cda1SBeau Belgrave struct user_event_validator *validator;
15582467cda1SBeau Belgrave void *pos, *end = data + len;
15592467cda1SBeau Belgrave u32 loc, offset, size;
15602467cda1SBeau Belgrave
1561dcbd1ac2SBeau Belgrave list_for_each_entry(validator, head, user_event_link) {
15622467cda1SBeau Belgrave pos = data + validator->offset;
15632467cda1SBeau Belgrave
15642467cda1SBeau Belgrave /* Already done min_size check, no bounds check here */
15652467cda1SBeau Belgrave loc = *(u32 *)pos;
15662467cda1SBeau Belgrave offset = loc & 0xffff;
15672467cda1SBeau Belgrave size = loc >> 16;
15682467cda1SBeau Belgrave
15692467cda1SBeau Belgrave if (likely(validator->flags & VALIDATOR_REL))
15702467cda1SBeau Belgrave pos += offset + sizeof(loc);
15712467cda1SBeau Belgrave else
15722467cda1SBeau Belgrave pos = data + offset;
15732467cda1SBeau Belgrave
15742467cda1SBeau Belgrave pos += size;
15752467cda1SBeau Belgrave
15762467cda1SBeau Belgrave if (unlikely(pos > end))
15772467cda1SBeau Belgrave return -EFAULT;
15782467cda1SBeau Belgrave
15792467cda1SBeau Belgrave if (likely(validator->flags & VALIDATOR_ENSURE_NULL))
15802467cda1SBeau Belgrave if (unlikely(*(char *)(pos - 1) != '\0'))
15812467cda1SBeau Belgrave return -EFAULT;
15822467cda1SBeau Belgrave }
15832467cda1SBeau Belgrave
15842467cda1SBeau Belgrave return 0;
15852467cda1SBeau Belgrave }
15862467cda1SBeau Belgrave
15877f5a08c7SBeau Belgrave /*
15887f5a08c7SBeau Belgrave * Writes the user supplied payload out to a trace file.
15897f5a08c7SBeau Belgrave */
user_event_ftrace(struct user_event * user,struct iov_iter * i,void * tpdata,bool * faulted)15900279400aSBeau Belgrave static void user_event_ftrace(struct user_event *user, struct iov_iter *i,
15912467cda1SBeau Belgrave void *tpdata, bool *faulted)
15927f5a08c7SBeau Belgrave {
15937f5a08c7SBeau Belgrave struct trace_event_file *file;
15947f5a08c7SBeau Belgrave struct trace_entry *entry;
15957f5a08c7SBeau Belgrave struct trace_event_buffer event_buffer;
15962467cda1SBeau Belgrave size_t size = sizeof(*entry) + i->count;
15977f5a08c7SBeau Belgrave
15987f5a08c7SBeau Belgrave file = (struct trace_event_file *)tpdata;
15997f5a08c7SBeau Belgrave
16007f5a08c7SBeau Belgrave if (!file ||
16017f5a08c7SBeau Belgrave !(file->flags & EVENT_FILE_FL_ENABLED) ||
16027f5a08c7SBeau Belgrave trace_trigger_soft_disabled(file))
16037f5a08c7SBeau Belgrave return;
16047f5a08c7SBeau Belgrave
16057f5a08c7SBeau Belgrave /* Allocates and fills trace_entry, + 1 of this is data payload */
16062467cda1SBeau Belgrave entry = trace_event_buffer_reserve(&event_buffer, file, size);
16077f5a08c7SBeau Belgrave
16087f5a08c7SBeau Belgrave if (unlikely(!entry))
16097f5a08c7SBeau Belgrave return;
16107f5a08c7SBeau Belgrave
16116f05dcabSsunliming if (unlikely(i->count != 0 && !copy_nofault(entry + 1, i->count, i)))
16122467cda1SBeau Belgrave goto discard;
16132467cda1SBeau Belgrave
16142467cda1SBeau Belgrave if (!list_empty(&user->validators) &&
16152467cda1SBeau Belgrave unlikely(user_event_validate(user, entry, size)))
16162467cda1SBeau Belgrave goto discard;
16172467cda1SBeau Belgrave
16182467cda1SBeau Belgrave trace_event_buffer_commit(&event_buffer);
16192467cda1SBeau Belgrave
16202467cda1SBeau Belgrave return;
16212467cda1SBeau Belgrave discard:
16222467cda1SBeau Belgrave *faulted = true;
16230279400aSBeau Belgrave __trace_event_discard_commit(event_buffer.buffer,
16240279400aSBeau Belgrave event_buffer.event);
16257f5a08c7SBeau Belgrave }
16267f5a08c7SBeau Belgrave
16273207d045SBeau Belgrave #ifdef CONFIG_PERF_EVENTS
16283207d045SBeau Belgrave /*
1629768c1e7fSBeau Belgrave * Writes the user supplied payload out to perf ring buffer.
16303207d045SBeau Belgrave */
user_event_perf(struct user_event * user,struct iov_iter * i,void * tpdata,bool * faulted)16310279400aSBeau Belgrave static void user_event_perf(struct user_event *user, struct iov_iter *i,
16322467cda1SBeau Belgrave void *tpdata, bool *faulted)
16333207d045SBeau Belgrave {
16343207d045SBeau Belgrave struct hlist_head *perf_head;
16353207d045SBeau Belgrave
16363207d045SBeau Belgrave perf_head = this_cpu_ptr(user->call.perf_events);
16373207d045SBeau Belgrave
16383207d045SBeau Belgrave if (perf_head && !hlist_empty(perf_head)) {
16393207d045SBeau Belgrave struct trace_entry *perf_entry;
16403207d045SBeau Belgrave struct pt_regs *regs;
16410279400aSBeau Belgrave size_t size = sizeof(*perf_entry) + i->count;
16423207d045SBeau Belgrave int context;
16433207d045SBeau Belgrave
16443207d045SBeau Belgrave perf_entry = perf_trace_buf_alloc(ALIGN(size, 8),
16453207d045SBeau Belgrave ®s, &context);
16463207d045SBeau Belgrave
16473207d045SBeau Belgrave if (unlikely(!perf_entry))
16483207d045SBeau Belgrave return;
16493207d045SBeau Belgrave
16503207d045SBeau Belgrave perf_fetch_caller_regs(regs);
16513207d045SBeau Belgrave
16526f05dcabSsunliming if (unlikely(i->count != 0 && !copy_nofault(perf_entry + 1, i->count, i)))
16532467cda1SBeau Belgrave goto discard;
16542467cda1SBeau Belgrave
16552467cda1SBeau Belgrave if (!list_empty(&user->validators) &&
16562467cda1SBeau Belgrave unlikely(user_event_validate(user, perf_entry, size)))
16572467cda1SBeau Belgrave goto discard;
16583207d045SBeau Belgrave
16593207d045SBeau Belgrave perf_trace_buf_submit(perf_entry, size, context,
16603207d045SBeau Belgrave user->call.event.type, 1, regs,
16613207d045SBeau Belgrave perf_head, NULL);
16622467cda1SBeau Belgrave
16632467cda1SBeau Belgrave return;
16642467cda1SBeau Belgrave discard:
16652467cda1SBeau Belgrave *faulted = true;
16662467cda1SBeau Belgrave perf_swevent_put_recursion_context(context);
16673207d045SBeau Belgrave }
16683207d045SBeau Belgrave }
16693207d045SBeau Belgrave #endif
16703207d045SBeau Belgrave
16717f5a08c7SBeau Belgrave /*
167272357590SBeau Belgrave * Update the enabled bit among all user processes.
16737f5a08c7SBeau Belgrave */
update_enable_bit_for(struct user_event * user)167472357590SBeau Belgrave static void update_enable_bit_for(struct user_event *user)
16757f5a08c7SBeau Belgrave {
16767f5a08c7SBeau Belgrave struct tracepoint *tp = &user->tracepoint;
16777f5a08c7SBeau Belgrave char status = 0;
16787f5a08c7SBeau Belgrave
16797f5a08c7SBeau Belgrave if (atomic_read(&tp->key.enabled) > 0) {
16807f5a08c7SBeau Belgrave struct tracepoint_func *probe_func_ptr;
16817f5a08c7SBeau Belgrave user_event_func_t probe_func;
16827f5a08c7SBeau Belgrave
16837f5a08c7SBeau Belgrave rcu_read_lock_sched();
16847f5a08c7SBeau Belgrave
16857f5a08c7SBeau Belgrave probe_func_ptr = rcu_dereference_sched(tp->funcs);
16867f5a08c7SBeau Belgrave
16877f5a08c7SBeau Belgrave if (probe_func_ptr) {
16887f5a08c7SBeau Belgrave do {
16897f5a08c7SBeau Belgrave probe_func = probe_func_ptr->func;
16907f5a08c7SBeau Belgrave
16917f5a08c7SBeau Belgrave if (probe_func == user_event_ftrace)
16927f5a08c7SBeau Belgrave status |= EVENT_STATUS_FTRACE;
16933207d045SBeau Belgrave #ifdef CONFIG_PERF_EVENTS
16943207d045SBeau Belgrave else if (probe_func == user_event_perf)
16953207d045SBeau Belgrave status |= EVENT_STATUS_PERF;
16963207d045SBeau Belgrave #endif
16977f5a08c7SBeau Belgrave else
16987f5a08c7SBeau Belgrave status |= EVENT_STATUS_OTHER;
16997f5a08c7SBeau Belgrave } while ((++probe_func_ptr)->func);
17007f5a08c7SBeau Belgrave }
17017f5a08c7SBeau Belgrave
17027f5a08c7SBeau Belgrave rcu_read_unlock_sched();
17037f5a08c7SBeau Belgrave }
17047f5a08c7SBeau Belgrave
170539d6d08bSBeau Belgrave user->status = status;
170672357590SBeau Belgrave
170772357590SBeau Belgrave user_event_enabler_update(user);
17087f5a08c7SBeau Belgrave }
17097f5a08c7SBeau Belgrave
17107f5a08c7SBeau Belgrave /*
17117f5a08c7SBeau Belgrave * Register callback for our events from tracing sub-systems.
17127f5a08c7SBeau Belgrave */
user_event_reg(struct trace_event_call * call,enum trace_reg type,void * data)17137f5a08c7SBeau Belgrave static int user_event_reg(struct trace_event_call *call,
17147f5a08c7SBeau Belgrave enum trace_reg type,
17157f5a08c7SBeau Belgrave void *data)
17167f5a08c7SBeau Belgrave {
17177f5a08c7SBeau Belgrave struct user_event *user = (struct user_event *)call->data;
17187f5a08c7SBeau Belgrave int ret = 0;
17197f5a08c7SBeau Belgrave
17207f5a08c7SBeau Belgrave if (!user)
17217f5a08c7SBeau Belgrave return -ENOENT;
17227f5a08c7SBeau Belgrave
17237f5a08c7SBeau Belgrave switch (type) {
17247f5a08c7SBeau Belgrave case TRACE_REG_REGISTER:
17257f5a08c7SBeau Belgrave ret = tracepoint_probe_register(call->tp,
17267f5a08c7SBeau Belgrave call->class->probe,
17277f5a08c7SBeau Belgrave data);
17287f5a08c7SBeau Belgrave if (!ret)
17297f5a08c7SBeau Belgrave goto inc;
17307f5a08c7SBeau Belgrave break;
17317f5a08c7SBeau Belgrave
17327f5a08c7SBeau Belgrave case TRACE_REG_UNREGISTER:
17337f5a08c7SBeau Belgrave tracepoint_probe_unregister(call->tp,
17347f5a08c7SBeau Belgrave call->class->probe,
17357f5a08c7SBeau Belgrave data);
17367f5a08c7SBeau Belgrave goto dec;
17377f5a08c7SBeau Belgrave
17383207d045SBeau Belgrave #ifdef CONFIG_PERF_EVENTS
17393207d045SBeau Belgrave case TRACE_REG_PERF_REGISTER:
17403207d045SBeau Belgrave ret = tracepoint_probe_register(call->tp,
17413207d045SBeau Belgrave call->class->perf_probe,
17423207d045SBeau Belgrave data);
17433207d045SBeau Belgrave if (!ret)
17443207d045SBeau Belgrave goto inc;
17457f5a08c7SBeau Belgrave break;
17463207d045SBeau Belgrave
17473207d045SBeau Belgrave case TRACE_REG_PERF_UNREGISTER:
17483207d045SBeau Belgrave tracepoint_probe_unregister(call->tp,
17493207d045SBeau Belgrave call->class->perf_probe,
17503207d045SBeau Belgrave data);
17513207d045SBeau Belgrave goto dec;
17523207d045SBeau Belgrave
17533207d045SBeau Belgrave case TRACE_REG_PERF_OPEN:
17543207d045SBeau Belgrave case TRACE_REG_PERF_CLOSE:
17553207d045SBeau Belgrave case TRACE_REG_PERF_ADD:
17563207d045SBeau Belgrave case TRACE_REG_PERF_DEL:
17573207d045SBeau Belgrave break;
17583207d045SBeau Belgrave #endif
17597f5a08c7SBeau Belgrave }
17607f5a08c7SBeau Belgrave
17617f5a08c7SBeau Belgrave return ret;
17627f5a08c7SBeau Belgrave inc:
1763f0dbf6fdSBeau Belgrave user_event_get(user);
176472357590SBeau Belgrave update_enable_bit_for(user);
17657f5a08c7SBeau Belgrave return 0;
17667f5a08c7SBeau Belgrave dec:
176772357590SBeau Belgrave update_enable_bit_for(user);
1768f0dbf6fdSBeau Belgrave user_event_put(user, true);
17697f5a08c7SBeau Belgrave return 0;
17707f5a08c7SBeau Belgrave }
17717f5a08c7SBeau Belgrave
user_event_create(const char * raw_command)17727f5a08c7SBeau Belgrave static int user_event_create(const char *raw_command)
17737f5a08c7SBeau Belgrave {
1774e5d27181SBeau Belgrave struct user_event_group *group;
17757f5a08c7SBeau Belgrave struct user_event *user;
17767f5a08c7SBeau Belgrave char *name;
17777f5a08c7SBeau Belgrave int ret;
17787f5a08c7SBeau Belgrave
17797f5a08c7SBeau Belgrave if (!str_has_prefix(raw_command, USER_EVENTS_PREFIX))
17807f5a08c7SBeau Belgrave return -ECANCELED;
17817f5a08c7SBeau Belgrave
17827f5a08c7SBeau Belgrave raw_command += USER_EVENTS_PREFIX_LEN;
17837f5a08c7SBeau Belgrave raw_command = skip_spaces(raw_command);
17847f5a08c7SBeau Belgrave
1785f9cce238SBeau Belgrave name = kstrdup(raw_command, GFP_KERNEL_ACCOUNT);
17867f5a08c7SBeau Belgrave
17877f5a08c7SBeau Belgrave if (!name)
17887f5a08c7SBeau Belgrave return -ENOMEM;
17897f5a08c7SBeau Belgrave
1790e5d27181SBeau Belgrave group = current_user_event_group();
17917e348b32SBeau Belgrave
1792ccc6e590SXiu Jianfeng if (!group) {
1793ccc6e590SXiu Jianfeng kfree(name);
1794e5d27181SBeau Belgrave return -ENOENT;
1795ccc6e590SXiu Jianfeng }
1796e5d27181SBeau Belgrave
1797e5d27181SBeau Belgrave mutex_lock(&group->reg_mutex);
1798e5d27181SBeau Belgrave
1799a65442edSBeau Belgrave /* Dyn events persist, otherwise they would cleanup immediately */
1800a65442edSBeau Belgrave ret = user_event_parse_cmd(group, name, &user, USER_EVENT_REG_PERSIST);
18017e348b32SBeau Belgrave
18027e348b32SBeau Belgrave if (!ret)
1803f0dbf6fdSBeau Belgrave user_event_put(user, false);
18047e348b32SBeau Belgrave
1805e5d27181SBeau Belgrave mutex_unlock(&group->reg_mutex);
18067f5a08c7SBeau Belgrave
18077f5a08c7SBeau Belgrave if (ret)
18087f5a08c7SBeau Belgrave kfree(name);
18097f5a08c7SBeau Belgrave
18107f5a08c7SBeau Belgrave return ret;
18117f5a08c7SBeau Belgrave }
18127f5a08c7SBeau Belgrave
user_event_show(struct seq_file * m,struct dyn_event * ev)18137f5a08c7SBeau Belgrave static int user_event_show(struct seq_file *m, struct dyn_event *ev)
18147f5a08c7SBeau Belgrave {
18157f5a08c7SBeau Belgrave struct user_event *user = container_of(ev, struct user_event, devent);
1816a943188dSEric Vaughn struct ftrace_event_field *field;
18177f5a08c7SBeau Belgrave struct list_head *head;
18187f5a08c7SBeau Belgrave int depth = 0;
18197f5a08c7SBeau Belgrave
18207f5a08c7SBeau Belgrave seq_printf(m, "%s%s", USER_EVENTS_PREFIX, EVENT_NAME(user));
18217f5a08c7SBeau Belgrave
18227f5a08c7SBeau Belgrave head = trace_get_fields(&user->call);
18237f5a08c7SBeau Belgrave
1824a943188dSEric Vaughn list_for_each_entry_reverse(field, head, link) {
18257f5a08c7SBeau Belgrave if (depth == 0)
18267f5a08c7SBeau Belgrave seq_puts(m, " ");
18277f5a08c7SBeau Belgrave else
18287f5a08c7SBeau Belgrave seq_puts(m, "; ");
18297f5a08c7SBeau Belgrave
18307f5a08c7SBeau Belgrave seq_printf(m, "%s %s", field->type, field->name);
18317f5a08c7SBeau Belgrave
18327f5a08c7SBeau Belgrave if (str_has_prefix(field->type, "struct "))
18337f5a08c7SBeau Belgrave seq_printf(m, " %d", field->size);
18347f5a08c7SBeau Belgrave
18357f5a08c7SBeau Belgrave depth++;
18367f5a08c7SBeau Belgrave }
18377f5a08c7SBeau Belgrave
18387f5a08c7SBeau Belgrave seq_puts(m, "\n");
18397f5a08c7SBeau Belgrave
18407f5a08c7SBeau Belgrave return 0;
18417f5a08c7SBeau Belgrave }
18427f5a08c7SBeau Belgrave
user_event_is_busy(struct dyn_event * ev)18437f5a08c7SBeau Belgrave static bool user_event_is_busy(struct dyn_event *ev)
18447f5a08c7SBeau Belgrave {
18457f5a08c7SBeau Belgrave struct user_event *user = container_of(ev, struct user_event, devent);
18467f5a08c7SBeau Belgrave
1847d401b724SBeau Belgrave return !user_event_last_ref(user);
18487f5a08c7SBeau Belgrave }
18497f5a08c7SBeau Belgrave
user_event_free(struct dyn_event * ev)18507f5a08c7SBeau Belgrave static int user_event_free(struct dyn_event *ev)
18517f5a08c7SBeau Belgrave {
18527f5a08c7SBeau Belgrave struct user_event *user = container_of(ev, struct user_event, devent);
18537f5a08c7SBeau Belgrave
1854d401b724SBeau Belgrave if (!user_event_last_ref(user))
18557f5a08c7SBeau Belgrave return -EBUSY;
18567f5a08c7SBeau Belgrave
18575dbd04edSBeau Belgrave if (!user_event_capable(user->reg_flags))
18585dbd04edSBeau Belgrave return -EPERM;
18595dbd04edSBeau Belgrave
18607f5a08c7SBeau Belgrave return destroy_user_event(user);
18617f5a08c7SBeau Belgrave }
18627f5a08c7SBeau Belgrave
user_field_match(struct ftrace_event_field * field,int argc,const char ** argv,int * iout)18639aed4e15SBeau Belgrave static bool user_field_match(struct ftrace_event_field *field, int argc,
18649aed4e15SBeau Belgrave const char **argv, int *iout)
18659aed4e15SBeau Belgrave {
1866e6f89a14SBeau Belgrave char *field_name = NULL, *dyn_field_name = NULL;
18679aed4e15SBeau Belgrave bool colon = false, match = false;
1868e6f89a14SBeau Belgrave int dyn_len, len;
18699aed4e15SBeau Belgrave
1870e6f89a14SBeau Belgrave if (*iout >= argc)
18719aed4e15SBeau Belgrave return false;
18729aed4e15SBeau Belgrave
1873e6f89a14SBeau Belgrave dyn_len = user_dyn_field_set_string(argc, argv, iout, dyn_field_name,
1874e6f89a14SBeau Belgrave 0, &colon);
18759aed4e15SBeau Belgrave
1876e6f89a14SBeau Belgrave len = user_field_set_string(field, field_name, 0, colon);
1877e6f89a14SBeau Belgrave
1878e6f89a14SBeau Belgrave if (dyn_len != len)
1879e6f89a14SBeau Belgrave return false;
1880e6f89a14SBeau Belgrave
1881e6f89a14SBeau Belgrave dyn_field_name = kmalloc(dyn_len, GFP_KERNEL);
1882e6f89a14SBeau Belgrave field_name = kmalloc(len, GFP_KERNEL);
1883e6f89a14SBeau Belgrave
1884e6f89a14SBeau Belgrave if (!dyn_field_name || !field_name)
18859aed4e15SBeau Belgrave goto out;
18869aed4e15SBeau Belgrave
1887e6f89a14SBeau Belgrave user_dyn_field_set_string(argc, argv, iout, dyn_field_name,
1888e6f89a14SBeau Belgrave dyn_len, &colon);
18899aed4e15SBeau Belgrave
1890e6f89a14SBeau Belgrave user_field_set_string(field, field_name, len, colon);
18919aed4e15SBeau Belgrave
1892e6f89a14SBeau Belgrave match = strcmp(dyn_field_name, field_name) == 0;
18939aed4e15SBeau Belgrave out:
1894e6f89a14SBeau Belgrave kfree(dyn_field_name);
18959aed4e15SBeau Belgrave kfree(field_name);
18969aed4e15SBeau Belgrave
18979aed4e15SBeau Belgrave return match;
18989aed4e15SBeau Belgrave }
18999aed4e15SBeau Belgrave
user_fields_match(struct user_event * user,int argc,const char ** argv)19009aed4e15SBeau Belgrave static bool user_fields_match(struct user_event *user, int argc,
19019aed4e15SBeau Belgrave const char **argv)
19029aed4e15SBeau Belgrave {
1903a943188dSEric Vaughn struct ftrace_event_field *field;
19049aed4e15SBeau Belgrave struct list_head *head = &user->fields;
19059aed4e15SBeau Belgrave int i = 0;
19069aed4e15SBeau Belgrave
19071e953de9SBeau Belgrave if (argc == 0)
19081e953de9SBeau Belgrave return list_empty(head);
19091e953de9SBeau Belgrave
1910a943188dSEric Vaughn list_for_each_entry_reverse(field, head, link) {
19119aed4e15SBeau Belgrave if (!user_field_match(field, argc, argv, &i))
19129aed4e15SBeau Belgrave return false;
1913a943188dSEric Vaughn }
19149aed4e15SBeau Belgrave
19159aed4e15SBeau Belgrave if (i != argc)
19169aed4e15SBeau Belgrave return false;
19179aed4e15SBeau Belgrave
19189aed4e15SBeau Belgrave return true;
19199aed4e15SBeau Belgrave }
19209aed4e15SBeau Belgrave
user_event_match(const char * system,const char * event,int argc,const char ** argv,struct dyn_event * ev)19217f5a08c7SBeau Belgrave static bool user_event_match(const char *system, const char *event,
19227f5a08c7SBeau Belgrave int argc, const char **argv, struct dyn_event *ev)
19237f5a08c7SBeau Belgrave {
19247f5a08c7SBeau Belgrave struct user_event *user = container_of(ev, struct user_event, devent);
19259aed4e15SBeau Belgrave bool match;
19267f5a08c7SBeau Belgrave
192764805e40SBeau Belgrave match = strcmp(EVENT_NAME(user), event) == 0;
192864805e40SBeau Belgrave
192964805e40SBeau Belgrave if (match && system) {
193064805e40SBeau Belgrave match = strcmp(system, user->group->system_name) == 0 ||
193164805e40SBeau Belgrave strcmp(system, user->group->system_multi_name) == 0;
193264805e40SBeau Belgrave }
19339aed4e15SBeau Belgrave
19341e953de9SBeau Belgrave if (match)
19359aed4e15SBeau Belgrave match = user_fields_match(user, argc, argv);
19369aed4e15SBeau Belgrave
19379aed4e15SBeau Belgrave return match;
19387f5a08c7SBeau Belgrave }
19397f5a08c7SBeau Belgrave
19407f5a08c7SBeau Belgrave static struct dyn_event_operations user_event_dops = {
19417f5a08c7SBeau Belgrave .create = user_event_create,
19427f5a08c7SBeau Belgrave .show = user_event_show,
19437f5a08c7SBeau Belgrave .is_busy = user_event_is_busy,
19447f5a08c7SBeau Belgrave .free = user_event_free,
19457f5a08c7SBeau Belgrave .match = user_event_match,
19467f5a08c7SBeau Belgrave };
19477f5a08c7SBeau Belgrave
user_event_trace_register(struct user_event * user)19487f5a08c7SBeau Belgrave static int user_event_trace_register(struct user_event *user)
19497f5a08c7SBeau Belgrave {
19507f5a08c7SBeau Belgrave int ret;
19517f5a08c7SBeau Belgrave
19527f5a08c7SBeau Belgrave ret = register_trace_event(&user->call.event);
19537f5a08c7SBeau Belgrave
19547f5a08c7SBeau Belgrave if (!ret)
19557f5a08c7SBeau Belgrave return -ENODEV;
19567f5a08c7SBeau Belgrave
1957089331d4SBeau Belgrave ret = user_event_set_call_visible(user, true);
19587f5a08c7SBeau Belgrave
19597f5a08c7SBeau Belgrave if (ret)
19607f5a08c7SBeau Belgrave unregister_trace_event(&user->call.event);
19617f5a08c7SBeau Belgrave
19627f5a08c7SBeau Belgrave return ret;
19637f5a08c7SBeau Belgrave }
19647f5a08c7SBeau Belgrave
user_event_set_tp_name(struct user_event * user)196564805e40SBeau Belgrave static int user_event_set_tp_name(struct user_event *user)
196664805e40SBeau Belgrave {
196764805e40SBeau Belgrave lockdep_assert_held(&user->group->reg_mutex);
196864805e40SBeau Belgrave
196964805e40SBeau Belgrave if (EVENT_MULTI_FORMAT(user->reg_flags)) {
197064805e40SBeau Belgrave char *multi_name;
197164805e40SBeau Belgrave
197264805e40SBeau Belgrave multi_name = kasprintf(GFP_KERNEL_ACCOUNT, "%s.%llx",
197364805e40SBeau Belgrave user->reg_name, user->group->multi_id);
197464805e40SBeau Belgrave
197564805e40SBeau Belgrave if (!multi_name)
197664805e40SBeau Belgrave return -ENOMEM;
197764805e40SBeau Belgrave
197864805e40SBeau Belgrave user->call.name = multi_name;
197964805e40SBeau Belgrave user->tracepoint.name = multi_name;
198064805e40SBeau Belgrave
198164805e40SBeau Belgrave /* Inc to ensure unique multi-event name next time */
198264805e40SBeau Belgrave user->group->multi_id++;
198364805e40SBeau Belgrave } else {
198464805e40SBeau Belgrave /* Non Multi-format uses register name */
198564805e40SBeau Belgrave user->call.name = user->reg_name;
198664805e40SBeau Belgrave user->tracepoint.name = user->reg_name;
198764805e40SBeau Belgrave }
198864805e40SBeau Belgrave
198964805e40SBeau Belgrave return 0;
199064805e40SBeau Belgrave }
199164805e40SBeau Belgrave
19927f5a08c7SBeau Belgrave /*
1993bd125a08SBeau Belgrave * Counts how many ';' without a trailing space are in the args.
1994bd125a08SBeau Belgrave */
count_semis_no_space(char * args)1995bd125a08SBeau Belgrave static int count_semis_no_space(char *args)
1996bd125a08SBeau Belgrave {
1997bd125a08SBeau Belgrave int count = 0;
1998bd125a08SBeau Belgrave
1999bd125a08SBeau Belgrave while ((args = strchr(args, ';'))) {
2000bd125a08SBeau Belgrave args++;
2001bd125a08SBeau Belgrave
2002bd125a08SBeau Belgrave if (!isspace(*args))
2003bd125a08SBeau Belgrave count++;
2004bd125a08SBeau Belgrave }
2005bd125a08SBeau Belgrave
2006bd125a08SBeau Belgrave return count;
2007bd125a08SBeau Belgrave }
2008bd125a08SBeau Belgrave
2009bd125a08SBeau Belgrave /*
2010bd125a08SBeau Belgrave * Copies the arguments while ensuring all ';' have a trailing space.
2011bd125a08SBeau Belgrave */
insert_space_after_semis(char * args,int count)2012bd125a08SBeau Belgrave static char *insert_space_after_semis(char *args, int count)
2013bd125a08SBeau Belgrave {
2014bd125a08SBeau Belgrave char *fixed, *pos;
2015bd125a08SBeau Belgrave int len;
2016bd125a08SBeau Belgrave
2017bd125a08SBeau Belgrave len = strlen(args) + count;
2018bd125a08SBeau Belgrave fixed = kmalloc(len + 1, GFP_KERNEL);
2019bd125a08SBeau Belgrave
2020bd125a08SBeau Belgrave if (!fixed)
2021bd125a08SBeau Belgrave return NULL;
2022bd125a08SBeau Belgrave
2023bd125a08SBeau Belgrave pos = fixed;
2024bd125a08SBeau Belgrave
2025bd125a08SBeau Belgrave /* Insert a space after ';' if there is no trailing space. */
2026bd125a08SBeau Belgrave while (*args) {
2027bd125a08SBeau Belgrave *pos = *args++;
2028bd125a08SBeau Belgrave
2029bd125a08SBeau Belgrave if (*pos++ == ';' && !isspace(*args))
2030bd125a08SBeau Belgrave *pos++ = ' ';
2031bd125a08SBeau Belgrave }
2032bd125a08SBeau Belgrave
2033bd125a08SBeau Belgrave *pos = '\0';
2034bd125a08SBeau Belgrave
2035bd125a08SBeau Belgrave return fixed;
2036bd125a08SBeau Belgrave }
2037bd125a08SBeau Belgrave
user_event_argv_split(char * args,int * argc)2038bd125a08SBeau Belgrave static char **user_event_argv_split(char *args, int *argc)
2039bd125a08SBeau Belgrave {
2040bd125a08SBeau Belgrave char **split;
2041bd125a08SBeau Belgrave char *fixed;
2042bd125a08SBeau Belgrave int count;
2043bd125a08SBeau Belgrave
2044bd125a08SBeau Belgrave /* Count how many ';' without a trailing space */
2045bd125a08SBeau Belgrave count = count_semis_no_space(args);
2046bd125a08SBeau Belgrave
2047bd125a08SBeau Belgrave /* No fixup is required */
2048bd125a08SBeau Belgrave if (!count)
2049bd125a08SBeau Belgrave return argv_split(GFP_KERNEL, args, argc);
2050bd125a08SBeau Belgrave
2051bd125a08SBeau Belgrave /* We must fixup 'field;field' to 'field; field' */
2052bd125a08SBeau Belgrave fixed = insert_space_after_semis(args, count);
2053bd125a08SBeau Belgrave
2054bd125a08SBeau Belgrave if (!fixed)
2055bd125a08SBeau Belgrave return NULL;
2056bd125a08SBeau Belgrave
2057bd125a08SBeau Belgrave /* We do a normal split afterwards */
2058bd125a08SBeau Belgrave split = argv_split(GFP_KERNEL, fixed, argc);
2059bd125a08SBeau Belgrave
2060bd125a08SBeau Belgrave /* We can free since argv_split makes a copy */
2061bd125a08SBeau Belgrave kfree(fixed);
2062bd125a08SBeau Belgrave
2063bd125a08SBeau Belgrave return split;
2064bd125a08SBeau Belgrave }
2065bd125a08SBeau Belgrave
2066bd125a08SBeau Belgrave /*
20677f5a08c7SBeau Belgrave * Parses the event name, arguments and flags then registers if successful.
20687f5a08c7SBeau Belgrave * The name buffer lifetime is owned by this method for success cases only.
20697e348b32SBeau Belgrave * Upon success the returned user_event has its ref count increased by 1.
20707f5a08c7SBeau Belgrave */
user_event_parse(struct user_event_group * group,char * name,char * args,char * flags,struct user_event ** newuser,int reg_flags)2071e5d27181SBeau Belgrave static int user_event_parse(struct user_event_group *group, char *name,
2072e5d27181SBeau Belgrave char *args, char *flags,
2073b08d7258SBeau Belgrave struct user_event **newuser, int reg_flags)
20747f5a08c7SBeau Belgrave {
20751e953de9SBeau Belgrave struct user_event *user;
20761e953de9SBeau Belgrave char **argv = NULL;
20771e953de9SBeau Belgrave int argc = 0;
20787f5a08c7SBeau Belgrave int ret;
20797f5a08c7SBeau Belgrave u32 key;
20807e348b32SBeau Belgrave
20815dbd04edSBeau Belgrave /* Currently don't support any text based flags */
20825dbd04edSBeau Belgrave if (flags != NULL)
2083a65442edSBeau Belgrave return -EINVAL;
2084a65442edSBeau Belgrave
20855dbd04edSBeau Belgrave if (!user_event_capable(reg_flags))
20865dbd04edSBeau Belgrave return -EPERM;
20875dbd04edSBeau Belgrave
2088ba470eebSsunliming if (args) {
2089bd125a08SBeau Belgrave argv = user_event_argv_split(args, &argc);
20901e953de9SBeau Belgrave
20911e953de9SBeau Belgrave if (!argv)
20921e953de9SBeau Belgrave return -ENOMEM;
2093ba470eebSsunliming }
2094ba470eebSsunliming
20951e953de9SBeau Belgrave /* Prevent dyn_event from racing */
20961e953de9SBeau Belgrave mutex_lock(&event_mutex);
20971e953de9SBeau Belgrave user = find_user_event(group, name, argc, (const char **)argv,
20981e953de9SBeau Belgrave reg_flags, &key);
20991e953de9SBeau Belgrave mutex_unlock(&event_mutex);
21001e953de9SBeau Belgrave
21011e953de9SBeau Belgrave if (argv)
2102ba470eebSsunliming argv_free(argv);
2103ba470eebSsunliming
21041e953de9SBeau Belgrave if (IS_ERR(user))
21051e953de9SBeau Belgrave return PTR_ERR(user);
2106ba470eebSsunliming
21071e953de9SBeau Belgrave if (user) {
21087f5a08c7SBeau Belgrave *newuser = user;
21097f5a08c7SBeau Belgrave /*
21107f5a08c7SBeau Belgrave * Name is allocated by caller, free it since it already exists.
21117f5a08c7SBeau Belgrave * Caller only worries about failure cases for freeing.
21127f5a08c7SBeau Belgrave */
21137f5a08c7SBeau Belgrave kfree(name);
2114ba470eebSsunliming
21157f5a08c7SBeau Belgrave return 0;
21167f5a08c7SBeau Belgrave }
21177f5a08c7SBeau Belgrave
2118f9cce238SBeau Belgrave user = kzalloc(sizeof(*user), GFP_KERNEL_ACCOUNT);
21197f5a08c7SBeau Belgrave
21207f5a08c7SBeau Belgrave if (!user)
21217f5a08c7SBeau Belgrave return -ENOMEM;
21227f5a08c7SBeau Belgrave
21237f5a08c7SBeau Belgrave INIT_LIST_HEAD(&user->class.fields);
21247f5a08c7SBeau Belgrave INIT_LIST_HEAD(&user->fields);
21252467cda1SBeau Belgrave INIT_LIST_HEAD(&user->validators);
21267f5a08c7SBeau Belgrave
2127e5d27181SBeau Belgrave user->group = group;
212864805e40SBeau Belgrave user->reg_name = name;
212964805e40SBeau Belgrave user->reg_flags = reg_flags;
213064805e40SBeau Belgrave
213164805e40SBeau Belgrave ret = user_event_set_tp_name(user);
213264805e40SBeau Belgrave
213364805e40SBeau Belgrave if (ret)
213464805e40SBeau Belgrave goto put_user;
21357f5a08c7SBeau Belgrave
21367f5a08c7SBeau Belgrave ret = user_event_parse_fields(user, args);
21377f5a08c7SBeau Belgrave
21387f5a08c7SBeau Belgrave if (ret)
21397f5a08c7SBeau Belgrave goto put_user;
21407f5a08c7SBeau Belgrave
2141aa3b2b4cSBeau Belgrave ret = user_event_create_print_fmt(user);
2142aa3b2b4cSBeau Belgrave
2143aa3b2b4cSBeau Belgrave if (ret)
2144aa3b2b4cSBeau Belgrave goto put_user;
21457f5a08c7SBeau Belgrave
21467f5a08c7SBeau Belgrave user->call.data = user;
21477f5a08c7SBeau Belgrave user->call.class = &user->class;
21487f5a08c7SBeau Belgrave user->call.flags = TRACE_EVENT_FL_TRACEPOINT;
21497f5a08c7SBeau Belgrave user->call.tp = &user->tracepoint;
21507f5a08c7SBeau Belgrave user->call.event.funcs = &user_event_funcs;
215164805e40SBeau Belgrave
215264805e40SBeau Belgrave if (EVENT_MULTI_FORMAT(user->reg_flags))
215364805e40SBeau Belgrave user->class.system = group->system_multi_name;
215464805e40SBeau Belgrave else
2155e5d27181SBeau Belgrave user->class.system = group->system_name;
21567f5a08c7SBeau Belgrave
21577f5a08c7SBeau Belgrave user->class.fields_array = user_event_fields_array;
21587f5a08c7SBeau Belgrave user->class.get_fields = user_event_get_fields;
21597f5a08c7SBeau Belgrave user->class.reg = user_event_reg;
21607f5a08c7SBeau Belgrave user->class.probe = user_event_ftrace;
21613207d045SBeau Belgrave #ifdef CONFIG_PERF_EVENTS
21623207d045SBeau Belgrave user->class.perf_probe = user_event_perf;
21633207d045SBeau Belgrave #endif
21647f5a08c7SBeau Belgrave
21657f5a08c7SBeau Belgrave mutex_lock(&event_mutex);
2166efe34e99SBeau Belgrave
2167ce58e96eSBeau Belgrave if (current_user_events >= max_user_events) {
2168ce58e96eSBeau Belgrave ret = -EMFILE;
2169ce58e96eSBeau Belgrave goto put_user_lock;
2170ce58e96eSBeau Belgrave }
2171ce58e96eSBeau Belgrave
21727f5a08c7SBeau Belgrave ret = user_event_trace_register(user);
21737f5a08c7SBeau Belgrave
21747f5a08c7SBeau Belgrave if (ret)
2175efe34e99SBeau Belgrave goto put_user_lock;
21767f5a08c7SBeau Belgrave
2177a65442edSBeau Belgrave if (user->reg_flags & USER_EVENT_REG_PERSIST) {
2178d401b724SBeau Belgrave /* Ensure we track self ref and caller ref (2) */
2179d401b724SBeau Belgrave refcount_set(&user->refcnt, 2);
2180a65442edSBeau Belgrave } else {
2181a65442edSBeau Belgrave /* Ensure we track only caller ref (1) */
2182a65442edSBeau Belgrave refcount_set(&user->refcnt, 1);
2183a65442edSBeau Belgrave }
21847e348b32SBeau Belgrave
21857f5a08c7SBeau Belgrave dyn_event_init(&user->devent, &user_event_dops);
21867f5a08c7SBeau Belgrave dyn_event_add(&user->devent, &user->call);
2187e5d27181SBeau Belgrave hash_add(group->register_table, &user->node, key);
2188ce58e96eSBeau Belgrave current_user_events++;
21897f5a08c7SBeau Belgrave
2190efe34e99SBeau Belgrave mutex_unlock(&event_mutex);
2191efe34e99SBeau Belgrave
21927f5a08c7SBeau Belgrave *newuser = user;
21937f5a08c7SBeau Belgrave return 0;
2194efe34e99SBeau Belgrave put_user_lock:
2195efe34e99SBeau Belgrave mutex_unlock(&event_mutex);
21967f5a08c7SBeau Belgrave put_user:
21977f5a08c7SBeau Belgrave user_event_destroy_fields(user);
21982467cda1SBeau Belgrave user_event_destroy_validators(user);
21994bded7afSBeau Belgrave kfree(user->call.print_fmt);
220064805e40SBeau Belgrave
220164805e40SBeau Belgrave /* Caller frees reg_name on error, but not multi-name */
220264805e40SBeau Belgrave if (EVENT_NAME(user) != EVENT_TP_NAME(user))
220364805e40SBeau Belgrave kfree(EVENT_TP_NAME(user));
220464805e40SBeau Belgrave
22057f5a08c7SBeau Belgrave kfree(user);
22067f5a08c7SBeau Belgrave return ret;
22077f5a08c7SBeau Belgrave }
22087f5a08c7SBeau Belgrave
22097f5a08c7SBeau Belgrave /*
22101e953de9SBeau Belgrave * Deletes previously created events if they are no longer being used.
22117f5a08c7SBeau Belgrave */
delete_user_event(struct user_event_group * group,char * name)2212e5d27181SBeau Belgrave static int delete_user_event(struct user_event_group *group, char *name)
22137f5a08c7SBeau Belgrave {
22141e953de9SBeau Belgrave struct user_event *user;
22151e953de9SBeau Belgrave struct hlist_node *tmp;
22161e953de9SBeau Belgrave u32 key = user_event_key(name);
22171e953de9SBeau Belgrave int ret = -ENOENT;
22187f5a08c7SBeau Belgrave
22191e953de9SBeau Belgrave /* Attempt to delete all event(s) with the name passed in */
22201e953de9SBeau Belgrave hash_for_each_possible_safe(group->register_table, user, tmp, node, key) {
22211e953de9SBeau Belgrave if (strcmp(EVENT_NAME(user), name))
22221e953de9SBeau Belgrave continue;
22237f5a08c7SBeau Belgrave
2224d401b724SBeau Belgrave if (!user_event_last_ref(user))
2225d401b724SBeau Belgrave return -EBUSY;
22267e348b32SBeau Belgrave
22275dbd04edSBeau Belgrave if (!user_event_capable(user->reg_flags))
22285dbd04edSBeau Belgrave return -EPERM;
22295dbd04edSBeau Belgrave
22301e953de9SBeau Belgrave ret = destroy_user_event(user);
22311e953de9SBeau Belgrave
22321e953de9SBeau Belgrave if (ret)
22331e953de9SBeau Belgrave goto out;
22341e953de9SBeau Belgrave }
22351e953de9SBeau Belgrave out:
22361e953de9SBeau Belgrave return ret;
22377f5a08c7SBeau Belgrave }
22387f5a08c7SBeau Belgrave
22397f5a08c7SBeau Belgrave /*
22407f5a08c7SBeau Belgrave * Validates the user payload and writes via iterator.
22417f5a08c7SBeau Belgrave */
user_events_write_core(struct file * file,struct iov_iter * i)22427f5a08c7SBeau Belgrave static ssize_t user_events_write_core(struct file *file, struct iov_iter *i)
22437f5a08c7SBeau Belgrave {
2244e5d27181SBeau Belgrave struct user_event_file_info *info = file->private_data;
22457f5a08c7SBeau Belgrave struct user_event_refs *refs;
22467f5a08c7SBeau Belgrave struct user_event *user = NULL;
22477f5a08c7SBeau Belgrave struct tracepoint *tp;
22487f5a08c7SBeau Belgrave ssize_t ret = i->count;
22497f5a08c7SBeau Belgrave int idx;
22507f5a08c7SBeau Belgrave
22517f5a08c7SBeau Belgrave if (unlikely(copy_from_iter(&idx, sizeof(idx), i) != sizeof(idx)))
22527f5a08c7SBeau Belgrave return -EFAULT;
22537f5a08c7SBeau Belgrave
2254cd98c932SBeau Belgrave if (idx < 0)
2255cd98c932SBeau Belgrave return -EINVAL;
2256cd98c932SBeau Belgrave
22577f5a08c7SBeau Belgrave rcu_read_lock_sched();
22587f5a08c7SBeau Belgrave
2259e5d27181SBeau Belgrave refs = rcu_dereference_sched(info->refs);
22607f5a08c7SBeau Belgrave
22617f5a08c7SBeau Belgrave /*
22627f5a08c7SBeau Belgrave * The refs->events array is protected by RCU, and new items may be
22637f5a08c7SBeau Belgrave * added. But the user retrieved from indexing into the events array
22647f5a08c7SBeau Belgrave * shall be immutable while the file is opened.
22657f5a08c7SBeau Belgrave */
22667f5a08c7SBeau Belgrave if (likely(refs && idx < refs->count))
22677f5a08c7SBeau Belgrave user = refs->events[idx];
22687f5a08c7SBeau Belgrave
22697f5a08c7SBeau Belgrave rcu_read_unlock_sched();
22707f5a08c7SBeau Belgrave
22717f5a08c7SBeau Belgrave if (unlikely(user == NULL))
22727f5a08c7SBeau Belgrave return -ENOENT;
22737f5a08c7SBeau Belgrave
22742467cda1SBeau Belgrave if (unlikely(i->count < user->min_size))
22752467cda1SBeau Belgrave return -EINVAL;
22762467cda1SBeau Belgrave
22777f5a08c7SBeau Belgrave tp = &user->tracepoint;
22787f5a08c7SBeau Belgrave
22797f5a08c7SBeau Belgrave /*
22807f5a08c7SBeau Belgrave * It's possible key.enabled disables after this check, however
22817f5a08c7SBeau Belgrave * we don't mind if a few events are included in this condition.
22827f5a08c7SBeau Belgrave */
22837f5a08c7SBeau Belgrave if (likely(atomic_read(&tp->key.enabled) > 0)) {
22847f5a08c7SBeau Belgrave struct tracepoint_func *probe_func_ptr;
22857f5a08c7SBeau Belgrave user_event_func_t probe_func;
22860279400aSBeau Belgrave struct iov_iter copy;
22877f5a08c7SBeau Belgrave void *tpdata;
22882467cda1SBeau Belgrave bool faulted;
22897f5a08c7SBeau Belgrave
22900279400aSBeau Belgrave if (unlikely(fault_in_iov_iter_readable(i, i->count)))
22910279400aSBeau Belgrave return -EFAULT;
22927f5a08c7SBeau Belgrave
22932467cda1SBeau Belgrave faulted = false;
22942467cda1SBeau Belgrave
22957f5a08c7SBeau Belgrave rcu_read_lock_sched();
22967f5a08c7SBeau Belgrave
22977f5a08c7SBeau Belgrave probe_func_ptr = rcu_dereference_sched(tp->funcs);
22987f5a08c7SBeau Belgrave
22997f5a08c7SBeau Belgrave if (probe_func_ptr) {
23007f5a08c7SBeau Belgrave do {
23010279400aSBeau Belgrave copy = *i;
23027f5a08c7SBeau Belgrave probe_func = probe_func_ptr->func;
23037f5a08c7SBeau Belgrave tpdata = probe_func_ptr->data;
23042467cda1SBeau Belgrave probe_func(user, ©, tpdata, &faulted);
23057f5a08c7SBeau Belgrave } while ((++probe_func_ptr)->func);
23067f5a08c7SBeau Belgrave }
23077f5a08c7SBeau Belgrave
23087f5a08c7SBeau Belgrave rcu_read_unlock_sched();
23092467cda1SBeau Belgrave
23102467cda1SBeau Belgrave if (unlikely(faulted))
23112467cda1SBeau Belgrave return -EFAULT;
2312f6d026eeSsunliming } else
2313f6d026eeSsunliming return -EBADF;
23147f5a08c7SBeau Belgrave
23157f5a08c7SBeau Belgrave return ret;
23167f5a08c7SBeau Belgrave }
23177f5a08c7SBeau Belgrave
user_events_open(struct inode * node,struct file * file)2318e5d27181SBeau Belgrave static int user_events_open(struct inode *node, struct file *file)
2319e5d27181SBeau Belgrave {
2320e5d27181SBeau Belgrave struct user_event_group *group;
2321e5d27181SBeau Belgrave struct user_event_file_info *info;
2322e5d27181SBeau Belgrave
2323e5d27181SBeau Belgrave group = current_user_event_group();
2324e5d27181SBeau Belgrave
2325e5d27181SBeau Belgrave if (!group)
2326e5d27181SBeau Belgrave return -ENOENT;
2327e5d27181SBeau Belgrave
2328f9cce238SBeau Belgrave info = kzalloc(sizeof(*info), GFP_KERNEL_ACCOUNT);
2329e5d27181SBeau Belgrave
2330e5d27181SBeau Belgrave if (!info)
2331e5d27181SBeau Belgrave return -ENOMEM;
2332e5d27181SBeau Belgrave
2333e5d27181SBeau Belgrave info->group = group;
2334e5d27181SBeau Belgrave
2335e5d27181SBeau Belgrave file->private_data = info;
2336e5d27181SBeau Belgrave
2337e5d27181SBeau Belgrave return 0;
2338e5d27181SBeau Belgrave }
2339e5d27181SBeau Belgrave
user_events_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)23407f5a08c7SBeau Belgrave static ssize_t user_events_write(struct file *file, const char __user *ubuf,
23417f5a08c7SBeau Belgrave size_t count, loff_t *ppos)
23427f5a08c7SBeau Belgrave {
23437f5a08c7SBeau Belgrave struct iov_iter i;
23447f5a08c7SBeau Belgrave
23457f5a08c7SBeau Belgrave if (unlikely(*ppos != 0))
23467f5a08c7SBeau Belgrave return -EFAULT;
23477f5a08c7SBeau Belgrave
23489fd7874cSJens Axboe if (unlikely(import_ubuf(ITER_SOURCE, (char __user *)ubuf, count, &i)))
23497f5a08c7SBeau Belgrave return -EFAULT;
23507f5a08c7SBeau Belgrave
23517f5a08c7SBeau Belgrave return user_events_write_core(file, &i);
23527f5a08c7SBeau Belgrave }
23537f5a08c7SBeau Belgrave
user_events_write_iter(struct kiocb * kp,struct iov_iter * i)23547f5a08c7SBeau Belgrave static ssize_t user_events_write_iter(struct kiocb *kp, struct iov_iter *i)
23557f5a08c7SBeau Belgrave {
23567f5a08c7SBeau Belgrave return user_events_write_core(kp->ki_filp, i);
23577f5a08c7SBeau Belgrave }
23587f5a08c7SBeau Belgrave
user_events_ref_add(struct user_event_file_info * info,struct user_event * user)2359e5d27181SBeau Belgrave static int user_events_ref_add(struct user_event_file_info *info,
2360e5d27181SBeau Belgrave struct user_event *user)
23617f5a08c7SBeau Belgrave {
2362e5d27181SBeau Belgrave struct user_event_group *group = info->group;
23637f5a08c7SBeau Belgrave struct user_event_refs *refs, *new_refs;
23647f5a08c7SBeau Belgrave int i, size, count = 0;
23657f5a08c7SBeau Belgrave
2366e5d27181SBeau Belgrave refs = rcu_dereference_protected(info->refs,
2367e5d27181SBeau Belgrave lockdep_is_held(&group->reg_mutex));
23687f5a08c7SBeau Belgrave
23697f5a08c7SBeau Belgrave if (refs) {
23707f5a08c7SBeau Belgrave count = refs->count;
23717f5a08c7SBeau Belgrave
23727f5a08c7SBeau Belgrave for (i = 0; i < count; ++i)
23737f5a08c7SBeau Belgrave if (refs->events[i] == user)
23747f5a08c7SBeau Belgrave return i;
23757f5a08c7SBeau Belgrave }
23767f5a08c7SBeau Belgrave
23777f5a08c7SBeau Belgrave size = struct_size(refs, events, count + 1);
23787f5a08c7SBeau Belgrave
2379f9cce238SBeau Belgrave new_refs = kzalloc(size, GFP_KERNEL_ACCOUNT);
23807f5a08c7SBeau Belgrave
23817f5a08c7SBeau Belgrave if (!new_refs)
23827f5a08c7SBeau Belgrave return -ENOMEM;
23837f5a08c7SBeau Belgrave
23847f5a08c7SBeau Belgrave new_refs->count = count + 1;
23857f5a08c7SBeau Belgrave
23867f5a08c7SBeau Belgrave for (i = 0; i < count; ++i)
23877f5a08c7SBeau Belgrave new_refs->events[i] = refs->events[i];
23887f5a08c7SBeau Belgrave
2389f0dbf6fdSBeau Belgrave new_refs->events[i] = user_event_get(user);
23907f5a08c7SBeau Belgrave
2391e5d27181SBeau Belgrave rcu_assign_pointer(info->refs, new_refs);
23927f5a08c7SBeau Belgrave
23937f5a08c7SBeau Belgrave if (refs)
23947f5a08c7SBeau Belgrave kfree_rcu(refs, rcu);
23957f5a08c7SBeau Belgrave
23967f5a08c7SBeau Belgrave return i;
23977f5a08c7SBeau Belgrave }
23987f5a08c7SBeau Belgrave
user_reg_get(struct user_reg __user * ureg,struct user_reg * kreg)23997f5a08c7SBeau Belgrave static long user_reg_get(struct user_reg __user *ureg, struct user_reg *kreg)
24007f5a08c7SBeau Belgrave {
24017f5a08c7SBeau Belgrave u32 size;
24027f5a08c7SBeau Belgrave long ret;
24037f5a08c7SBeau Belgrave
24047f5a08c7SBeau Belgrave ret = get_user(size, &ureg->size);
24057f5a08c7SBeau Belgrave
24067f5a08c7SBeau Belgrave if (ret)
24077f5a08c7SBeau Belgrave return ret;
24087f5a08c7SBeau Belgrave
24097f5a08c7SBeau Belgrave if (size > PAGE_SIZE)
24107f5a08c7SBeau Belgrave return -E2BIG;
24117f5a08c7SBeau Belgrave
241239d6d08bSBeau Belgrave if (size < offsetofend(struct user_reg, write_index))
241339d6d08bSBeau Belgrave return -EINVAL;
241439d6d08bSBeau Belgrave
241539d6d08bSBeau Belgrave ret = copy_struct_from_user(kreg, sizeof(*kreg), ureg, size);
241639d6d08bSBeau Belgrave
241739d6d08bSBeau Belgrave if (ret)
241839d6d08bSBeau Belgrave return ret;
241939d6d08bSBeau Belgrave
2420a65442edSBeau Belgrave /* Ensure only valid flags */
2421a65442edSBeau Belgrave if (kreg->flags & ~(USER_EVENT_REG_MAX-1))
242272357590SBeau Belgrave return -EINVAL;
242372357590SBeau Belgrave
242472357590SBeau Belgrave /* Ensure supported size */
242572357590SBeau Belgrave switch (kreg->enable_size) {
242672357590SBeau Belgrave case 4:
242772357590SBeau Belgrave /* 32-bit */
242872357590SBeau Belgrave break;
242972357590SBeau Belgrave #if BITS_PER_LONG >= 64
243072357590SBeau Belgrave case 8:
243172357590SBeau Belgrave /* 64-bit */
243272357590SBeau Belgrave break;
243372357590SBeau Belgrave #endif
243472357590SBeau Belgrave default:
243572357590SBeau Belgrave return -EINVAL;
243672357590SBeau Belgrave }
243772357590SBeau Belgrave
243872357590SBeau Belgrave /* Ensure natural alignment */
243972357590SBeau Belgrave if (kreg->enable_addr % kreg->enable_size)
244072357590SBeau Belgrave return -EINVAL;
244172357590SBeau Belgrave
244272357590SBeau Belgrave /* Ensure bit range for size */
244372357590SBeau Belgrave if (kreg->enable_bit > (kreg->enable_size * BITS_PER_BYTE) - 1)
244472357590SBeau Belgrave return -EINVAL;
244572357590SBeau Belgrave
244672357590SBeau Belgrave /* Ensure accessible */
244772357590SBeau Belgrave if (!access_ok((const void __user *)(uintptr_t)kreg->enable_addr,
244872357590SBeau Belgrave kreg->enable_size))
244972357590SBeau Belgrave return -EFAULT;
245072357590SBeau Belgrave
245139d6d08bSBeau Belgrave kreg->size = size;
245239d6d08bSBeau Belgrave
245339d6d08bSBeau Belgrave return 0;
24547f5a08c7SBeau Belgrave }
24557f5a08c7SBeau Belgrave
24567f5a08c7SBeau Belgrave /*
24577f5a08c7SBeau Belgrave * Registers a user_event on behalf of a user process.
24587f5a08c7SBeau Belgrave */
user_events_ioctl_reg(struct user_event_file_info * info,unsigned long uarg)2459e5d27181SBeau Belgrave static long user_events_ioctl_reg(struct user_event_file_info *info,
2460e5d27181SBeau Belgrave unsigned long uarg)
24617f5a08c7SBeau Belgrave {
24627f5a08c7SBeau Belgrave struct user_reg __user *ureg = (struct user_reg __user *)uarg;
24637f5a08c7SBeau Belgrave struct user_reg reg;
24647f5a08c7SBeau Belgrave struct user_event *user;
246572357590SBeau Belgrave struct user_event_enabler *enabler;
24667f5a08c7SBeau Belgrave char *name;
24677f5a08c7SBeau Belgrave long ret;
246872357590SBeau Belgrave int write_result;
24697f5a08c7SBeau Belgrave
24707f5a08c7SBeau Belgrave ret = user_reg_get(ureg, ®);
24717f5a08c7SBeau Belgrave
24727f5a08c7SBeau Belgrave if (ret)
24737f5a08c7SBeau Belgrave return ret;
24747f5a08c7SBeau Belgrave
247597bbce89SBeau Belgrave /*
247697bbce89SBeau Belgrave * Prevent users from using the same address and bit multiple times
247797bbce89SBeau Belgrave * within the same mm address space. This can cause unexpected behavior
247897bbce89SBeau Belgrave * for user processes that is far easier to debug if this is explictly
247997bbce89SBeau Belgrave * an error upon registering.
248097bbce89SBeau Belgrave */
248197bbce89SBeau Belgrave if (current_user_event_enabler_exists((unsigned long)reg.enable_addr,
248297bbce89SBeau Belgrave reg.enable_bit))
248397bbce89SBeau Belgrave return -EADDRINUSE;
248497bbce89SBeau Belgrave
24857f5a08c7SBeau Belgrave name = strndup_user((const char __user *)(uintptr_t)reg.name_args,
24867f5a08c7SBeau Belgrave MAX_EVENT_DESC);
24877f5a08c7SBeau Belgrave
24887f5a08c7SBeau Belgrave if (IS_ERR(name)) {
24897f5a08c7SBeau Belgrave ret = PTR_ERR(name);
24907f5a08c7SBeau Belgrave return ret;
24917f5a08c7SBeau Belgrave }
24927f5a08c7SBeau Belgrave
2493b08d7258SBeau Belgrave ret = user_event_parse_cmd(info->group, name, &user, reg.flags);
24947f5a08c7SBeau Belgrave
24957f5a08c7SBeau Belgrave if (ret) {
24967f5a08c7SBeau Belgrave kfree(name);
24977f5a08c7SBeau Belgrave return ret;
24987f5a08c7SBeau Belgrave }
24997f5a08c7SBeau Belgrave
2500e5d27181SBeau Belgrave ret = user_events_ref_add(info, user);
25017f5a08c7SBeau Belgrave
25027e348b32SBeau Belgrave /* No longer need parse ref, ref_add either worked or not */
2503f0dbf6fdSBeau Belgrave user_event_put(user, false);
25047e348b32SBeau Belgrave
25057f5a08c7SBeau Belgrave /* Positive number is index and valid */
25067f5a08c7SBeau Belgrave if (ret < 0)
25077f5a08c7SBeau Belgrave return ret;
25087f5a08c7SBeau Belgrave
250972357590SBeau Belgrave /*
251072357590SBeau Belgrave * user_events_ref_add succeeded:
251172357590SBeau Belgrave * At this point we have a user_event, it's lifetime is bound by the
251272357590SBeau Belgrave * reference count, not this file. If anything fails, the user_event
251372357590SBeau Belgrave * still has a reference until the file is released. During release
251472357590SBeau Belgrave * any remaining references (from user_events_ref_add) are decremented.
251572357590SBeau Belgrave *
251672357590SBeau Belgrave * Attempt to create an enabler, which too has a lifetime tied in the
251772357590SBeau Belgrave * same way for the event. Once the task that caused the enabler to be
251872357590SBeau Belgrave * created exits or issues exec() then the enablers it has created
251972357590SBeau Belgrave * will be destroyed and the ref to the event will be decremented.
252072357590SBeau Belgrave */
252172357590SBeau Belgrave enabler = user_event_enabler_create(®, user, &write_result);
252272357590SBeau Belgrave
252372357590SBeau Belgrave if (!enabler)
252472357590SBeau Belgrave return -ENOMEM;
252572357590SBeau Belgrave
252672357590SBeau Belgrave /* Write failed/faulted, give error back to caller */
252772357590SBeau Belgrave if (write_result)
252872357590SBeau Belgrave return write_result;
252972357590SBeau Belgrave
25307f5a08c7SBeau Belgrave put_user((u32)ret, &ureg->write_index);
25317f5a08c7SBeau Belgrave
25327f5a08c7SBeau Belgrave return 0;
25337f5a08c7SBeau Belgrave }
25347f5a08c7SBeau Belgrave
25357f5a08c7SBeau Belgrave /*
25367f5a08c7SBeau Belgrave * Deletes a user_event on behalf of a user process.
25377f5a08c7SBeau Belgrave */
user_events_ioctl_del(struct user_event_file_info * info,unsigned long uarg)2538e5d27181SBeau Belgrave static long user_events_ioctl_del(struct user_event_file_info *info,
2539e5d27181SBeau Belgrave unsigned long uarg)
25407f5a08c7SBeau Belgrave {
25417f5a08c7SBeau Belgrave void __user *ubuf = (void __user *)uarg;
25427f5a08c7SBeau Belgrave char *name;
25437f5a08c7SBeau Belgrave long ret;
25447f5a08c7SBeau Belgrave
25457f5a08c7SBeau Belgrave name = strndup_user(ubuf, MAX_EVENT_DESC);
25467f5a08c7SBeau Belgrave
25477f5a08c7SBeau Belgrave if (IS_ERR(name))
25487f5a08c7SBeau Belgrave return PTR_ERR(name);
25497f5a08c7SBeau Belgrave
25507e348b32SBeau Belgrave /* event_mutex prevents dyn_event from racing */
25517e348b32SBeau Belgrave mutex_lock(&event_mutex);
2552e5d27181SBeau Belgrave ret = delete_user_event(info->group, name);
25537e348b32SBeau Belgrave mutex_unlock(&event_mutex);
25547f5a08c7SBeau Belgrave
25557f5a08c7SBeau Belgrave kfree(name);
25567f5a08c7SBeau Belgrave
25577f5a08c7SBeau Belgrave return ret;
25587f5a08c7SBeau Belgrave }
25597f5a08c7SBeau Belgrave
user_unreg_get(struct user_unreg __user * ureg,struct user_unreg * kreg)2560dcb8177cSBeau Belgrave static long user_unreg_get(struct user_unreg __user *ureg,
2561dcb8177cSBeau Belgrave struct user_unreg *kreg)
2562dcb8177cSBeau Belgrave {
2563dcb8177cSBeau Belgrave u32 size;
2564dcb8177cSBeau Belgrave long ret;
2565dcb8177cSBeau Belgrave
2566dcb8177cSBeau Belgrave ret = get_user(size, &ureg->size);
2567dcb8177cSBeau Belgrave
2568dcb8177cSBeau Belgrave if (ret)
2569dcb8177cSBeau Belgrave return ret;
2570dcb8177cSBeau Belgrave
2571dcb8177cSBeau Belgrave if (size > PAGE_SIZE)
2572dcb8177cSBeau Belgrave return -E2BIG;
2573dcb8177cSBeau Belgrave
2574dcb8177cSBeau Belgrave if (size < offsetofend(struct user_unreg, disable_addr))
2575dcb8177cSBeau Belgrave return -EINVAL;
2576dcb8177cSBeau Belgrave
2577dcb8177cSBeau Belgrave ret = copy_struct_from_user(kreg, sizeof(*kreg), ureg, size);
2578dcb8177cSBeau Belgrave
2579dcb8177cSBeau Belgrave /* Ensure no reserved values, since we don't support any yet */
2580dcb8177cSBeau Belgrave if (kreg->__reserved || kreg->__reserved2)
2581dcb8177cSBeau Belgrave return -EINVAL;
2582dcb8177cSBeau Belgrave
2583dcb8177cSBeau Belgrave return ret;
2584dcb8177cSBeau Belgrave }
2585dcb8177cSBeau Belgrave
user_event_mm_clear_bit(struct user_event_mm * user_mm,unsigned long uaddr,unsigned char bit,unsigned long flags)258617b439dbSBeau Belgrave static int user_event_mm_clear_bit(struct user_event_mm *user_mm,
25872de9ee94SBeau Belgrave unsigned long uaddr, unsigned char bit,
25882de9ee94SBeau Belgrave unsigned long flags)
258917b439dbSBeau Belgrave {
259017b439dbSBeau Belgrave struct user_event_enabler enabler;
259117b439dbSBeau Belgrave int result;
259241d8fba1SBeau Belgrave int attempt = 0;
259317b439dbSBeau Belgrave
259417b439dbSBeau Belgrave memset(&enabler, 0, sizeof(enabler));
259517b439dbSBeau Belgrave enabler.addr = uaddr;
25962de9ee94SBeau Belgrave enabler.values = bit | flags;
259717b439dbSBeau Belgrave retry:
259817b439dbSBeau Belgrave /* Prevents state changes from racing with new enablers */
259917b439dbSBeau Belgrave mutex_lock(&event_mutex);
260017b439dbSBeau Belgrave
260117b439dbSBeau Belgrave /* Force the bit to be cleared, since no event is attached */
260217b439dbSBeau Belgrave mmap_read_lock(user_mm->mm);
260341d8fba1SBeau Belgrave result = user_event_enabler_write(user_mm, &enabler, false, &attempt);
260417b439dbSBeau Belgrave mmap_read_unlock(user_mm->mm);
260517b439dbSBeau Belgrave
260617b439dbSBeau Belgrave mutex_unlock(&event_mutex);
260717b439dbSBeau Belgrave
260817b439dbSBeau Belgrave if (result) {
260917b439dbSBeau Belgrave /* Attempt to fault-in and retry if it worked */
261041d8fba1SBeau Belgrave if (!user_event_mm_fault_in(user_mm, uaddr, attempt))
261117b439dbSBeau Belgrave goto retry;
261217b439dbSBeau Belgrave }
261317b439dbSBeau Belgrave
261417b439dbSBeau Belgrave return result;
261517b439dbSBeau Belgrave }
261617b439dbSBeau Belgrave
2617dcb8177cSBeau Belgrave /*
2618dcb8177cSBeau Belgrave * Unregisters an enablement address/bit within a task/user mm.
2619dcb8177cSBeau Belgrave */
user_events_ioctl_unreg(unsigned long uarg)2620dcb8177cSBeau Belgrave static long user_events_ioctl_unreg(unsigned long uarg)
2621dcb8177cSBeau Belgrave {
2622dcb8177cSBeau Belgrave struct user_unreg __user *ureg = (struct user_unreg __user *)uarg;
2623dcb8177cSBeau Belgrave struct user_event_mm *mm = current->user_event_mm;
2624dcb8177cSBeau Belgrave struct user_event_enabler *enabler, *next;
2625dcb8177cSBeau Belgrave struct user_unreg reg;
26262de9ee94SBeau Belgrave unsigned long flags;
2627dcb8177cSBeau Belgrave long ret;
2628dcb8177cSBeau Belgrave
2629dcb8177cSBeau Belgrave ret = user_unreg_get(ureg, ®);
2630dcb8177cSBeau Belgrave
2631dcb8177cSBeau Belgrave if (ret)
2632dcb8177cSBeau Belgrave return ret;
2633dcb8177cSBeau Belgrave
2634dcb8177cSBeau Belgrave if (!mm)
2635dcb8177cSBeau Belgrave return -ENOENT;
2636dcb8177cSBeau Belgrave
26372de9ee94SBeau Belgrave flags = 0;
2638dcb8177cSBeau Belgrave ret = -ENOENT;
2639dcb8177cSBeau Belgrave
2640dcb8177cSBeau Belgrave /*
2641dcb8177cSBeau Belgrave * Flags freeing and faulting are used to indicate if the enabler is in
2642dcb8177cSBeau Belgrave * use at all. When faulting is set a page-fault is occurring asyncly.
2643dcb8177cSBeau Belgrave * During async fault if freeing is set, the enabler will be destroyed.
2644dcb8177cSBeau Belgrave * If no async fault is happening, we can destroy it now since we hold
2645dcb8177cSBeau Belgrave * the event_mutex during these checks.
2646dcb8177cSBeau Belgrave */
2647dcb8177cSBeau Belgrave mutex_lock(&event_mutex);
2648dcb8177cSBeau Belgrave
2649dcbd1ac2SBeau Belgrave list_for_each_entry_safe(enabler, next, &mm->enablers, mm_enablers_link) {
2650dcb8177cSBeau Belgrave if (enabler->addr == reg.disable_addr &&
2651ee7751b5SBeau Belgrave ENABLE_BIT(enabler) == reg.disable_bit) {
2652dcb8177cSBeau Belgrave set_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler));
2653dcb8177cSBeau Belgrave
26542de9ee94SBeau Belgrave /* We must keep compat flags for the clear */
26552de9ee94SBeau Belgrave flags |= enabler->values & ENABLE_VAL_COMPAT_MASK;
26562de9ee94SBeau Belgrave
2657dcb8177cSBeau Belgrave if (!test_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler)))
2658f0dbf6fdSBeau Belgrave user_event_enabler_destroy(enabler, true);
2659dcb8177cSBeau Belgrave
2660dcb8177cSBeau Belgrave /* Removed at least one */
2661dcb8177cSBeau Belgrave ret = 0;
2662dcb8177cSBeau Belgrave }
2663dcbd1ac2SBeau Belgrave }
2664dcb8177cSBeau Belgrave
2665dcb8177cSBeau Belgrave mutex_unlock(&event_mutex);
2666dcb8177cSBeau Belgrave
266717b439dbSBeau Belgrave /* Ensure bit is now cleared for user, regardless of event status */
266817b439dbSBeau Belgrave if (!ret)
266917b439dbSBeau Belgrave ret = user_event_mm_clear_bit(mm, reg.disable_addr,
26702de9ee94SBeau Belgrave reg.disable_bit, flags);
267117b439dbSBeau Belgrave
2672dcb8177cSBeau Belgrave return ret;
2673dcb8177cSBeau Belgrave }
2674dcb8177cSBeau Belgrave
26757f5a08c7SBeau Belgrave /*
26767f5a08c7SBeau Belgrave * Handles the ioctl from user mode to register or alter operations.
26777f5a08c7SBeau Belgrave */
user_events_ioctl(struct file * file,unsigned int cmd,unsigned long uarg)26787f5a08c7SBeau Belgrave static long user_events_ioctl(struct file *file, unsigned int cmd,
26797f5a08c7SBeau Belgrave unsigned long uarg)
26807f5a08c7SBeau Belgrave {
2681e5d27181SBeau Belgrave struct user_event_file_info *info = file->private_data;
2682e5d27181SBeau Belgrave struct user_event_group *group = info->group;
26837f5a08c7SBeau Belgrave long ret = -ENOTTY;
26847f5a08c7SBeau Belgrave
26857f5a08c7SBeau Belgrave switch (cmd) {
26867f5a08c7SBeau Belgrave case DIAG_IOCSREG:
2687e5d27181SBeau Belgrave mutex_lock(&group->reg_mutex);
2688e5d27181SBeau Belgrave ret = user_events_ioctl_reg(info, uarg);
2689e5d27181SBeau Belgrave mutex_unlock(&group->reg_mutex);
26907f5a08c7SBeau Belgrave break;
26917f5a08c7SBeau Belgrave
26927f5a08c7SBeau Belgrave case DIAG_IOCSDEL:
2693e5d27181SBeau Belgrave mutex_lock(&group->reg_mutex);
2694e5d27181SBeau Belgrave ret = user_events_ioctl_del(info, uarg);
2695e5d27181SBeau Belgrave mutex_unlock(&group->reg_mutex);
26967f5a08c7SBeau Belgrave break;
2697dcb8177cSBeau Belgrave
2698dcb8177cSBeau Belgrave case DIAG_IOCSUNREG:
2699dcb8177cSBeau Belgrave mutex_lock(&group->reg_mutex);
2700dcb8177cSBeau Belgrave ret = user_events_ioctl_unreg(uarg);
2701dcb8177cSBeau Belgrave mutex_unlock(&group->reg_mutex);
2702dcb8177cSBeau Belgrave break;
27037f5a08c7SBeau Belgrave }
27047f5a08c7SBeau Belgrave
27057f5a08c7SBeau Belgrave return ret;
27067f5a08c7SBeau Belgrave }
27077f5a08c7SBeau Belgrave
27087f5a08c7SBeau Belgrave /*
27097f5a08c7SBeau Belgrave * Handles the final close of the file from user mode.
27107f5a08c7SBeau Belgrave */
user_events_release(struct inode * node,struct file * file)27117f5a08c7SBeau Belgrave static int user_events_release(struct inode *node, struct file *file)
27127f5a08c7SBeau Belgrave {
2713e5d27181SBeau Belgrave struct user_event_file_info *info = file->private_data;
2714e5d27181SBeau Belgrave struct user_event_group *group;
27157f5a08c7SBeau Belgrave struct user_event_refs *refs;
27167f5a08c7SBeau Belgrave int i;
27177f5a08c7SBeau Belgrave
2718e5d27181SBeau Belgrave if (!info)
2719e5d27181SBeau Belgrave return -EINVAL;
2720e5d27181SBeau Belgrave
2721e5d27181SBeau Belgrave group = info->group;
2722e5d27181SBeau Belgrave
27237f5a08c7SBeau Belgrave /*
27247f5a08c7SBeau Belgrave * Ensure refs cannot change under any situation by taking the
27257f5a08c7SBeau Belgrave * register mutex during the final freeing of the references.
27267f5a08c7SBeau Belgrave */
2727e5d27181SBeau Belgrave mutex_lock(&group->reg_mutex);
27287f5a08c7SBeau Belgrave
2729e5d27181SBeau Belgrave refs = info->refs;
27307f5a08c7SBeau Belgrave
27317f5a08c7SBeau Belgrave if (!refs)
27327f5a08c7SBeau Belgrave goto out;
27337f5a08c7SBeau Belgrave
27347f5a08c7SBeau Belgrave /*
27357f5a08c7SBeau Belgrave * The lifetime of refs has reached an end, it's tied to this file.
27367f5a08c7SBeau Belgrave * The underlying user_events are ref counted, and cannot be freed.
27377f5a08c7SBeau Belgrave * After this decrement, the user_events may be freed elsewhere.
27387f5a08c7SBeau Belgrave */
2739f0dbf6fdSBeau Belgrave for (i = 0; i < refs->count; ++i)
2740f0dbf6fdSBeau Belgrave user_event_put(refs->events[i], false);
27417f5a08c7SBeau Belgrave
27427f5a08c7SBeau Belgrave out:
27437f5a08c7SBeau Belgrave file->private_data = NULL;
27447f5a08c7SBeau Belgrave
2745e5d27181SBeau Belgrave mutex_unlock(&group->reg_mutex);
27467f5a08c7SBeau Belgrave
27477f5a08c7SBeau Belgrave kfree(refs);
2748e5d27181SBeau Belgrave kfree(info);
27497f5a08c7SBeau Belgrave
27507f5a08c7SBeau Belgrave return 0;
27517f5a08c7SBeau Belgrave }
27527f5a08c7SBeau Belgrave
27537f5a08c7SBeau Belgrave static const struct file_operations user_data_fops = {
2754e5d27181SBeau Belgrave .open = user_events_open,
27557f5a08c7SBeau Belgrave .write = user_events_write,
27567f5a08c7SBeau Belgrave .write_iter = user_events_write_iter,
27577f5a08c7SBeau Belgrave .unlocked_ioctl = user_events_ioctl,
27587f5a08c7SBeau Belgrave .release = user_events_release,
27597f5a08c7SBeau Belgrave };
27607f5a08c7SBeau Belgrave
user_seq_start(struct seq_file * m,loff_t * pos)27617f5a08c7SBeau Belgrave static void *user_seq_start(struct seq_file *m, loff_t *pos)
27627f5a08c7SBeau Belgrave {
27637f5a08c7SBeau Belgrave if (*pos)
27647f5a08c7SBeau Belgrave return NULL;
27657f5a08c7SBeau Belgrave
27667f5a08c7SBeau Belgrave return (void *)1;
27677f5a08c7SBeau Belgrave }
27687f5a08c7SBeau Belgrave
user_seq_next(struct seq_file * m,void * p,loff_t * pos)27697f5a08c7SBeau Belgrave static void *user_seq_next(struct seq_file *m, void *p, loff_t *pos)
27707f5a08c7SBeau Belgrave {
27717f5a08c7SBeau Belgrave ++*pos;
27727f5a08c7SBeau Belgrave return NULL;
27737f5a08c7SBeau Belgrave }
27747f5a08c7SBeau Belgrave
user_seq_stop(struct seq_file * m,void * p)27757f5a08c7SBeau Belgrave static void user_seq_stop(struct seq_file *m, void *p)
27767f5a08c7SBeau Belgrave {
27777f5a08c7SBeau Belgrave }
27787f5a08c7SBeau Belgrave
user_seq_show(struct seq_file * m,void * p)27797f5a08c7SBeau Belgrave static int user_seq_show(struct seq_file *m, void *p)
27807f5a08c7SBeau Belgrave {
2781e5d27181SBeau Belgrave struct user_event_group *group = m->private;
27827f5a08c7SBeau Belgrave struct user_event *user;
27837f5a08c7SBeau Belgrave char status;
278472357590SBeau Belgrave int i, active = 0, busy = 0;
27857f5a08c7SBeau Belgrave
2786e5d27181SBeau Belgrave if (!group)
2787e5d27181SBeau Belgrave return -EINVAL;
27887f5a08c7SBeau Belgrave
2789e5d27181SBeau Belgrave mutex_lock(&group->reg_mutex);
2790e5d27181SBeau Belgrave
2791e5d27181SBeau Belgrave hash_for_each(group->register_table, i, user, node) {
279239d6d08bSBeau Belgrave status = user->status;
27937f5a08c7SBeau Belgrave
279464805e40SBeau Belgrave seq_printf(m, "%s", EVENT_TP_NAME(user));
27957f5a08c7SBeau Belgrave
279672357590SBeau Belgrave if (status != 0)
27977f5a08c7SBeau Belgrave seq_puts(m, " #");
27987f5a08c7SBeau Belgrave
27997f5a08c7SBeau Belgrave if (status != 0) {
28007f5a08c7SBeau Belgrave seq_puts(m, " Used by");
28017f5a08c7SBeau Belgrave if (status & EVENT_STATUS_FTRACE)
28027f5a08c7SBeau Belgrave seq_puts(m, " ftrace");
28037f5a08c7SBeau Belgrave if (status & EVENT_STATUS_PERF)
28047f5a08c7SBeau Belgrave seq_puts(m, " perf");
28057f5a08c7SBeau Belgrave if (status & EVENT_STATUS_OTHER)
28067f5a08c7SBeau Belgrave seq_puts(m, " other");
28077f5a08c7SBeau Belgrave busy++;
28087f5a08c7SBeau Belgrave }
28097f5a08c7SBeau Belgrave
28107f5a08c7SBeau Belgrave seq_puts(m, "\n");
28117f5a08c7SBeau Belgrave active++;
28127f5a08c7SBeau Belgrave }
28137f5a08c7SBeau Belgrave
2814e5d27181SBeau Belgrave mutex_unlock(&group->reg_mutex);
28157f5a08c7SBeau Belgrave
28167f5a08c7SBeau Belgrave seq_puts(m, "\n");
28177f5a08c7SBeau Belgrave seq_printf(m, "Active: %d\n", active);
28187f5a08c7SBeau Belgrave seq_printf(m, "Busy: %d\n", busy);
28197f5a08c7SBeau Belgrave
28207f5a08c7SBeau Belgrave return 0;
28217f5a08c7SBeau Belgrave }
28227f5a08c7SBeau Belgrave
28237f5a08c7SBeau Belgrave static const struct seq_operations user_seq_ops = {
28247f5a08c7SBeau Belgrave .start = user_seq_start,
28257f5a08c7SBeau Belgrave .next = user_seq_next,
28267f5a08c7SBeau Belgrave .stop = user_seq_stop,
28277f5a08c7SBeau Belgrave .show = user_seq_show,
28287f5a08c7SBeau Belgrave };
28297f5a08c7SBeau Belgrave
user_status_open(struct inode * node,struct file * file)28307f5a08c7SBeau Belgrave static int user_status_open(struct inode *node, struct file *file)
28317f5a08c7SBeau Belgrave {
2832e5d27181SBeau Belgrave struct user_event_group *group;
2833e5d27181SBeau Belgrave int ret;
2834e5d27181SBeau Belgrave
2835e5d27181SBeau Belgrave group = current_user_event_group();
2836e5d27181SBeau Belgrave
2837e5d27181SBeau Belgrave if (!group)
2838e5d27181SBeau Belgrave return -ENOENT;
2839e5d27181SBeau Belgrave
2840e5d27181SBeau Belgrave ret = seq_open(file, &user_seq_ops);
2841e5d27181SBeau Belgrave
2842e5d27181SBeau Belgrave if (!ret) {
2843e5d27181SBeau Belgrave /* Chain group to seq_file */
2844e5d27181SBeau Belgrave struct seq_file *m = file->private_data;
2845e5d27181SBeau Belgrave
2846e5d27181SBeau Belgrave m->private = group;
2847e5d27181SBeau Belgrave }
2848e5d27181SBeau Belgrave
2849e5d27181SBeau Belgrave return ret;
28507f5a08c7SBeau Belgrave }
28517f5a08c7SBeau Belgrave
28527f5a08c7SBeau Belgrave static const struct file_operations user_status_fops = {
28537f5a08c7SBeau Belgrave .open = user_status_open,
28547f5a08c7SBeau Belgrave .read = seq_read,
28557f5a08c7SBeau Belgrave .llseek = seq_lseek,
28567f5a08c7SBeau Belgrave .release = seq_release,
28577f5a08c7SBeau Belgrave };
28587f5a08c7SBeau Belgrave
28597f5a08c7SBeau Belgrave /*
28607f5a08c7SBeau Belgrave * Creates a set of tracefs files to allow user mode interactions.
28617f5a08c7SBeau Belgrave */
create_user_tracefs(void)28627f5a08c7SBeau Belgrave static int create_user_tracefs(void)
28637f5a08c7SBeau Belgrave {
28647f5a08c7SBeau Belgrave struct dentry *edata, *emmap;
28657f5a08c7SBeau Belgrave
28667f5a08c7SBeau Belgrave edata = tracefs_create_file("user_events_data", TRACE_MODE_WRITE,
28677f5a08c7SBeau Belgrave NULL, NULL, &user_data_fops);
28687f5a08c7SBeau Belgrave
28697f5a08c7SBeau Belgrave if (!edata) {
28707f5a08c7SBeau Belgrave pr_warn("Could not create tracefs 'user_events_data' entry\n");
28717f5a08c7SBeau Belgrave goto err;
28727f5a08c7SBeau Belgrave }
28737f5a08c7SBeau Belgrave
287472357590SBeau Belgrave emmap = tracefs_create_file("user_events_status", TRACE_MODE_READ,
28757f5a08c7SBeau Belgrave NULL, NULL, &user_status_fops);
28767f5a08c7SBeau Belgrave
28777f5a08c7SBeau Belgrave if (!emmap) {
28787f5a08c7SBeau Belgrave tracefs_remove(edata);
28797f5a08c7SBeau Belgrave pr_warn("Could not create tracefs 'user_events_mmap' entry\n");
28807f5a08c7SBeau Belgrave goto err;
28817f5a08c7SBeau Belgrave }
28827f5a08c7SBeau Belgrave
28837f5a08c7SBeau Belgrave return 0;
28847f5a08c7SBeau Belgrave err:
28857f5a08c7SBeau Belgrave return -ENODEV;
28867f5a08c7SBeau Belgrave }
28877f5a08c7SBeau Belgrave
set_max_user_events_sysctl(const struct ctl_table * table,int write,void * buffer,size_t * lenp,loff_t * ppos)2888*78eb4ea2SJoel Granados static int set_max_user_events_sysctl(const struct ctl_table *table, int write,
2889ce58e96eSBeau Belgrave void *buffer, size_t *lenp, loff_t *ppos)
2890ce58e96eSBeau Belgrave {
2891ce58e96eSBeau Belgrave int ret;
2892ce58e96eSBeau Belgrave
2893ce58e96eSBeau Belgrave mutex_lock(&event_mutex);
2894ce58e96eSBeau Belgrave
2895ce58e96eSBeau Belgrave ret = proc_douintvec(table, write, buffer, lenp, ppos);
2896ce58e96eSBeau Belgrave
2897ce58e96eSBeau Belgrave mutex_unlock(&event_mutex);
2898ce58e96eSBeau Belgrave
2899ce58e96eSBeau Belgrave return ret;
2900ce58e96eSBeau Belgrave }
2901ce58e96eSBeau Belgrave
2902ce58e96eSBeau Belgrave static struct ctl_table user_event_sysctls[] = {
2903ce58e96eSBeau Belgrave {
2904ce58e96eSBeau Belgrave .procname = "user_events_max",
2905ce58e96eSBeau Belgrave .data = &max_user_events,
2906ce58e96eSBeau Belgrave .maxlen = sizeof(unsigned int),
2907ce58e96eSBeau Belgrave .mode = 0644,
2908ce58e96eSBeau Belgrave .proc_handler = set_max_user_events_sysctl,
2909ce58e96eSBeau Belgrave },
2910ce58e96eSBeau Belgrave };
2911ce58e96eSBeau Belgrave
trace_events_user_init(void)29127f5a08c7SBeau Belgrave static int __init trace_events_user_init(void)
29137f5a08c7SBeau Belgrave {
29147f5a08c7SBeau Belgrave int ret;
29157f5a08c7SBeau Belgrave
291681f8fb65SBeau Belgrave fault_cache = KMEM_CACHE(user_event_enabler_fault, 0);
291781f8fb65SBeau Belgrave
291881f8fb65SBeau Belgrave if (!fault_cache)
291981f8fb65SBeau Belgrave return -ENOMEM;
292081f8fb65SBeau Belgrave
2921ed0e0ae0SBeau Belgrave init_group = user_event_group_create();
29227f5a08c7SBeau Belgrave
292381f8fb65SBeau Belgrave if (!init_group) {
292481f8fb65SBeau Belgrave kmem_cache_destroy(fault_cache);
29257f5a08c7SBeau Belgrave return -ENOMEM;
292681f8fb65SBeau Belgrave }
29277f5a08c7SBeau Belgrave
29287f5a08c7SBeau Belgrave ret = create_user_tracefs();
29297f5a08c7SBeau Belgrave
29307f5a08c7SBeau Belgrave if (ret) {
29317f5a08c7SBeau Belgrave pr_warn("user_events could not register with tracefs\n");
2932e5d27181SBeau Belgrave user_event_group_destroy(init_group);
293381f8fb65SBeau Belgrave kmem_cache_destroy(fault_cache);
2934e5d27181SBeau Belgrave init_group = NULL;
29357f5a08c7SBeau Belgrave return ret;
29367f5a08c7SBeau Belgrave }
29377f5a08c7SBeau Belgrave
29387f5a08c7SBeau Belgrave if (dyn_event_register(&user_event_dops))
29397f5a08c7SBeau Belgrave pr_warn("user_events could not register with dyn_events\n");
29407f5a08c7SBeau Belgrave
2941ce58e96eSBeau Belgrave register_sysctl_init("kernel", user_event_sysctls);
2942ce58e96eSBeau Belgrave
29437f5a08c7SBeau Belgrave return 0;
29447f5a08c7SBeau Belgrave }
29457f5a08c7SBeau Belgrave
29467f5a08c7SBeau Belgrave fs_initcall(trace_events_user_init);
2947