Commit 6805ca03 authored by Kumar Gala's avatar Kumar Gala Committed by Linus Torvalds

[PATCH] ppc32: fix SPE state corruption on e500

Unfortunately the restoring of SPE state was causing data corruption
since we were restoring based on the size of the altivec context and not
the SPE context.  Also, fixed setting of last_task_used_spe on
start_thread, flush_thread, and exit_thread. 
Signed-off-by: default avatarKumar Gala <kumar.gala@freescale.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 31373a87
...@@ -321,7 +321,7 @@ void show_regs(struct pt_regs * regs) ...@@ -321,7 +321,7 @@ void show_regs(struct pt_regs * regs)
trap = TRAP(regs); trap = TRAP(regs);
if (trap == 0x300 || trap == 0x600) if (trap == 0x300 || trap == 0x600)
printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr); printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr);
printk("TASK = %p[%d] '%s' THREAD: %p", printk("TASK = %p[%d] '%s' THREAD: %p\n",
current, current->pid, current->comm, current->thread_info); current, current->pid, current->comm, current->thread_info);
printk("Last syscall: %ld ", current->thread.last_syscall); printk("Last syscall: %ld ", current->thread.last_syscall);
...@@ -370,6 +370,10 @@ void exit_thread(void) ...@@ -370,6 +370,10 @@ void exit_thread(void)
last_task_used_math = NULL; last_task_used_math = NULL;
if (last_task_used_altivec == current) if (last_task_used_altivec == current)
last_task_used_altivec = NULL; last_task_used_altivec = NULL;
#ifdef CONFIG_SPE
if (last_task_used_spe == current)
last_task_used_spe = NULL;
#endif
} }
void flush_thread(void) void flush_thread(void)
...@@ -378,6 +382,10 @@ void flush_thread(void) ...@@ -378,6 +382,10 @@ void flush_thread(void)
last_task_used_math = NULL; last_task_used_math = NULL;
if (last_task_used_altivec == current) if (last_task_used_altivec == current)
last_task_used_altivec = NULL; last_task_used_altivec = NULL;
#ifdef CONFIG_SPE
if (last_task_used_spe == current)
last_task_used_spe = NULL;
#endif
} }
void void
...@@ -480,6 +488,10 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) ...@@ -480,6 +488,10 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
last_task_used_math = NULL; last_task_used_math = NULL;
if (last_task_used_altivec == current) if (last_task_used_altivec == current)
last_task_used_altivec = NULL; last_task_used_altivec = NULL;
#ifdef CONFIG_SPE
if (last_task_used_spe == current)
last_task_used_spe = NULL;
#endif
memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
current->thread.fpscr = 0; current->thread.fpscr = 0;
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
......
...@@ -319,7 +319,7 @@ restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig) ...@@ -319,7 +319,7 @@ restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig)
if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) { if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
/* restore spe registers from the stack */ /* restore spe registers from the stack */
if (__copy_from_user(current->thread.evr, &sr->mc_vregs, if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
sizeof(sr->mc_vregs))) ELF_NEVRREG * sizeof(u32)))
return 1; return 1;
} else if (current->thread.used_spe) } else if (current->thread.used_spe)
memset(&current->thread.evr, 0, ELF_NEVRREG * sizeof(u32)); memset(&current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment