aboutsummaryrefslogtreecommitdiff
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2017-01-27 10:45:27 -0800
committerMister Oyster <oysterized@gmail.com>2017-07-04 11:51:29 +0200
commit0d579bbb5bc024776de5e0c7e9f2081b09e4786c (patch)
treec6007a05b90cc3dc97fb42296710e650234fb5e4 /arch/arc/kernel
parent1e11e3eebe655ca84b5f0dc5b8a6febdd68266be (diff)
ARC: [arcompact] handle unaligned access delay slot corner case
commit 9aed02feae57bf7a40cb04ea0e3017cb7a998db4 upstream. After emulating an unaligned access in delay slot of a branch, we pretend as the delay slot never happened - so return back to actual branch target (or next PC if branch was not taken). Curently we did this by handling STATUS32.DE, we also need to clear the BTA.T bit, which is disregarded when returning from original misaligned exception, but could cause weirdness if it took the interrupt return path (in case interrupt was acive too) One ARC700 customer ran into this when enabling unaligned access fixup for kernel mode accesses as well Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Signed-off-by: Willy Tarreau <w@1wt.eu>
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r--arch/arc/kernel/unaligned.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c
index 116d3e09b..b13b422a8 100644
--- a/arch/arc/kernel/unaligned.c
+++ b/arch/arc/kernel/unaligned.c
@@ -228,8 +228,9 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs,
if (state.fault)
goto fault;
+ /* clear any remanants of delay slot */
if (delay_mode(regs)) {
- regs->ret = regs->bta;
+ regs->ret = regs->bta ~1U;
regs->status32 &= ~STATUS_DE_MASK;
} else {
regs->ret += state.instr_len;