summaryrefslogtreecommitdiff
path: root/include/linux/user_events.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/user_events.h')
-rw-r--r--include/linux/user_events.h53
1 files changed, 52 insertions, 1 deletions
diff --git a/include/linux/user_events.h b/include/linux/user_events.h
index 3d747c45d2fa..0120b3dd5b03 100644
--- a/include/linux/user_events.h
+++ b/include/linux/user_events.h
@@ -9,13 +9,63 @@
#ifndef _LINUX_USER_EVENTS_H
#define _LINUX_USER_EVENTS_H
+#include <linux/list.h>
+#include <linux/refcount.h>
+#include <linux/mm_types.h>
+#include <linux/workqueue.h>
#include <uapi/linux/user_events.h>
#ifdef CONFIG_USER_EVENTS
struct user_event_mm {
+ struct list_head link;
+ struct list_head enablers;
+ struct mm_struct *mm;
+ struct user_event_mm *next;
+ refcount_t refcnt;
+ refcount_t tasks;
+ struct rcu_work put_rwork;
};
-#endif
+extern void user_event_mm_dup(struct task_struct *t,
+ struct user_event_mm *old_mm);
+
+extern void user_event_mm_remove(struct task_struct *t);
+
+static inline void user_events_fork(struct task_struct *t,
+ unsigned long clone_flags)
+{
+ struct user_event_mm *old_mm;
+
+ if (!t || !current->user_event_mm)
+ return;
+
+ old_mm = current->user_event_mm;
+
+ if (clone_flags & CLONE_VM) {
+ t->user_event_mm = old_mm;
+ refcount_inc(&old_mm->tasks);
+ return;
+ }
+
+ user_event_mm_dup(t, old_mm);
+}
+
+static inline void user_events_execve(struct task_struct *t)
+{
+ if (!t || !t->user_event_mm)
+ return;
+
+ user_event_mm_remove(t);
+}
+
+static inline void user_events_exit(struct task_struct *t)
+{
+ if (!t || !t->user_event_mm)
+ return;
+
+ user_event_mm_remove(t);
+}
+#else
static inline void user_events_fork(struct task_struct *t,
unsigned long clone_flags)
{
@@ -28,5 +78,6 @@ static inline void user_events_execve(struct task_struct *t)
static inline void user_events_exit(struct task_struct *t)
{
}
+#endif /* CONFIG_USER_EVENTS */
#endif /* _LINUX_USER_EVENTS_H */