forked from mirrors/linux
		
	struct timex is not y2038 safe.
Replace all uses of timex with y2038 safe __kernel_timex.
Note that struct __kernel_timex is an ABI interface definition.
We could define a new structure based on __kernel_timex that
is only available internally instead. Right now, there isn't
a strong motivation for this as the structure is isolated to
a few defined struct timex interfaces and such a structure would
be exactly the same as struct timex.
The patch was generated by the following coccinelle script:
virtual patch
@depends on patch forall@
identifier ts;
expression e;
@@
(
- struct timex ts;
+ struct __kernel_timex ts;
|
- struct timex ts = {};
+ struct __kernel_timex ts = {};
|
- struct timex ts = e;
+ struct __kernel_timex ts = e;
|
- struct timex *ts;
+ struct __kernel_timex *ts;
|
(memset \| copy_from_user \| copy_to_user \)(...,
- sizeof(struct timex))
+ sizeof(struct __kernel_timex))
)
@depends on patch forall@
identifier ts;
identifier fn;
@@
fn(...,
- struct timex *ts,
+ struct __kernel_timex *ts,
...) {
...
}
@depends on patch forall@
identifier ts;
identifier fn;
@@
fn(...,
- struct timex *ts) {
+ struct __kernel_timex *ts) {
...
}
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: linux-alpha@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
		
	
			
		
			
				
	
	
		
			234 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#ifndef _LINUX_TIME32_H
 | 
						|
#define _LINUX_TIME32_H
 | 
						|
/*
 | 
						|
 * These are all interfaces based on the old time_t definition
 | 
						|
 * that overflows in 2038 on 32-bit architectures. New code
 | 
						|
 * should use the replacements based on time64_t and timespec64.
 | 
						|
 *
 | 
						|
 * Any interfaces in here that become unused as we migrate
 | 
						|
 * code to time64_t should get removed.
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/time64.h>
 | 
						|
#include <linux/timex.h>
 | 
						|
 | 
						|
#define TIME_T_MAX	(time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
 | 
						|
 | 
						|
typedef s32		old_time32_t;
 | 
						|
 | 
						|
struct old_timespec32 {
 | 
						|
	old_time32_t	tv_sec;
 | 
						|
	s32		tv_nsec;
 | 
						|
};
 | 
						|
 | 
						|
struct old_timeval32 {
 | 
						|
	old_time32_t	tv_sec;
 | 
						|
	s32		tv_usec;
 | 
						|
};
 | 
						|
 | 
						|
struct old_itimerspec32 {
 | 
						|
	struct old_timespec32 it_interval;
 | 
						|
	struct old_timespec32 it_value;
 | 
						|
};
 | 
						|
 | 
						|
struct old_utimbuf32 {
 | 
						|
	old_time32_t	actime;
 | 
						|
	old_time32_t	modtime;
 | 
						|
};
 | 
						|
 | 
						|
struct old_timex32 {
 | 
						|
	u32 modes;
 | 
						|
	s32 offset;
 | 
						|
	s32 freq;
 | 
						|
	s32 maxerror;
 | 
						|
	s32 esterror;
 | 
						|
	s32 status;
 | 
						|
	s32 constant;
 | 
						|
	s32 precision;
 | 
						|
	s32 tolerance;
 | 
						|
	struct old_timeval32 time;
 | 
						|
	s32 tick;
 | 
						|
	s32 ppsfreq;
 | 
						|
	s32 jitter;
 | 
						|
	s32 shift;
 | 
						|
	s32 stabil;
 | 
						|
	s32 jitcnt;
 | 
						|
	s32 calcnt;
 | 
						|
	s32 errcnt;
 | 
						|
	s32 stbcnt;
 | 
						|
	s32 tai;
 | 
						|
 | 
						|
	s32:32; s32:32; s32:32; s32:32;
 | 
						|
	s32:32; s32:32; s32:32; s32:32;
 | 
						|
	s32:32; s32:32; s32:32;
 | 
						|
};
 | 
						|
 | 
						|
extern int get_old_timespec32(struct timespec64 *, const void __user *);
 | 
						|
extern int put_old_timespec32(const struct timespec64 *, void __user *);
 | 
						|
extern int get_old_itimerspec32(struct itimerspec64 *its,
 | 
						|
			const struct old_itimerspec32 __user *uits);
 | 
						|
extern int put_old_itimerspec32(const struct itimerspec64 *its,
 | 
						|
			struct old_itimerspec32 __user *uits);
 | 
						|
struct __kernel_timex;
 | 
						|
int get_old_timex32(struct __kernel_timex *, const struct old_timex32 __user *);
 | 
						|
int put_old_timex32(struct old_timex32 __user *, const struct __kernel_timex *);
 | 
						|
 | 
						|
#if __BITS_PER_LONG == 64
 | 
						|
 | 
						|
/* timespec64 is defined as timespec here */
 | 
						|
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
 | 
						|
{
 | 
						|
	return *(const struct timespec *)&ts64;
 | 
						|
}
 | 
						|
 | 
						|
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
 | 
						|
{
 | 
						|
	return *(const struct timespec64 *)&ts;
 | 
						|
}
 | 
						|
 | 
						|
