|
@@ -24,6 +24,7 @@
|
|
|
#include <linux/tracepoint.h>
|
|
|
#include <linux/err.h>
|
|
|
#include <linux/slab.h>
|
|
|
+#include <linux/sched.h>
|
|
|
|
|
|
extern struct tracepoint __start___tracepoints[];
|
|
|
extern struct tracepoint __stop___tracepoints[];
|
|
@@ -577,3 +578,40 @@ static int init_tracepoints(void)
|
|
|
__initcall(init_tracepoints);
|
|
|
|
|
|
#endif /* CONFIG_MODULES */
|
|
|
+
|
|
|
+static DEFINE_MUTEX(regfunc_mutex);
|
|
|
+static int sys_tracepoint_refcount;
|
|
|
+
|
|
|
+void syscall_regfunc(void)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+ struct task_struct *g, *t;
|
|
|
+
|
|
|
+ mutex_lock(®func_mutex);
|
|
|
+ if (!sys_tracepoint_refcount) {
|
|
|
+ read_lock_irqsave(&tasklist_lock, flags);
|
|
|
+ do_each_thread(g, t) {
|
|
|
+ set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
|
|
|
+ } while_each_thread(g, t);
|
|
|
+ read_unlock_irqrestore(&tasklist_lock, flags);
|
|
|
+ }
|
|
|
+ sys_tracepoint_refcount++;
|
|
|
+ mutex_unlock(®func_mutex);
|
|
|
+}
|
|
|
+
|
|
|
+void syscall_unregfunc(void)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+ struct task_struct *g, *t;
|
|
|
+
|
|
|
+ mutex_lock(®func_mutex);
|
|
|
+ sys_tracepoint_refcount--;
|
|
|
+ if (!sys_tracepoint_refcount) {
|
|
|
+ read_lock_irqsave(&tasklist_lock, flags);
|
|
|
+ do_each_thread(g, t) {
|
|
|
+ clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
|
|
|
+ } while_each_thread(g, t);
|
|
|
+ read_unlock_irqrestore(&tasklist_lock, flags);
|
|
|
+ }
|
|
|
+ mutex_unlock(®func_mutex);
|
|
|
+}
|