[lkml]   [2012]   [Feb]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[patch 11/86] ARM: 7306/1: vfp: flush thread hwstate before restoring context from sigframe
    3.2-stable review patch.  If anyone has any objections, please let me know.


    From: Will Deacon <>

    commit 2af276dfb1722e97b190bd2e646b079a2aa674db upstream.

    Following execution of a signal handler, we currently restore the VFP
    context from the ucontext in the signal frame. This involves copying
    from the user stack into the current thread's vfp_hard_struct and then
    flushing the new data out to the hardware registers.

    This is problematic when using a preemptible kernel because we could be
    context switched whilst updating the vfp_hard_struct. If the current
    thread has made use of VFP since the last context switch, the VFP
    notifier will copy from the hardware registers into the vfp_hard_struct,
    overwriting any data that had been partially copied by the signal code.

    Disabling preemption across copy_from_user calls is a terrible idea, so
    instead we move the VFP thread flush *before* we update the
    vfp_hard_struct. Since the flushing is performed lazily, this has the
    effect of disabling VFP and clearing the CPU's VFP state pointer,
    therefore preventing the thread from being updated with stale data on
    the next context switch.

    Tested-by: Peter Maydell <>
    Signed-off-by: Will Deacon <>
    Signed-off-by: Russell King <>
    Signed-off-by: Greg Kroah-Hartman <>

    arch/arm/kernel/signal.c | 5 ++---
    1 file changed, 2 insertions(+), 3 deletions(-)

    --- a/arch/arm/kernel/signal.c
    +++ b/arch/arm/kernel/signal.c
    @@ -227,6 +227,8 @@ static int restore_vfp_context(struct vf
    if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
    return -EINVAL;

    + vfp_flush_hwstate(thread);
    * Copy the floating point registers. There can be unused
    * registers see asm/hwcap.h for details.
    @@ -251,9 +253,6 @@ static int restore_vfp_context(struct vf
    __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
    __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);

    - if (!err)
    - vfp_flush_hwstate(thread);
    return err ? -EFAULT : 0;

     \ /
      Last update: 2012-02-10 23:43    [W:0.021 / U:15.056 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site