0001
0002
0003 #include <linux/user-return-notifier.h>
0004 #include <linux/percpu.h>
0005 #include <linux/sched.h>
0006 #include <linux/export.h>
0007
0008 static DEFINE_PER_CPU(struct hlist_head, return_notifier_list);
0009
0010
0011
0012
0013
0014
0015 void user_return_notifier_register(struct user_return_notifier *urn)
0016 {
0017 set_tsk_thread_flag(current, TIF_USER_RETURN_NOTIFY);
0018 hlist_add_head(&urn->link, this_cpu_ptr(&return_notifier_list));
0019 }
0020 EXPORT_SYMBOL_GPL(user_return_notifier_register);
0021
0022
0023
0024
0025
0026 void user_return_notifier_unregister(struct user_return_notifier *urn)
0027 {
0028 hlist_del(&urn->link);
0029 if (hlist_empty(this_cpu_ptr(&return_notifier_list)))
0030 clear_tsk_thread_flag(current, TIF_USER_RETURN_NOTIFY);
0031 }
0032 EXPORT_SYMBOL_GPL(user_return_notifier_unregister);
0033
0034
0035 void fire_user_return_notifiers(void)
0036 {
0037 struct user_return_notifier *urn;
0038 struct hlist_node *tmp2;
0039 struct hlist_head *head;
0040
0041 head = &get_cpu_var(return_notifier_list);
0042 hlist_for_each_entry_safe(urn, tmp2, head, link)
0043 urn->on_user_return(urn);
0044 put_cpu_var(return_notifier_list);
0045 }