core: fix user return notifier on fork()
Subsystems (4)
PATCH 1/1 core: fix user return notifier on fork()
fork() clones all thread_info flags, including TIF_USER_RETURN_NOTIFY; if the new task is first scheduled on a cpu which doesn't have user return notifiers set, this causes user return notifiers to trigger without any way of clearing itself.
This is easy to trigger with a forky workload on the host in parallel with kvm, resulting in a cpu in an endless loop on the verge of returning to userspace.
Fix by dropping the TIF_USER_RETURN_NOTIFY immediately after fork.
--- include/linux/user-return-notifier.h | 7 +++++++ kernel/fork.c | 2 ++ 2 files changed, 9 insertions(+), 0 deletions(-)
include/linux/user-return-notifier.h +7 -0
@@ -26,6 +26,11 @@ static inline void propagate_user_return_notify(struct task_struct *prev,void fire_user_return_notifiers (void ); +static inline void clear_user_return_notifier (struct task_struct *p) +{ +clear_tsk_thread_flag (p,TIF_USER_RETURN_NOTIFY ); +} +#else struct user_return_notifier {};
@@ -37,6 +42,8 @@ static inline void propagate_user_return_notify(struct task_struct *prev,static inline void fire_user_return_notifiers (void ) {} +static inline void clear_user_return_notifier (struct task_struct *p) {} +#endif #endif
kernel/fork.c +2 -0
@@ -64,6 +64,7 @@#include <linux/magic.h> #include <linux/perf_event.h> #include <linux/posix-timers.h> +#include <linux/user-return-notifier.h> #include <asm/pgtable.h> #include <asm/pgalloc.h>
@@ -249,6 +250,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) goto out;setup_thread_stack (tsk, orig); +clear_user_return_notifier (tsk); stackend =end_of_stack (tsk); *stackend =STACK_END_MAGIC ;/* for overflow detection */
Signature · 1 line
1.6.5.2
[tip:x86/entry] core: Fix user return notifier on fork()
Commit-ID: 8e7cac79808b62f242069a6ac88d364d35621371 Gitweb: http://git.kernel.org/tip/8e7cac79808b62f242069a6ac88d364d35621371 Author: Avi Kivity <[email protected]> AuthorDate: Sun, 29 Nov 2009 16:34:48 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 29 Nov 2009 22:03:04 +0100
core: Fix user return notifier on fork()
fork() clones all thread_info flags, including TIF_USER_RETURN_NOTIFY; if the new task is first scheduled on a cpu which doesn't have user return notifiers set, this causes user return notifiers to trigger without any way of clearing itself.
This is easy to trigger with a forky workload on the host in parallel with kvm, resulting in a cpu in an endless loop on the verge of returning to userspace.
Fix by dropping the TIF_USER_RETURN_NOTIFY immediately after fork.
LKML-Reference: <[email protected]>
--- include/linux/user-return-notifier.h | 7 +++++++ kernel/fork.c | 2 ++ 2 files changed, 9 insertions(+), 0 deletions(-)
include/linux/user-return-notifier.h +7 -0
@@ -26,6 +26,11 @@ static inline void propagate_user_return_notify(struct task_struct *prev,void fire_user_return_notifiers (void ); +static inline void clear_user_return_notifier (struct task_struct *p) +{ +clear_tsk_thread_flag (p,TIF_USER_RETURN_NOTIFY ); +} +#else struct user_return_notifier {};
@@ -37,6 +42,8 @@ static inline void propagate_user_return_notify(struct task_struct *prev,static inline void fire_user_return_notifiers (void ) {} +static inline void clear_user_return_notifier (struct task_struct *p) {} +#endif #endif
kernel/fork.c +2 -0
@@ -64,6 +64,7 @@#include <linux/magic.h> #include <linux/perf_event.h> #include <linux/posix-timers.h> +#include <linux/user-return-notifier.h> #include <asm/pgtable.h> #include <asm/pgalloc.h>
@@ -249,6 +250,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) goto out;setup_thread_stack (tsk, orig); +clear_user_return_notifier (tsk); stackend =end_of_stack (tsk); *stackend =STACK_END_MAGIC ;/* for overflow detection */