| .. | .. | 
|---|
 | 1 | +// SPDX-License-Identifier: GPL-2.0  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 |  | - *  linux/kernel/time.c  | 
|---|
| 3 |  | - *  | 
|---|
| 4 | 3 |   *  Copyright (C) 1991, 1992  Linus Torvalds | 
|---|
| 5 | 4 |   * | 
|---|
| 6 |  | - *  This file contains the interface functions for the various  | 
|---|
| 7 |  | - *  time related system calls: time, stime, gettimeofday, settimeofday,  | 
|---|
| 8 |  | - *			       adjtime  | 
|---|
| 9 |  | - */  | 
|---|
| 10 |  | -/*  | 
|---|
| 11 |  | - * Modification history kernel/time.c  | 
|---|
 | 5 | + *  This file contains the interface functions for the various time related  | 
|---|
 | 6 | + *  system calls: time, stime, gettimeofday, settimeofday, adjtime  | 
|---|
 | 7 | + *  | 
|---|
 | 8 | + * Modification history:  | 
|---|
| 12 | 9 |   * | 
|---|
| 13 | 10 |   * 1993-09-02    Philip Gladstone | 
|---|
| 14 | 11 |   *      Created file with time related functions from sched/core.c and adjtimex() | 
|---|
| .. | .. | 
|---|
| 62 | 59 |   * why not move it into the appropriate arch directory (for those | 
|---|
| 63 | 60 |   * architectures that need it). | 
|---|
| 64 | 61 |   */ | 
|---|
| 65 |  | -SYSCALL_DEFINE1(time, time_t __user *, tloc)  | 
|---|
 | 62 | +SYSCALL_DEFINE1(time, __kernel_old_time_t __user *, tloc)  | 
