diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index aa196c6f0670751b54cc6c7190b041583179472e..76b37d1bcac16861ed16636a959c5350336fceda 100755 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -177,7 +177,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, fpu_clone(p, clone_flags); /* Kernel thread ? */ - if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) { + if (unlikely(p->flags & PF_KTHREAD)) { p->thread.pkru = pkru_get_init_value(); memset(childregs, 0, sizeof(struct pt_regs)); kthread_frame_init(frame, sp, arg); @@ -200,6 +200,23 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, task_user_gs(p) = get_user_gs(current_pt_regs()); #endif + if (unlikely(p->flags & PF_IO_WORKER)) { + /* + * An IO thread is a user space thread, but it doesn't + * return to ret_after_fork(). + * + * In order to indicate that to tools like gdb, + * we reset the stack and instruction pointers. + * + * It does the same kernel frame setup to return to a kernel + * function that a kernel thread does. + */ + childregs->sp = 0; + childregs->ip = 0; + kthread_frame_init(frame, sp, arg); + return 0; + } + /* Set a new TLS for the child thread? */ if (clone_flags & CLONE_SETTLS) ret = set_new_tls(p, tls);