Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'y2038-timekeeping' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground into timers/core

Pull y2038 timekeeping syscall changes from Arnd Bergmann:

This is the first set of system call entry point changes to enable 32-bit
architectures to have variants on both 32-bit and 64-bit time_t. Typically
these system calls take a 'struct timespec' argument, but that structure
is defined in user space by the C library and its layout will change.

The kernel already supports handling the 32-bit time_t on 64-bit
architectures through the CONFIG_COMPAT mechanism. As there are a total
of 51 system calls suffering from this problem, reusing that mechanism
on 32-bit architectures.

We already have patches for most of the remaining system calls, but this
set contains most of the complexity and is best tested. There was one
last-minute regression that prevented it from going into 4.17, but that
is fixed now.

More details from Deepa's patch series description:

Big picture is as per the lwn article:
https://lwn.net/Articles/643234/ [2]

The series is directed at converting posix clock syscalls:
clock_gettime, clock_settime, clock_getres and clock_nanosleep
to use a new data structure __kernel_timespec at syscall boundaries.
__kernel_timespec maintains 64 bit time_t across all execution modes.

vdso will be handled as part of each architecture when they enable
support for 64 bit time_t.

The compat syscalls are repurposed to provide backward compatibility
by using them as native syscalls as well for 32 bit architectures.
They will continue to use timespec at syscall boundaries.

CONFIG_64_BIT_TIME controls whether the syscalls use __kernel_timespec
or timespec at syscall boundaries.

