Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
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  * Request a notification when the current cpu returns to userspace.  Must be
0012  * called in atomic context.  The notifier will also be called in atomic
0013  * context.
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  * Removes a registered user return notifier.  Must be called from atomic
0024  * context, and from the same cpu registration occurred in.
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 /* Calls registered user return notifiers */
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 }