summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-08-08 02:47:01 (GMT)
committerRalf Baechle <ralf@linux-mips.org>2006-09-27 12:37:33 (GMT)
commit13fdd31abec5f48cf97693bd14d2e11e0779b4ca (patch)
tree66eff81e11545ef5259812a1a83dd75a8d520567 /arch/mips
parent847b9dfccad7dd34b2e44b1c6ceeb1c4cb88084a (diff)
downloadlinux-fsl-qoriq-13fdd31abec5f48cf97693bd14d2e11e0779b4ca.tar.xz
[MIPS] Avoid double signal restarting.
In entry.S resume_userspace ... jal do_notify_resume form a loop through which the kernel will iterate as long as work is pending. If we iterate through this loop more than once with no signal pending for at least one but the last iteration we will take do the syscall restarting multiple times resulting in a syscall return prior to the the syscall instruction in userspace. This may happen when debugging a multithreaded program. Debugging and original fix by Maciej; extended to other ABIs by me. Signed-off-by: Maciej W. Rozycki <macro@mips.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/kernel/irixsig.c1
-rw-r--r--arch/mips/kernel/signal.c2
-rw-r--r--arch/mips/kernel/signal32.c1
3 files changed, 3 insertions, 1 deletions
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 052ea15..7193647 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -224,6 +224,7 @@ void do_irix_signal(struct pt_regs *regs)
regs->regs[7] = regs->regs[26];
regs->cp0_epc -= 4;
}
+ regs->regs[0] = 0; /* Don't deal with this again. */
}
/*
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 56bf429..b9d358e 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -429,7 +429,6 @@ void do_signal(struct pt_regs *regs)
else
oldset = &current->blocked;
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Whee! Actually deliver the signal. */
@@ -464,6 +463,7 @@ void do_signal(struct pt_regs *regs)
regs->regs[7] = regs->regs[26];
regs->cp0_epc -= 4;
}
+ regs->regs[0] = 0; /* Don't deal with this again. */
}
/*
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 282e85a..c86a5dd 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -854,6 +854,7 @@ void do_signal32(struct pt_regs *regs)
regs->regs[7] = regs->regs[26];
regs->cp0_epc -= 4;
}
+ regs->regs[0] = 0; /* Don't deal with this again. */
}
/*