summary refs log tree commit diff
path: root/arch/arm/kernel/signal.c
diff options
context:
space:
mode:
authorT.J. Purtell <tj@mobisocial.us>2013-11-06 18:38:05 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-11-07 00:19:06 +0000
commit6ecf830e5029598732e04067e325d946097519cb (patch)
treeb174b452cca9b7c9aa44a79cfa963b7c03539628 /arch/arm/kernel/signal.c
parente16b31bf47738f4498d7ce632e12d7d2a6a2492a (diff)
downloadlinux-6ecf830e5029598732e04067e325d946097519cb.tar.gz
ARM: 7880/1: Clear the IT state independent of the Thumb-2 mode
The ARM architecture reference specifies that the IT state bits in the
PSR must be all zeros in ARM mode or behavior is unspecified.  On the
Qualcomm Snapdragon S4/Krait architecture CPUs the processor continues
to consider the IT state bits while in ARM mode.  This makes it so
that some instructions are skipped by the CPU.

Signed-off-by: T.J. Purtell <tj@mobisocial.us>
[rmk+kernel@arm.linux.org.uk: fixed whitespace formatting in patch]
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/signal.c')
-rw-r--r--arch/arm/kernel/signal.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index ab3304225272..1aa5ecdd1b3d 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -375,12 +375,18 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig,
 		 */
 		thumb = handler & 1;
 
-		if (thumb) {
-			cpsr |= PSR_T_BIT;
 #if __LINUX_ARM_ARCH__ >= 7
-			/* clear the If-Then Thumb-2 execution state */
-			cpsr &= ~PSR_IT_MASK;
+		/*
+		 * Clear the If-Then Thumb-2 execution state
+		 * ARM spec requires this to be all 000s in ARM mode
+		 * Snapdragon S4/Krait misbehaves on a Thumb=>ARM
+		 * signal transition without this.
+		 */
+		cpsr &= ~PSR_IT_MASK;
 #endif
+
+		if (thumb) {
+			cpsr |= PSR_T_BIT;
 		} else
 			cpsr &= ~PSR_T_BIT;
 	}