summary refs log tree commit diff
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 7624677f6628..d61dd599169f 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 ffe3e3ee580d..a5323364cbca 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 209cc9b42186..9005b2f12aaa 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 d7d98d691c64..b32c35a7c0a3 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 7b40f0ff3dfc..1446d12ba220 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. */