From: Mans Rullgard <mans@mansr.com>
Date: Sat, 16 Aug 2008 23:03:06 +0000 (+0100)
Subject: ARM: Workaround for erratum 451034
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=b84fa87873ffb68ad23930cf6cddeea8bec43ede

ARM: Workaround for erratum 451034

On Cortex-A8 r1p0 and r1p1, executing a NEON store with an integer
store in the store buffer, can cause a processor deadlock under
certain conditions.

Executing a DMB instruction before saving NEON/VFP registers and before
return to userspace makes it safe to run code which includes similar
counter-measures.  Userspace code can still trigger the deadlock, so
a different workaround is required to safely run untrusted code.

See ARM Cortex-A8 Errata Notice (PR120-PRDC-008070) for full details.

Signed-off-by: Mans Rullgard <mans@mansr.com>
---

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index aa475d9..41d536e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1117,6 +1117,22 @@ config NEON
 	  Say Y to include support code for NEON, the ARMv7 Advanced SIMD
 	  Extension.
 
+config ARM_ERRATUM_451034
+	bool "Enable workaround for ARM erratum 451034"
+	depends on VFPv3
+	help
+	  On Cortex-A8 r1p0 and r1p1, executing a NEON store with an integer
+	  store in the store buffer, can cause a processor deadlock under
+	  certain conditions.
+
+	  See ARM Cortex-A8 Errata Notice (PR120-PRDC-008070) for full details.
+
+	  Say Y to include a partial workaround.
+
+	  WARNING: Even with this option enabled, userspace code can trigger
+	  the deadlock.	 To safely run untrusted code, a different fix is
+	  required.
+
 endmenu
 
 menu "Userspace binary formats"
diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
index 422f3cc..934798b 100644
--- a/arch/arm/include/asm/vfpmacros.h
+++ b/arch/arm/include/asm/vfpmacros.h
@@ -32,6 +32,9 @@
 
 	@ write all the working registers out of the VFP
 	.macro	VFPFSTMIA, base, tmp
+#ifdef CONFIG_ARM_ERRATUM_451034
+	dmb
+#endif
 #if __LINUX_ARM_ARCH__ < 6
 	STC	p11, cr0, [\base],#33*4		    @ FSTMIAX \base!, {d0-d15}
 #else
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 060d7e2..9799a35 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -69,6 +69,10 @@ no_work_pending:
 	/* perform architecture specific actions before user return */
 	arch_ret_to_user r1, lr
 
+#ifdef CONFIG_ARM_ERRATUM_451034
+	dmb
+#endif
+
 	@ slow_restore_user_regs
 	ldr	r1, [sp, #S_PSR]		@ get calling cpsr
 	ldr	lr, [sp, #S_PC]!		@ get pc
