diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-30 00:27:40 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-14 19:33:54 -0400 |
commit | c19e6d67e4be16e20ff90f0baa98b16d926d23a5 (patch) | |
tree | c5421d406815c7341c26179acf8b71bdaf251a18 | |
parent | c4aee363af2a81f9726c5fa13e136ebaf02852bd (diff) |
ia64: don't mess with ar_bspstore in kernel_thread()
the only thing we use that for is in copy_thread(), where the way
we set it will result in rbs_size being 0. Just move that calculating
rbs_size and copying rbs to non-kernel-thread side of
if (user_mode(regs)) in copy_thread() and set rbs_size to 0 on
kernel thread side.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/ia64/kernel/process.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 63a77b8b5cfa..6a48775d9363 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -411,12 +411,11 @@ copy_thread(unsigned long clone_flags, | |||
411 | 411 | ||
412 | rbs = (unsigned long) current + IA64_RBS_OFFSET; | 412 | rbs = (unsigned long) current + IA64_RBS_OFFSET; |
413 | child_rbs = (unsigned long) p + IA64_RBS_OFFSET; | 413 | child_rbs = (unsigned long) p + IA64_RBS_OFFSET; |
414 | rbs_size = stack->ar_bspstore - rbs; | ||
415 | |||
416 | /* copy the parent's register backing store to the child: */ | ||
417 | memcpy((void *) child_rbs, (void *) rbs, rbs_size); | ||
418 | 414 | ||
419 | if (likely(user_mode(child_ptregs))) { | 415 | if (likely(user_mode(child_ptregs))) { |
416 | /* copy the parent's register backing store to the child: */ | ||
417 | rbs_size = stack->ar_bspstore - rbs; | ||
418 | memcpy((void *) child_rbs, (void *) rbs, rbs_size); | ||
420 | if (clone_flags & CLONE_SETTLS) | 419 | if (clone_flags & CLONE_SETTLS) |
421 | child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */ | 420 | child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */ |
422 | if (user_stack_base) { | 421 | if (user_stack_base) { |
@@ -433,6 +432,7 @@ copy_thread(unsigned long clone_flags, | |||
433 | * been taken care of by the caller of sys_clone() | 432 | * been taken care of by the caller of sys_clone() |
434 | * already. | 433 | * already. |
435 | */ | 434 | */ |
435 | rbs_size = 0; | ||
436 | child_ptregs->r12 = (unsigned long) child_ptregs - 16; /* kernel sp */ | 436 | child_ptregs->r12 = (unsigned long) child_ptregs - 16; /* kernel sp */ |
437 | child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */ | 437 | child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */ |
438 | } | 438 | } |
@@ -637,7 +637,6 @@ kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) | |||
637 | regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN; | 637 | regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN; |
638 | regs.pt.cr_ifs = 1UL << 63; /* mark as valid, empty frame */ | 638 | regs.pt.cr_ifs = 1UL << 63; /* mark as valid, empty frame */ |
639 | regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR); | 639 | regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR); |
640 | regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET; | ||
641 | regs.sw.pr = (1 << PRED_KERNEL_STACK); | 640 | regs.sw.pr = (1 << PRED_KERNEL_STACK); |
642 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s.pt, 0, NULL, NULL); | 641 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s.pt, 0, NULL, NULL); |
643 | } | 642 | } |