diff options
Diffstat (limited to 'arch/sh/kernel/process_64.c')
-rw-r--r-- | arch/sh/kernel/process_64.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 24de74214940..1192398ef582 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c | |||
@@ -425,7 +425,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
425 | struct task_struct *p, struct pt_regs *regs) | 425 | struct task_struct *p, struct pt_regs *regs) |
426 | { | 426 | { |
427 | struct pt_regs *childregs; | 427 | struct pt_regs *childregs; |
428 | unsigned long long se; /* Sign extension */ | ||
429 | 428 | ||
430 | #ifdef CONFIG_SH_FPU | 429 | #ifdef CONFIG_SH_FPU |
431 | if(last_task_used_math == current) { | 430 | if(last_task_used_math == current) { |
@@ -441,11 +440,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
441 | 440 | ||
442 | *childregs = *regs; | 441 | *childregs = *regs; |
443 | 442 | ||
443 | /* | ||
444 | * Sign extend the edited stack. | ||
445 | * Note that thread.pc and thread.pc will stay | ||
446 | * 32-bit wide and context switch must take care | ||
447 | * of NEFF sign extension. | ||
448 | */ | ||
444 | if (user_mode(regs)) { | 449 | if (user_mode(regs)) { |
445 | childregs->regs[15] = usp; | 450 | childregs->regs[15] = neff_sign_extend(usp); |
446 | p->thread.uregs = childregs; | 451 | p->thread.uregs = childregs; |
447 | } else { | 452 | } else { |
448 | childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; | 453 | childregs->regs[15] = |
454 | neff_sign_extend((unsigned long)task_stack_page(p) + | ||
455 | THREAD_SIZE); | ||
449 | } | 456 | } |
450 | 457 | ||
451 | childregs->regs[9] = 0; /* Set return value for child */ | 458 | childregs->regs[9] = 0; /* Set return value for child */ |
@@ -454,17 +461,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
454 | p->thread.sp = (unsigned long) childregs; | 461 | p->thread.sp = (unsigned long) childregs; |
455 | p->thread.pc = (unsigned long) ret_from_fork; | 462 | p->thread.pc = (unsigned long) ret_from_fork; |
456 | 463 | ||
457 | /* | ||
458 | * Sign extend the edited stack. | ||
459 | * Note that thread.pc and thread.pc will stay | ||
460 | * 32-bit wide and context switch must take care | ||
461 | * of NEFF sign extension. | ||
462 | */ | ||
463 | |||
464 | se = childregs->regs[15]; | ||
465 | se = (se & NEFF_SIGN) ? (se | NEFF_MASK) : se; | ||
466 | childregs->regs[15] = se; | ||
467 | |||
468 | return 0; | 464 | return 0; |
469 | } | 465 | } |
470 | 466 | ||