|
@@ -310,6 +310,35 @@ give_sigsegv:
|
|
return -EFAULT;
|
|
return -EFAULT;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Return -1L or the syscall number that @regs is executing.
|
|
|
|
+ */
|
|
|
|
+static long current_syscall(struct pt_regs *regs)
|
|
|
|
+{
|
|
|
|
+ /*
|
|
|
|
+ * We always sign-extend a -1 value being set here,
|
|
|
|
+ * so this is always either -1L or a syscall number.
|
|
|
|
+ */
|
|
|
|
+ return regs->orig_ax;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Return a value that is -EFOO if the system call in @regs->orig_ax
|
|
|
|
+ * returned an error. This only works for @regs from @current.
|
|
|
|
+ */
|
|
|
|
+static long current_syscall_ret(struct pt_regs *regs)
|
|
|
|
+{
|
|
|
|
+#ifdef CONFIG_IA32_EMULATION
|
|
|
|
+ if (test_thread_flag(TIF_IA32))
|
|
|
|
+ /*
|
|
|
|
+ * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
|
|
|
|
+ * and will match correctly in comparisons.
|
|
|
|
+ */
|
|
|
|
+ return (int) regs->ax;
|
|
|
|
+#endif
|
|
|
|
+ return regs->ax;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* OK, we're invoking a handler
|
|
* OK, we're invoking a handler
|
|
*/
|
|
*/
|
|
@@ -327,9 +356,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* Are we from a system call? */
|
|
/* Are we from a system call? */
|
|
- if ((long)regs->orig_ax >= 0) {
|
|
|
|
|
|
+ if (current_syscall(regs) >= 0) {
|
|
/* If so, check system call restarting.. */
|
|
/* If so, check system call restarting.. */
|
|
- switch (regs->ax) {
|
|
|
|
|
|
+ switch (current_syscall_ret(regs)) {
|
|
case -ERESTART_RESTARTBLOCK:
|
|
case -ERESTART_RESTARTBLOCK:
|
|
case -ERESTARTNOHAND:
|
|
case -ERESTARTNOHAND:
|
|
regs->ax = -EINTR;
|
|
regs->ax = -EINTR;
|
|
@@ -426,10 +455,9 @@ static void do_signal(struct pt_regs *regs)
|
|
}
|
|
}
|
|
|
|
|
|
/* Did we come from a system call? */
|
|
/* Did we come from a system call? */
|
|
- if ((long)regs->orig_ax >= 0) {
|
|
|
|
|
|
+ if (current_syscall(regs) >= 0) {
|
|
/* Restart the system call - no handlers present */
|
|
/* Restart the system call - no handlers present */
|
|
- long res = regs->ax;
|
|
|
|
- switch (res) {
|
|
|
|
|
|
+ switch (current_syscall_ret(regs)) {
|
|
case -ERESTARTNOHAND:
|
|
case -ERESTARTNOHAND:
|
|
case -ERESTARTSYS:
|
|
case -ERESTARTSYS:
|
|
case -ERESTARTNOINTR:
|
|
case -ERESTARTNOINTR:
|