summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c3
-rw-r--r--arch/sh/kernel/kgdb_stub.c2
-rw-r--r--arch/sh/kernel/process.c4
-rw-r--r--arch/sh/kernel/signal.c11
-rw-r--r--arch/sh/kernel/traps.c4
5 files changed, 14 insertions, 10 deletions
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index 7624677f662..d61dd599169 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -16,6 +16,7 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <asm/processor.h>
+#include <asm/system.h>
#include <asm/io.h>
/* The PR (precision) bit in the FP Status Register must be clear when
@@ -265,7 +266,7 @@ ieee_fpe_handler (struct pt_regs *regs)
nextpc = regs->pr;
finsn = *(unsigned short *) (regs->pc + 2);
} else {
- nextpc = regs->pc + 2;
+ nextpc = regs->pc + instruction_size(insn);
finsn = insn;
}
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index ffe3e3ee580..a5323364cbc 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -867,7 +867,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
trap 0xff, since that indicates a compiled-in breakpoint which
will not be replaced (and we would retake the trap forever) */
if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
- trap_registers.pc -= instruction_size(trap_registers.pc);
+ trap_registers.pc -= 2;
/* Undo any stepping we may have done */
undo_single_step();
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 209cc9b4218..9005b2f12aa 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -498,7 +498,7 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5,
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
/* Rewind */
- regs->pc -= instruction_size(regs->pc);
+ regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
if (notify_die(DIE_TRAP, regs, regs->tra & 0xff,
SIGTRAP) == NOTIFY_STOP)
@@ -517,7 +517,7 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5,
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
/* Rewind */
- regs->pc -= instruction_size(regs->pc);
+ regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
if (notify_die(DIE_TRAP, regs, TRAPA_BUG_OPCODE & 0xff,
SIGTRAP) == NOTIFY_STOP)
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index d7d98d691c6..b32c35a7c0a 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -500,7 +500,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
}
/* fallthrough */
case -ERESTARTNOINTR:
- regs->pc -= instruction_size(regs->pc);
+ regs->pc -= instruction_size(
+ ctrl_inw(regs->pc - 4));
+ break;
}
} else {
/* gUSA handling */
@@ -516,7 +518,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
regs->regs[15] = regs->regs[1];
if (regs->pc < regs->regs[0])
/* Go to rewind point #1 */
- regs->pc = regs->regs[0] + offset - 2;
+ regs->pc = regs->regs[0] + offset -
+ instruction_size(ctrl_inw(regs->pc-4));
}
#ifdef CONFIG_PREEMPT
local_irq_restore(flags);
@@ -600,9 +603,9 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
regs->regs[0] == -ERESTARTSYS ||
regs->regs[0] == -ERESTARTNOINTR) {
regs->regs[0] = save_r0;
- regs->pc -= instruction_size(regs->pc);
+ regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
} else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
- regs->pc -= instruction_size(regs->pc);
+ regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
regs->regs[3] = __NR_restart_syscall;
}
}
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 7b40f0ff3df..1446d12ba22 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -505,7 +505,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
simple:
ret = handle_unaligned_ins(instruction,regs);
if (ret==0)
- regs->pc += 2;
+ regs->pc += instruction_size(instruction);
return ret;
}
#endif /* CONFIG_CPU_SH2A */
@@ -682,7 +682,7 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
err = do_fpu_inst(inst, regs);
if (!err) {
- regs->pc += 2;
+ regs->pc += instruction_size(inst);
return;
}
/* not a FPU inst. */