lkml.org 
[lkml]   [2004]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] PPC/PPC64: Fix FP state corruption on UP
    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/
    \
     
     \ /
      Last update: 2005-03-22 14:07    [W:0.023 / U:29.416 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site