[PATCH] PPC/PPC64: Fix FP state corruption on UP

From: Paul Mackerras (paulus_at_samba.org)
Date: 10/27/04

  • Next message: Jens Axboe: "Re: Strange IO behaviour on wakeup from sleep"
    Date:	Wed, 27 Oct 2004 16:15:21 +1000
    To: akpm@osdl.org, torvalds@osdl.org
    
    

    Unfortunately the patch Ben sent last week to fix a bug in the saving
    and restoring of floating-point and altivec context across signal
    handlers introduced another bug, which tends to corrupt the FP and
    altivec contexts of other tasks. This patch fixes the problem for
    both ppc32 and ppc64. Please apply.

    Signed-off-by: Paul Mackerras <paulus@samba.org>

    diff -urN linux-2.5/arch/ppc/kernel/signal.c test/arch/ppc/kernel/signal.c
    --- linux-2.5/arch/ppc/kernel/signal.c 2004-10-20 08:16:36.000000000 +1000
    +++ test/arch/ppc/kernel/signal.c 2004-10-27 14:29:48.494955208 +1000
    @@ -290,7 +290,7 @@
     
             /* force the process to reload the FP registers from
                current->thread when it next does FP instructions */
    - regs->msr &= ~MSR_FP;
    + regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
             if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
                                  sizeof(sr->mc_fregs)))
                     return 1;
    @@ -330,9 +330,14 @@
     #endif /* CONFIG_SPE */
     
     #ifndef CONFIG_SMP
    - last_task_used_math = NULL;
    - last_task_used_altivec = NULL;
    - last_task_used_spe = NULL;
    + preempt_disable();
    + if (last_task_used_math == current)
    + last_task_used_math = NULL;
    + if (last_task_used_altivec == current)
    + last_task_used_altivec = NULL;
    + if (last_task_used_spe == current)
    + last_task_used_spe = NULL;
    + preempt_enable();
     #endif
             return 0;
     }
    diff -urN linux-2.5/arch/ppc64/kernel/signal.c test/arch/ppc64/kernel/signal.c
    --- linux-2.5/arch/ppc64/kernel/signal.c 2004-10-20 08:16:36.000000000 +1000
    +++ test/arch/ppc64/kernel/signal.c 2004-10-27 14:31:57.301942136 +1000
    @@ -224,8 +224,12 @@
     #endif /* CONFIG_ALTIVEC */
     
     #ifndef CONFIG_SMP
    - last_task_used_math = NULL;
    - last_task_used_altivec = NULL;
    + preempt_disable();
    + if (last_task_used_math == current)
    + last_task_used_math = NULL;
    + if (last_task_used_altivec == current)
    + last_task_used_altivec = NULL;
    + preempt_enable();
     #endif
             /* Force reload of FP/VEC */
             regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC);
    diff -urN linux-2.5/arch/ppc64/kernel/signal32.c test/arch/ppc64/kernel/signal32.c
    --- linux-2.5/arch/ppc64/kernel/signal32.c 2004-10-20 08:16:36.000000000 +1000
    +++ test/arch/ppc64/kernel/signal32.c 2004-10-27 14:32:45.086999136 +1000
    @@ -235,8 +235,12 @@
     #endif /* CONFIG_ALTIVEC */
     
     #ifndef CONFIG_SMP
    - last_task_used_math = NULL;
    - last_task_used_altivec = NULL;
    + preempt_disable();
    + if (last_task_used_math == current)
    + last_task_used_math = NULL;
    + if (last_task_used_altivec == current)
    + last_task_used_altivec = NULL;
    + preempt_enable();
     #endif
             return 0;
     }
    -
    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: Jens Axboe: "Re: Strange IO behaviour on wakeup from sleep"

    Relevant Pages