diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/vfp/entry.S | 23 | ||||
-rw-r--r-- | arch/arm/vfp/vfphw.S | 12 | ||||
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 6 |
3 files changed, 35 insertions, 6 deletions
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index ba592a9e6fb3..a2bed62aec21 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S | |||
@@ -15,13 +15,16 @@ | |||
15 | * r10 = thread_info structure | 15 | * r10 = thread_info structure |
16 | * lr = failure return | 16 | * lr = failure return |
17 | */ | 17 | */ |
18 | #include <linux/linkage.h> | 18 | #include <asm/thread_info.h> |
19 | #include <linux/init.h> | ||
20 | #include <asm/asm-offsets.h> | ||
21 | #include <asm/assembler.h> | ||
22 | #include <asm/vfpmacros.h> | 19 | #include <asm/vfpmacros.h> |
20 | #include "../kernel/entry-header.S" | ||
23 | 21 | ||
24 | ENTRY(do_vfp) | 22 | ENTRY(do_vfp) |
23 | #ifdef CONFIG_PREEMPT | ||
24 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count | ||
25 | add r11, r4, #1 @ increment it | ||
26 | str r11, [r10, #TI_PREEMPT] | ||
27 | #endif | ||
25 | enable_irq | 28 | enable_irq |
26 | ldr r4, .LCvfp | 29 | ldr r4, .LCvfp |
27 | ldr r11, [r10, #TI_CPU] @ CPU number | 30 | ldr r11, [r10, #TI_CPU] @ CPU number |
@@ -30,6 +33,12 @@ ENTRY(do_vfp) | |||
30 | ENDPROC(do_vfp) | 33 | ENDPROC(do_vfp) |
31 | 34 | ||
32 | ENTRY(vfp_null_entry) | 35 | ENTRY(vfp_null_entry) |
36 | #ifdef CONFIG_PREEMPT | ||
37 | get_thread_info r10 | ||
38 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count | ||
39 | sub r11, r4, #1 @ decrement it | ||
40 | str r11, [r10, #TI_PREEMPT] | ||
41 | #endif | ||
33 | mov pc, lr | 42 | mov pc, lr |
34 | ENDPROC(vfp_null_entry) | 43 | ENDPROC(vfp_null_entry) |
35 | 44 | ||
@@ -41,6 +50,12 @@ ENDPROC(vfp_null_entry) | |||
41 | 50 | ||
42 | __INIT | 51 | __INIT |
43 | ENTRY(vfp_testing_entry) | 52 | ENTRY(vfp_testing_entry) |
53 | #ifdef CONFIG_PREEMPT | ||
54 | get_thread_info r10 | ||
55 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count | ||
56 | sub r11, r4, #1 @ decrement it | ||
57 | str r11, [r10, #TI_PREEMPT] | ||
58 | #endif | ||
44 | ldr r0, VFP_arch_address | 59 | ldr r0, VFP_arch_address |
45 | str r5, [r0] @ known non-zero value | 60 | str r5, [r0] @ known non-zero value |
46 | mov pc, r9 @ we have handled the fault | 61 | mov pc, r9 @ we have handled the fault |
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index a5a4e57763c3..83c4e384b16d 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
@@ -137,6 +137,12 @@ check_for_exception: | |||
137 | VFPFMXR FPEXC, r1 @ restore FPEXC last | 137 | VFPFMXR FPEXC, r1 @ restore FPEXC last |
138 | sub r2, r2, #4 | 138 | sub r2, r2, #4 |
139 | str r2, [sp, #S_PC] @ retry the instruction | 139 | str r2, [sp, #S_PC] @ retry the instruction |
140 | #ifdef CONFIG_PREEMPT | ||
141 | get_thread_info r10 | ||
142 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count | ||
143 | sub r11, r4, #1 @ decrement it | ||
144 | str r11, [r10, #TI_PREEMPT] | ||
145 | #endif | ||
140 | mov pc, r9 @ we think we have handled things | 146 | mov pc, r9 @ we think we have handled things |
141 | 147 | ||
142 | 148 | ||
@@ -155,6 +161,12 @@ look_for_VFP_exceptions: | |||
155 | @ not recognised by VFP | 161 | @ not recognised by VFP |
156 | 162 | ||
157 | DBGSTR "not VFP" | 163 | DBGSTR "not VFP" |
164 | #ifdef CONFIG_PREEMPT | ||
165 | get_thread_info r10 | ||
166 | ldr r4, [r10, #TI_PREEMPT] @ get preempt count | ||
167 | sub r11, r4, #1 @ decrement it | ||
168 | str r11, [r10, #TI_PREEMPT] | ||
169 | #endif | ||
158 | mov pc, lr | 170 | mov pc, lr |
159 | 171 | ||
160 | process_exception: | 172 | process_exception: |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 75457b30d813..01599c4ef726 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -266,7 +266,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
266 | * on VFP subarch 1. | 266 | * on VFP subarch 1. |
267 | */ | 267 | */ |
268 | vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs); | 268 | vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs); |
269 | return; | 269 | goto exit; |
270 | } | 270 | } |
271 | 271 | ||
272 | /* | 272 | /* |
@@ -297,7 +297,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
297 | * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1. | 297 | * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1. |
298 | */ | 298 | */ |
299 | if (fpexc ^ (FPEXC_EX | FPEXC_FP2V)) | 299 | if (fpexc ^ (FPEXC_EX | FPEXC_FP2V)) |
300 | return; | 300 | goto exit; |
301 | 301 | ||
302 | /* | 302 | /* |
303 | * The barrier() here prevents fpinst2 being read | 303 | * The barrier() here prevents fpinst2 being read |
@@ -310,6 +310,8 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
310 | exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs); | 310 | exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs); |
311 | if (exceptions) | 311 | if (exceptions) |
312 | vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); | 312 | vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); |
313 | exit: | ||
314 | preempt_enable(); | ||
313 | } | 315 | } |
314 | 316 | ||
315 | static void vfp_enable(void *unused) | 317 | static void vfp_enable(void *unused) |