y2038: timekeeping syscall changes
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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJa2IAgAAoJEGCrR//JCVInWDMP/2n44rfblcBVZSt+WPOBXIxD nXkCrFqUQzhK/7ccQhd9Ij/Zjl+eed+nSe98fyfq23//eg18s9FCHqFYLlTTkJRt iXvxCdjiKTO527VZcHy4gIQaovytbzLSn9PMKgaaOTh8bFiPi/JLHHw2IcC7Hg4X oLxg+6XNBAN63JXgjzWF1mwmRyCOyN5JIUCIIQPySfRuQekPAd0EbgW8hvWvZJl/ L42VSszP5gPoSF1u+JKVtpNlDXB9POhoBSpVn+Kh19TJAYH9yxOOPxJ3RRvWGSS+ thMkNHlwJpyF3e5xgc24FgozW1lyKzMWSaUcYxLr0JNuehDX2oJCdpDkDQTXWPL2 IFIX7w/5wwVlC152wkAcwR/OdfrwhNiU9Ed6sgXZscm9MRN8Qdn1DjQ+xU79zalM feeTdYST8L0MiLOafkQOJWbZzALibUQ+wnFWYGd66O5CMZLDcNU8oE3LbwODi8Gb 91LcFxCmdJMC+O3tRVONpZknG6+qyjXvNmaosgTE8KiHeOY7+FgCRRnVz5yYPKty PHIajRP82+tf5b6tCZRkbQZJMWVA9AzCTS51DOXXrYK3LDF6X8wbQXPguVVZFbiN mmXLHDEVjKC3SHhY/Y8FDkUfy+1dWA1Wd121T/84+UfTchLRJ2S9Yrye/0EvU4gj Szb79+vKmtgK+R+Dn4Cu =8Bch -----END PGP SIGNATURE----- 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.
This commit is contained in:
Коммит
1cfd904f16
15
arch/Kconfig
15
arch/Kconfig
|
@ -870,6 +870,21 @@ config OLD_SIGACTION
|
|||
config COMPAT_OLD_SIGACTION
|
||||
bool
|
||||
|
||||
config 64BIT_TIME
|
||||
def_bool ARCH_HAS_64BIT_TIME
|
||||
help
|
||||
This should be selected by all architectures that need to support
|
||||
new system calls with a 64-bit time_t. This is relevant on all 32-bit
|
||||
architectures, and 64-bit architectures as part of compat syscall
|
||||
handling.
|
||||
|
||||
config COMPAT_32BIT_TIME
|
||||
def_bool (!64BIT && 64BIT_TIME) || COMPAT
|
||||
help
|
||||
This enables 32 bit time_t support in addition to 64 bit time_t support.
|
||||
This is relevant on all 32-bit architectures, and 64-bit architectures
|
||||
as part of compat syscall handling.
|
||||
|
||||
config ARCH_NO_COHERENT_DMA_MMAP
|
||||
bool
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
|
||||
generic-y += compat.h
|
||||
generic-y += exec.h
|
||||
generic-y += export.h
|
||||
generic-y += fb.h
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
generic-y += bugs.h
|
||||
generic-y += compat.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
generic-y += emergency-restart.h
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += early_ioremap.h
|
||||
generic-y += emergency-restart.h
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u16 __compat_uid_t;
|
||||
|
@ -66,16 +65,6 @@ typedef u32 compat_ulong_t;
|
|||
typedef u64 compat_u64;
|
||||
typedef u32 compat_uptr_t;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
#ifdef __AARCH64EB__
|
||||
short st_dev;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
#include <linux/compat_time.h>
|
||||
#include <asm/compat.h>
|
||||
|
||||
/*
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <linux/smp.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/debug-monitors.h>
|
||||
#include <asm/hw_breakpoint.h>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/compat.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <asm/perf_regs.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
generic-y += atomic.h
|
||||
generic-y += barrier.h
|
||||
generic-y += bugs.h
|
||||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
|
|
|
@ -3,6 +3,7 @@ generic-y += barrier.h
|
|||
generic-y += bugs.h
|
||||
generic-y += cacheflush.h
|
||||
generic-y += checksum.h
|
||||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += delay.h
|
||||
generic-y += device.h
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
generic-y += barrier.h
|
||||
generic-y += bug.h
|
||||
generic-y += bugs.h
|
||||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
generic-y += compat.h
|
||||
generic-y += exec.h
|
||||
generic-y += irq_work.h
|
||||
generic-y += mcs_spinlock.h
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
generic-y += barrier.h
|
||||
generic-y += compat.h
|
||||
generic-y += device.h
|
||||
generic-y += emergency-restart.h
|
||||
generic-y += exec.h
|
||||
|
|
|
@ -2,6 +2,7 @@ generic-y += barrier.h
|
|||
generic-y += bitops.h
|
||||
generic-y += bug.h
|
||||
generic-y += bugs.h
|
||||
generic-y += compat.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
generic-y += emergency-restart.h
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_suseconds_t;
|
||||
|
||||
|
@ -46,16 +45,6 @@ typedef u32 compat_ulong_t;
|
|||
typedef u64 compat_u64;
|
||||
typedef u32 compat_uptr_t;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
s32 st_pad1[3];
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
||||
* Copyright (C) 2016, Imagination Technologies Ltd.
|
||||
*/
|
||||
#include <linux/compat.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <asm/compat-signal.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/unistd.h>
|
||||
|
|
|
@ -9,6 +9,7 @@ generic-y += checksum.h
|
|||
generic-y += clkdev.h
|
||||
generic-y += cmpxchg.h
|
||||
generic-y += cmpxchg-local.h
|
||||
generic-y += compat.h
|
||||
generic-y += cputime.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
|
|
|
@ -4,6 +4,7 @@ generic-y += bitops.h
|
|||
generic-y += bug.h
|
||||
generic-y += bugs.h
|
||||
generic-y += cmpxchg.h
|
||||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
|
|
|
@ -2,6 +2,7 @@ generic-y += barrier.h
|
|||
generic-y += bug.h
|
||||
generic-y += bugs.h
|
||||
generic-y += checksum.h
|
||||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u32 __compat_uid_t;
|
||||
|
@ -40,16 +39,6 @@ typedef u32 compat_ulong_t;
|
|||
typedef u64 compat_u64;
|
||||
typedef u32 compat_uptr_t;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev; /* dev_t is 32 bits on parisc */
|
||||
compat_ino_t st_ino; /* 32 bits */
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u32 __compat_uid_t;
|
||||
|
@ -45,16 +44,6 @@ typedef u32 compat_ulong_t;
|
|||
typedef u64 compat_u64;
|
||||
typedef u32 compat_uptr_t;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
compat_ino_t st_ino;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
|
@ -42,7 +43,6 @@
|
|||
#include <asm/paca.h>
|
||||
#include <asm/lppaca.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/hvcall.h>
|
||||
#include <asm/xics.h>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* 2 of the License, or (at your option) any later version.
|
||||
**/
|
||||
|
||||
#include <linux/compat_time.h>
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/processor.h>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/diag.h>
|
||||
#include <asm/sclp.h>
|
||||
#include "hypfs.h"
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u16 __compat_uid_t;
|
||||
|
@ -97,16 +96,6 @@ typedef struct {
|
|||
u32 gprs_high[NUM_GPRS];
|
||||
} s390_compat_regs_high;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
u16 __pad1;
|
||||
|
|
|
@ -125,8 +125,9 @@
|
|||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
#include <linux/compat.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/syscall.h>
|
||||
#include <asm/user.h>
|
||||
|
||||
|
@ -136,7 +137,6 @@ typedef s390_regs elf_gregset_t;
|
|||
typedef s390_fp_regs compat_elf_fpregset_t;
|
||||
typedef s390_compat_regs compat_elf_gregset_t;
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/sched/mm.h> /* for task_struct */
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <asm/gmap.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/sclp.h>
|
||||
#include "gaccess.h"
|
||||
#include "kvm-s390.h"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <asm/pci_debug.h>
|
||||
#include <asm/pci_clp.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/clp.h>
|
||||
#include <uapi/asm/clp.h>
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += delay.h
|
||||
generic-y += div64.h
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u16 __compat_uid_t;
|
||||
|
@ -39,16 +38,6 @@ typedef u32 compat_ulong_t;
|
|||
typedef u64 compat_u64;
|
||||
typedef u32 compat_uptr_t;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
compat_ino_t st_ino;
|
||||
|
@ -168,6 +157,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
|||
return (u32)(unsigned long)uptr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static inline void __user *arch_compat_alloc_user_space(long len)
|
||||
{
|
||||
struct pt_regs *regs = current_thread_info()->kregs;
|
||||
|
@ -184,6 +174,7 @@ static inline void __user *arch_compat_alloc_user_space(long len)
|
|||
|
||||
return (void __user *) usp;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
|
@ -243,6 +234,7 @@ struct compat_shmid64_ds {
|
|||
unsigned int __unused2;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static inline int is_compat_task(void)
|
||||
{
|
||||
return test_thread_flag(TIF_32BIT);
|
||||
|
@ -254,5 +246,6 @@ static inline bool in_compat_syscall(void)
|
|||
return pt_regs_trap_type(current_pt_regs()) == 0x110;
|
||||
}
|
||||
#define in_compat_syscall in_compat_syscall
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_SPARC64_COMPAT_H */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
generic-y += barrier.h
|
||||
generic-y += bpf_perf_event.h
|
||||
generic-y += bug.h
|
||||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += delay.h
|
||||
generic-y += device.h
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
generic-y += atomic.h
|
||||
generic-y += bugs.h
|
||||
generic-y += compat.h
|
||||
generic-y += current.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
|
|
|
@ -2391,7 +2391,7 @@ static unsigned long get_segment_base(unsigned int segment)
|
|||
|
||||
#ifdef CONFIG_IA32_EMULATION
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <linux/compat.h>
|
||||
|
||||
static inline int
|
||||
perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry)
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u16 __compat_uid_t;
|
||||
|
@ -46,16 +45,6 @@ typedef u32 compat_u32;
|
|||
typedef u64 __attribute__((aligned(4))) compat_u64;
|
||||
typedef u32 compat_uptr_t;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
u16 __pad1;
|
||||
|
|
|
@ -49,7 +49,7 @@ int ftrace_int3_handler(struct pt_regs *regs);
|
|||
#if !defined(__ASSEMBLY__) && !defined(COMPILE_OFFSETS)
|
||||
|
||||
#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_IA32_EMULATION)
|
||||
#include <asm/compat.h>
|
||||
#include <linux/compat.h>
|
||||
|
||||
/*
|
||||
* Because ia32 syscalls do not map to x86_64 syscall numbers
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/compat.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
@ -19,7 +20,6 @@
|
|||
#include <linux/elf.h>
|
||||
|
||||
#include <asm/elf.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/ia32.h>
|
||||
#include <asm/syscalls.h>
|
||||
#include <asm/mpx.h>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
generic-y += bug.h
|
||||
generic-y += compat.h
|
||||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
generic-y += dma-contiguous.h
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/blkpg.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/ccwdev.h>
|
||||
#include <asm/schid.h>
|
||||
#include <asm/cmb.h>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <asm/ccwdev.h>
|
||||
#include <asm/cio.h>
|
||||
#include <asm/ebcdic.h>
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/sclp_ctl.h>
|
||||
#include <asm/sclp.h>
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/cma.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/cpcmd.h>
|
||||
#include <asm/debug.h>
|
||||
#include <asm/vmcp.h>
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <linux/miscdevice.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <asm/cio.h>
|
||||
#include <asm/chsc.h>
|
||||
#include <asm/isc.h>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define KMSG_COMPONENT "qeth"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/string.h>
|
||||
|
@ -32,7 +33,6 @@
|
|||
#include <asm/chpid.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sysinfo.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/diag.h>
|
||||
#include <asm/cio.h>
|
||||
#include <asm/ccwdev.h>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
/* This is an empty stub for 32-bit-only architectures */
|
|
@ -7,8 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat_time.h>
|
||||
|
||||
#include <linux/stat.h>
|
||||
#include <linux/param.h> /* for HZ */
|
||||
|
@ -21,8 +20,11 @@
|
|||
#include <linux/unistd.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <asm/siginfo.h>
|
||||
#include <asm/signal.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
|
||||
/*
|
||||
|
@ -83,6 +85,8 @@
|
|||
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
|
||||
#endif /* COMPAT_SYSCALL_DEFINEx */
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
#ifndef compat_user_stack_pointer
|
||||
#define compat_user_stack_pointer() current_user_stack_pointer()
|
||||
#endif
|
||||
|
@ -290,8 +294,6 @@ extern int compat_get_timespec(struct timespec *, const void __user *);
|
|||
extern int compat_put_timespec(const struct timespec *, void __user *);
|
||||
extern int compat_get_timeval(struct timeval *, const void __user *);
|
||||
extern int compat_put_timeval(const struct timeval *, void __user *);
|
||||
extern int compat_get_timespec64(struct timespec64 *, const void __user *);
|
||||
extern int compat_put_timespec64(const struct timespec64 *, void __user *);
|
||||
extern int get_compat_itimerspec64(struct itimerspec64 *its,
|
||||
const struct compat_itimerspec __user *uits);
|
||||
extern int put_compat_itimerspec64(const struct itimerspec64 *its,
|
||||
|
@ -1016,7 +1018,9 @@ static inline struct compat_timeval ns_to_compat_timeval(s64 nsec)
|
|||
#else /* !CONFIG_COMPAT */
|
||||
|
||||
#define is_compat_task() (0)
|
||||
#ifndef in_compat_syscall
|
||||
static inline bool in_compat_syscall(void) { return false; }
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LINUX_COMPAT_TIME_H
|
||||
#define _LINUX_COMPAT_TIME_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/time64.h>
|
||||
|
||||
typedef s32 compat_time_t;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
extern int compat_get_timespec64(struct timespec64 *, const void __user *);
|
||||
extern int compat_put_timespec64(const struct timespec64 *, void __user *);
|
||||
|
||||
#endif /* _LINUX_COMPAT_TIME_H */
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/time64.h>
|
||||
|
||||
struct timespec;
|
||||
struct compat_timespec;
|
||||
|
@ -15,9 +16,7 @@ struct pollfd;
|
|||
enum timespec_type {
|
||||
TT_NONE = 0,
|
||||
TT_NATIVE = 1,
|
||||
#ifdef CONFIG_COMPAT
|
||||
TT_COMPAT = 2,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -40,10 +39,8 @@ struct restart_block {
|
|||
clockid_t clockid;
|
||||
enum timespec_type type;
|
||||
union {
|
||||
struct timespec __user *rmtp;
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct __kernel_timespec __user *rmtp;
|
||||
struct compat_timespec __user *compat_rmtp;
|
||||
#endif
|
||||
};
|
||||
u64 expires;
|
||||
} nanosleep;
|
||||
|
|
|
@ -536,7 +536,8 @@ asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
|
|||
size_t len);
|
||||
|
||||
/* kernel/hrtimer.c */
|
||||
asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp);
|
||||
asmlinkage long sys_nanosleep(struct __kernel_timespec __user *rqtp,
|
||||
struct __kernel_timespec __user *rmtp);
|
||||
|
||||
/* kernel/itimer.c */
|
||||
asmlinkage long sys_getitimer(int which, struct itimerval __user *value);
|
||||
|
@ -567,14 +568,14 @@ asmlinkage long sys_timer_settime(timer_t timer_id, int flags,
|
|||
struct itimerspec __user *old_setting);
|
||||
asmlinkage long sys_timer_delete(timer_t timer_id);
|
||||
asmlinkage long sys_clock_settime(clockid_t which_clock,
|
||||
const struct timespec __user *tp);
|
||||
const struct __kernel_timespec __user *tp);
|
||||
asmlinkage long sys_clock_gettime(clockid_t which_clock,
|
||||
struct timespec __user *tp);
|
||||
struct __kernel_timespec __user *tp);
|
||||
asmlinkage long sys_clock_getres(clockid_t which_clock,
|
||||
struct timespec __user *tp);
|
||||
struct __kernel_timespec __user *tp);
|
||||
asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags,
|
||||
const struct timespec __user *rqtp,
|
||||
struct timespec __user *rmtp);
|
||||
const struct __kernel_timespec __user *rqtp,
|
||||
struct __kernel_timespec __user *rmtp);
|
||||
|
||||
/* kernel/printk.c */
|
||||
asmlinkage long sys_syslog(int type, char __user *buf, int len);
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
extern struct timezone sys_tz;
|
||||
|
||||
int get_timespec64(struct timespec64 *ts,
|
||||
const struct timespec __user *uts);
|
||||
const struct __kernel_timespec __user *uts);
|
||||
int put_timespec64(const struct timespec64 *ts,
|
||||
struct timespec __user *uts);
|
||||
struct __kernel_timespec __user *uts);
|
||||
int get_itimerspec64(struct itimerspec64 *it,
|
||||
const struct itimerspec __user *uit);
|
||||
int put_itimerspec64(const struct itimerspec64 *it,
|
||||
|
|
|
@ -2,12 +2,20 @@
|
|||
#ifndef _LINUX_TIME64_H
|
||||
#define _LINUX_TIME64_H
|
||||
|
||||
#include <uapi/linux/time.h>
|
||||
#include <linux/math64.h>
|
||||
|
||||
typedef __s64 time64_t;
|
||||
typedef __u64 timeu64_t;
|
||||
|
||||
/* CONFIG_64BIT_TIME enables new 64 bit time_t syscalls in the compat path
|
||||
* and 32-bit emulation.
|
||||
*/
|
||||
#ifndef CONFIG_64BIT_TIME
|
||||
#define __kernel_timespec timespec
|
||||
#endif
|
||||
|
||||
#include <uapi/linux/time.h>
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
/* this trick allows us to optimize out timespec64_to_timespec */
|
||||
# define timespec64 timespec
|
||||
|
|
|
@ -87,6 +87,7 @@ typedef struct {
|
|||
typedef __kernel_long_t __kernel_off_t;
|
||||
typedef long long __kernel_loff_t;
|
||||
typedef __kernel_long_t __kernel_time_t;
|
||||
typedef long long __kernel_time64_t;
|
||||
typedef __kernel_long_t __kernel_clock_t;
|
||||
typedef int __kernel_timer_t;
|
||||
typedef int __kernel_clockid_t;
|
||||
|
|
|
@ -42,6 +42,13 @@ struct itimerval {
|
|||
struct timeval it_value; /* current value */
|
||||
};
|
||||
|
||||
#ifndef __kernel_timespec
|
||||
struct __kernel_timespec {
|
||||
__kernel_time64_t tv_sec; /* seconds */
|
||||
long long tv_nsec; /* nanoseconds */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* legacy timeval structure, only embedded in structures that
|
||||
* traditionally used 'timeval' to pass time intervals (not absolute
|
||||
|
|
|
@ -120,50 +120,6 @@ static int __compat_put_timespec(const struct timespec *ts, struct compat_timesp
|
|||
__put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int __compat_get_timespec64(struct timespec64 *ts64,
|
||||
const struct compat_timespec __user *cts)
|
||||
{
|
||||
struct compat_timespec ts;
|
||||
int ret;
|
||||
|
||||
ret = copy_from_user(&ts, cts, sizeof(ts));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
ts64->tv_sec = ts.tv_sec;
|
||||
ts64->tv_nsec = ts.tv_nsec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __compat_put_timespec64(const struct timespec64 *ts64,
|
||||
struct compat_timespec __user *cts)
|
||||
{
|
||||
struct compat_timespec ts = {
|
||||
.tv_sec = ts64->tv_sec,
|
||||
.tv_nsec = ts64->tv_nsec
|
||||
};
|
||||
return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
int compat_get_timespec64(struct timespec64 *ts, const void __user *uts)
|
||||
{
|
||||
if (COMPAT_USE_64BIT_TIME)
|
||||
return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0;
|
||||
else
|
||||
return __compat_get_timespec64(ts, uts);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(compat_get_timespec64);
|
||||
|
||||
int compat_put_timespec64(const struct timespec64 *ts, void __user *uts)
|
||||
{
|
||||
if (COMPAT_USE_64BIT_TIME)
|
||||
return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0;
|
||||
else
|
||||
return __compat_put_timespec64(ts, uts);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(compat_put_timespec64);
|
||||
|
||||
int compat_get_timeval(struct timeval *tv, const void __user *utv)
|
||||
{
|
||||
if (COMPAT_USE_64BIT_TIME)
|
||||
|
@ -367,6 +323,14 @@ COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t, pid, unsigned int, len,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Todo: Delete these extern declarations when get/put_compat_itimerspec64()
|
||||
* are moved to kernel/time/time.c .
|
||||
*/
|
||||
extern int __compat_get_timespec64(struct timespec64 *ts64,
|
||||
const struct compat_timespec __user *cts);
|
||||
extern int __compat_put_timespec64(const struct timespec64 *ts64,
|
||||
struct compat_timespec __user *cts);
|
||||
|
||||
int get_compat_itimerspec64(struct itimerspec64 *its,
|
||||
const struct compat_itimerspec __user *uits)
|
||||
{
|
||||
|
|
|
@ -1747,8 +1747,10 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
|
||||
struct timespec __user *, rmtp)
|
||||
#if !defined(CONFIG_64BIT_TIME) || defined(CONFIG_64BIT)
|
||||
|
||||
SYSCALL_DEFINE2(nanosleep, struct __kernel_timespec __user *, rqtp,
|
||||
struct __kernel_timespec __user *, rmtp)
|
||||
{
|
||||
struct timespec64 tu;
|
||||
|
||||
|
@ -1763,7 +1765,9 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
|
|||
return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMPAT_32BIT_TIME
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
|
||||
struct compat_timespec __user *, rmtp)
|
||||
|
|
|
@ -59,7 +59,7 @@ SYS_NI(alarm);
|
|||
*/
|
||||
|
||||
SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
||||
const struct timespec __user *, tp)
|
||||
const struct __kernel_timespec __user *, tp)
|
||||
{
|
||||
struct timespec64 new_tp;
|
||||
|
||||
|
@ -92,7 +92,7 @@ int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
|
|||
return 0;
|
||||
}
|
||||
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
||||
struct timespec __user *, tp)
|
||||
struct __kernel_timespec __user *, tp)
|
||||
{
|
||||
int ret;
|
||||
struct timespec64 kernel_tp;
|
||||
|
@ -106,7 +106,7 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
|||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
|
||||
SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct __kernel_timespec __user *, tp)
|
||||
{
|
||||
struct timespec64 rtn_tp = {
|
||||
.tv_sec = 0,
|
||||
|
@ -126,8 +126,8 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __us
|
|||
}
|
||||
|
||||
SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
|
||||
const struct timespec __user *, rqtp,
|
||||
struct timespec __user *, rmtp)
|
||||
const struct __kernel_timespec __user *, rqtp,
|
||||
struct __kernel_timespec __user *, rmtp)
|
||||
{
|
||||
struct timespec64 t;
|
||||
|
||||
|
@ -160,7 +160,9 @@ COMPAT_SYS_NI(timer_settime);
|
|||
COMPAT_SYS_NI(timer_gettime);
|
||||
COMPAT_SYS_NI(getitimer);
|
||||
COMPAT_SYS_NI(setitimer);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMPAT_32BIT_TIME
|
||||
COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
|
|
|
@ -1041,7 +1041,7 @@ void exit_itimers(struct signal_struct *sig)
|
|||
}
|
||||
|
||||
SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
||||
const struct timespec __user *, tp)
|
||||
const struct __kernel_timespec __user *, tp)
|
||||
{
|
||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||
struct timespec64 new_tp;
|
||||
|
@ -1056,7 +1056,7 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
|
|||
}
|
||||
|
||||
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
|
||||
struct timespec __user *,tp)
|
||||
struct __kernel_timespec __user *, tp)
|
||||
{
|
||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||
struct timespec64 kernel_tp;
|
||||
|
@ -1097,7 +1097,7 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
|
|||
}
|
||||
|
||||
SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
||||
struct timespec __user *, tp)
|
||||
struct __kernel_timespec __user *, tp)
|
||||
{
|
||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||
struct timespec64 rtn_tp;
|
||||
|
@ -1114,7 +1114,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
|
|||
return error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#ifdef CONFIG_COMPAT_32BIT_TIME
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
|
@ -1149,6 +1149,10 @@ COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
|
|||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
|
||||
struct compat_timex __user *, utp)
|
||||
{
|
||||
|
@ -1173,6 +1177,10 @@ COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
|
|||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMPAT_32BIT_TIME
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
|
||||
struct compat_timespec __user *, tp)
|
||||
{
|
||||
|
@ -1204,8 +1212,8 @@ static int common_nsleep(const clockid_t which_clock, int flags,
|
|||
}
|
||||
|
||||
SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
|
||||
const struct timespec __user *, rqtp,
|
||||
struct timespec __user *, rmtp)
|
||||
const struct __kernel_timespec __user *, rqtp,
|
||||
struct __kernel_timespec __user *, rmtp)
|
||||
{
|
||||
const struct k_clock *kc = clockid_to_kclock(which_clock);
|
||||
struct timespec64 t;
|
||||
|
@ -1228,7 +1236,8 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
|
|||
return kc->nsleep(which_clock, flags, &t);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#ifdef CONFIG_COMPAT_32BIT_TIME
|
||||
|
||||
COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
|
||||
struct compat_timespec __user *, rqtp,
|
||||
struct compat_timespec __user *, rmtp)
|
||||
|
@ -1253,6 +1262,7 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
|
|||
|
||||
return kc->nsleep(which_clock, flags, &t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const struct k_clock clock_realtime = {
|
||||
|
|
|
@ -853,9 +853,9 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
|
|||
}
|
||||
|
||||
int get_timespec64(struct timespec64 *ts,
|
||||
const struct timespec __user *uts)
|
||||
const struct __kernel_timespec __user *uts)
|
||||
{
|
||||
struct timespec kts;
|
||||
struct __kernel_timespec kts;
|
||||
int ret;
|
||||
|
||||
ret = copy_from_user(&kts, uts, sizeof(kts));
|
||||
|
@ -863,6 +863,11 @@ int get_timespec64(struct timespec64 *ts,
|
|||
return -EFAULT;
|
||||
|
||||
ts->tv_sec = kts.tv_sec;
|
||||
|
||||
/* Zero out the padding for 32 bit systems or in compat mode */
|
||||
if (IS_ENABLED(CONFIG_64BIT_TIME) && (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()))
|
||||
kts.tv_nsec &= 0xFFFFFFFFUL;
|
||||
|
||||
ts->tv_nsec = kts.tv_nsec;
|
||||
|
||||
return 0;
|
||||
|
@ -870,16 +875,61 @@ int get_timespec64(struct timespec64 *ts,
|
|||
EXPORT_SYMBOL_GPL(get_timespec64);
|
||||
|
||||
int put_timespec64(const struct timespec64 *ts,
|
||||
struct timespec __user *uts)
|
||||
struct __kernel_timespec __user *uts)
|
||||
{
|
||||
struct timespec kts = {
|
||||
struct __kernel_timespec kts = {
|
||||
.tv_sec = ts->tv_sec,
|
||||
.tv_nsec = ts->tv_nsec
|
||||
};
|
||||
|
||||
return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(put_timespec64);
|
||||
|
||||
int __compat_get_timespec64(struct timespec64 *ts64,
|
||||
const struct compat_timespec __user *cts)
|
||||
{
|
||||
struct compat_timespec ts;
|
||||
int ret;
|
||||
|
||||
ret = copy_from_user(&ts, cts, sizeof(ts));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
ts64->tv_sec = ts.tv_sec;
|
||||
ts64->tv_nsec = ts.tv_nsec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __compat_put_timespec64(const struct timespec64 *ts64,
|
||||
struct compat_timespec __user *cts)
|
||||
{
|
||||
struct compat_timespec ts = {
|
||||
.tv_sec = ts64->tv_sec,
|
||||
.tv_nsec = ts64->tv_nsec
|
||||
};
|
||||
return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
int compat_get_timespec64(struct timespec64 *ts, const void __user *uts)
|
||||
{
|
||||
if (COMPAT_USE_64BIT_TIME)
|
||||
return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0;
|
||||
else
|
||||
return __compat_get_timespec64(ts, uts);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(compat_get_timespec64);
|
||||
|
||||
int compat_put_timespec64(const struct timespec64 *ts, void __user *uts)
|
||||
{
|
||||
if (COMPAT_USE_64BIT_TIME)
|
||||
return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0;
|
||||
else
|
||||
return __compat_put_timespec64(ts, uts);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(compat_put_timespec64);
|
||||
|
||||
int get_itimerspec64(struct itimerspec64 *it,
|
||||
const struct itimerspec __user *uit)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче