diff options
| author | Robin Murphy <robin.murphy@arm.com> | 2014-09-25 11:56:19 +0100 | 
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-09-25 15:32:57 +0100 | 
| commit | 5ca918e5e3f9df4634077c06585c42bc6a8d699a (patch) | |
| tree | 09ba26eae5c513a24604e4c707b9ee9aa5acab95 | |
| parent | 2c553ac19e73235b61b67fdc5c14be9913a2758d (diff) | |
ARM: 8165/1: alignment: don't break misaligned NEON load/store
The alignment fixup incorrectly decodes faulting ARM VLDn/VSTn
instructions (where the optional alignment hint is given but incorrect)
as LDR/STR, leading to register corruption. Detect these and correctly
treat them as unhandled, so that userspace gets the fault it expects.
Reported-by: Simon Hosie <simon.hosie@arm.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | arch/arm/mm/alignment.c | 3 | 
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 0c1ab49e5f7b..83792f4324ea 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -41,6 +41,7 @@   * This code is not portable to processors with late data abort handling.   */  #define CODING_BITS(i)	(i & 0x0e000000) +#define COND_BITS(i)	(i & 0xf0000000)  #define LDST_I_BIT(i)	(i & (1 << 26))		/* Immediate constant	*/  #define LDST_P_BIT(i)	(i & (1 << 24))		/* Preindex		*/ @@ -821,6 +822,8 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)  		break;  	case 0x04000000:	/* ldr or str immediate */ +		if (COND_BITS(instr) == 0xf0000000) /* NEON VLDn, VSTn */ +			goto bad;  		offset.un = OFFSET_BITS(instr);  		handler = do_alignment_ldrstr;  		break;  | 