#else
 | 
						|
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
 | 
						|
{
 | 
						|
	struct timespec ret;
 | 
						|
 | 
						|
	ret.tv_sec = (time_t)ts64.tv_sec;
 | 
						|
	ret.tv_nsec = ts64.tv_nsec;
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
 | 
						|
{
 | 
						|
	struct timespec64 ret;
 | 
						|
 | 
						|
	ret.tv_sec = ts.tv_sec;
 | 
						|
	ret.tv_nsec = ts.tv_nsec;
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static inline int timespec_equal(const struct timespec *a,
 | 
						|
				 const struct timespec *b)
 | 
						|
{
 | 
						|
	return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * lhs < rhs:  return <0
 | 
						|
 * lhs == rhs: return 0
 | 
						|
 * lhs > rhs:  return >0
 | 
						|
 */
 | 
						|
static inline int timespec_compare(const struct timespec *lhs, const struct timespec *rhs)
 | 
						|
{
 | 
						|
	if (lhs->tv_sec < rhs->tv_sec)
 | 
						|
		return -1;
 | 
						|
	if (lhs->tv_sec > rhs->tv_sec)
 | 
						|
		return 1;
 | 
						|
	return lhs->tv_nsec - rhs->tv_nsec;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Returns true if the timespec is norm, false if denorm:
 | 
						|
 */
 | 
						|
static inline bool timespec_valid(const struct timespec *ts)
 | 
						|
{
 | 
						|
	/* Dates before 1970 are bogus */
 | 
						|
	if (ts->tv_sec < 0)
 | 
						|
		return false;
 | 
						|
	/* Can't have more nanoseconds then a second */
 | 
						|
	if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
 | 
						|
		return false;
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * timespec_to_ns - Convert timespec to nanoseconds
 | 
						|
 * @ts:		pointer to the timespec variable to be converted
 | 
						|
 *
 | 
						|
 * Returns the scalar nanosecond representation of the timespec
 | 
						|
 * parameter.
 | 
						|
 */
 | 
						|
static inline s64 timespec_to_ns(const struct timespec *ts)
 | 
						|
{
 | 
						|
	return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * ns_to_timespec - Convert nanoseconds to timespec
 | 
						|
 * @nsec:	the nanoseconds value to be converted
 | 
						|
 *
 | 
						|
 * Returns the timespec representation of the nsec parameter.
 | 
						|
 */
 | 
						|
extern struct timespec ns_to_timespec(const s64 nsec);
 | 
						|
 | 
						|
/**
 | 
						|
 * timespec_add_ns - Adds nanoseconds to a timespec
 | 
						|
 * @a:		pointer to timespec to be incremented
 | 
						|
 * @ns:		unsigned nanoseconds value to be added
 | 
						|
 *
 | 
						|
 * This must always be inlined because its used from the x86-64 vdso,
 | 
						|
 * which cannot call other kernel functions.
 | 
						|
 */
 | 
						|
static __always_inline void timespec_add_ns(struct timespec *a, u64 ns)
 | 
						|
{
 | 
						|
	a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
 | 
						|
	a->tv_nsec = ns;
 | 
						|
}
 | 
						|
 | 
						|
static inline unsigned long mktime(const unsigned int year,
 | 
						|
			const unsigned int mon, const unsigned int day,
 | 
						|
			const unsigned int hour, const unsigned int min,
 | 
						|
			const unsigned int sec)
 | 
						|
{
 | 
						|
	return mktime64(year, mon, day, hour, min, sec);
 | 
						|
}
 | 
						|
 | 
						|
static inline bool timeval_valid(const struct timeval *tv)
 | 
						|
{
 | 
						|
	/* Dates before 1970 are bogus */
 | 
						|
	if (tv->tv_sec < 0)
 | 
						|
		return false;
 | 
						|
 | 
						|
	/* Can't have more microseconds then a second */
 | 
						|
	if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
 | 
						|
		return false;
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * timeval_to_ns - Convert timeval to nanoseconds
 | 
						|
 * @ts:		pointer to the timeval variable to be converted
 | 
						|
 *
 | 
						|
 * Returns the scalar nanosecond representation of the timeval
 | 
						|
 * parameter.
 | 
						|
 */
 | 
						|
static inline s64 timeval_to_ns(const struct timeval *tv)
 | 
						|
{
 | 
						|
	return ((s64) tv->tv_sec * NSEC_PER_SEC) +
 | 
						|
		tv->tv_usec * NSEC_PER_USEC;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * ns_to_timeval - Convert nanoseconds to timeval
 | 
						|
 * @nsec:	the nanoseconds value to be converted
 | 
						|
 *
 | 
						|
 * Returns the timeval representation of the nsec parameter.
 | 
						|
 */
 | 
						|
extern struct timeval ns_to_timeval(const s64 nsec);
 | 
						|
extern struct __kernel_old_timeval ns_to_kernel_old_timeval(s64 nsec);
 | 
						|
 | 
						|
/*
 | 
						|
 * Old names for the 32-bit time_t interfaces, these will be removed
 | 
						|
 * when everything uses the new names.
 | 
						|
 */
 | 
						|
#define compat_time_t		old_time32_t
 | 
						|
#define compat_timeval		old_timeval32
 | 
						|
#define compat_timespec		old_timespec32
 | 
						|
#define compat_itimerspec	old_itimerspec32
 | 
						|
#define ns_to_compat_timeval	ns_to_old_timeval32
 | 
						|
#define get_compat_itimerspec64	get_old_itimerspec32
 | 
						|
#define put_compat_itimerspec64	put_old_itimerspec32
 | 
						|
#define compat_get_timespec64	get_old_timespec32
 | 
						|
#define compat_put_timespec64	put_old_timespec32
 | 
						|
 | 
						|
#endif
 |