diff options
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0031-ARM-VFP-add-support-to-sync-the-VFP-state-of-the-cur.patch')
-rw-r--r-- | extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0031-ARM-VFP-add-support-to-sync-the-VFP-state-of-the-cur.patch | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0031-ARM-VFP-add-support-to-sync-the-VFP-state-of-the-cur.patch b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0031-ARM-VFP-add-support-to-sync-the-VFP-state-of-the-cur.patch new file mode 100644 index 00000000..28d9f376 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0031-ARM-VFP-add-support-to-sync-the-VFP-state-of-the-cur.patch | |||
@@ -0,0 +1,109 @@ | |||
1 | From b366c2810c736d8d544cf261f3354eebaf5e5655 Mon Sep 17 00:00:00 2001 | ||
2 | From: Imre Deak <imre.deak@nokia.com> | ||
3 | Date: Thu, 4 Feb 2010 21:38:02 +0200 | ||
4 | Subject: [PATCH 31/45] ARM: VFP: add support to sync the VFP state of the current thread | ||
5 | |||
6 | ARM: VFP: add support to sync the VFP state of the current thread | ||
7 | |||
8 | So far vfp_sync_state worked only for threads other than the current | ||
9 | one. This worked for tracing other threads, but not for PTRACE_TRACEME. | ||
10 | Syncing for the current thread will also be needed by an upcoming patch | ||
11 | adding support for VFP context save / restore around signal handlers. | ||
12 | |||
13 | For SMP we need get_cpu now, since we have to protect the FPEXC | ||
14 | register, other than this things remained the same for threads other | ||
15 | than the current. | ||
16 | |||
17 | Signed-off-by: Imre Deak <imre.deak@nokia.com> | ||
18 | Signed-off-by: Bryan Wu <bryan.wu@canonical.com> | ||
19 | --- | ||
20 | arch/arm/vfp/vfpmodule.c | 46 +++++++++++++++++++++++++++++++--------------- | ||
21 | 1 files changed, 31 insertions(+), 15 deletions(-) | ||
22 | |||
23 | diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c | ||
24 | index aed05bc..f28f45b 100644 | ||
25 | --- a/arch/arm/vfp/vfpmodule.c | ||
26 | +++ b/arch/arm/vfp/vfpmodule.c | ||
27 | @@ -423,12 +423,19 @@ static inline void vfp_pm_init(void) { } | ||
28 | #endif /* CONFIG_PM */ | ||
29 | |||
30 | /* | ||
31 | - * Synchronise the hardware VFP state of a thread other than current with the | ||
32 | - * saved one. This function is used by the ptrace mechanism. | ||
33 | + * Synchronise the hardware VFP state of a thread with the saved one. | ||
34 | + * This function is used by the ptrace mechanism and the signal handler path. | ||
35 | */ | ||
36 | -#ifdef CONFIG_SMP | ||
37 | void vfp_sync_state(struct thread_info *thread) | ||
38 | { | ||
39 | + unsigned int cpu = get_cpu(); | ||
40 | + u32 fpexc = fmrx(FPEXC); | ||
41 | + int vfp_enabled; | ||
42 | + int self; | ||
43 | + | ||
44 | + vfp_enabled = fpexc & FPEXC_EN; | ||
45 | + self = thread == current_thread_info(); | ||
46 | +#ifdef CONFIG_SMP | ||
47 | /* | ||
48 | * On SMP systems, the VFP state is automatically saved at every | ||
49 | * context switch. We mark the thread VFP state as belonging to a | ||
50 | @@ -436,18 +443,22 @@ void vfp_sync_state(struct thread_info *thread) | ||
51 | * needed. | ||
52 | */ | ||
53 | thread->vfpstate.hard.cpu = NR_CPUS; | ||
54 | -} | ||
55 | -#else | ||
56 | -void vfp_sync_state(struct thread_info *thread) | ||
57 | -{ | ||
58 | - unsigned int cpu = get_cpu(); | ||
59 | - u32 fpexc = fmrx(FPEXC); | ||
60 | - | ||
61 | /* | ||
62 | - * If VFP is enabled, the previous state was already saved and | ||
63 | - * last_VFP_context updated. | ||
64 | + * Only the current thread's saved VFP context can be out-of-date. | ||
65 | + * For others there is nothing else to do, since we already ensured | ||
66 | + * force loading above. | ||
67 | */ | ||
68 | - if (fpexc & FPEXC_EN) | ||
69 | + if (!self) | ||
70 | + goto out; | ||
71 | +#endif | ||
72 | + /* | ||
73 | + * If the VFP is enabled only the current thread's saved VFP | ||
74 | + * context can get out-of-date. For other threads the context | ||
75 | + * was updated when the current thread started to use the VFP. | ||
76 | + * This also means that the context will be reloaded next time | ||
77 | + * the thread uses the VFP, so no need to enforce it. | ||
78 | + */ | ||
79 | + if (vfp_enabled && !self) | ||
80 | goto out; | ||
81 | |||
82 | if (!last_VFP_context[cpu]) | ||
83 | @@ -456,8 +467,14 @@ void vfp_sync_state(struct thread_info *thread) | ||
84 | /* | ||
85 | * Save the last VFP state on this CPU. | ||
86 | */ | ||
87 | - fmxr(FPEXC, fpexc | FPEXC_EN); | ||
88 | + if (!vfp_enabled) | ||
89 | + fmxr(FPEXC, fpexc | FPEXC_EN); | ||
90 | vfp_save_state(last_VFP_context[cpu], fpexc); | ||
91 | + /* | ||
92 | + * Disable VFP in case it was enabled so that the force reload | ||
93 | + * can happen. | ||
94 | + */ | ||
95 | + fpexc &= ~FPEXC_EN; | ||
96 | fmxr(FPEXC, fpexc); | ||
97 | |||
98 | /* | ||
99 | @@ -469,7 +486,6 @@ void vfp_sync_state(struct thread_info *thread) | ||
100 | out: | ||
101 | put_cpu(); | ||
102 | } | ||
103 | -#endif | ||
104 | |||
105 | #include <linux/smp.h> | ||
106 | |||
107 | -- | ||
108 | 1.6.6.1 | ||
109 | |||