diff options
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r-- | arch/powerpc/kernel/process.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index e477c9d0498..15998b57767 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -354,6 +354,14 @@ static void show_instructions(struct pt_regs *regs) if (!(i % 8)) printk("\n"); +#if !defined(CONFIG_BOOKE) + /* If executing with the IMMU off, adjust pc rather + * than print XXXXXXXX. + */ + if (!(regs->msr & MSR_IR)) + pc = (unsigned long)phys_to_virt(pc); +#endif + /* We use __get_user here *only* to avoid an OOPS on a * bad address because the pc *should* only be a * kernel address. @@ -605,6 +613,13 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->ccr = 0; regs->gpr[1] = sp; + /* + * We have just cleared all the nonvolatile GPRs, so make + * FULL_REGS(regs) return true. This is necessary to allow + * ptrace to examine the thread immediately after exec. + */ + regs->trap &= ~1UL; + #ifdef CONFIG_PPC32 regs->mq = 0; regs->nip = start; @@ -669,9 +684,13 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val) * mode (asyn, precise, disabled) for 'Classic' FP. */ if (val & PR_FP_EXC_SW_ENABLE) { #ifdef CONFIG_SPE - tsk->thread.fpexc_mode = val & - (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT); - return 0; + if (cpu_has_feature(CPU_FTR_SPE)) { + tsk->thread.fpexc_mode = val & + (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT); + return 0; + } else { + return -EINVAL; + } #else return -EINVAL; #endif @@ -697,7 +716,10 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) #ifdef CONFIG_SPE - val = tsk->thread.fpexc_mode; + if (cpu_has_feature(CPU_FTR_SPE)) + val = tsk->thread.fpexc_mode; + else + return -EINVAL; #else return -EINVAL; #endif |