diff options
| -rw-r--r-- | arch/m32r/kernel/signal.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index a56fcbd8abe6..7bbe38645ed5 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
| @@ -251,6 +251,19 @@ give_sigsegv: | |||
| 251 | return -EFAULT; | 251 | return -EFAULT; |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | static int prev_insn(struct pt_regs *regs) | ||
| 255 | { | ||
| 256 | u16 inst; | ||
| 257 | if (get_user(&inst, (u16 __user *)(regs->bpc - 2))) | ||
| 258 | return -EFAULT; | ||
| 259 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
| 260 | regs->bpc -= 2; | ||
| 261 | else | ||
| 262 | regs->bpc -= 4; | ||
| 263 | regs->syscall_nr = -1; | ||
| 264 | return 0; | ||
| 265 | } | ||
| 266 | |||
| 254 | /* | 267 | /* |
| 255 | * OK, we're invoking a handler | 268 | * OK, we're invoking a handler |
| 256 | */ | 269 | */ |
| @@ -259,8 +272,6 @@ static int | |||
| 259 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | 272 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, |
| 260 | sigset_t *oldset, struct pt_regs *regs) | 273 | sigset_t *oldset, struct pt_regs *regs) |
| 261 | { | 274 | { |
| 262 | unsigned short inst; | ||
| 263 | |||
| 264 | /* Are we from a system call? */ | 275 | /* Are we from a system call? */ |
| 265 | if (regs->syscall_nr >= 0) { | 276 | if (regs->syscall_nr >= 0) { |
| 266 | /* If so, check system call restarting.. */ | 277 | /* If so, check system call restarting.. */ |
| @@ -278,12 +289,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 278 | /* fallthrough */ | 289 | /* fallthrough */ |
| 279 | case -ERESTARTNOINTR: | 290 | case -ERESTARTNOINTR: |
| 280 | regs->r0 = regs->orig_r0; | 291 | regs->r0 = regs->orig_r0; |
| 281 | inst = *(unsigned short *)(regs->bpc - 2); | 292 | if (prev_insn(regs) < 0) |
| 282 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | 293 | return -EFAULT; |
| 283 | regs->bpc -= 2; | ||
| 284 | else | ||
| 285 | regs->bpc -= 4; | ||
| 286 | regs->syscall_nr = -1; | ||
| 287 | } | 294 | } |
| 288 | } | 295 | } |
| 289 | 296 | ||
| @@ -310,7 +317,6 @@ static void do_signal(struct pt_regs *regs) | |||
| 310 | siginfo_t info; | 317 | siginfo_t info; |
| 311 | int signr; | 318 | int signr; |
| 312 | struct k_sigaction ka; | 319 | struct k_sigaction ka; |
| 313 | unsigned short inst; | ||
| 314 | sigset_t *oldset; | 320 | sigset_t *oldset; |
| 315 | 321 | ||
| 316 | /* | 322 | /* |
| @@ -353,21 +359,11 @@ static void do_signal(struct pt_regs *regs) | |||
| 353 | regs->r0 == -ERESTARTSYS || | 359 | regs->r0 == -ERESTARTSYS || |
| 354 | regs->r0 == -ERESTARTNOINTR) { | 360 | regs->r0 == -ERESTARTNOINTR) { |
| 355 | regs->r0 = regs->orig_r0; | 361 | regs->r0 = regs->orig_r0; |
| 356 | inst = *(unsigned short *)(regs->bpc - 2); | 362 | prev_insn(regs); |
| 357 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
| 358 | regs->bpc -= 2; | ||
| 359 | else | ||
| 360 | regs->bpc -= 4; | ||
| 361 | regs->syscall_nr = -1; | ||
| 362 | } else if (regs->r0 == -ERESTART_RESTARTBLOCK){ | 363 | } else if (regs->r0 == -ERESTART_RESTARTBLOCK){ |
| 363 | regs->r0 = regs->orig_r0; | 364 | regs->r0 = regs->orig_r0; |
| 364 | regs->r7 = __NR_restart_syscall; | 365 | regs->r7 = __NR_restart_syscall; |
| 365 | inst = *(unsigned short *)(regs->bpc - 2); | 366 | prev_insn(regs); |
| 366 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
| 367 | regs->bpc -= 2; | ||
| 368 | else | ||
| 369 | regs->bpc -= 4; | ||
| 370 | regs->syscall_nr = -1; | ||
| 371 | } | 367 | } |
| 372 | } | 368 | } |
| 373 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 369 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { |
