floating point register corruption

From: Paolo Galtieri (pgaltieri_at_mvista.com)
Date: 11/29/05

  • Next message: Salyzyn, Mark: "Outlook Sux (Was: [2.6 patch] dpt_i2o fix for deadlock condition)"
    To: Linux Kernel <linux-kernel@vger.kernel.org>
    Date:	Tue, 29 Nov 2005 12:24:01 -0700
    
    

    Folks,
      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.

    Paolo

    Signed-off-by: pgaltieri@mvista.com

    --- linux-2.6.15-rc3/arch/ppc/kernel/process.c 2005-11-29
    07:01:55.000000000 -0700
    +++ new-linux-2.6.15-rc3/arch/ppc/kernel/process.c 2005-11-29
    07:20:37.000000000 -0700
    @@ -417,6 +417,7 @@
     
     void exit_thread(void)
     {
    + preempt_disable();
             if (last_task_used_math == current)
                     last_task_used_math = NULL;
             if (last_task_used_altivec == current)
    @@ -425,10 +426,12 @@
             if (last_task_used_spe == current)
                     last_task_used_spe = NULL;
     #endif
    + preempt_enable();
     }
     
     void flush_thread(void)
     {
    + preempt_disable();
             if (last_task_used_math == current)
                     last_task_used_math = NULL;
             if (last_task_used_altivec == current)
    @@ -437,6 +440,7 @@
             if (last_task_used_spe == current)
                     last_task_used_spe = NULL;
     #endif
    + preempt_enable();
     }
     
     void
    @@ -535,6 +539,7 @@
             regs->nip = nip;
             regs->gpr[1] = sp;
             regs->msr = MSR_USER;
    + preempt_disable();
             if (last_task_used_math == current)
                     last_task_used_math = NULL;
             if (last_task_used_altivec == current)
    @@ -543,6 +548,7 @@
             if (last_task_used_spe == current)
                     last_task_used_spe = NULL;
     #endif
    + preempt_enable();
             memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
             current->thread.fpscr.val = 0;
     #ifdef CONFIG_ALTIVEC

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/


  • Next message: Salyzyn, Mark: "Outlook Sux (Was: [2.6 patch] dpt_i2o fix for deadlock condition)"

    Relevant Pages