[PATCH] ppc: fix floating point register corruption

I recently discovered a bug on PPC which causes the floating point
registers to get corrupted when CONFIG_PREEMPT=y.

The problem occurred while running a multi threaded Java application that
does floating point. The problem could be reproduced in anywhere from 2 to
6 hours. With the patch I have included below it ran for over a week
without failure.

Signed-off-by: Paolo Galtieri <pgaltieri@mvista.com>
Cc: Kumar Gala <galak@gate.crashing.org>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Tom Rini <trini@kernel.crashing.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Paolo Galtieri and committed by Linus Torvalds 9f232a12 123d3c13

+6
+6
arch/ppc/kernel/process.c
··· 417 417 418 418 void exit_thread(void) 419 419 { 420 + preempt_disable(); 420 421 if (last_task_used_math == current) 421 422 last_task_used_math = NULL; 422 423 if (last_task_used_altivec == current) ··· 426 425 if (last_task_used_spe == current) 427 426 last_task_used_spe = NULL; 428 427 #endif 428 + preempt_enable(); 429 429 } 430 430 431 431 void flush_thread(void) 432 432 { 433 + preempt_disable(); 433 434 if (last_task_used_math == current) 434 435 last_task_used_math = NULL; 435 436 if (last_task_used_altivec == current) ··· 440 437 if (last_task_used_spe == current) 441 438 last_task_used_spe = NULL; 442 439 #endif 440 + preempt_enable(); 443 441 } 444 442 445 443 void ··· 539 535 regs->nip = nip; 540 536 regs->gpr[1] = sp; 541 537 regs->msr = MSR_USER; 538 + preempt_disable(); 542 539 if (last_task_used_math == current) 543 540 last_task_used_math = NULL; 544 541 if (last_task_used_altivec == current) ··· 548 543 if (last_task_used_spe == current) 549 544 last_task_used_spe = NULL; 550 545 #endif 546 + preempt_enable(); 551 547 memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); 552 548 current->thread.fpscr.val = 0; 553 549 #ifdef CONFIG_ALTIVEC