From: Kaz K. <kk...@rr...> - 2007-06-16 22:20:47
|
Hi, I'm working on the latest GNU libc with the 2.6.22-rc4 kernel and I've found a few kernel problems. This is the first one. We use R0 as the 5th argument of syscall. When the syscall restarts after signal handling, we should restore the old value of R0. The attached patch does it. Without this patch, I've experienced random failures in the situation which signals are issued frequently. Regards, kaz Signed-off-by: Kaz Kojima <kk...@rr...> --- GIT/linux-2.6/arch/sh/kernel/signal.c 2007-06-09 07:33:58.000000000 +0900 +++ linux-2.6.22-rc4/arch/sh/kernel/signal.c 2007-06-15 10:56:43.000000000 +0900 @@ -481,7 +481,7 @@ give_sigsegv: static int handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs) + sigset_t *oldset, struct pt_regs *regs, unsigned int save_r0) { int ret; @@ -500,6 +500,7 @@ handle_signal(unsigned long sig, struct } /* fallthrough */ case -ERESTARTNOINTR: + regs->regs[0] = save_r0; regs->pc -= instruction_size( ctrl_inw(regs->pc - 4)); break; @@ -583,7 +584,8 @@ static void do_signal(struct pt_regs *re signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { + if (handle_signal(signr, &ka, &info, oldset, regs, save_r0) + == 0) { /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply |