Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull generic execve() changes from Al Viro: "This introduces the generic kernel_thread() and kernel_execve() functions, and switches x86, arm, alpha, um and s390 over to them." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (26 commits) s390: convert to generic kernel_execve() s390: switch to generic kernel_thread() s390: fold kernel_thread_helper() into ret_from_fork() s390: fold execve_tail() into start_thread(), convert to generic sys_execve() um: switch to generic kernel_thread() x86, um/x86: switch to generic sys_execve and kernel_execve x86: split ret_from_fork alpha: introduce ret_from_kernel_execve(), switch to generic kernel_execve() alpha: switch to generic kernel_thread() alpha: switch to generic sys_execve() arm: get rid of execve wrapper, switch to generic execve() implementation arm: optimized current_pt_regs() arm: introduce ret_from_kernel_execve(), switch to generic kernel_execve() arm: split ret_from_fork, simplify kernel_thread() [based on patch by rmk] generic sys_execve() generic kernel_execve() new helper: current_pt_regs() preparation for generic kernel_thread() um: kill thread->forking um: let signal_delivered() do SIGTRAP on singlestepping into handler ...
This commit is contained in:
@@ -146,29 +146,18 @@ static inline u32 read_32bit_tls(struct task_struct *t, int tls)
|
||||
}
|
||||
|
||||
int copy_thread(unsigned long clone_flags, unsigned long sp,
|
||||
unsigned long unused,
|
||||
unsigned long arg,
|
||||
struct task_struct *p, struct pt_regs *regs)
|
||||
{
|
||||
int err;
|
||||
struct pt_regs *childregs;
|
||||
struct task_struct *me = current;
|
||||
|
||||
childregs = ((struct pt_regs *)
|
||||
(THREAD_SIZE + task_stack_page(p))) - 1;
|
||||
*childregs = *regs;
|
||||
|
||||
childregs->ax = 0;
|
||||
if (user_mode(regs))
|
||||
childregs->sp = sp;
|
||||
else
|
||||
childregs->sp = (unsigned long)childregs;
|
||||
|
||||
p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE;
|
||||
childregs = task_pt_regs(p);
|
||||
p->thread.sp = (unsigned long) childregs;
|
||||
p->thread.sp0 = (unsigned long) (childregs+1);
|
||||
p->thread.usersp = me->thread.usersp;
|
||||
|
||||
set_tsk_thread_flag(p, TIF_FORK);
|
||||
|
||||
p->fpu_counter = 0;
|
||||
p->thread.io_bitmap_ptr = NULL;
|
||||
|
||||
@@ -178,6 +167,24 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
|
||||
p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
|
||||
savesegment(es, p->thread.es);
|
||||
savesegment(ds, p->thread.ds);
|
||||
memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
|
||||
|
||||
if (unlikely(!regs)) {
|
||||
/* kernel thread */
|
||||
memset(childregs, 0, sizeof(struct pt_regs));
|
||||
childregs->sp = (unsigned long)childregs;
|
||||
childregs->ss = __KERNEL_DS;
|
||||
childregs->bx = sp; /* function */
|
||||
childregs->bp = arg;
|
||||
childregs->orig_ax = -1;
|
||||
childregs->cs = __KERNEL_CS | get_kernel_rpl();
|
||||
childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
|
||||
return 0;
|
||||
}
|
||||
*childregs = *regs;
|
||||
|
||||
childregs->ax = 0;
|
||||
childregs->sp = sp;
|
||||
|
||||
err = -ENOMEM;
|
||||
memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
|
||||
|
||||
Reference in New Issue
Block a user