|---|
| 66 | 63 |  { | 
|---|
| 67 |  | -	time_t i = (time_t)ktime_get_real_seconds();  | 
|---|
 | 64 | +	__kernel_old_time_t i = (__kernel_old_time_t)ktime_get_real_seconds();  | 
|---|
| 68 | 65 |   | 
|---|
| 69 | 66 |  	if (tloc) { | 
|---|
| 70 | 67 |  		if (put_user(i,tloc)) | 
|---|
| .. | .. | 
|---|
| 81 | 78 |   * architectures that need it). | 
|---|
| 82 | 79 |   */ | 
|---|
| 83 | 80 |   | 
|---|
| 84 |  | -SYSCALL_DEFINE1(stime, time_t __user *, tptr)  | 
|---|
 | 81 | +SYSCALL_DEFINE1(stime, __kernel_old_time_t __user *, tptr)  | 
|---|
| 85 | 82 |  { | 
|---|
| 86 | 83 |  	struct timespec64 tv; | 
|---|
| 87 | 84 |  	int err; | 
|---|
| .. | .. | 
|---|
| 101 | 98 |   | 
|---|
| 102 | 99 |  #endif /* __ARCH_WANT_SYS_TIME */ | 
|---|
| 103 | 100 |   | 
|---|
| 104 |  | -#ifdef CONFIG_COMPAT  | 
|---|
| 105 |  | -#ifdef __ARCH_WANT_COMPAT_SYS_TIME  | 
|---|
 | 101 | +#ifdef CONFIG_COMPAT_32BIT_TIME  | 
|---|
 | 102 | +#ifdef __ARCH_WANT_SYS_TIME32  | 
|---|
| 106 | 103 |   | 
|---|
| 107 |  | -/* compat_time_t is a 32 bit "long" and needs to get converted. */  | 
|---|
| 108 |  | -COMPAT_SYSCALL_DEFINE1(time, compat_time_t __user *, tloc)  | 
|---|
 | 104 | +/* old_time32_t is a 32 bit "long" and needs to get converted. */  | 
|---|
 | 105 | +SYSCALL_DEFINE1(time32, old_time32_t __user *, tloc)  | 
|---|
| 109 | 106 |  { | 
|---|
| 110 |  | -	compat_time_t i;  | 
|---|
 | 107 | +	old_time32_t i;  | 
|---|
| 111 | 108 |   | 
|---|
| 112 |  | -	i = (compat_time_t)ktime_get_real_seconds();  | 
|---|
 | 109 | +	i = (old_time32_t)ktime_get_real_seconds();  | 
|---|
| 113 | 110 |   | 
|---|
| 114 | 111 |  	if (tloc) { | 
|---|
| 115 | 112 |  		if (put_user(i,tloc)) | 
|---|
| .. | .. | 
|---|
| 119 | 116 |  	return i; | 
|---|
| 120 | 117 |  } | 
|---|
| 121 | 118 |   | 
|---|
| 122 |  | -COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr)  | 
|---|
 | 119 | +SYSCALL_DEFINE1(stime32, old_time32_t __user *, tptr)  | 
|---|
| 123 | 120 |  { | 
|---|
| 124 | 121 |  	struct timespec64 tv; | 
|---|
| 125 | 122 |  	int err; | 
|---|
| .. | .. | 
|---|
| 137 | 134 |  	return 0; | 
|---|
| 138 | 135 |  } | 
|---|
| 139 | 136 |   | 
|---|
| 140 |  | -#endif /* __ARCH_WANT_COMPAT_SYS_TIME */  | 
|---|
 | 137 | +#endif /* __ARCH_WANT_SYS_TIME32 */  | 
|---|
| 141 | 138 |  #endif | 
|---|
| 142 | 139 |   | 
|---|
| 143 |  | -SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,  | 
|---|
 | 140 | +SYSCALL_DEFINE2(gettimeofday, struct __kernel_old_timeval __user *, tv,  | 
|---|
| 144 | 141 |  		struct timezone __user *, tz) | 
|---|
| 145 | 142 |  { | 
|---|
| 146 | 143 |  	if (likely(tv != NULL)) { | 
|---|
| .. | .. | 
|---|
| 182 | 179 |  		return error; | 
|---|
| 183 | 180 |   | 
|---|
| 184 | 181 |  	if (tz) { | 
|---|
| 185 |  | -		/* Verify we're witin the +-15 hrs range */  | 
|---|
 | 182 | +		/* Verify we're within the +-15 hrs range */  | 
|---|
| 186 | 183 |  		if (tz->tz_minuteswest > 15*60 || tz->tz_minuteswest < -15*60) | 
|---|
| 187 | 184 |  			return -EINVAL; | 
|---|
| 188 | 185 |   | 
|---|
| .. | .. | 
|---|
| 199 | 196 |  	return 0; | 
|---|
| 200 | 197 |  } | 
|---|
| 201 | 198 |   | 
|---|
| 202 |  | -SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv,  | 
|---|
 | 199 | +SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv,  | 
|---|
| 203 | 200 |  		struct timezone __user *, tz) | 
|---|
| 204 | 201 |  { | 
|---|
| 205 | 202 |  	struct timespec64 new_ts; | 
|---|
| 206 |  | -	struct timeval user_tv;  | 
|---|
| 207 | 203 |  	struct timezone new_tz; | 
|---|
| 208 | 204 |   | 
|---|
| 209 | 205 |  	if (tv) { | 
|---|
| 210 |  | -		if (copy_from_user(&user_tv, tv, sizeof(*tv)))  | 
|---|
 | 206 | +		if (get_user(new_ts.tv_sec, &tv->tv_sec) ||  | 
|---|
 | 207 | +		    get_user(new_ts.tv_nsec, &tv->tv_usec))  | 
|---|
| 211 | 208 |  			return -EFAULT; | 
|---|
| 212 | 209 |   | 
|---|
| 213 |  | -		if (!timeval_valid(&user_tv))  | 
|---|
 | 210 | +		if (new_ts.tv_nsec > USEC_PER_SEC || new_ts.tv_nsec < 0)  | 
|---|
| 214 | 211 |  			return -EINVAL; | 
|---|
| 215 | 212 |   | 
|---|
| 216 |  | -		new_ts.tv_sec = user_tv.tv_sec;  | 
|---|
| 217 |  | -		new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;  | 
|---|
 | 213 | +		new_ts.tv_nsec *= NSEC_PER_USEC;  | 
|---|
| 218 | 214 |  	} | 
|---|
| 219 | 215 |  	if (tz) { | 
|---|
| 220 | 216 |  		if (copy_from_user(&new_tz, tz, sizeof(*tz))) | 
|---|
| .. | .. | 
|---|
| 225 | 221 |  } | 
|---|
| 226 | 222 |   | 
|---|
| 227 | 223 |  #ifdef CONFIG_COMPAT | 
|---|
| 228 |  | -COMPAT_SYSCALL_DEFINE2(gettimeofday, struct compat_timeval __user *, tv,  | 
|---|
 | 224 | +COMPAT_SYSCALL_DEFINE2(gettimeofday, struct old_timeval32 __user *, tv,  | 
|---|
| 229 | 225 |  		       struct timezone __user *, tz) | 
|---|
| 230 | 226 |  { | 
|---|
| 231 | 227 |  	if (tv) { | 
|---|
| .. | .. | 
|---|
| 244 | 240 |  	return 0; | 
|---|
| 245 | 241 |  } | 
|---|
| 246 | 242 |   | 
|---|
| 247 |  | -COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv,  | 
|---|
 | 243 | +COMPAT_SYSCALL_DEFINE2(settimeofday, struct old_timeval32 __user *, tv,  | 
|---|
| 248 | 244 |  		       struct timezone __user *, tz) | 
|---|
| 249 | 245 |  { | 
|---|
| 250 | 246 |  	struct timespec64 new_ts; | 
|---|
| 251 |  | -	struct timeval user_tv;  | 
|---|
| 252 | 247 |  	struct timezone new_tz; | 
|---|
| 253 | 248 |   | 
|---|
| 254 | 249 |  	if (tv) { | 
|---|
| 255 |  | -		if (compat_get_timeval(&user_tv, tv))  | 
|---|
 | 250 | +		if (get_user(new_ts.tv_sec, &tv->tv_sec) ||  | 
|---|
 | 251 | +		    get_user(new_ts.tv_nsec, &tv->tv_usec))  | 
|---|
| 256 | 252 |  			return -EFAULT; | 
|---|
| 257 |  | -		new_ts.tv_sec = user_tv.tv_sec;  | 
|---|
| 258 |  | -		new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;  | 
|---|
 | 253 | +  | 
|---|
 | 254 | +		if (new_ts.tv_nsec > USEC_PER_SEC || new_ts.tv_nsec < 0)  | 
|---|
 | 255 | +			return -EINVAL;  | 
|---|
 | 256 | +  | 
|---|
 | 257 | +		new_ts.tv_nsec *= NSEC_PER_USEC;  | 
|---|
| 259 | 258 |  	} | 
|---|
| 260 | 259 |  	if (tz) { | 
|---|
| 261 | 260 |  		if (copy_from_user(&new_tz, tz, sizeof(*tz))) | 
|---|
| .. | .. | 
|---|
| 266 | 265 |  } | 
|---|
| 267 | 266 |  #endif | 
|---|
| 268 | 267 |   | 
|---|
| 269 |  | -SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p)  | 
|---|
 | 268 | +#ifdef CONFIG_64BIT  | 
|---|
 | 269 | +SYSCALL_DEFINE1(adjtimex, struct __kernel_timex __user *, txc_p)  | 
|---|
| 270 | 270 |  { | 
|---|
| 271 |  | -	struct timex txc;		/* Local copy of parameter */  | 
|---|
 | 271 | +	struct __kernel_timex txc;		/* Local copy of parameter */  | 
|---|
| 272 | 272 |  	int ret; | 
|---|
| 273 | 273 |   | 
|---|
| 274 | 274 |  	/* Copy the user data space into the kernel copy | 
|---|
| 275 | 275 |  	 * structure. But bear in mind that the structures | 
|---|
| 276 | 276 |  	 * may change | 
|---|
| 277 | 277 |  	 */ | 
|---|
| 278 |  | -	if (copy_from_user(&txc, txc_p, sizeof(struct timex)))  | 
|---|
 | 278 | +	if (copy_from_user(&txc, txc_p, sizeof(struct __kernel_timex)))  | 
|---|
| 279 | 279 |  		return -EFAULT; | 
|---|
| 280 | 280 |  	ret = do_adjtimex(&txc); | 
|---|
| 281 |  | -	return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;  | 
|---|
 | 281 | +	return copy_to_user(txc_p, &txc, sizeof(struct __kernel_timex)) ? -EFAULT : ret;  | 
|---|
 | 282 | +}  | 
|---|
 | 283 | +#endif  | 
|---|
 | 284 | +  | 
|---|
 | 285 | +#ifdef CONFIG_COMPAT_32BIT_TIME  | 
|---|
 | 286 | +int get_old_timex32(struct __kernel_timex *txc, const struct old_timex32 __user *utp)  | 
|---|
 | 287 | +{  | 
|---|
 | 288 | +	struct old_timex32 tx32;  | 
|---|
 | 289 | +  | 
|---|
 | 290 | +	memset(txc, 0, sizeof(struct __kernel_timex));  | 
|---|
 | 291 | +	if (copy_from_user(&tx32, utp, sizeof(struct old_timex32)))  | 
|---|
 | 292 | +		return -EFAULT;  | 
|---|
 | 293 | +  | 
|---|
 | 294 | +	txc->modes = tx32.modes;  | 
|---|
 | 295 | +	txc->offset = tx32.offset;  | 
|---|
 | 296 | +	txc->freq = tx32.freq;  | 
|---|
 | 297 | +	txc->maxerror = tx32.maxerror;  | 
|---|
 | 298 | +	txc->esterror = tx32.esterror;  | 
|---|
 | 299 | +	txc->status = tx32.status;  | 
|---|
 | 300 | +	txc->constant = tx32.constant;  | 
|---|
 | 301 | +	txc->precision = tx32.precision;  | 
|---|
 | 302 | +	txc->tolerance = tx32.tolerance;  | 
|---|
 | 303 | +	txc->time.tv_sec = tx32.time.tv_sec;  | 
|---|
 | 304 | +	txc->time.tv_usec = tx32.time.tv_usec;  | 
|---|
 | 305 | +	txc->tick = tx32.tick;  | 
|---|
 | 306 | +	txc->ppsfreq = tx32.ppsfreq;  | 
|---|
 | 307 | +	txc->jitter = tx32.jitter;  | 
|---|
 | 308 | +	txc->shift = tx32.shift;  | 
|---|
 | 309 | +	txc->stabil = tx32.stabil;  | 
|---|
 | 310 | +	txc->jitcnt = tx32.jitcnt;  | 
|---|
 | 311 | +	txc->calcnt = tx32.calcnt;  | 
|---|
 | 312 | +	txc->errcnt = tx32.errcnt;  | 
|---|
 | 313 | +	txc->stbcnt = tx32.stbcnt;  | 
|---|
 | 314 | +  | 
|---|
 | 315 | +	return 0;  | 
|---|
| 282 | 316 |  } | 
|---|
| 283 | 317 |   | 
|---|
| 284 |  | -#ifdef CONFIG_COMPAT  | 
|---|
| 285 |  | -  | 
|---|
| 286 |  | -COMPAT_SYSCALL_DEFINE1(adjtimex, struct compat_timex __user *, utp)  | 
|---|
 | 318 | +int put_old_timex32(struct old_timex32 __user *utp, const struct __kernel_timex *txc)  | 
|---|
| 287 | 319 |  { | 
|---|
| 288 |  | -	struct timex txc;  | 
|---|
 | 320 | +	struct old_timex32 tx32;  | 
|---|
 | 321 | +  | 
|---|
 | 322 | +	memset(&tx32, 0, sizeof(struct old_timex32));  | 
|---|
 | 323 | +	tx32.modes = txc->modes;  | 
|---|
 | 324 | +	tx32.offset = txc->offset;  | 
|---|
 | 325 | +	tx32.freq = txc->freq;  | 
|---|
 | 326 | +	tx32.maxerror = txc->maxerror;  | 
|---|
 | 327 | +	tx32.esterror = txc->esterror;  | 
|---|
 | 328 | +	tx32.status = txc->status;  | 
|---|
 | 329 | +	tx32.constant = txc->constant;  | 
|---|
 | 330 | +	tx32.precision = txc->precision;  | 
|---|
 | 331 | +	tx32.tolerance = txc->tolerance;  | 
|---|
 | 332 | +	tx32.time.tv_sec = txc->time.tv_sec;  | 
|---|
 | 333 | +	tx32.time.tv_usec = txc->time.tv_usec;  | 
|---|
 | 334 | +	tx32.tick = txc->tick;  | 
|---|
 | 335 | +	tx32.ppsfreq = txc->ppsfreq;  | 
|---|
 | 336 | +	tx32.jitter = txc->jitter;  | 
|---|
 | 337 | +	tx32.shift = txc->shift;  | 
|---|
 | 338 | +	tx32.stabil = txc->stabil;  | 
|---|
 | 339 | +	tx32.jitcnt = txc->jitcnt;  | 
|---|
 | 340 | +	tx32.calcnt = txc->calcnt;  | 
|---|
 | 341 | +	tx32.errcnt = txc->errcnt;  | 
|---|
 | 342 | +	tx32.stbcnt = txc->stbcnt;  | 
|---|
 | 343 | +	tx32.tai = txc->tai;  | 
|---|
 | 344 | +	if (copy_to_user(utp, &tx32, sizeof(struct old_timex32)))  | 
|---|
 | 345 | +		return -EFAULT;  | 
|---|
 | 346 | +	return 0;  | 
|---|
 | 347 | +}  | 
|---|
 | 348 | +  | 
|---|
 | 349 | +SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp)  | 
|---|
 | 350 | +{  | 
|---|
 | 351 | +	struct __kernel_timex txc;  | 
|---|
| 289 | 352 |  	int err, ret; | 
|---|
| 290 | 353 |   | 
|---|
| 291 |  | -	err = compat_get_timex(&txc, utp);  | 
|---|
 | 354 | +	err = get_old_timex32(&txc, utp);  | 
|---|
| 292 | 355 |  	if (err) | 
|---|
| 293 | 356 |  		return err; | 
|---|
| 294 | 357 |   | 
|---|
| 295 | 358 |  	ret = do_adjtimex(&txc); | 
|---|
| 296 | 359 |   | 
|---|
| 297 |  | -	err = compat_put_timex(utp, &txc);  | 
|---|
 | 360 | +	err = put_old_timex32(utp, &txc);  | 
|---|
| 298 | 361 |  	if (err) | 
|---|
| 299 | 362 |  		return err; | 
|---|
| 300 | 363 |   | 
|---|
| .. | .. | 
|---|
| 345 | 408 |  } | 
|---|
| 346 | 409 |  EXPORT_SYMBOL(jiffies_to_usecs); | 
|---|
| 347 | 410 |   | 
|---|
| 348 |  | -/**  | 
|---|
| 349 |  | - * timespec_trunc - Truncate timespec to a granularity  | 
|---|
| 350 |  | - * @t: Timespec  | 
|---|
| 351 |  | - * @gran: Granularity in ns.  | 
|---|
| 352 |  | - *  | 
|---|
| 353 |  | - * Truncate a timespec to a granularity. Always rounds down. gran must  | 
|---|
| 354 |  | - * not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns).  | 
|---|
| 355 |  | - */  | 
|---|
| 356 |  | -struct timespec timespec_trunc(struct timespec t, unsigned gran)  | 
|---|
| 357 |  | -{  | 
|---|
| 358 |  | -	/* Avoid division in the common cases 1 ns and 1 s. */  | 
|---|
| 359 |  | -	if (gran == 1) {  | 
|---|
| 360 |  | -		/* nothing */  | 
|---|
| 361 |  | -	} else if (gran == NSEC_PER_SEC) {  | 
|---|
| 362 |  | -		t.tv_nsec = 0;  | 
|---|
| 363 |  | -	} else if (gran > 1 && gran < NSEC_PER_SEC) {  | 
|---|
| 364 |  | -		t.tv_nsec -= t.tv_nsec % gran;  | 
|---|
| 365 |  | -	} else {  | 
|---|
| 366 |  | -		WARN(1, "illegal file time granularity: %u", gran);  | 
|---|
| 367 |  | -	}  | 
|---|
| 368 |  | -	return t;  | 
|---|
| 369 |  | -}  | 
|---|
| 370 |  | -EXPORT_SYMBOL(timespec_trunc);  | 
|---|
| 371 |  | -  | 
|---|
| 372 | 411 |  /* | 
|---|
| 373 | 412 |   * mktime64 - Converts date to seconds. | 
|---|
| 374 | 413 |   * Converts Gregorian date to seconds since 1970-01-01 00:00:00. | 
|---|
| .. | .. | 
|---|
| 409 | 448 |  	)*60 + sec; /* finally seconds */ | 
|---|
| 410 | 449 |  } | 
|---|
| 411 | 450 |  EXPORT_SYMBOL(mktime64); | 
|---|
| 412 |  | -  | 
|---|
| 413 |  | -/**  | 
|---|
| 414 |  | - * set_normalized_timespec - set timespec sec and nsec parts and normalize  | 
|---|
| 415 |  | - *  | 
|---|
| 416 |  | - * @ts:		pointer to timespec variable to be set  | 
|---|
| 417 |  | - * @sec:	seconds to set  | 
|---|
| 418 |  | - * @nsec:	nanoseconds to set  | 
|---|
| 419 |  | - *  | 
|---|
| 420 |  | - * Set seconds and nanoseconds field of a timespec variable and  | 
|---|
| 421 |  | - * normalize to the timespec storage format  | 
|---|
| 422 |  | - *  | 
|---|
| 423 |  | - * Note: The tv_nsec part is always in the range of  | 
|---|
| 424 |  | - *	0 <= tv_nsec < NSEC_PER_SEC  | 
|---|
| 425 |  | - * For negative values only the tv_sec field is negative !  | 
|---|
| 426 |  | - */  | 
|---|
| 427 |  | -void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)  | 
|---|
| 428 |  | -{  | 
|---|
| 429 |  | -	while (nsec >= NSEC_PER_SEC) {  | 
|---|
| 430 |  | -		/*  | 
|---|
| 431 |  | -		 * The following asm() prevents the compiler from  | 
|---|
| 432 |  | -		 * optimising this loop into a modulo operation. See  | 
|---|
| 433 |  | -		 * also __iter_div_u64_rem() in include/linux/time.h  | 
|---|
| 434 |  | -		 */  | 
|---|
| 435 |  | -		asm("" : "+rm"(nsec));  | 
|---|
| 436 |  | -		nsec -= NSEC_PER_SEC;  | 
|---|
| 437 |  | -		++sec;  | 
|---|
| 438 |  | -	}  | 
|---|
| 439 |  | -	while (nsec < 0) {  | 
|---|
| 440 |  | -		asm("" : "+rm"(nsec));  | 
|---|
| 441 |  | -		nsec += NSEC_PER_SEC;  | 
|---|
| 442 |  | -		--sec;  | 
|---|
| 443 |  | -	}  | 
|---|
| 444 |  | -	ts->tv_sec = sec;  | 
|---|
| 445 |  | -	ts->tv_nsec = nsec;  | 
|---|
| 446 |  | -}  | 
|---|
| 447 |  | -EXPORT_SYMBOL(set_normalized_timespec);  | 
|---|
| 448 |  | -  | 
|---|
| 449 |  | -/**  | 
|---|
| 450 |  | - * ns_to_timespec - Convert nanoseconds to timespec  | 
|---|
| 451 |  | - * @nsec:       the nanoseconds value to be converted  | 
|---|
| 452 |  | - *  | 
|---|
| 453 |  | - * Returns the timespec representation of the nsec parameter.  | 
|---|
| 454 |  | - */  | 
|---|
| 455 |  | -struct timespec ns_to_timespec(const s64 nsec)  | 
|---|
| 456 |  | -{  | 
|---|
| 457 |  | -	struct timespec ts;  | 
|---|
| 458 |  | -	s32 rem;  | 
|---|
| 459 |  | -  | 
|---|
| 460 |  | -	if (!nsec)  | 
|---|
| 461 |  | -		return (struct timespec) {0, 0};  | 
|---|
| 462 |  | -  | 
|---|
| 463 |  | -	ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);  | 
|---|
| 464 |  | -	if (unlikely(rem < 0)) {  | 
|---|
| 465 |  | -		ts.tv_sec--;  | 
|---|
| 466 |  | -		rem += NSEC_PER_SEC;  | 
|---|
| 467 |  | -	}  | 
|---|
| 468 |  | -	ts.tv_nsec = rem;  | 
|---|
| 469 |  | -  | 
|---|
| 470 |  | -	return ts;  | 
|---|
| 471 |  | -}  | 
|---|
| 472 |  | -EXPORT_SYMBOL(ns_to_timespec);  | 
|---|
| 473 |  | -  | 
|---|
| 474 |  | -/**  | 
|---|
| 475 |  | - * ns_to_timeval - Convert nanoseconds to timeval  | 
|---|
| 476 |  | - * @nsec:       the nanoseconds value to be converted  | 
|---|
| 477 |  | - *  | 
|---|
| 478 |  | - * Returns the timeval representation of the nsec parameter.  | 
|---|
| 479 |  | - */  | 
|---|
| 480 |  | -struct timeval ns_to_timeval(const s64 nsec)  | 
|---|
| 481 |  | -{  | 
|---|
| 482 |  | -	struct timespec ts = ns_to_timespec(nsec);  | 
|---|
| 483 |  | -	struct timeval tv;  | 
|---|
| 484 |  | -  | 
|---|
| 485 |  | -	tv.tv_sec = ts.tv_sec;  | 
|---|
| 486 |  | -	tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;  | 
|---|
| 487 |  | -  | 
|---|
| 488 |  | -	return tv;  | 
|---|
| 489 |  | -}  | 
|---|
| 490 |  | -EXPORT_SYMBOL(ns_to_timeval);  | 
|---|
| 491 | 451 |   | 
|---|
| 492 | 452 |  struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec) | 
|---|
| 493 | 453 |  { | 
|---|
| .. | .. | 
|---|
| 545 | 505 |   */ | 
|---|
| 546 | 506 |  struct timespec64 ns_to_timespec64(const s64 nsec) | 
|---|
| 547 | 507 |  { | 
|---|
| 548 |  | -	struct timespec64 ts;  | 
|---|
 | 508 | +	struct timespec64 ts = { 0, 0 };  | 
|---|
| 549 | 509 |  	s32 rem; | 
|---|
| 550 | 510 |   | 
|---|
| 551 |  | -	if (!nsec)  | 
|---|
| 552 |  | -		return (struct timespec64) {0, 0};  | 
|---|
| 553 |  | -  | 
|---|
| 554 |  | -	ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);  | 
|---|
| 555 |  | -	if (unlikely(rem < 0)) {  | 
|---|
| 556 |  | -		ts.tv_sec--;  | 
|---|
| 557 |  | -		rem += NSEC_PER_SEC;  | 
|---|
 | 511 | +	if (likely(nsec > 0)) {  | 
|---|
 | 512 | +		ts.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);  | 
|---|
 | 513 | +		ts.tv_nsec = rem;  | 
|---|
 | 514 | +	} else if (nsec < 0) {  | 
|---|
 | 515 | +		/*  | 
|---|
 | 516 | +		 * With negative times, tv_sec points to the earlier  | 
|---|
 | 517 | +		 * second, and tv_nsec counts the nanoseconds since  | 
|---|
 | 518 | +		 * then, so tv_nsec is always a positive number.  | 
|---|
 | 519 | +		 */  | 
|---|
 | 520 | +		ts.tv_sec = -div_u64_rem(-nsec - 1, NSEC_PER_SEC, &rem) - 1;  | 
|---|
 | 521 | +		ts.tv_nsec = NSEC_PER_SEC - rem - 1;  | 
|---|
| 558 | 522 |  	} | 
|---|
| 559 |  | -	ts.tv_nsec = rem;  | 
|---|
| 560 | 523 |   | 
|---|
| 561 | 524 |  	return ts; | 
|---|
| 562 | 525 |  } | 
|---|
| .. | .. | 
|---|
| 620 | 583 |   * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec | 
|---|
| 621 | 584 |   * value to a scaled second value. | 
|---|
| 622 | 585 |   */ | 
|---|
| 623 |  | -static unsigned long  | 
|---|
| 624 |  | -__timespec64_to_jiffies(u64 sec, long nsec)  | 
|---|
 | 586 | +  | 
|---|
 | 587 | +unsigned long  | 
|---|
 | 588 | +timespec64_to_jiffies(const struct timespec64 *value)  | 
|---|
| 625 | 589 |  { | 
|---|
| 626 |  | -	nsec = nsec + TICK_NSEC - 1;  | 
|---|
 | 590 | +	u64 sec = value->tv_sec;  | 
|---|
 | 591 | +	long nsec = value->tv_nsec + TICK_NSEC - 1;  | 
|---|
| 627 | 592 |   | 
|---|
| 628 | 593 |  	if (sec >= MAX_SEC_IN_JIFFIES){ | 
|---|
| 629 | 594 |  		sec = MAX_SEC_IN_JIFFIES; | 
|---|
| .. | .. | 
|---|
| 633 | 598 |  		(((u64)nsec * NSEC_CONVERSION) >> | 
|---|
| 634 | 599 |  		 (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; | 
|---|
| 635 | 600 |   | 
|---|
| 636 |  | -}  | 
|---|
| 637 |  | -  | 
|---|
| 638 |  | -static unsigned long  | 
|---|
| 639 |  | -__timespec_to_jiffies(unsigned long sec, long nsec)  | 
|---|
| 640 |  | -{  | 
|---|
| 641 |  | -	return __timespec64_to_jiffies((u64)sec, nsec);  | 
|---|
| 642 |  | -}  | 
|---|
| 643 |  | -  | 
|---|
| 644 |  | -unsigned long  | 
|---|
| 645 |  | -timespec64_to_jiffies(const struct timespec64 *value)  | 
|---|
| 646 |  | -{  | 
|---|
| 647 |  | -	return __timespec64_to_jiffies(value->tv_sec, value->tv_nsec);  | 
|---|
| 648 | 601 |  } | 
|---|
| 649 | 602 |  EXPORT_SYMBOL(timespec64_to_jiffies); | 
|---|
| 650 | 603 |   | 
|---|
| .. | .. | 
|---|
| 661 | 614 |  	value->tv_nsec = rem; | 
|---|
| 662 | 615 |  } | 
|---|
| 663 | 616 |  EXPORT_SYMBOL(jiffies_to_timespec64); | 
|---|
| 664 |  | -  | 
|---|
| 665 |  | -/*  | 
|---|
| 666 |  | - * We could use a similar algorithm to timespec_to_jiffies (with a  | 
|---|
| 667 |  | - * different multiplier for usec instead of nsec). But this has a  | 
|---|
| 668 |  | - * problem with rounding: we can't exactly add TICK_NSEC - 1 to the  | 
|---|
| 669 |  | - * usec value, since it's not necessarily integral.  | 
|---|
| 670 |  | - *  | 
|---|
| 671 |  | - * We could instead round in the intermediate scaled representation  | 
|---|
| 672 |  | - * (i.e. in units of 1/2^(large scale) jiffies) but that's also  | 
|---|
| 673 |  | - * perilous: the scaling introduces a small positive error, which  | 
|---|
| 674 |  | - * combined with a division-rounding-upward (i.e. adding 2^(scale) - 1  | 
|---|
| 675 |  | - * units to the intermediate before shifting) leads to accidental  | 
|---|
| 676 |  | - * overflow and overestimates.  | 
|---|
| 677 |  | - *  | 
|---|
| 678 |  | - * At the cost of one additional multiplication by a constant, just  | 
|---|
| 679 |  | - * use the timespec implementation.  | 
|---|
| 680 |  | - */  | 
|---|
| 681 |  | -unsigned long  | 
|---|
| 682 |  | -timeval_to_jiffies(const struct timeval *value)  | 
|---|
| 683 |  | -{  | 
|---|
| 684 |  | -	return __timespec_to_jiffies(value->tv_sec,  | 
|---|
| 685 |  | -				     value->tv_usec * NSEC_PER_USEC);  | 
|---|
| 686 |  | -}  | 
|---|
| 687 |  | -EXPORT_SYMBOL(timeval_to_jiffies);  | 
|---|
| 688 |  | -  | 
|---|
| 689 |  | -void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)  | 
|---|
| 690 |  | -{  | 
|---|
| 691 |  | -	/*  | 
|---|
| 692 |  | -	 * Convert jiffies to nanoseconds and separate with  | 
|---|
| 693 |  | -	 * one divide.  | 
|---|
| 694 |  | -	 */  | 
|---|
| 695 |  | -	u32 rem;  | 
|---|
| 696 |  | -  | 
|---|
| 697 |  | -	value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,  | 
|---|
| 698 |  | -				    NSEC_PER_SEC, &rem);  | 
|---|
| 699 |  | -	value->tv_usec = rem / NSEC_PER_USEC;  | 
|---|
| 700 |  | -}  | 
|---|
| 701 |  | -EXPORT_SYMBOL(jiffies_to_timeval);  | 
|---|
| 702 | 617 |   | 
|---|
| 703 | 618 |  /* | 
|---|
| 704 | 619 |   * Convert jiffies/jiffies_64 to clock_t and back. | 
|---|
| .. | .. | 
|---|
| 771 | 686 |  	return div_u64(x * 9, (9ull * NSEC_PER_SEC + (USER_HZ / 2)) / USER_HZ); | 
|---|
| 772 | 687 |  #endif | 
|---|
| 773 | 688 |  } | 
|---|
 | 689 | +EXPORT_SYMBOL_GPL(nsec_to_clock_t);  | 
|---|
| 774 | 690 |   | 
|---|
| 775 | 691 |  u64 jiffies64_to_nsecs(u64 j) | 
|---|
| 776 | 692 |  { | 
|---|
| .. | .. | 
|---|
| 781 | 697 |  #endif | 
|---|
| 782 | 698 |  } | 
|---|
| 783 | 699 |  EXPORT_SYMBOL(jiffies64_to_nsecs); | 
|---|
 | 700 | +  | 
|---|
 | 701 | +u64 jiffies64_to_msecs(const u64 j)  | 
|---|
 | 702 | +{  | 
|---|
 | 703 | +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)  | 
|---|
 | 704 | +	return (MSEC_PER_SEC / HZ) * j;  | 
|---|
 | 705 | +#else  | 
|---|
 | 706 | +	return div_u64(j * HZ_TO_MSEC_NUM, HZ_TO_MSEC_DEN);  | 
|---|
 | 707 | +#endif  | 
|---|
 | 708 | +}  | 
|---|
 | 709 | +EXPORT_SYMBOL(jiffies64_to_msecs);  | 
|---|
| 784 | 710 |   | 
|---|
| 785 | 711 |  /** | 
|---|
| 786 | 712 |   * nsecs_to_jiffies64 - Convert nsecs in u64 to jiffies64 | 
|---|
| .. | .. | 
|---|
| 865 | 791 |   | 
|---|
| 866 | 792 |  	ts->tv_sec = kts.tv_sec; | 
|---|
| 867 | 793 |   | 
|---|
| 868 |  | -	/* Zero out the padding for 32 bit systems or in compat mode */  | 
|---|
| 869 |  | -	if (IS_ENABLED(CONFIG_64BIT_TIME) && (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()))  | 
|---|
 | 794 | +	/* Zero out the padding in compat mode */  | 
|---|
 | 795 | +	if (in_compat_syscall())  | 
|---|
| 870 | 796 |  		kts.tv_nsec &= 0xFFFFFFFFUL; | 
|---|
| 871 | 797 |   | 
|---|
 | 798 | +	/* In 32-bit mode, this drops the padding */  | 
|---|
| 872 | 799 |  	ts->tv_nsec = kts.tv_nsec; | 
|---|
| 873 | 800 |   | 
|---|
| 874 | 801 |  	return 0; | 
|---|
| .. | .. | 
|---|
| 887 | 814 |  } | 
|---|
| 888 | 815 |  EXPORT_SYMBOL_GPL(put_timespec64); | 
|---|
| 889 | 816 |   | 
|---|
| 890 |  | -int __compat_get_timespec64(struct timespec64 *ts64,  | 
|---|
| 891 |  | -				   const struct compat_timespec __user *cts)  | 
|---|
 | 817 | +static int __get_old_timespec32(struct timespec64 *ts64,  | 
|---|
 | 818 | +				   const struct old_timespec32 __user *cts)  | 
|---|
| 892 | 819 |  { | 
|---|
| 893 |  | -	struct compat_timespec ts;  | 
|---|
 | 820 | +	struct old_timespec32 ts;  | 
|---|
| 894 | 821 |  	int ret; | 
|---|
| 895 | 822 |   | 
|---|
| 896 | 823 |  	ret = copy_from_user(&ts, cts, sizeof(ts)); | 
|---|
| .. | .. | 
|---|
| 903 | 830 |  	return 0; | 
|---|
| 904 | 831 |  } | 
|---|
| 905 | 832 |   | 
|---|
| 906 |  | -int __compat_put_timespec64(const struct timespec64 *ts64,  | 
|---|
| 907 |  | -				   struct compat_timespec __user *cts)  | 
|---|
 | 833 | +static int __put_old_timespec32(const struct timespec64 *ts64,  | 
|---|
 | 834 | +				   struct old_timespec32 __user *cts)  | 
|---|
| 908 | 835 |  { | 
|---|
| 909 |  | -	struct compat_timespec ts = {  | 
|---|
 | 836 | +	struct old_timespec32 ts = {  | 
|---|
| 910 | 837 |  		.tv_sec = ts64->tv_sec, | 
|---|
| 911 | 838 |  		.tv_nsec = ts64->tv_nsec | 
|---|
| 912 | 839 |  	}; | 
|---|
| 913 | 840 |  	return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0; | 
|---|
| 914 | 841 |  } | 
|---|
| 915 | 842 |   | 
|---|
| 916 |  | -int compat_get_timespec64(struct timespec64 *ts, const void __user *uts)  | 
|---|
 | 843 | +int get_old_timespec32(struct timespec64 *ts, const void __user *uts)  | 
|---|
| 917 | 844 |  { | 
|---|
| 918 | 845 |  	if (COMPAT_USE_64BIT_TIME) | 
|---|
| 919 | 846 |  		return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0; | 
|---|
| 920 | 847 |  	else | 
|---|
| 921 |  | -		return __compat_get_timespec64(ts, uts);  | 
|---|
 | 848 | +		return __get_old_timespec32(ts, uts);  | 
|---|
| 922 | 849 |  } | 
|---|
| 923 |  | -EXPORT_SYMBOL_GPL(compat_get_timespec64);  | 
|---|
 | 850 | +EXPORT_SYMBOL_GPL(get_old_timespec32);  | 
|---|
| 924 | 851 |   | 
|---|
| 925 |  | -int compat_put_timespec64(const struct timespec64 *ts, void __user *uts)  | 
|---|
 | 852 | +int put_old_timespec32(const struct timespec64 *ts, void __user *uts)  | 
|---|
| 926 | 853 |  { | 
|---|
| 927 | 854 |  	if (COMPAT_USE_64BIT_TIME) | 
|---|
| 928 | 855 |  		return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0; | 
|---|
| 929 | 856 |  	else | 
|---|
| 930 |  | -		return __compat_put_timespec64(ts, uts);  | 
|---|
 | 857 | +		return __put_old_timespec32(ts, uts);  | 
|---|
| 931 | 858 |  } | 
|---|
| 932 |  | -EXPORT_SYMBOL_GPL(compat_put_timespec64);  | 
|---|
 | 859 | +EXPORT_SYMBOL_GPL(put_old_timespec32);  | 
|---|
| 933 | 860 |   | 
|---|
| 934 | 861 |  int get_itimerspec64(struct itimerspec64 *it, | 
|---|
| 935 | 862 |  			const struct __kernel_itimerspec __user *uit) | 
|---|
| .. | .. | 
|---|
| 961 | 888 |  } | 
|---|
| 962 | 889 |  EXPORT_SYMBOL_GPL(put_itimerspec64); | 
|---|
| 963 | 890 |   | 
|---|
| 964 |  | -int get_compat_itimerspec64(struct itimerspec64 *its,  | 
|---|
| 965 |  | -			const struct compat_itimerspec __user *uits)  | 
|---|
 | 891 | +int get_old_itimerspec32(struct itimerspec64 *its,  | 
|---|
 | 892 | +			const struct old_itimerspec32 __user *uits)  | 
|---|
| 966 | 893 |  { | 
|---|
| 967 | 894 |   | 
|---|
| 968 |  | -	if (__compat_get_timespec64(&its->it_interval, &uits->it_interval) ||  | 
|---|
| 969 |  | -	    __compat_get_timespec64(&its->it_value, &uits->it_value))  | 
|---|
 | 895 | +	if (__get_old_timespec32(&its->it_interval, &uits->it_interval) ||  | 
|---|
 | 896 | +	    __get_old_timespec32(&its->it_value, &uits->it_value))  | 
|---|
| 970 | 897 |  		return -EFAULT; | 
|---|
| 971 | 898 |  	return 0; | 
|---|
| 972 | 899 |  } | 
|---|
| 973 |  | -EXPORT_SYMBOL_GPL(get_compat_itimerspec64);  | 
|---|
 | 900 | +EXPORT_SYMBOL_GPL(get_old_itimerspec32);  | 
|---|
| 974 | 901 |   | 
|---|
| 975 |  | -int put_compat_itimerspec64(const struct itimerspec64 *its,  | 
|---|
| 976 |  | -			struct compat_itimerspec __user *uits)  | 
|---|
 | 902 | +int put_old_itimerspec32(const struct itimerspec64 *its,  | 
|---|
 | 903 | +			struct old_itimerspec32 __user *uits)  | 
|---|
| 977 | 904 |  { | 
|---|
| 978 |  | -	if (__compat_put_timespec64(&its->it_interval, &uits->it_interval) ||  | 
|---|
| 979 |  | -	    __compat_put_timespec64(&its->it_value, &uits->it_value))  | 
|---|
 | 905 | +	if (__put_old_timespec32(&its->it_interval, &uits->it_interval) ||  | 
|---|
 | 906 | +	    __put_old_timespec32(&its->it_value, &uits->it_value))  | 
|---|
| 980 | 907 |  		return -EFAULT; | 
|---|
| 981 | 908 |  	return 0; | 
|---|
| 982 | 909 |  } | 
|---|
| 983 |  | -EXPORT_SYMBOL_GPL(put_compat_itimerspec64);  | 
|---|
 | 910 | +EXPORT_SYMBOL_GPL(put_old_itimerspec32);  | 
|---|