Loading arch/x86/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ config X86 select KTIME_SCALAR if X86_32 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select GENERIC_KERNEL_THREAD config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS || UPROBES) Loading arch/x86/include/asm/processor.h +0 −5 Original line number Diff line number Diff line Loading @@ -589,11 +589,6 @@ typedef struct { } mm_segment_t; /* * create a kernel thread without removing it from tasklists */ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); Loading arch/x86/kernel/entry_32.S +10 −5 Original line number Diff line number Diff line Loading @@ -994,15 +994,20 @@ END(spurious_interrupt_bug) */ .popsection ENTRY(kernel_thread_helper) pushl $0 # fake return address for unwinder ENTRY(ret_from_kernel_thread) CFI_STARTPROC movl %edi,%eax call *%esi pushl_cfi %eax call schedule_tail GET_THREAD_INFO(%ebp) popl_cfi %eax pushl_cfi $0x0202 # Reset kernel eflags popfl_cfi movl PT_EBP(%esp),%eax call *PT_EBX(%esp) call do_exit ud2 # padding for call trace CFI_ENDPROC ENDPROC(kernel_thread_helper) ENDPROC(ret_from_kernel_thread) #ifdef CONFIG_XEN /* Xen doesn't set %esp to be precisely what the normal sysenter Loading arch/x86/kernel/entry_64.S +11 −16 Original line number Diff line number Diff line Loading @@ -450,7 +450,7 @@ ENTRY(ret_from_fork) RESTORE_REST testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? jz retint_restore_args jz 1f testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET jnz int_ret_from_sys_call Loading @@ -458,6 +458,16 @@ ENTRY(ret_from_fork) RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET jmp ret_from_sys_call # go to the SYSRET fastpath 1: subq $REST_SKIP, %rsp # move the stack pointer back CFI_ADJUST_CFA_OFFSET REST_SKIP movq %rbp, %rdi call *%rbx # exit mov %eax, %edi call do_exit ud2 # padding for call trace CFI_ENDPROC END(ret_from_fork) Loading Loading @@ -1206,21 +1216,6 @@ bad_gs: jmp 2b .previous ENTRY(kernel_thread_helper) pushq $0 # fake return address CFI_STARTPROC /* * Here we are in the child and the registers are set as they were * at kernel_thread() invocation in the parent. */ call *%rsi # exit mov %eax, %edi call do_exit ud2 # padding for call trace CFI_ENDPROC END(kernel_thread_helper) /* * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. * Loading arch/x86/kernel/process.c +0 −38 Original line number Diff line number Diff line Loading @@ -298,44 +298,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp, return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } /* * This gets run with %si containing the * function to call, and %di containing * the "args". */ extern void kernel_thread_helper(void); /* * Create a kernel thread */ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { struct pt_regs regs; memset(®s, 0, sizeof(regs)); regs.si = (unsigned long) fn; regs.di = (unsigned long) arg; #ifdef CONFIG_X86_32 regs.ds = __USER_DS; regs.es = __USER_DS; regs.fs = __KERNEL_PERCPU; regs.gs = __KERNEL_STACK_CANARY; #else regs.ss = __KERNEL_DS; #endif regs.orig_ax = -1; regs.ip = (unsigned long) kernel_thread_helper; regs.cs = __KERNEL_CS | get_kernel_rpl(); regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1; /* Ok, create the new process.. */ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); /* * sys_execve() executes a new program. */ Loading Loading
arch/x86/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ config X86 select KTIME_SCALAR if X86_32 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select GENERIC_KERNEL_THREAD config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS || UPROBES) Loading
arch/x86/include/asm/processor.h +0 −5 Original line number Diff line number Diff line Loading @@ -589,11 +589,6 @@ typedef struct { } mm_segment_t; /* * create a kernel thread without removing it from tasklists */ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); Loading
arch/x86/kernel/entry_32.S +10 −5 Original line number Diff line number Diff line Loading @@ -994,15 +994,20 @@ END(spurious_interrupt_bug) */ .popsection ENTRY(kernel_thread_helper) pushl $0 # fake return address for unwinder ENTRY(ret_from_kernel_thread) CFI_STARTPROC movl %edi,%eax call *%esi pushl_cfi %eax call schedule_tail GET_THREAD_INFO(%ebp) popl_cfi %eax pushl_cfi $0x0202 # Reset kernel eflags popfl_cfi movl PT_EBP(%esp),%eax call *PT_EBX(%esp) call do_exit ud2 # padding for call trace CFI_ENDPROC ENDPROC(kernel_thread_helper) ENDPROC(ret_from_kernel_thread) #ifdef CONFIG_XEN /* Xen doesn't set %esp to be precisely what the normal sysenter Loading
arch/x86/kernel/entry_64.S +11 −16 Original line number Diff line number Diff line Loading @@ -450,7 +450,7 @@ ENTRY(ret_from_fork) RESTORE_REST testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? jz retint_restore_args jz 1f testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET jnz int_ret_from_sys_call Loading @@ -458,6 +458,16 @@ ENTRY(ret_from_fork) RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET jmp ret_from_sys_call # go to the SYSRET fastpath 1: subq $REST_SKIP, %rsp # move the stack pointer back CFI_ADJUST_CFA_OFFSET REST_SKIP movq %rbp, %rdi call *%rbx # exit mov %eax, %edi call do_exit ud2 # padding for call trace CFI_ENDPROC END(ret_from_fork) Loading Loading @@ -1206,21 +1216,6 @@ bad_gs: jmp 2b .previous ENTRY(kernel_thread_helper) pushq $0 # fake return address CFI_STARTPROC /* * Here we are in the child and the registers are set as they were * at kernel_thread() invocation in the parent. */ call *%rsi # exit mov %eax, %edi call do_exit ud2 # padding for call trace CFI_ENDPROC END(kernel_thread_helper) /* * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. * Loading
arch/x86/kernel/process.c +0 −38 Original line number Diff line number Diff line Loading @@ -298,44 +298,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp, return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } /* * This gets run with %si containing the * function to call, and %di containing * the "args". */ extern void kernel_thread_helper(void); /* * Create a kernel thread */ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { struct pt_regs regs; memset(®s, 0, sizeof(regs)); regs.si = (unsigned long) fn; regs.di = (unsigned long) arg; #ifdef CONFIG_X86_32 regs.ds = __USER_DS; regs.es = __USER_DS; regs.fs = __KERNEL_PERCPU; regs.gs = __KERNEL_STACK_CANARY; #else regs.ss = __KERNEL_DS; #endif regs.orig_ax = -1; regs.ip = (unsigned long) kernel_thread_helper; regs.cs = __KERNEL_CS | get_kernel_rpl(); regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1; /* Ok, create the new process.. */ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); /* * sys_execve() executes a new program. */ Loading