diff options
Diffstat (limited to 'arch/ppc/kernel/traps.c')
-rw-r--r-- | arch/ppc/kernel/traps.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 99a9c2bce..07e45db6b 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -129,6 +129,42 @@ MachineCheckException(struct pt_regs *regs) } void +AltiVecUnavailable(struct pt_regs *regs) +{ + /* + * This should be changed so we don't take a trap if coming + * back when last_task_used_altivec == current. We should also + * allow the kernel to use the altivec regs on UP to store tasks + * regs during switch + * -- Cort + */ + if ( regs->msr & MSR_VEC ) + { + show_regs(regs); + panic("AltiVec trap with Altivec enabled!\n"); + } + + if ( !user_mode(regs) ) + { + show_regs(regs); + panic("Kernel Used Altivec with MSR_VEC off!\n"); + } + + if ( last_task_used_altivec != current ) + { + if ( last_task_used_altivec ) + giveup_altivec(current); + load_up_altivec(current); + /* on SMP we always save/restore on switch */ +#ifndef __SMP__ + last_task_used_altivec = current; +#endif + } + /* enable altivec for the task on return */ + regs->msr |= MSR_VEC; +} + +void UnknownException(struct pt_regs *regs) { printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", |