[ARM] 5440/1: Fix VFP state corruption due to preemption during VFP exceptions
We've observed that ARM VFP state can be corrupted during VFP exception handling when PREEMPT is enabled. The exact conditions are difficult to reproduce but appear to occur during VFP exception handling when a task causes a VFP exception which is handled via VFP_bounce and is then preempted by yet another task which in turn causes yet another VFP exception. Since the VFP_bounce code is not preempt safe, VFP state then becomes corrupt. In order to prevent preemption from occuring while handling a VFP exception, this patch disables preemption while handling VFP exceptions. Signed-off-by: George G. Davis <gdavis@mvista.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
@@ -15,13 +15,16 @@
|
||||
* r10 = thread_info structure
|
||||
* lr = failure return
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/vfpmacros.h>
|
||||
#include "../kernel/entry-header.S"
|
||||
|
||||
ENTRY(do_vfp)
|
||||
#ifdef CONFIG_PREEMPT
|
||||
ldr r4, [r10, #TI_PREEMPT] @ get preempt count
|
||||
add r11, r4, #1 @ increment it
|
||||
str r11, [r10, #TI_PREEMPT]
|
||||
#endif
|
||||
enable_irq
|
||||
ldr r4, .LCvfp
|
||||
ldr r11, [r10, #TI_CPU] @ CPU number
|
||||
@@ -30,6 +33,12 @@ ENTRY(do_vfp)
|
||||
ENDPROC(do_vfp)
|
||||
|
||||
ENTRY(vfp_null_entry)
|
||||
#ifdef CONFIG_PREEMPT
|
||||
get_thread_info r10
|
||||
ldr r4, [r10, #TI_PREEMPT] @ get preempt count
|
||||
sub r11, r4, #1 @ decrement it
|
||||
str r11, [r10, #TI_PREEMPT]
|
||||
#endif
|
||||
mov pc, lr
|
||||
ENDPROC(vfp_null_entry)
|
||||
|
||||
@@ -41,6 +50,12 @@ ENDPROC(vfp_null_entry)
|
||||
|
||||
__INIT
|
||||
ENTRY(vfp_testing_entry)
|
||||
#ifdef CONFIG_PREEMPT
|
||||
get_thread_info r10
|
||||
ldr r4, [r10, #TI_PREEMPT] @ get preempt count
|
||||
sub r11, r4, #1 @ decrement it
|
||||
str r11, [r10, #TI_PREEMPT]
|
||||
#endif
|
||||
ldr r0, VFP_arch_address
|
||||
str r5, [r0] @ known non-zero value
|
||||
mov pc, r9 @ we have handled the fault
|
||||
|
Reference in New Issue
Block a user