summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/signal.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 13:08:20 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 13:08:20 -0700
commitd84c4124c4b6611301b402e8611b7e36de3bd351 (patch)
treed83cfaabfb901755d85074815ad948028dc7b03f /arch/sh/kernel/signal.c
parent932c37c375cca25175f9b6acee4c75d7a96d985f (diff)
parenta3cf4ea8729a5d448742fd5a0a003827c9f25cb6 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6: sh: Fix stacktrace simplification fallout. sh: SH7760 DMABRG support. sh: clockevent/clocksource/hrtimers/nohz TMU support. sh: Truncate MAX_ACTIVE_REGIONS for the common case. rtc: rtc-sh: Fix rtc_dev pointer for rtc_update_irq(). sh: Convert to common die chain. sh: Wire up utimensat syscall. sh: landisk mv_nr_irqs definition. sh: Fixup ndelay() xloops calculation for alternate HZ. sh: Add 32-bit opcode feature CPU flag. sh: Fix PC adjustments for varying opcode length. sh: Support for SH-2A 32-bit opcodes. sh: Kill off redundant __div64_32 symbol export. sh: Share exception vector table for SH-3/4. sh: Always define TRAPA_BUG_OPCODE. sh: __GFP_REPEAT for pte allocations, too. rtc: rtc-sh: Fix up dev_dbg() warnings. sh: generic quicklist support.
Diffstat (limited to 'arch/sh/kernel/signal.c')
-rw-r--r--arch/sh/kernel/signal.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index eb0191c374b..b32c35a7c0a 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -23,7 +23,7 @@
#include <linux/personality.h>
#include <linux/binfmts.h>
#include <linux/freezer.h>
-
+#include <asm/system.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -500,7 +500,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
}
/* fallthrough */
case -ERESTARTNOINTR:
- regs->pc -= 2;
+ 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 -= 2;
+ regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
} else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
- regs->pc -= 2;
+ regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
regs->regs[3] = __NR_restart_syscall;
}
}