The series does the following:
1. Enable compat syscalls on 32 bit architectures.
2. Add a new __kernel_timespec type to be used as the data structure
for all the new syscalls.
3. Add new config CONFIG_64BIT_TIME(intead of the CONFIG_COMPAT_TIME in
[1] and [2] to switch to new definition of __kernel_timespec. It is
the same as struct timespec otherwise.
4. Add new CONFIG_32BIT_TIME to conditionally compile compat syscalls.

+201 -176
+15
arch/Kconfig
··· 870 870 config COMPAT_OLD_SIGACTION 871 871 bool 872 872 873 + config 64BIT_TIME 874 + def_bool ARCH_HAS_64BIT_TIME 875 + help 876 + This should be selected by all architectures that need to support 877 + new system calls with a 64-bit time_t. This is relevant on all 32-bit 878 + architectures, and 64-bit architectures as part of compat syscall 879 + handling. 880 + 881 + config COMPAT_32BIT_TIME 882 + def_bool (!64BIT && 64BIT_TIME) || COMPAT 883 + help 884 + This enables 32 bit time_t support in addition to 64 bit time_t support. 885 + This is relevant on all 32-bit architectures, and 64-bit architectures 886 + as part of compat syscall handling. 887 + 873 888 config ARCH_NO_COHERENT_DMA_MMAP 874 889 bool 875 890
+1
arch/alpha/include/asm/Kbuild
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 3 3 4 + generic-y += compat.h 4 5 generic-y += exec.h 5 6 generic-y += export.h 6 7 generic-y += fb.h
+1
arch/arc/include/asm/Kbuild
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 generic-y += bugs.h 3 + generic-y += compat.h 3 4 generic-y += device.h 4 5 generic-y += div64.h 5 6 generic-y += emergency-restart.h
+1
arch/arm/include/asm/Kbuild
··· 1 + generic-y += compat.h 1 2 generic-y += current.h 2 3 generic-y += early_ioremap.h 3 4 generic-y += emergency-restart.h
-11
arch/arm64/include/asm/compat.h
··· 34 34 35 35 typedef u32 compat_size_t; 36 36 typedef s32 compat_ssize_t; 37 - typedef s32 compat_time_t; 38 37 typedef s32 compat_clock_t; 39 38 typedef s32 compat_pid_t; 40 39 typedef u16 __compat_uid_t; ··· 64 65 typedef u32 compat_ulong_t; 65 66 typedef u64 compat_u64; 66 67 typedef u32 compat_uptr_t; 67 - 68 - struct compat_timespec { 69 - compat_time_t tv_sec; 70 - s32 tv_nsec; 71 - }; 72 - 73 - struct compat_timeval { 74 - compat_time_t tv_sec; 75 - s32 tv_usec; 76 - }; 77 68 78 69 struct compat_stat { 79 70 #ifdef __AARCH64EB__
+1
arch/arm64/include/asm/stat.h
··· 20 20 21 21 #ifdef CONFIG_COMPAT 22 22 23 + #include <linux/compat_time.h> 23 24 #include <asm/compat.h> 24 25 25 26 /*
-1
arch/arm64/kernel/hw_breakpoint.c
··· 30 30 #include <linux/smp.h> 31 31 #include <linux/uaccess.h> 32 32 33 - #include <asm/compat.h> 34 33 #include <asm/current.h> 35 34 #include <asm/debug-monitors.h> 36 35 #include <asm/hw_breakpoint.h>
+1 -1
arch/arm64/kernel/perf_regs.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/compat.h> 2 3 #include <linux/errno.h> 3 4 #include <linux/kernel.h> 4 5 #include <linux/perf_event.h> 5 6 #include <linux/bug.h> 6 7 #include <linux/sched/task_stack.h> 7 8 8 - #include <asm/compat.h> 9 9 #include <asm/perf_regs.h> 10 10 #include <asm/ptrace.h> 11 11
+1
arch/c6x/include/asm/Kbuild
··· 1 1 generic-y += atomic.h 2 2 generic-y += barrier.h 3 3 generic-y += bugs.h 4 + generic-y += compat.h 4 5 generic-y += current.h 5 6 generic-y += device.h 6 7 generic-y += div64.h
+1
arch/h8300/include/asm/Kbuild
··· 3 3 generic-y += bugs.h 4 4 generic-y += cacheflush.h 5 5 generic-y += checksum.h 6 + generic-y += compat.h 6 7 generic-y += current.h 7 8 generic-y += delay.h 8 9 generic-y += device.h
+1
arch/hexagon/include/asm/Kbuild
··· 2 2 generic-y += barrier.h 3 3 generic-y += bug.h 4 4 generic-y += bugs.h 5 + generic-y += compat.h 5 6 generic-y += current.h 6 7 generic-y += device.h 7 8 generic-y += div64.h
+1
arch/ia64/include/asm/Kbuild
··· 1 + generic-y += compat.h 1 2 generic-y += exec.h 2 3 generic-y += irq_work.h 3 4 generic-y += mcs_spinlock.h
+1
arch/m68k/include/asm/Kbuild
··· 1 1 generic-y += barrier.h 2 + generic-y += compat.h 2 3 generic-y += device.h 3 4 generic-y += emergency-restart.h 4 5 generic-y += exec.h
+1
arch/microblaze/include/asm/Kbuild
··· 2 2 generic-y += bitops.h 3 3 generic-y += bug.h 4 4 generic-y += bugs.h 5 + generic-y += compat.h 5 6 generic-y += device.h 6 7 generic-y += div64.h 7 8 generic-y += emergency-restart.h
-11
arch/mips/include/asm/compat.h
··· 14 14 15 15 typedef u32 compat_size_t; 16 16 typedef s32 compat_ssize_t; 17 - typedef s32 compat_time_t; 18 17 typedef s32 compat_clock_t; 19 18 typedef s32 compat_suseconds_t; 20 19 ··· 44 45 typedef u32 compat_ulong_t; 45 46 typedef u64 compat_u64; 46 47 typedef u32 compat_uptr_t; 47 - 48 - struct compat_timespec { 49 - compat_time_t tv_sec; 50 - s32 tv_nsec; 51 - }; 52 - 53 - struct compat_timeval { 54 - compat_time_t tv_sec; 55 - s32 tv_usec; 56 - }; 57 48 58 49 struct compat_stat { 59 50 compat_dev_t st_dev;
+1 -1
arch/mips/kernel/signal32.c
··· 8 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 9 9 * Copyright (C) 2016, Imagination Technologies Ltd. 10 10 */ 11 + #include <linux/compat.h> 11 12 #include <linux/compiler.h> 12 13 #include <linux/errno.h> 13 14 #include <linux/kernel.h> 14 15 #include <linux/signal.h> 15 16 #include <linux/syscalls.h> 16 17 17 - #include <asm/compat.h> 18 18 #include <asm/compat-signal.h> 19 19 #include <linux/uaccess.h> 20 20 #include <asm/unistd.h>
+1
arch/nds32/include/asm/Kbuild
··· 9 9 generic-y += clkdev.h 10 10 generic-y += cmpxchg.h 11 11 generic-y += cmpxchg-local.h 12 + generic-y += compat.h 12 13 generic-y += cputime.h 13 14 generic-y += device.h 14 15 generic-y += div64.h
+1
arch/nios2/include/asm/Kbuild
··· 4 4 generic-y += bug.h 5 5 generic-y += bugs.h 6 6 generic-y += cmpxchg.h 7 + generic-y += compat.h 7 8 generic-y += current.h 8 9 generic-y += device.h 9 10 generic-y += div64.h
+1
arch/openrisc/include/asm/Kbuild
··· 2 2 generic-y += bug.h 3 3 generic-y += bugs.h 4 4 generic-y += checksum.h 5 + generic-y += compat.h 5 6 generic-y += current.h 6 7 generic-y += device.h 7 8 generic-y += div64.h
-11
arch/parisc/include/asm/compat.h
··· 13 13 14 14 typedef u32 compat_size_t; 15 15 typedef s32 compat_ssize_t; 16 - typedef s32 compat_time_t; 17 16 typedef s32 compat_clock_t; 18 17 typedef s32 compat_pid_t; 19 18 typedef u32 __compat_uid_t; ··· 38 39 typedef u32 compat_ulong_t; 39 40 typedef u64 compat_u64; 40 41 typedef u32 compat_uptr_t; 41 - 42 - struct compat_timespec { 43 - compat_time_t tv_sec; 44 - s32 tv_nsec; 45 - }; 46 - 47 - struct compat_timeval { 48 - compat_time_t tv_sec; 49 - s32 tv_usec; 50 - }; 51 42 52 43 struct compat_stat { 53 44 compat_dev_t st_dev; /* dev_t is 32 bits on parisc */
-11
arch/powerpc/include/asm/compat.h
··· 17 17 18 18 typedef u32 compat_size_t; 19 19 typedef s32 compat_ssize_t; 20 - typedef s32 compat_time_t; 21 20 typedef s32 compat_clock_t; 22 21 typedef s32 compat_pid_t; 23 22 typedef u32 __compat_uid_t; ··· 43 44 typedef u32 compat_ulong_t; 44 45 typedef u64 compat_u64; 45 46 typedef u32 compat_uptr_t; 46 - 47 - struct compat_timespec { 48 - compat_time_t tv_sec; 49 - s32 tv_nsec; 50 - }; 51 - 52 - struct compat_timeval { 53 - compat_time_t tv_sec; 54 - s32 tv_usec; 55 - }; 56 47 57 48 struct compat_stat { 58 49 compat_dev_t st_dev;
+1 -1
arch/powerpc/kernel/asm-offsets.c
··· 13 13 * 2 of the License, or (at your option) any later version. 14 14 */ 15 15 16 + #include <linux/compat.h> 16 17 #include <linux/signal.h> 17 18 #include <linux/sched.h> 18 19 #include <linux/kernel.h> ··· 43 42 #include <asm/paca.h> 44 43 #include <asm/lppaca.h> 45 44 #include <asm/cache.h> 46 - #include <asm/compat.h> 47 45 #include <asm/mmu.h> 48 46 #include <asm/hvcall.h> 49 47 #include <asm/xics.h>
+1
arch/powerpc/oprofile/backtrace.c
··· 7 7 * 2 of the License, or (at your option) any later version. 8 8 **/ 9 9 10 + #include <linux/compat_time.h> 10 11 #include <linux/oprofile.h> 11 12 #include <linux/sched.h> 12 13 #include <asm/processor.h>
-1
arch/s390/hypfs/hypfs_sprp.c
··· 13 13 #include <linux/string.h> 14 14 #include <linux/types.h> 15 15 #include <linux/uaccess.h> 16 - #include <asm/compat.h> 17 16 #include <asm/diag.h> 18 17 #include <asm/sclp.h> 19 18 #include "hypfs.h"
-11
arch/s390/include/asm/compat.h
··· 53 53 54 54 typedef u32 compat_size_t; 55 55 typedef s32 compat_ssize_t; 56 - typedef s32 compat_time_t; 57 56 typedef s32 compat_clock_t; 58 57 typedef s32 compat_pid_t; 59 58 typedef u16 __compat_uid_t; ··· 95 96 typedef struct { 96 97 u32 gprs_high[NUM_GPRS]; 97 98 } s390_compat_regs_high; 98 - 99 - struct compat_timespec { 100 - compat_time_t tv_sec; 101 - s32 tv_nsec; 102 - }; 103 - 104 - struct compat_timeval { 105 - compat_time_t tv_sec; 106 - s32 tv_usec; 107 - }; 108 99 109 100 struct compat_stat { 110 101 compat_dev_t st_dev;
+2 -2
arch/s390/include/asm/elf.h
··· 125 125 * ELF register definitions.. 126 126 */ 127 127 128 + #include <linux/compat.h> 129 + 128 130 #include <asm/ptrace.h> 129 - #include <asm/compat.h> 130 131 #include <asm/syscall.h> 131 132 #include <asm/user.h> 132 133 ··· 137 136 typedef s390_fp_regs compat_elf_fpregset_t; 138 137 typedef s390_compat_regs compat_elf_gregset_t; 139 138 140 - #include <linux/compat.h> 141 139 #include <linux/sched/mm.h> /* for task_struct */ 142 140 #include <asm/mmu_context.h> 143 141
-1
arch/s390/kvm/priv.c
··· 26 26 #include <asm/gmap.h> 27 27 #include <asm/io.h> 28 28 #include <asm/ptrace.h> 29 - #include <asm/compat.h> 30 29 #include <asm/sclp.h> 31 30 #include "gaccess.h" 32 31 #include "kvm-s390.h"
-1
arch/s390/pci/pci_clp.c
··· 19 19 #include <linux/uaccess.h> 20 20 #include <asm/pci_debug.h> 21 21 #include <asm/pci_clp.h> 22 - #include <asm/compat.h> 23 22 #include <asm/clp.h> 24 23 #include <uapi/asm/clp.h> 25 24
+1
arch/sh/include/asm/Kbuild
··· 1 + generic-y += compat.h 1 2 generic-y += current.h 2 3 generic-y += delay.h 3 4 generic-y += div64.h
+4 -11
arch/sparc/include/asm/compat.h
··· 11 11 12 12 typedef u32 compat_size_t; 13 13 typedef s32 compat_ssize_t; 14 - typedef s32 compat_time_t; 15 14 typedef s32 compat_clock_t; 16 15 typedef s32 compat_pid_t; 17 16 typedef u16 __compat_uid_t; ··· 37 38 typedef u32 compat_ulong_t; 38 39 typedef u64 compat_u64; 39 40 typedef u32 compat_uptr_t; 40 - 41 - struct compat_timespec { 42 - compat_time_t tv_sec; 43 - s32 tv_nsec; 44 - }; 45 - 46 - struct compat_timeval { 47 - compat_time_t tv_sec; 48 - s32 tv_usec; 49 - }; 50 41 51 42 struct compat_stat { 52 43 compat_dev_t st_dev; ··· 157 168 return (u32)(unsigned long)uptr; 158 169 } 159 170 171 + #ifdef CONFIG_COMPAT 160 172 static inline void __user *arch_compat_alloc_user_space(long len) 161 173 { 162 174 struct pt_regs *regs = current_thread_info()->kregs; ··· 174 184 175 185 return (void __user *) usp; 176 186 } 187 + #endif 177 188 178 189 struct compat_ipc64_perm { 179 190 compat_key_t key; ··· 234 243 unsigned int __unused2; 235 244 }; 236 245 246 + #ifdef CONFIG_COMPAT 237 247 static inline int is_compat_task(void) 238 248 { 239 249 return test_thread_flag(TIF_32BIT); ··· 246 254 return pt_regs_trap_type(current_pt_regs()) == 0x110; 247 255 } 248 256 #define in_compat_syscall in_compat_syscall 257 + #endif 249 258 250 259 #endif /* _ASM_SPARC64_COMPAT_H */
+1
arch/um/include/asm/Kbuild
··· 1 1 generic-y += barrier.h 2 2 generic-y += bpf_perf_event.h 3 3 generic-y += bug.h 4 + generic-y += compat.h 4 5 generic-y += current.h 5 6 generic-y += delay.h 6 7 generic-y += device.h
+1
arch/unicore32/include/asm/Kbuild
··· 1 1 generic-y += atomic.h 2 2 generic-y += bugs.h 3 + generic-y += compat.h 3 4 generic-y += current.h 4 5 generic-y += device.h 5 6 generic-y += div64.h
+1 -1
arch/x86/events/core.c
··· 2391 2391 2392 2392 #ifdef CONFIG_IA32_EMULATION 2393 2393 2394 - #include <asm/compat.h> 2394 + #include <linux/compat.h> 2395 2395 2396 2396 static inline int 2397 2397 perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry)
-11
arch/x86/include/asm/compat.h
··· 17 17 18 18 typedef u32 compat_size_t; 19 19 typedef s32 compat_ssize_t; 20 - typedef s32 compat_time_t; 21 20 typedef s32 compat_clock_t; 22 21 typedef s32 compat_pid_t; 23 22 typedef u16 __compat_uid_t; ··· 44 45 typedef u32 compat_u32; 45 46 typedef u64 __attribute__((aligned(4))) compat_u64; 46 47 typedef u32 compat_uptr_t; 47 - 48 - struct compat_timespec { 49 - compat_time_t tv_sec; 50 - s32 tv_nsec; 51 - }; 52 - 53 - struct compat_timeval { 54 - compat_time_t tv_sec; 55 - s32 tv_usec; 56 - }; 57 48 58 49 struct compat_stat { 59 50 compat_dev_t st_dev;
+1 -1
arch/x86/include/asm/ftrace.h
··· 49 49 #if !defined(__ASSEMBLY__) && !defined(COMPILE_OFFSETS) 50 50 51 51 #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_IA32_EMULATION) 52 - #include <asm/compat.h> 52 + #include <linux/compat.h> 53 53 54 54 /* 55 55 * Because ia32 syscalls do not map to x86_64 syscall numbers
+1 -1
arch/x86/kernel/sys_x86_64.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/compat.h> 2 3 #include <linux/errno.h> 3 4 #include <linux/sched.h> 4 5 #include <linux/sched/mm.h> ··· 20 19 #include <linux/elf.h> 21 20 22 21 #include <asm/elf.h> 23 - #include <asm/compat.h> 24 22 #include <asm/ia32.h> 25 23 #include <asm/syscalls.h> 26 24 #include <asm/mpx.h>
+1
arch/xtensa/include/asm/Kbuild
··· 1 1 generic-y += bug.h 2 + generic-y += compat.h 2 3 generic-y += device.h 3 4 generic-y += div64.h 4 5 generic-y += dma-contiguous.h
-1
drivers/s390/block/dasd_ioctl.c
··· 18 18 #include <linux/fs.h> 19 19 #include <linux/blkpg.h> 20 20 #include <linux/slab.h> 21 - #include <asm/compat.h> 22 21 #include <asm/ccwdev.h> 23 22 #include <asm/schid.h> 24 23 #include <asm/cmb.h>
-1
drivers/s390/char/fs3270.c
··· 19 19 #include <linux/slab.h> 20 20 #include <linux/types.h> 21 21 22 - #include <asm/compat.h> 23 22 #include <asm/ccwdev.h> 24 23 #include <asm/cio.h> 25 24 #include <asm/ebcdic.h>
-1
drivers/s390/char/sclp_ctl.c
··· 14 14 #include <linux/init.h> 15 15 #include <linux/ioctl.h> 16 16 #include <linux/fs.h> 17 - #include <asm/compat.h> 18 17 #include <asm/sclp_ctl.h> 19 18 #include <asm/sclp.h> 20 19
-1
drivers/s390/char/vmcp.c
··· 23 23 #include <linux/mutex.h> 24 24 #include <linux/cma.h> 25 25 #include <linux/mm.h> 26 - #include <asm/compat.h> 27 26 #include <asm/cpcmd.h> 28 27 #include <asm/debug.h> 29 28 #include <asm/vmcp.h>
-1
drivers/s390/cio/chsc_sch.c
··· 16 16 #include <linux/miscdevice.h> 17 17 #include <linux/kernel_stat.h> 18 18 19 - #include <asm/compat.h> 20 19 #include <asm/cio.h> 21 20 #include <asm/chsc.h> 22 21 #include <asm/isc.h>
+1 -1
drivers/s390/net/qeth_core_main.c
··· 10 10 #define KMSG_COMPONENT "qeth" 11 11 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 12 12 13 + #include <linux/compat.h> 13 14 #include <linux/module.h> 14 15 #include <linux/moduleparam.h> 15 16 #include <linux/string.h> ··· 33 32 #include <asm/chpid.h> 34 33 #include <asm/io.h> 35 34 #include <asm/sysinfo.h> 36 - #include <asm/compat.h> 37 35 #include <asm/diag.h> 38 36 #include <asm/cio.h> 39 37 #include <asm/ccwdev.h>
+3
include/asm-generic/compat.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + /* This is an empty stub for 32-bit-only architectures */
+8 -4
include/linux/compat.h
··· 7 7 */ 8 8 9 9 #include <linux/types.h> 10 - 11 - #ifdef CONFIG_COMPAT 10 + #include <linux/compat_time.h> 12 11 13 12 #include <linux/stat.h> 14 13 #include <linux/param.h> /* for HZ */ ··· 20 21 #include <linux/unistd.h> 21 22 22 23 #include <asm/compat.h> 24 + 25 + #ifdef CONFIG_COMPAT 23 26 #include <asm/siginfo.h> 24 27 #include <asm/signal.h> 28 + #endif 25 29 26 30 #ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER 27 31 /* ··· 84 82 } \ 85 83 static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) 86 84 #endif /* COMPAT_SYSCALL_DEFINEx */ 85 + 86 + #ifdef CONFIG_COMPAT 87 87 88 88 #ifndef compat_user_stack_pointer 89 89 #define compat_user_stack_pointer() current_user_stack_pointer() ··· 294 290 extern int compat_put_timespec(const struct timespec *, void __user *); 295 291 extern int compat_get_timeval(struct timeval *, const void __user *); 296 292 extern int compat_put_timeval(const struct timeval *, void __user *); 297 - extern int compat_get_timespec64(struct timespec64 *, const void __user *); 298 - extern int compat_put_timespec64(const struct timespec64 *, void __user *); 299 293 extern int get_compat_itimerspec64(struct itimerspec64 *its, 300 294 const struct compat_itimerspec __user *uits); 301 295 extern int put_compat_itimerspec64(const struct itimerspec64 *its, ··· 1018 1016 #else /* !CONFIG_COMPAT */ 1019 1017 1020 1018 #define is_compat_task() (0) 1019 + #ifndef in_compat_syscall 1021 1020 static inline bool in_compat_syscall(void) { return false; } 1021 + #endif 1022 1022 1023 1023 #endif /* CONFIG_COMPAT */ 1024 1024
+23
include/linux/compat_time.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_COMPAT_TIME_H 3 + #define _LINUX_COMPAT_TIME_H 4 + 5 + #include <linux/types.h> 6 + #include <linux/time64.h> 7 + 8 + typedef s32 compat_time_t; 9 + 10 + struct compat_timespec { 11 + compat_time_t tv_sec; 12 + s32 tv_nsec; 13 + }; 14 + 15 + struct compat_timeval { 16 + compat_time_t tv_sec; 17 + s32 tv_usec; 18 + }; 19 + 20 + extern int compat_get_timespec64(struct timespec64 *, const void __user *); 21 + extern int compat_put_timespec64(const struct timespec64 *, void __user *); 22 + 23 + #endif /* _LINUX_COMPAT_TIME_H */
+2 -5
include/linux/restart_block.h
··· 7 7 8 8 #include <linux/compiler.h> 9 9 #include <linux/types.h> 10 + #include <linux/time64.h> 10 11 11 12 struct timespec; 12 13 struct compat_timespec; ··· 16 15 enum timespec_type { 17 16 TT_NONE = 0, 18 17 TT_NATIVE = 1, 19 - #ifdef CONFIG_COMPAT 20 18 TT_COMPAT = 2, 21 - #endif 22 19 }; 23 20 24 21 /* ··· 39 40 clockid_t clockid; 40 41 enum timespec_type type; 41 42 union { 42 - struct timespec __user *rmtp; 43 - #ifdef CONFIG_COMPAT 43 + struct __kernel_timespec __user *rmtp; 44 44 struct compat_timespec __user *compat_rmtp; 45 - #endif 46 45 }; 47 46 u64 expires; 48 47 } nanosleep;
+7 -6
include/linux/syscalls.h
··· 536 536 size_t len); 537 537 538 538 /* kernel/hrtimer.c */ 539 - asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp); 539 + asmlinkage long sys_nanosleep(struct __kernel_timespec __user *rqtp, 540 + struct __kernel_timespec __user *rmtp); 540 541 541 542 /* kernel/itimer.c */ 542 543 asmlinkage long sys_getitimer(int which, struct itimerval __user *value); ··· 568 567 struct itimerspec __user *old_setting); 569 568 asmlinkage long sys_timer_delete(timer_t timer_id); 570 569 asmlinkage long sys_clock_settime(clockid_t which_clock, 571 - const struct timespec __user *tp); 570 + const struct __kernel_timespec __user *tp); 572 571 asmlinkage long sys_clock_gettime(clockid_t which_clock, 573 - struct timespec __user *tp); 572 + struct __kernel_timespec __user *tp); 574 573 asmlinkage long sys_clock_getres(clockid_t which_clock, 575 - struct timespec __user *tp); 574 + struct __kernel_timespec __user *tp); 576 575 asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags, 577 - const struct timespec __user *rqtp, 578 - struct timespec __user *rmtp); 576 + const struct __kernel_timespec __user *rqtp, 577 + struct __kernel_timespec __user *rmtp); 579 578 580 579 /* kernel/printk.c */ 581 580 asmlinkage long sys_syslog(int type, char __user *buf, int len);
+2 -2
include/linux/time.h
··· 10 10 extern struct timezone sys_tz; 11 11 12 12 int get_timespec64(struct timespec64 *ts, 13 - const struct timespec __user *uts); 13 + const struct __kernel_timespec __user *uts); 14 14 int put_timespec64(const struct timespec64 *ts, 15 - struct timespec __user *uts); 15 + struct __kernel_timespec __user *uts); 16 16 int get_itimerspec64(struct itimerspec64 *it, 17 17 const struct itimerspec __user *uit); 18 18 int put_itimerspec64(const struct itimerspec64 *it,
+9 -1
include/linux/time64.h
··· 2 2 #ifndef _LINUX_TIME64_H 3 3 #define _LINUX_TIME64_H 4 4 5 - #include <uapi/linux/time.h> 6 5 #include <linux/math64.h> 7 6 8 7 typedef __s64 time64_t; 9 8 typedef __u64 timeu64_t; 9 + 10 + /* CONFIG_64BIT_TIME enables new 64 bit time_t syscalls in the compat path 11 + * and 32-bit emulation. 12 + */ 13 + #ifndef CONFIG_64BIT_TIME 14 + #define __kernel_timespec timespec 15 + #endif 16 + 17 + #include <uapi/linux/time.h> 10 18 11 19 #if __BITS_PER_LONG == 64 12 20 /* this trick allows us to optimize out timespec64_to_timespec */
+1
include/uapi/asm-generic/posix_types.h
··· 87 87 typedef __kernel_long_t __kernel_off_t; 88 88 typedef long long __kernel_loff_t; 89 89 typedef __kernel_long_t __kernel_time_t; 90 + typedef long long __kernel_time64_t; 90 91 typedef __kernel_long_t __kernel_clock_t; 91 92 typedef int __kernel_timer_t; 92 93 typedef int __kernel_clockid_t;
+7
include/uapi/linux/time.h
··· 42 42 struct timeval it_value; /* current value */ 43 43 }; 44 44 45 + #ifndef __kernel_timespec 46 + struct __kernel_timespec { 47 + __kernel_time64_t tv_sec; /* seconds */ 48 + long long tv_nsec; /* nanoseconds */ 49 + }; 50 + #endif 51 + 45 52 /* 46 53 * legacy timeval structure, only embedded in structures that 47 54 * traditionally used 'timeval' to pass time intervals (not absolute
+8 -44
kernel/compat.c
··· 120 120 __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0; 121 121 } 122 122 123 - static int __compat_get_timespec64(struct timespec64 *ts64, 124 - const struct compat_timespec __user *cts) 125 - { 126 - struct compat_timespec ts; 127 - int ret; 128 - 129 - ret = copy_from_user(&ts, cts, sizeof(ts)); 130 - if (ret) 131 - return -EFAULT; 132 - 133 - ts64->tv_sec = ts.tv_sec; 134 - ts64->tv_nsec = ts.tv_nsec; 135 - 136 - return 0; 137 - } 138 - 139 - static int __compat_put_timespec64(const struct timespec64 *ts64, 140 - struct compat_timespec __user *cts) 141 - { 142 - struct compat_timespec ts = { 143 - .tv_sec = ts64->tv_sec, 144 - .tv_nsec = ts64->tv_nsec 145 - }; 146 - return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0; 147 - } 148 - 149 - int compat_get_timespec64(struct timespec64 *ts, const void __user *uts) 150 - { 151 - if (COMPAT_USE_64BIT_TIME) 152 - return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0; 153 - else 154 - return __compat_get_timespec64(ts, uts); 155 - } 156 - EXPORT_SYMBOL_GPL(compat_get_timespec64); 157 - 158 - int compat_put_timespec64(const struct timespec64 *ts, void __user *uts) 159 - { 160 - if (COMPAT_USE_64BIT_TIME) 161 - return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0; 162 - else 163 - return __compat_put_timespec64(ts, uts); 164 - } 165 - EXPORT_SYMBOL_GPL(compat_put_timespec64); 166 - 167 123 int compat_get_timeval(struct timeval *tv, const void __user *utv) 168 124 { 169 125 if (COMPAT_USE_64BIT_TIME) ··· 322 366 323 367 return ret; 324 368 } 369 + 370 + /* Todo: Delete these extern declarations when get/put_compat_itimerspec64() 371 + * are moved to kernel/time/time.c . 372 + */ 373 + extern int __compat_get_timespec64(struct timespec64 *ts64, 374 + const struct compat_timespec __user *cts); 375 + extern int __compat_put_timespec64(const struct timespec64 *ts64, 376 + struct compat_timespec __user *cts); 325 377 326 378 int get_compat_itimerspec64(struct itimerspec64 *its, 327 379 const struct compat_itimerspec __user *uits)
+7 -3
kernel/time/hrtimer.c
··· 1747 1747 return ret; 1748 1748 } 1749 1749 1750 - SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, 1751 - struct timespec __user *, rmtp) 1750 + #if !defined(CONFIG_64BIT_TIME) || defined(CONFIG_64BIT) 1751 + 1752 + SYSCALL_DEFINE2(nanosleep, struct __kernel_timespec __user *, rqtp, 1753 + struct __kernel_timespec __user *, rmtp) 1752 1754 { 1753 1755 struct timespec64 tu; 1754 1756 ··· 1765 1763 return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC); 1766 1764 } 1767 1765 1768 - #ifdef CONFIG_COMPAT 1766 + #endif 1767 + 1768 + #ifdef CONFIG_COMPAT_32BIT_TIME 1769 1769 1770 1770 COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, 1771 1771 struct compat_timespec __user *, rmtp)
+7 -5
kernel/time/posix-stubs.c
··· 59 59 */ 60 60 61 61 SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 62 - const struct timespec __user *, tp) 62 + const struct __kernel_timespec __user *, tp) 63 63 { 64 64 struct timespec64 new_tp; 65 65 ··· 92 92 return 0; 93 93 } 94 94 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 95 - struct timespec __user *, tp) 95 + struct __kernel_timespec __user *, tp) 96 96 { 97 97 int ret; 98 98 struct timespec64 kernel_tp; ··· 106 106 return 0; 107 107 } 108 108 109 - SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) 109 + SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct __kernel_timespec __user *, tp) 110 110 { 111 111 struct timespec64 rtn_tp = { 112 112 .tv_sec = 0, ··· 126 126 } 127 127 128 128 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 129 - const struct timespec __user *, rqtp, 130 - struct timespec __user *, rmtp) 129 + const struct __kernel_timespec __user *, rqtp, 130 + struct __kernel_timespec __user *, rmtp) 131 131 { 132 132 struct timespec64 t; 133 133 ··· 160 160 COMPAT_SYS_NI(timer_gettime); 161 161 COMPAT_SYS_NI(getitimer); 162 162 COMPAT_SYS_NI(setitimer); 163 + #endif 163 164 165 + #ifdef CONFIG_COMPAT_32BIT_TIME 164 166 COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 165 167 struct compat_timespec __user *, tp) 166 168 {
+17 -7
kernel/time/posix-timers.c
··· 1041 1041 } 1042 1042 1043 1043 SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 1044 - const struct timespec __user *, tp) 1044 + const struct __kernel_timespec __user *, tp) 1045 1045 { 1046 1046 const struct k_clock *kc = clockid_to_kclock(which_clock); 1047 1047 struct timespec64 new_tp; ··· 1056 1056 } 1057 1057 1058 1058 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, 1059 - struct timespec __user *,tp) 1059 + struct __kernel_timespec __user *, tp) 1060 1060 { 1061 1061 const struct k_clock *kc = clockid_to_kclock(which_clock); 1062 1062 struct timespec64 kernel_tp; ··· 1097 1097 } 1098 1098 1099 1099 SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, 1100 - struct timespec __user *, tp) 1100 + struct __kernel_timespec __user *, tp) 1101 1101 { 1102 1102 const struct k_clock *kc = clockid_to_kclock(which_clock); 1103 1103 struct timespec64 rtn_tp; ··· 1114 1114 return error; 1115 1115 } 1116 1116 1117 - #ifdef CONFIG_COMPAT 1117 + #ifdef CONFIG_COMPAT_32BIT_TIME 1118 1118 1119 1119 COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock, 1120 1120 struct compat_timespec __user *, tp) ··· 1149 1149 return err; 1150 1150 } 1151 1151 1152 + #endif 1153 + 1154 + #ifdef CONFIG_COMPAT 1155 + 1152 1156 COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock, 1153 1157 struct compat_timex __user *, utp) 1154 1158 { ··· 1176 1172 1177 1173 return err; 1178 1174 } 1175 + 1176 + #endif 1177 + 1178 + #ifdef CONFIG_COMPAT_32BIT_TIME 1179 1179 1180 1180 COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock, 1181 1181 struct compat_timespec __user *, tp) ··· 1212 1204 } 1213 1205 1214 1206 SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, 1215 - const struct timespec __user *, rqtp, 1216 - struct timespec __user *, rmtp) 1207 + const struct __kernel_timespec __user *, rqtp, 1208 + struct __kernel_timespec __user *, rmtp) 1217 1209 { 1218 1210 const struct k_clock *kc = clockid_to_kclock(which_clock); 1219 1211 struct timespec64 t; ··· 1236 1228 return kc->nsleep(which_clock, flags, &t); 1237 1229 } 1238 1230 1239 - #ifdef CONFIG_COMPAT 1231 + #ifdef CONFIG_COMPAT_32BIT_TIME 1232 + 1240 1233 COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, 1241 1234 struct compat_timespec __user *, rqtp, 1242 1235 struct compat_timespec __user *, rmtp) ··· 1262 1253 1263 1254 return kc->nsleep(which_clock, flags, &t); 1264 1255 } 1256 + 1265 1257 #endif 1266 1258 1267 1259 static const struct k_clock clock_realtime = {
+54 -4
kernel/time/time.c
··· 853 853 } 854 854 855 855 int get_timespec64(struct timespec64 *ts, 856 - const struct timespec __user *uts) 856 + const struct __kernel_timespec __user *uts) 857 857 { 858 - struct timespec kts; 858 + struct __kernel_timespec kts; 859 859 int ret; 860 860 861 861 ret = copy_from_user(&kts, uts, sizeof(kts)); ··· 863 863 return -EFAULT; 864 864 865 865 ts->tv_sec = kts.tv_sec; 866 + 867 + /* Zero out the padding for 32 bit systems or in compat mode */ 868 + if (IS_ENABLED(CONFIG_64BIT_TIME) && (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall())) 869 + kts.tv_nsec &= 0xFFFFFFFFUL; 870 + 866 871 ts->tv_nsec = kts.tv_nsec; 867 872 868 873 return 0; ··· 875 870 EXPORT_SYMBOL_GPL(get_timespec64); 876 871 877 872 int put_timespec64(const struct timespec64 *ts, 878 - struct timespec __user *uts) 873 + struct __kernel_timespec __user *uts) 879 874 { 880 - struct timespec kts = { 875 + struct __kernel_timespec kts = { 881 876 .tv_sec = ts->tv_sec, 882 877 .tv_nsec = ts->tv_nsec 883 878 }; 879 + 884 880 return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0; 885 881 } 886 882 EXPORT_SYMBOL_GPL(put_timespec64); 883 + 884 + int __compat_get_timespec64(struct timespec64 *ts64, 885 + const struct compat_timespec __user *cts) 886 + { 887 + struct compat_timespec ts; 888 + int ret; 889 + 890 + ret = copy_from_user(&ts, cts, sizeof(ts)); 891 + if (ret) 892 + return -EFAULT; 893 + 894 + ts64->tv_sec = ts.tv_sec; 895 + ts64->tv_nsec = ts.tv_nsec; 896 + 897 + return 0; 898 + } 899 + 900 + int __compat_put_timespec64(const struct timespec64 *ts64, 901 + struct compat_timespec __user *cts) 902 + { 903 + struct compat_timespec ts = { 904 + .tv_sec = ts64->tv_sec, 905 + .tv_nsec = ts64->tv_nsec 906 + }; 907 + return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0; 908 + } 909 + 910 + int compat_get_timespec64(struct timespec64 *ts, const void __user *uts) 911 + { 912 + if (COMPAT_USE_64BIT_TIME) 913 + return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0; 914 + else 915 + return __compat_get_timespec64(ts, uts); 916 + } 917 + EXPORT_SYMBOL_GPL(compat_get_timespec64); 918 + 919 + int compat_put_timespec64(const struct timespec64 *ts, void __user *uts) 920 + { 921 + if (COMPAT_USE_64BIT_TIME) 922 + return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0; 923 + else 924 + return __compat_put_timespec64(ts, uts); 925 + } 926 + EXPORT_SYMBOL_GPL(compat_put_timespec64); 887 927 888 928 int get_itimerspec64(struct itimerspec64 *it, 889 929 const struct itimerspec __user *uit)