From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753097AbbF2O0c (ORCPT ); Mon, 29 Jun 2015 10:26:32 -0400 Received: from mail-pd0-f180.google.com ([209.85.192.180]:34685 "EHLO mail-pd0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751850AbbF2O0U (ORCPT ); Mon, 29 Jun 2015 10:26:20 -0400 From: Bamvor Zhang Jian To: arnd@arndb.de, john.stultz@linaro.org, tglx@linutronix.de Cc: y2039@lists.linaro.org, linux-kernel@vger.kernel.org, bamvor.zhangjian@linaro.org Subject: [RFC PATCH v2 1/4] y2038: add 64bit time_t support in timeval for 32bit architecture Date: Mon, 29 Jun 2015 22:23:24 +0800 Message-Id: <1435587807-10008-2-git-send-email-bamvor.zhangjian@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1435587807-10008-1-git-send-email-bamvor.zhangjian@linaro.org> References: <1435587807-10008-1-git-send-email-bamvor.zhangjian@linaro.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add timeval64 structure and copy_(from)|(to)_user functions. Add __kernel_timeval for syscalls. This changes follow the similar way in the followings commit: 361a3bf time64: Add time64.h header and define struct timespec64 49cd6f8 time: More core infrastructure for timespec64 ca2c9c5 y2038: introduce struct __kernel_timespec[1]. [1] http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/commit/?h=y2038-syscalls&id=9005d4f4a44fc56bd0a1fe7c08e8e3f13eb75de7 Signed-off-by: Bamvor Zhang Jian --- include/linux/time64.h | 20 ++++++++++++++++++-- include/uapi/linux/time.h | 10 ++++++++++ kernel/time/time.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/include/linux/time64.h b/include/linux/time64.h index 77b5df2..2ca4f85 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -1,24 +1,35 @@ #ifndef _LINUX_TIME64_H #define _LINUX_TIME64_H -#include -#include typedef __s64 time64_t; +#ifndef CONFIG_COMPAT_TIME +# define __kernel_timeval timeval +#endif + /* * This wants to go into uapi/linux/time.h once we agreed about the * userspace interfaces. */ #if __BITS_PER_LONG == 64 # define timespec64 timespec +# define timeval64 timeval #else struct timespec64 { time64_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; + +struct timeval64 { + time64_t tv_sec; /* seconds */ + __kernel_suseconds_t tv_usec; /* microseconds */ +}; #endif +#include +#include + /* Parameters used to convert the timespec values: */ #define MSEC_PER_SEC 1000L #define USEC_PER_MSEC 1000L @@ -189,4 +200,9 @@ static __always_inline void timespec64_add_ns(struct timespec64 *a, u64 ns) #endif +extern int get_timeval64(struct timeval64 *tv, + const struct __kernel_timeval __user *utv); +extern int put_timeval64(const struct timeval64 *tv, + struct __kernel_timeval __user *utv); + #endif /* _LINUX_TIME64_H */ diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h index e75e1b6..2ca6a31 100644 --- a/include/uapi/linux/time.h +++ b/include/uapi/linux/time.h @@ -66,4 +66,14 @@ struct itimerval { */ #define TIMER_ABSTIME 0x01 +/* types based on 64-bit time_t */ +#ifndef __kernel_timeval +typedef __s64 __kernel_time64_t; + +struct __kernel_timeval { + __kernel_time64_t tv_sec; + __s64 tv_usec; +}; +#endif + #endif /* _UAPI_LINUX_TIME_H */ diff --git a/kernel/time/time.c b/kernel/time/time.c index 85d5bb1..adf0455 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -759,3 +760,38 @@ struct timespec timespec_add_safe(const struct timespec lhs, return res; } + +int get_timeval64(struct timeval64 *tv, + const struct __kernel_timeval __user *utv) +{ + struct __kernel_timeval ktv; + int ret; + + ret = copy_from_user(&ktv, utv, sizeof(ktv)); + if (ret) + return -EFAULT; + + tv->tv_sec = ktv.tv_sec; + if (!IS_ENABLED(CONFIG_64BIT) +#ifdef CONFIG_COMPAT + || is_compat_task() +#endif + ) + ktv.tv_usec &= 0xfffffffful; + tv->tv_usec = ktv.tv_usec; + + return 0; +} +EXPORT_SYMBOL_GPL(get_timeval64); + +int put_timeval64(const struct timeval64 *tv, + struct __kernel_timeval __user *utv) +{ + struct __kernel_timeval ktv = { + .tv_sec = tv->tv_sec, + .tv_usec = tv->tv_usec + }; + return copy_to_user(utv, &utv, sizeof(ktv)) ? -EFAULT : 0; +} +EXPORT_SYMBOL_GPL(put_timeval64); + -- 2.1.4