Commit e3d5a27d authored by Paul Mackerras's avatar Paul Mackerras Committed by Linus Torvalds

Allow times and time system calls to return small negative values

At the moment, the times() system call will appear to fail for a period
shortly after boot, while the value it want to return is between -4095 and
-1.  The same thing will also happen for the time() system call on 32-bit
platforms some time in 2106 or so.

On some platforms, such as x86, this is unavoidable because of the system
call ABI, but other platforms such as powerpc have a separate error
indication from the return value, so system calls can in fact return small
negative values without indicating an error.  On those platforms,
force_successful_syscall_return() provides a way to indicate that the
system call return value should not be treated as an error even if it is
in the range which would normally be taken as a negative error number.

This adds a force_successful_syscall_return() call to the time() and
times() system calls plus their 32-bit compat versions, so that they don't
erroneously indicate an error on those platforms whose system call ABI has
a separate error indication.  This will not affect anything on other
platforms.

Joakim Tjernlund added the fix for time() and the compat versions of
time() and times(), after I did the fix for times().
Signed-off-by: default avatarJoakim Tjernlund <Joakim.Tjernlund@transmode.se>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent af9379c7
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/migrate.h> #include <linux/migrate.h>
#include <linux/posix-timers.h> #include <linux/posix-timers.h>
#include <linux/times.h> #include <linux/times.h>
#include <linux/ptrace.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -229,6 +230,7 @@ asmlinkage long compat_sys_times(struct compat_tms __user *tbuf) ...@@ -229,6 +230,7 @@ asmlinkage long compat_sys_times(struct compat_tms __user *tbuf)
if (copy_to_user(tbuf, &tmp, sizeof(tmp))) if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
return -EFAULT; return -EFAULT;
} }
force_successful_syscall_return();
return compat_jiffies_to_clock_t(jiffies); return compat_jiffies_to_clock_t(jiffies);
} }
...@@ -894,8 +896,9 @@ asmlinkage long compat_sys_time(compat_time_t __user * tloc) ...@@ -894,8 +896,9 @@ asmlinkage long compat_sys_time(compat_time_t __user * tloc)
if (tloc) { if (tloc) {
if (put_user(i,tloc)) if (put_user(i,tloc))
i = -EFAULT; return -EFAULT;
} }
force_successful_syscall_return();
return i; return i;
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/task_io_accounting_ops.h> #include <linux/task_io_accounting_ops.h>
#include <linux/seccomp.h> #include <linux/seccomp.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/ptrace.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
...@@ -927,6 +928,7 @@ asmlinkage long sys_times(struct tms __user * tbuf) ...@@ -927,6 +928,7 @@ asmlinkage long sys_times(struct tms __user * tbuf)
if (copy_to_user(tbuf, &tmp, sizeof(struct tms))) if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
return -EFAULT; return -EFAULT;
} }
force_successful_syscall_return();
return (long) jiffies_64_to_clock_t(get_jiffies_64()); return (long) jiffies_64_to_clock_t(get_jiffies_64());
} }
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/math64.h> #include <linux/math64.h>
#include <linux/ptrace.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unistd.h> #include <asm/unistd.h>
...@@ -65,8 +66,9 @@ asmlinkage long sys_time(time_t __user * tloc) ...@@ -65,8 +66,9 @@ asmlinkage long sys_time(time_t __user * tloc)
if (tloc) { if (tloc) {
if (put_user(i,tloc)) if (put_user(i,tloc))
i = -EFAULT; return -EFAULT;
} }
force_successful_syscall_return();
return i; return i;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment