Skip to content

Commit

Permalink
Merge tag 'y2038-drivers-for-v5.6-signed' of git://git.kernel.org:/pu…
Browse files Browse the repository at this point in the history
…b/scm/linux/kernel/git/arnd/playground

Pull y2038 updates from Arnd Bergmann:
 "Core, driver and file system changes

  These are updates to device drivers and file systems that for some
  reason or another were not included in the kernel in the previous
  y2038 series.

  I've gone through all users of time_t again to make sure the kernel is
  in a long-term maintainable state, replacing all remaining references
  to time_t with safe alternatives.

  Some related parts of the series were picked up into the nfsd, xfs,
  alsa and v4l2 trees. A final set of patches in linux-mm removes the
  now unused time_t/timeval/timespec types and helper functions after
  all five branches are merged for linux-5.6, ensuring that no new users
  get merged.

  As a result, linux-5.6, or my backport of the patches to 5.4 [1],
  should be the first release that can serve as a base for a 32-bit
  system designed to run beyond year 2038, with a few remaining caveats:

   - All user space must be compiled with a 64-bit time_t, which will be
     supported in the coming musl-1.2 and glibc-2.32 releases, along
     with installed kernel headers from linux-5.6 or higher.

   - Applications that use the system call interfaces directly need to
     be ported to use the time64 syscalls added in linux-5.1 in place of
     the existing system calls. This impacts most users of futex() and
     seccomp() as well as programming languages that have their own
     runtime environment not based on libc.

   - Applications that use a private copy of kernel uapi header files or
     their contents may need to update to the linux-5.6 version, in
     particular for sound/asound.h, xfs/xfs_fs.h, linux/input.h,
     linux/elfcore.h, linux/sockios.h, linux/timex.h and
     linux/can/bcm.h.

   - A few remaining interfaces cannot be changed to pass a 64-bit
     time_t in a compatible way, so they must be configured to use
     CLOCK_MONOTONIC times or (with a y2106 problem) unsigned 32-bit
     timestamps. Most importantly this impacts all users of 'struct
     input_event'.

   - All y2038 problems that are present on 64-bit machines also apply
     to 32-bit machines. In particular this affects file systems with
     on-disk timestamps using signed 32-bit seconds: ext4 with
     ext3-style small inodes, ext2, xfs (to be fixed soon) and ufs"

[1] https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=y2038-endgame

* tag 'y2038-drivers-for-v5.6-signed' of git://git.kernel.org:/pub/scm/linux/kernel/git/arnd/playground: (21 commits)
  Revert "drm/etnaviv: reject timeouts with tv_nsec >= NSEC_PER_SEC"
  y2038: sh: remove timeval/timespec usage from headers
  y2038: sparc: remove use of struct timex
  y2038: rename itimerval to __kernel_old_itimerval
  y2038: remove obsolete jiffies conversion functions
  nfs: fscache: use timespec64 in inode auxdata
  nfs: fix timstamp debug prints
  nfs: use time64_t internally
  sunrpc: convert to time64_t for expiry
  drm/etnaviv: avoid deprecated timespec
  drm/etnaviv: reject timeouts with tv_nsec >= NSEC_PER_SEC
  drm/msm: avoid using 'timespec'
  hfs/hfsplus: use 64-bit inode timestamps
  hostfs: pass 64-bit timestamps to/from user space
  packet: clarify timestamp overflow
  tsacct: add 64-bit btime field
  acct: stop using get_seconds()
  um: ubd: use 64-bit time_t where possible
  xtensa: ISS: avoid struct timeval
  dlm: use SO_SNDTIMEO_NEW instead of SO_SNDTIMEO_OLD
  ...
  • Loading branch information
torvalds committed Jan 29, 2020
2 parents a4fe2b4 + c4e7121 commit 22b17db
Show file tree
Hide file tree
Showing 49 changed files with 283 additions and 266 deletions.
4 changes: 2 additions & 2 deletions arch/sh/include/uapi/asm/sockios.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#define SIOCSPGRP _IOW('s', 8, pid_t)
#define SIOCGPGRP _IOR('s', 9, pid_t)

#define SIOCGSTAMP_OLD _IOR('s', 100, struct timeval) /* Get stamp (timeval) */
#define SIOCGSTAMPNS_OLD _IOR('s', 101, struct timespec) /* Get stamp (timespec) */
#define SIOCGSTAMP_OLD _IOR('s', 100, struct __kernel_old_timeval) /* Get stamp (timeval) */
#define SIOCGSTAMPNS_OLD _IOR('s', 101, struct __kernel_old_timespec) /* Get stamp (timespec) */

#endif /* __ASM_SH_SOCKIOS_H */
33 changes: 17 additions & 16 deletions arch/sparc/kernel/sys_sparc_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,34 +548,35 @@ SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len)
return err;
}

SYSCALL_DEFINE1(sparc_adjtimex, struct timex __user *, txc_p)
SYSCALL_DEFINE1(sparc_adjtimex, struct __kernel_timex __user *, txc_p)
{
struct timex txc; /* Local copy of parameter */
struct __kernel_timex *kt = (void *)&txc;
struct __kernel_timex txc;
struct __kernel_old_timeval *tv = (void *)&txc_p->time;
int ret;

/* Copy the user data space into the kernel copy
* structure. But bear in mind that the structures
* may change
*/
if (copy_from_user(&txc, txc_p, sizeof(struct timex)))
if (copy_from_user(&txc, txc_p, sizeof(txc)))
return -EFAULT;

/*
* override for sparc64 specific timeval type: tv_usec
* is 32 bit wide instead of 64-bit in __kernel_timex
*/
kt->time.tv_usec = txc.time.tv_usec;
ret = do_adjtimex(kt);
txc.time.tv_usec = kt->time.tv_usec;
txc.time.tv_usec = tv->tv_usec;
ret = do_adjtimex(&txc);
tv->tv_usec = txc.time.tv_usec;

return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
return copy_to_user(txc_p, &txc, sizeof(txc)) ? -EFAULT : ret;
}

SYSCALL_DEFINE2(sparc_clock_adjtime, const clockid_t, which_clock,struct timex __user *, txc_p)
SYSCALL_DEFINE2(sparc_clock_adjtime, const clockid_t, which_clock,
struct __kernel_timex __user *, txc_p)
{
struct timex txc; /* Local copy of parameter */
struct __kernel_timex *kt = (void *)&txc;
struct __kernel_timex txc;
struct __kernel_old_timeval *tv = (void *)&txc_p->time;
int ret;

if (!IS_ENABLED(CONFIG_POSIX_TIMERS)) {
Expand All @@ -590,18 +591,18 @@ SYSCALL_DEFINE2(sparc_clock_adjtime, const clockid_t, which_clock,struct timex _
* structure. But bear in mind that the structures
* may change
*/
if (copy_from_user(&txc, txc_p, sizeof(struct timex)))
if (copy_from_user(&txc, txc_p, sizeof(txc)))
return -EFAULT;

/*
* override for sparc64 specific timeval type: tv_usec
* is 32 bit wide instead of 64-bit in __kernel_timex
*/
kt->time.tv_usec = txc.time.tv_usec;
ret = do_clock_adjtime(which_clock, kt);
txc.time.tv_usec = kt->time.tv_usec;
txc.time.tv_usec = tv->tv_usec;
ret = do_clock_adjtime(which_clock, &txc);
tv->tv_usec = txc.time.tv_usec;

return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
return copy_to_user(txc_p, &txc, sizeof(txc)) ? -EFAULT : ret;
}

SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type,
Expand Down
2 changes: 1 addition & 1 deletion arch/um/drivers/cow.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern int init_cow_file(int fd, char *cow_file, char *backing_file,
extern int file_reader(__u64 offset, char *buf, int len, void *arg);
extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
void *arg, __u32 *version_out,
char **backing_file_out, time_t *mtime_out,
char **backing_file_out, long long *mtime_out,
unsigned long long *size_out, int *sectorsize_out,
__u32 *align_out, int *bitmap_offset_out);

Expand Down
7 changes: 4 additions & 3 deletions arch/um/drivers/cow_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#define PATH_LEN_V1 256

/* unsigned time_t works until year 2106 */
typedef __u32 time32_t;

struct cow_header_v1 {
Expand Down Expand Up @@ -197,7 +198,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
int sectorsize, int alignment, unsigned long long *size)
{
struct cow_header_v3 *header;
unsigned long modtime;
long long modtime;
int err;

err = cow_seek_file(fd, 0);
Expand Down Expand Up @@ -276,7 +277,7 @@ int file_reader(__u64 offset, char *buf, int len, void *arg)

int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
__u32 *version_out, char **backing_file_out,
time_t *mtime_out, unsigned long long *size_out,
long long *mtime_out, unsigned long long *size_out,
int *sectorsize_out, __u32 *align_out,
int *bitmap_offset_out)
{
Expand Down Expand Up @@ -363,7 +364,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,

/*
* this was used until Dec2005 - 64bits are needed to represent
* 2038+. I.e. we can safely do this truncating cast.
* 2106+. I.e. we can safely do this truncating cast.
*
* Additionally, we must use be32toh() instead of be64toh(), since
* the program used to use the former (tested - I got mtime
Expand Down
10 changes: 5 additions & 5 deletions arch/um/drivers/ubd_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
__u32 version;
__u32 align;
char *backing_file;
time_t mtime;
time64_t mtime;
unsigned long long size;
int sector_size;
int bitmap_offset;
Expand Down Expand Up @@ -600,9 +600,9 @@ static int read_cow_bitmap(int fd, void *buf, int offset, int len)
return 0;
}

static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
static int backing_file_mismatch(char *file, __u64 size, time64_t mtime)
{
unsigned long modtime;
time64_t modtime;
unsigned long long actual;
int err;

Expand All @@ -628,7 +628,7 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
return -EINVAL;
}
if (modtime != mtime) {
printk(KERN_ERR "mtime mismatch (%ld vs %ld) of COW header vs "
printk(KERN_ERR "mtime mismatch (%lld vs %lld) of COW header vs "
"backing file\n", mtime, modtime);
return -EINVAL;
}
Expand Down Expand Up @@ -671,7 +671,7 @@ static int open_ubd_file(char *file, struct openflags *openflags, int shared,
unsigned long *bitmap_len_out, int *data_offset_out,
int *create_cow_out)
{
time_t mtime;
time64_t mtime;
unsigned long long size;
__u32 version, align;
char *backing_file;
Expand Down
2 changes: 1 addition & 1 deletion arch/um/include/shared/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ extern int os_sync_file(int fd);
extern int os_file_size(const char *file, unsigned long long *size_out);
extern int os_pread_file(int fd, void *buf, int len, unsigned long long offset);
extern int os_pwrite_file(int fd, const void *buf, int count, unsigned long long offset);
extern int os_file_modtime(const char *file, unsigned long *modtime);
extern int os_file_modtime(const char *file, long long *modtime);
extern int os_pipe(int *fd, int stream, int close_on_exec);
extern int os_set_fd_async(int fd);
extern int os_clear_fd_async(int fd);
Expand Down
2 changes: 1 addition & 1 deletion arch/um/os-Linux/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ int os_file_size(const char *file, unsigned long long *size_out)
return 0;
}

int os_file_modtime(const char *file, unsigned long *modtime)
int os_file_modtime(const char *file, long long *modtime)
{
struct uml_stat buf;
int err;
Expand Down
4 changes: 2 additions & 2 deletions arch/xtensa/platforms/iss/include/platform/simcall.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ static inline int simc_write(int fd, const void *buf, size_t count)

static inline int simc_poll(int fd)
{
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
long timeval[2] = { 0, 0 };

return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv);
return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&timeval);
}

static inline int simc_lseek(int fd, uint32_t off, int whence)
Expand Down
11 changes: 3 additions & 8 deletions drivers/gpu/drm/etnaviv/etnaviv_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,6 @@ static int etnaviv_ioctl_gem_new(struct drm_device *dev, void *data,
args->flags, &args->handle);
}

#define TS(t) ((struct timespec){ \
.tv_sec = (t).tv_sec, \
.tv_nsec = (t).tv_nsec \
})

static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
struct drm_file *file)
{
Expand All @@ -301,7 +296,7 @@ static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
if (!obj)
return -ENOENT;

ret = etnaviv_gem_cpu_prep(obj, args->op, &TS(args->timeout));
ret = etnaviv_gem_cpu_prep(obj, args->op, &args->timeout);

drm_gem_object_put_unlocked(obj);

Expand Down Expand Up @@ -354,7 +349,7 @@ static int etnaviv_ioctl_wait_fence(struct drm_device *dev, void *data,
{
struct drm_etnaviv_wait_fence *args = data;
struct etnaviv_drm_private *priv = dev->dev_private;
struct timespec *timeout = &TS(args->timeout);
struct drm_etnaviv_timespec *timeout = &args->timeout;
struct etnaviv_gpu *gpu;

if (args->flags & ~(ETNA_WAIT_NONBLOCK))
Expand Down Expand Up @@ -403,7 +398,7 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data,
{
struct etnaviv_drm_private *priv = dev->dev_private;
struct drm_etnaviv_gem_wait *args = data;
struct timespec *timeout = &TS(args->timeout);
struct drm_etnaviv_timespec *timeout = &args->timeout;
struct drm_gem_object *obj;
struct etnaviv_gpu *gpu;
int ret;
Expand Down
11 changes: 6 additions & 5 deletions drivers/gpu/drm/etnaviv/etnaviv_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ int etnaviv_gem_prime_pin(struct drm_gem_object *obj);
void etnaviv_gem_prime_unpin(struct drm_gem_object *obj);
void *etnaviv_gem_vmap(struct drm_gem_object *obj);
int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
struct timespec *timeout);
struct drm_etnaviv_timespec *timeout);
int etnaviv_gem_cpu_fini(struct drm_gem_object *obj);
void etnaviv_gem_free_object(struct drm_gem_object *obj);
int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
Expand Down Expand Up @@ -107,11 +107,12 @@ static inline size_t size_vstruct(size_t nelem, size_t elem_size, size_t base)
* between the specified timeout and the current CLOCK_MONOTONIC time.
*/
static inline unsigned long etnaviv_timeout_to_jiffies(
const struct timespec *timeout)
const struct drm_etnaviv_timespec *timeout)
{
struct timespec64 ts, to;

to = timespec_to_timespec64(*timeout);
struct timespec64 ts, to = {
.tv_sec = timeout->tv_sec,
.tv_nsec = timeout->tv_nsec,
};

ktime_get_ts64(&ts);

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/etnaviv/etnaviv_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op)
}

int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
struct timespec *timeout)
struct drm_etnaviv_timespec *timeout)
{
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
struct drm_device *dev = obj->dev;
Expand Down Expand Up @@ -431,7 +431,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj)
}

int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj,
struct timespec *timeout)
struct drm_etnaviv_timespec *timeout)
{
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/etnaviv/etnaviv_gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ struct etnaviv_gem_submit {
void etnaviv_submit_put(struct etnaviv_gem_submit * submit);

int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj,
struct timespec *timeout);
struct drm_etnaviv_timespec *timeout);
int etnaviv_gem_new_private(struct drm_device *dev, size_t size, u32 flags,
const struct etnaviv_gem_ops *ops, struct etnaviv_gem_object **res);
void etnaviv_gem_obj_add(struct drm_device *dev, struct drm_gem_object *obj);
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/etnaviv/etnaviv_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,7 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
* Cmdstream submission/retirement:
*/
int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu,
u32 id, struct timespec *timeout)
u32 id, struct drm_etnaviv_timespec *timeout)
{
struct dma_fence *fence;
int ret;
Expand Down Expand Up @@ -1179,7 +1179,8 @@ int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu,
* that lock in this function while waiting.
*/
int etnaviv_gpu_wait_obj_inactive(struct etnaviv_gpu *gpu,
struct etnaviv_gem_object *etnaviv_obj, struct timespec *timeout)
struct etnaviv_gem_object *etnaviv_obj,
struct drm_etnaviv_timespec *timeout)
{
unsigned long remaining;
long ret;
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/etnaviv/etnaviv_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,10 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m);
void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu);
void etnaviv_gpu_retire(struct etnaviv_gpu *gpu);
int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu,
u32 fence, struct timespec *timeout);
u32 fence, struct drm_etnaviv_timespec *timeout);
int etnaviv_gpu_wait_obj_inactive(struct etnaviv_gpu *gpu,
struct etnaviv_gem_object *etnaviv_obj, struct timespec *timeout);
struct etnaviv_gem_object *etnaviv_obj,
struct drm_etnaviv_timespec *timeout);
struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit);
int etnaviv_gpu_pm_get_sync(struct etnaviv_gpu *gpu);
void etnaviv_gpu_pm_put(struct etnaviv_gpu *gpu);
Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/msm/msm_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,7 @@ static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
remaining_jiffies = 0;
} else {
ktime_t rem = ktime_sub(*timeout, now);
struct timespec ts = ktime_to_timespec(rem);
remaining_jiffies = timespec_to_jiffies(&ts);
remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ);
}

return remaining_jiffies;
Expand Down
6 changes: 3 additions & 3 deletions fs/dlm/lowcomms.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,7 @@ static void sctp_connect_to_sock(struct connection *con)
int result;
int addr_len;
struct socket *sock;
struct timeval tv = { .tv_sec = 5, .tv_usec = 0 };
struct __kernel_sock_timeval tv = { .tv_sec = 5, .tv_usec = 0 };

if (con->nodeid == 0) {
log_print("attempt to connect sock 0 foiled");
Expand Down Expand Up @@ -1087,12 +1087,12 @@ static void sctp_connect_to_sock(struct connection *con)
* since O_NONBLOCK argument in connect() function does not work here,
* then, we should restore the default value of this attribute.
*/
kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO_OLD, (char *)&tv,
kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO_NEW, (char *)&tv,
sizeof(tv));
result = sock->ops->connect(sock, (struct sockaddr *)&daddr, addr_len,
0);
memset(&tv, 0, sizeof(tv));
kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO_OLD, (char *)&tv,
kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO_NEW, (char *)&tv,
sizeof(tv));

if (result == -EINPROGRESS)
Expand Down
3 changes: 2 additions & 1 deletion fs/fat/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
#include <asm/unaligned.h>
#include <linux/random.h>
#include <linux/iversion.h>
#include "fat.h"

Expand Down Expand Up @@ -521,7 +522,7 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
inode->i_uid = sbi->options.fs_uid;
inode->i_gid = sbi->options.fs_gid;
inode_inc_iversion(inode);
inode->i_generation = get_seconds();
inode->i_generation = prandom_u32();

if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
inode->i_generation &= ~1;
Expand Down
Loading

0 comments on commit 22b17db

Please sign in to comment.