[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / 3.2.6 / 0011-ARM-7306-1-vfp-flush-thread-hwstate-before-restoring.patch
1 From 68fcfb203bfa59a51cbe8b5828b0e61b3a75e751 Mon Sep 17 00:00:00 2001
2 From: Will Deacon <will.deacon@arm.com>
3 Date: Mon, 30 Jan 2012 20:21:42 +0100
4 Subject: [PATCH 11/87] ARM: 7306/1: vfp: flush thread hwstate before
5 restoring context from sigframe
7 commit 2af276dfb1722e97b190bd2e646b079a2aa674db upstream.
9 Following execution of a signal handler, we currently restore the VFP
10 context from the ucontext in the signal frame. This involves copying
11 from the user stack into the current thread's vfp_hard_struct and then
12 flushing the new data out to the hardware registers.
14 This is problematic when using a preemptible kernel because we could be
15 context switched whilst updating the vfp_hard_struct. If the current
16 thread has made use of VFP since the last context switch, the VFP
17 notifier will copy from the hardware registers into the vfp_hard_struct,
18 overwriting any data that had been partially copied by the signal code.
20 Disabling preemption across copy_from_user calls is a terrible idea, so
21 instead we move the VFP thread flush *before* we update the
22 vfp_hard_struct. Since the flushing is performed lazily, this has the
23 effect of disabling VFP and clearing the CPU's VFP state pointer,
24 therefore preventing the thread from being updated with stale data on
25 the next context switch.
27 Tested-by: Peter Maydell <peter.maydell@linaro.org>
28 Signed-off-by: Will Deacon <will.deacon@arm.com>
29 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
30 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31 ---
32 arch/arm/kernel/signal.c | 5 ++---
33 1 file changed, 2 insertions(+), 3 deletions(-)
35 diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
36 index 0340224..9e617bd 100644
37 --- a/arch/arm/kernel/signal.c
38 +++ b/arch/arm/kernel/signal.c
39 @@ -227,6 +227,8 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
40 if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
41 return -EINVAL;
43 + vfp_flush_hwstate(thread);
44 +
45 /*
46 * Copy the floating point registers. There can be unused
47 * registers see asm/hwcap.h for details.
48 @@ -251,9 +253,6 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
49 __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
50 __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
52 - if (!err)
53 - vfp_flush_hwstate(thread);
54 -
55 return err ? -EFAULT : 0;
56 }
58 --
59 1.7.9.4