diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
commit | bcd6acd51f3d4d1ada201e9bc5c40a31d6d80c71 (patch) | |
tree | 2f6dffd2d3e4dd67355a224de7e7a960335a92fd /kernel/user-return-notifier.c | |
parent | 11c34c7deaeeebcee342cbc35e1bb2a6711b2431 (diff) | |
parent | 3ff6a468b45b5dfeb0e903e56f4eb27d34b2437c (diff) |
Merge commit 'origin/master' into next
Conflicts:
include/linux/kvm.h
Diffstat (limited to 'kernel/user-return-notifier.c')
-rw-r--r-- | kernel/user-return-notifier.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/kernel/user-return-notifier.c b/kernel/user-return-notifier.c new file mode 100644 index 000000000000..eb27fd3430a2 --- /dev/null +++ b/kernel/user-return-notifier.c | |||
@@ -0,0 +1,44 @@ | |||
1 | |||
2 | #include <linux/user-return-notifier.h> | ||
3 | #include <linux/percpu.h> | ||
4 | #include <linux/sched.h> | ||
5 | #include <linux/module.h> | ||
6 | |||
7 | static DEFINE_PER_CPU(struct hlist_head, return_notifier_list); | ||
8 | |||
9 | /* | ||
10 | * Request a notification when the current cpu returns to userspace. Must be | ||
11 | * called in atomic context. The notifier will also be called in atomic | ||
12 | * context. | ||
13 | */ | ||
14 | void user_return_notifier_register(struct user_return_notifier *urn) | ||
15 | { | ||
16 | set_tsk_thread_flag(current, TIF_USER_RETURN_NOTIFY); | ||
17 | hlist_add_head(&urn->link, &__get_cpu_var(return_notifier_list)); | ||
18 | } | ||
19 | EXPORT_SYMBOL_GPL(user_return_notifier_register); | ||
20 | |||
21 | /* | ||
22 | * Removes a registered user return notifier. Must be called from atomic | ||
23 | * context, and from the same cpu registration occured in. | ||
24 | */ | ||
25 | void user_return_notifier_unregister(struct user_return_notifier *urn) | ||
26 | { | ||
27 | hlist_del(&urn->link); | ||
28 | if (hlist_empty(&__get_cpu_var(return_notifier_list))) | ||
29 | clear_tsk_thread_flag(current, TIF_USER_RETURN_NOTIFY); | ||
30 | } | ||
31 | EXPORT_SYMBOL_GPL(user_return_notifier_unregister); | ||
32 | |||
33 | /* Calls registered user return notifiers */ | ||
34 | void fire_user_return_notifiers(void) | ||
35 | { | ||
36 | struct user_return_notifier *urn; | ||
37 | struct hlist_node *tmp1, *tmp2; | ||
38 | struct hlist_head *head; | ||
39 | |||
40 | head = &get_cpu_var(return_notifier_list); | ||
41 | hlist_for_each_entry_safe(urn, tmp1, tmp2, head, link) | ||
42 | urn->on_user_return(urn); | ||
43 | put_cpu_var(return_notifier_list); | ||
44 | } | ||