Commit 0bbcce5d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timers and timekeeping updates from Thomas Gleixner:

 - Core infrastucture work for Y2038 to address the COMPAT interfaces:

     + Add a new Y2038 safe __kernel_timespec and use it in the core
       code

     + Introduce config switches which allow to control the various
       compat mechanisms

     + Use the new config switch in the posix timer code to control the
       32bit compat syscall implementation.

 - Prevent bogus selection of CPU local clocksources which causes an
   endless reselection loop

 - Remove the extra kthread in the clocksource code which has no value
   and just adds another level of indirection

 - The usual bunch of trivial updates, cleanups and fixlets all over the
   place

 - More SPDX conversions

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits)
  clocksource/drivers/mxs_timer: Switch to SPDX identifier
  clocksource/drivers/timer-imx-tpm: Switch to SPDX identifier
  clocksource/drivers/timer-imx-gpt: Switch to SPDX identifier
  clocksource/drivers/timer-imx-gpt: Remove outdated file path
  clocksource/drivers/arc_timer: Add comments about locking while read GFRC
  clocksource/drivers/mips-gic-timer: Add pr_fmt and reword pr_* messages
  clocksource/drivers/sprd: Fix Kconfig dependency
  clocksource: Move inline keyword to the beginning of function declarations
  timer_list: Remove unused function pointer typedef
  timers: Adjust a kernel-doc comment
  tick: Prefer a lower rating device only if it's CPU local device
  clocksource: Remove kthread
  time: Change nanosleep to safe __kernel_* types
  time: Change types to new y2038 safe __kernel_* types
  time: Fix get_timespec64() for y2038 safe compat interfaces
  time: Add new y2038 safe __kernel_timespec
  posix-timers: Make compat syscalls depend on CONFIG_COMPAT_32BIT_TIME
  time: Introduce CONFIG_COMPAT_32BIT_TIME
  time: Introduce CONFIG_64BIT_TIME in architectures
  compat: Enable compat_get/put_timespec64 always
  ...
parents 0ef283d4 e45e778f
...@@ -871,6 +871,21 @@ config OLD_SIGACTION ...@@ -871,6 +871,21 @@ config OLD_SIGACTION
config COMPAT_OLD_SIGACTION config COMPAT_OLD_SIGACTION
bool 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 config ARCH_NO_COHERENT_DMA_MMAP
bool bool
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
generic-y += compat.h
generic-y += exec.h generic-y += exec.h
generic-y += export.h generic-y += export.h
generic-y += fb.h generic-y += fb.h
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
generic-y += bugs.h generic-y += bugs.h
generic-y += compat.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
generic-y += dma-mapping.h generic-y += dma-mapping.h
......
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += early_ioremap.h generic-y += early_ioremap.h
generic-y += emergency-restart.h generic-y += emergency-restart.h
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
typedef u32 compat_size_t; typedef u32 compat_size_t;
typedef s32 compat_ssize_t; typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t; typedef s32 compat_clock_t;
typedef s32 compat_pid_t; typedef s32 compat_pid_t;
typedef u16 __compat_uid_t; typedef u16 __compat_uid_t;
...@@ -66,16 +65,6 @@ typedef u32 compat_ulong_t; ...@@ -66,16 +65,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64; typedef u64 compat_u64;
typedef u32 compat_uptr_t; 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 { struct compat_stat {
#ifdef __AARCH64EB__ #ifdef __AARCH64EB__
short st_dev; short st_dev;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#include <linux/compat_time.h>
#include <asm/compat.h> #include <asm/compat.h>
/* /*
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/compat.h>
#include <asm/current.h> #include <asm/current.h>
#include <asm/debug-monitors.h> #include <asm/debug-monitors.h>
#include <asm/hw_breakpoint.h> #include <asm/hw_breakpoint.h>
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/compat.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <asm/compat.h>
#include <asm/perf_regs.h> #include <asm/perf_regs.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
......
generic-y += atomic.h generic-y += atomic.h
generic-y += barrier.h generic-y += barrier.h
generic-y += bugs.h generic-y += bugs.h
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
......
...@@ -3,6 +3,7 @@ generic-y += barrier.h ...@@ -3,6 +3,7 @@ generic-y += barrier.h
generic-y += bugs.h generic-y += bugs.h
generic-y += cacheflush.h generic-y += cacheflush.h
generic-y += checksum.h generic-y += checksum.h
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += delay.h generic-y += delay.h
generic-y += device.h generic-y += device.h
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
generic-y += barrier.h generic-y += barrier.h
generic-y += bug.h generic-y += bug.h
generic-y += bugs.h generic-y += bugs.h
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
......
generic-y += compat.h
generic-y += exec.h generic-y += exec.h
generic-y += irq_work.h generic-y += irq_work.h
generic-y += mcs_spinlock.h generic-y += mcs_spinlock.h
......
generic-y += barrier.h generic-y += barrier.h
generic-y += compat.h
generic-y += device.h generic-y += device.h
generic-y += emergency-restart.h generic-y += emergency-restart.h
generic-y += exec.h generic-y += exec.h
......
...@@ -2,6 +2,7 @@ generic-y += barrier.h ...@@ -2,6 +2,7 @@ generic-y += barrier.h
generic-y += bitops.h generic-y += bitops.h
generic-y += bug.h generic-y += bug.h
generic-y += bugs.h generic-y += bugs.h
generic-y += compat.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
generic-y += emergency-restart.h generic-y += emergency-restart.h
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
typedef u32 compat_size_t; typedef u32 compat_size_t;
typedef s32 compat_ssize_t; typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t; typedef s32 compat_clock_t;
typedef s32 compat_suseconds_t; typedef s32 compat_suseconds_t;
...@@ -46,16 +45,6 @@ typedef u32 compat_ulong_t; ...@@ -46,16 +45,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64; typedef u64 compat_u64;
typedef u32 compat_uptr_t; 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 { struct compat_stat {
compat_dev_t st_dev; compat_dev_t st_dev;
s32 st_pad1[3]; s32 st_pad1[3];
......
...@@ -8,13 +8,13 @@ ...@@ -8,13 +8,13 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 2016, Imagination Technologies Ltd. * Copyright (C) 2016, Imagination Technologies Ltd.
*/ */
#include <linux/compat.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <asm/compat.h>
#include <asm/compat-signal.h> #include <asm/compat-signal.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/unistd.h> #include <asm/unistd.h>
......
...@@ -9,6 +9,7 @@ generic-y += checksum.h ...@@ -9,6 +9,7 @@ generic-y += checksum.h
generic-y += clkdev.h generic-y += clkdev.h
generic-y += cmpxchg.h generic-y += cmpxchg.h
generic-y += cmpxchg-local.h generic-y += cmpxchg-local.h
generic-y += compat.h
generic-y += cputime.h generic-y += cputime.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
......
...@@ -4,6 +4,7 @@ generic-y += bitops.h ...@@ -4,6 +4,7 @@ generic-y += bitops.h
generic-y += bug.h generic-y += bug.h
generic-y += bugs.h generic-y += bugs.h
generic-y += cmpxchg.h generic-y += cmpxchg.h
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
......
...@@ -2,6 +2,7 @@ generic-y += barrier.h ...@@ -2,6 +2,7 @@ generic-y += barrier.h
generic-y += bug.h generic-y += bug.h
generic-y += bugs.h generic-y += bugs.h
generic-y += checksum.h generic-y += checksum.h
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
typedef u32 compat_size_t; typedef u32 compat_size_t;
typedef s32 compat_ssize_t; typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t; typedef s32 compat_clock_t;
typedef s32 compat_pid_t; typedef s32 compat_pid_t;
typedef u32 __compat_uid_t; typedef u32 __compat_uid_t;
...@@ -40,16 +39,6 @@ typedef u32 compat_ulong_t; ...@@ -40,16 +39,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64; typedef u64 compat_u64;
typedef u32 compat_uptr_t; 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 { struct compat_stat {
compat_dev_t st_dev; /* dev_t is 32 bits on parisc */ compat_dev_t st_dev; /* dev_t is 32 bits on parisc */
compat_ino_t st_ino; /* 32 bits */ compat_ino_t st_ino; /* 32 bits */
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
typedef u32 compat_size_t; typedef u32 compat_size_t;
typedef s32 compat_ssize_t; typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t; typedef s32 compat_clock_t;
typedef s32 compat_pid_t; typedef s32 compat_pid_t;
typedef u32 __compat_uid_t; typedef u32 __compat_uid_t;
...@@ -45,16 +44,6 @@ typedef u32 compat_ulong_t; ...@@ -45,16 +44,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64; typedef u64 compat_u64;
typedef u32 compat_uptr_t; 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 { struct compat_stat {
compat_dev_t st_dev; compat_dev_t st_dev;
compat_ino_t st_ino; compat_ino_t st_ino;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <linux/compat.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -42,7 +43,6 @@ ...@@ -42,7 +43,6 @@
#include <asm/paca.h> #include <asm/paca.h>
#include <asm/lppaca.h> #include <asm/lppaca.h>
#include <asm/cache.h> #include <asm/cache.h>
#include <asm/compat.h>
#include <asm/mmu.h> #include <asm/mmu.h>
#include <asm/hvcall.h> #include <asm/hvcall.h>
#include <asm/xics.h> #include <asm/xics.h>
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
**/ **/
#include <linux/compat_time.h>
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <asm/processor.h> #include <asm/processor.h>
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/compat.h>
#include <asm/diag.h> #include <asm/diag.h>
#include <asm/sclp.h> #include <asm/sclp.h>
#include "hypfs.h" #include "hypfs.h"
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
typedef u32 compat_size_t; typedef u32 compat_size_t;
typedef s32 compat_ssize_t; typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t; typedef s32 compat_clock_t;
typedef s32 compat_pid_t; typedef s32 compat_pid_t;
typedef u16 __compat_uid_t; typedef u16 __compat_uid_t;
...@@ -97,16 +96,6 @@ typedef struct { ...@@ -97,16 +96,6 @@ typedef struct {
u32 gprs_high[NUM_GPRS]; u32 gprs_high[NUM_GPRS];
} s390_compat_regs_high; } 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 { struct compat_stat {
compat_dev_t st_dev; compat_dev_t st_dev;
u16 __pad1; u16 __pad1;
......
...@@ -125,8 +125,9 @@ ...@@ -125,8 +125,9 @@
* ELF register definitions.. * ELF register definitions..
*/ */
#include <linux/compat.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/compat.h>
#include <asm/syscall.h> #include <asm/syscall.h>
#include <asm/user.h> #include <asm/user.h>
...@@ -136,7 +137,6 @@ typedef s390_regs elf_gregset_t; ...@@ -136,7 +137,6 @@ typedef s390_regs elf_gregset_t;
typedef s390_fp_regs compat_elf_fpregset_t; typedef s390_fp_regs compat_elf_fpregset_t;
typedef s390_compat_regs compat_elf_gregset_t; typedef s390_compat_regs compat_elf_gregset_t;
#include <linux/compat.h>
#include <linux/sched/mm.h> /* for task_struct */ #include <linux/sched/mm.h> /* for task_struct */
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <asm/gmap.h> #include <asm/gmap.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/compat.h>
#include <asm/sclp.h> #include <asm/sclp.h>
#include "gaccess.h" #include "gaccess.h"
#include "kvm-s390.h" #include "kvm-s390.h"
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/pci_debug.h> #include <asm/pci_debug.h>
#include <asm/pci_clp.h> #include <asm/pci_clp.h>
#include <asm/compat.h>
#include <asm/clp.h> #include <asm/clp.h>
#include <uapi/asm/clp.h> #include <uapi/asm/clp.h>
......
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += delay.h generic-y += delay.h
generic-y += div64.h generic-y += div64.h
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
typedef u32 compat_size_t; typedef u32 compat_size_t;
typedef s32 compat_ssize_t; typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t; typedef s32 compat_clock_t;
typedef s32 compat_pid_t; typedef s32 compat_pid_t;
typedef u16 __compat_uid_t; typedef u16 __compat_uid_t;
...@@ -39,16 +38,6 @@ typedef u32 compat_ulong_t; ...@@ -39,16 +38,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64; typedef u64 compat_u64;
typedef u32 compat_uptr_t; 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 { struct compat_stat {
compat_dev_t st_dev; compat_dev_t st_dev;
compat_ino_t st_ino; compat_ino_t st_ino;
...@@ -168,6 +157,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) ...@@ -168,6 +157,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
return (u32)(unsigned long)uptr; return (u32)(unsigned long)uptr;
} }
#ifdef CONFIG_COMPAT
static inline void __user *arch_compat_alloc_user_space(long len) static inline void __user *arch_compat_alloc_user_space(long len)
{ {
struct pt_regs *regs = current_thread_info()->kregs; struct pt_regs *regs = current_thread_info()->kregs;
...@@ -184,6 +174,7 @@ static inline void __user *arch_compat_alloc_user_space(long len) ...@@ -184,6 +174,7 @@ static inline void __user *arch_compat_alloc_user_space(long len)
return (void __user *) usp; return (void __user *) usp;
} }
#endif
struct compat_ipc64_perm { struct compat_ipc64_perm {
compat_key_t key; compat_key_t key;
...@@ -243,6 +234,7 @@ struct compat_shmid64_ds { ...@@ -243,6 +234,7 @@ struct compat_shmid64_ds {
unsigned int __unused2; unsigned int __unused2;
}; };
#ifdef CONFIG_COMPAT
static inline int is_compat_task(void) static inline int is_compat_task(void)
{ {
return test_thread_flag(TIF_32BIT); return test_thread_flag(TIF_32BIT);
...@@ -254,5 +246,6 @@ static inline bool in_compat_syscall(void) ...@@ -254,5 +246,6 @@ static inline bool in_compat_syscall(void)
return pt_regs_trap_type(current_pt_regs()) == 0x110; return pt_regs_trap_type(current_pt_regs()) == 0x110;
} }
#define in_compat_syscall in_compat_syscall #define in_compat_syscall in_compat_syscall
#endif
#endif /* _ASM_SPARC64_COMPAT_H */ #endif /* _ASM_SPARC64_COMPAT_H */
generic-y += barrier.h generic-y += barrier.h
generic-y += bpf_perf_event.h generic-y += bpf_perf_event.h
generic-y += bug.h generic-y += bug.h
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += delay.h generic-y += delay.h
generic-y += device.h generic-y += device.h
......
generic-y += atomic.h generic-y += atomic.h
generic-y += bugs.h generic-y += bugs.h
generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
......
...@@ -2397,7 +2397,7 @@ static unsigned long get_segment_base(unsigned int segment) ...@@ -2397,7 +2397,7 @@ static unsigned long get_segment_base(unsigned int segment)
#ifdef CONFIG_IA32_EMULATION #ifdef CONFIG_IA32_EMULATION
#include <asm/compat.h> #include <linux/compat.h>
static inline int static inline int
perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry) perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *entry)
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
typedef u32 compat_size_t; typedef u32 compat_size_t;
typedef s32 compat_ssize_t; typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t; typedef s32 compat_clock_t;
typedef s32 compat_pid_t; typedef s32 compat_pid_t;
typedef u16 __compat_uid_t; typedef u16 __compat_uid_t;
...@@ -46,16 +45,6 @@ typedef u32 compat_u32; ...@@ -46,16 +45,6 @@ typedef u32 compat_u32;
typedef u64 __attribute__((aligned(4))) compat_u64; typedef u64 __attribute__((aligned(4))) compat_u64;
typedef u32 compat_uptr_t; 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 { struct compat_stat {
compat_dev_t st_dev; compat_dev_t st_dev;
u16 __pad1; u16 __pad1;
......
...@@ -63,7 +63,7 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name ...@@ -63,7 +63,7 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name
#ifndef COMPILE_OFFSETS #ifndef COMPILE_OFFSETS
#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_IA32_EMULATION) #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 * Because ia32 syscalls do not map to x86_64 syscall numbers
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/compat.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/mm.h> #include <linux/sched/mm.h>
...@@ -19,7 +20,6 @@ ...@@ -19,7 +20,6 @@
#include <linux/elf.h> #include <linux/elf.h>
#include <asm/elf.h> #include <asm/elf.h>
#include <asm/compat.h>
#include <asm/ia32.h> #include <asm/ia32.h>
#include <asm/syscalls.h> #include <asm/syscalls.h>
#include <asm/mpx.h> #include <asm/mpx.h>
......
generic-y += bug.h generic-y += bug.h
generic-y += compat.h
generic-y += device.h generic-y += device.h
generic-y += div64.h generic-y += div64.h
generic-y += dma-contiguous.h generic-y += dma-contiguous.h
......
...@@ -450,8 +450,10 @@ config MTK_TIMER ...@@ -450,8 +450,10 @@ config MTK_TIMER
Support for Mediatek timer driver. Support for Mediatek timer driver.
config SPRD_TIMER config SPRD_TIMER
bool "Spreadtrum timer driver" if COMPILE_TEST bool "Spreadtrum timer driver" if EXPERT
depends on HAS_IOMEM depends on HAS_IOMEM
depends on (ARCH_SPRD || COMPILE_TEST)
default ARCH_SPRD
select TIMER_OF select TIMER_OF
help help
Enables support for the Spreadtrum timer driver. Enables support for the Spreadtrum timer driver.
......
...@@ -61,6 +61,20 @@ static u64 arc_read_gfrc(struct clocksource *cs) ...@@ -61,6 +61,20 @@ static u64 arc_read_gfrc(struct clocksource *cs)
unsigned long flags; unsigned long flags;
u32 l, h; u32 l, h;
/*
* From a programming model pov, there seems to be just one instance of
* MCIP_CMD/MCIP_READBACK however micro-architecturally there's
* an instance PER ARC CORE (not per cluster), and there are dedicated
* hardware decode logic (per core) inside ARConnect to handle
* simultaneous read/write accesses from cores via those two registers.
* So several concurrent commands to ARConnect are OK if they are
* trying to access two different sub-components (like GFRC,
* inter-core interrupt, etc...). HW also supports simultaneously
* accessing GFRC by multiple cores.
* That's why it is safe to disable hard interrupts on the local CPU
* before access to GFRC instead of taking global MCIP spinlock
* defined in arch/arc/kernel/mcip.c
*/
local_irq_save(flags); local_irq_save(flags);
__mcip_cmd(CMD_GFRC_READ_LO, 0); __mcip_cmd(CMD_GFRC_READ_LO, 0);
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
*/ */
#define pr_fmt(fmt) "mips-gic-timer: " fmt
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/cpu.h> #include <linux/cpu.h>
...@@ -136,8 +139,7 @@ static int gic_clockevent_init(void) ...@@ -136,8 +139,7 @@ static int gic_clockevent_init(void)
ret = setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); ret = setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction);
if (ret < 0) { if (ret < 0) {
pr_err("GIC timer IRQ %d setup failed: %d\n", pr_err("IRQ %d setup failed (%d)\n", gic_timer_irq, ret);
gic_timer_irq, ret);
return ret; return ret;
} }
...@@ -176,7 +178,7 @@ static int __init __gic_clocksource_init(void) ...@@ -176,7 +178,7 @@ static int __init __gic_clocksource_init(void)
ret = clocksource_register_hz(&gic_clocksource, gic_frequency); ret = clocksource_register_hz(&gic_clocksource, gic_frequency);
if (ret < 0) if (ret < 0)
pr_warn("GIC: Unable to register clocksource\n"); pr_warn("Unable to register clocksource\n");
return ret; return ret;
} }
...@@ -188,7 +190,7 @@ static int __init gic_clocksource_of_init(struct device_node *node) ...@@ -188,7 +190,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
if (!mips_gic_present() || !node->parent || if (!mips_gic_present() || !node->parent ||
!of_device_is_compatible(node->parent, "mti,gic")) { !of_device_is_compatible(node->parent, "mti,gic")) {
pr_warn("No DT definition for the mips gic driver\n"); pr_warn("No DT definition\n");
return -ENXIO; return -ENXIO;
} }
...@@ -196,7 +198,7 @@ static int __init gic_clocksource_of_init(struct device_node *node) ...@@ -196,7 +198,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
if (!IS_ERR(clk)) { if (!IS_ERR(clk)) {
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
if (ret < 0) { if (ret < 0) {
pr_err("GIC failed to enable clock\n"); pr_err("Failed to enable clock\n");
clk_put(clk); clk_put(clk);
return ret; return ret;
} }
...@@ -204,12 +206,12 @@ static int __init gic_clocksource_of_init(struct device_node *node) ...@@ -204,12 +206,12 @@ static int __init gic_clocksource_of_init(struct device_node *node)
gic_frequency = clk_get_rate(clk); gic_frequency = clk_get_rate(clk);
} else if (of_property_read_u32(node, "clock-frequency", } else if (of_property_read_u32(node, "clock-frequency",
&gic_frequency)) { &gic_frequency)) {
pr_err("GIC frequency not specified.\n"); pr_err("Frequency not specified\n");
return -EINVAL; return -EINVAL;
} }
gic_timer_irq = irq_of_parse_and_map(node, 0); gic_timer_irq = irq_of_parse_and_map(node, 0);
if (!gic_timer_irq) { if (!gic_timer_irq) {
pr_err("GIC timer IRQ not specified.\n"); pr_err("IRQ not specified\n");
return -EINVAL; return -EINVAL;
} }
...@@ -220,7 +222,7 @@ static int __init gic_clocksource_of_init(struct device_node *node) ...@@ -220,7 +222,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
ret = gic_clockevent_init(); ret = gic_clockevent_init();
if (!ret && !IS_ERR(clk)) { if (!ret && !IS_ERR(clk)) {
if (clk_notifier_register(clk, &gic_clk_nb) < 0) if (clk_notifier_register(clk, &gic_clk_nb) < 0)
pr_warn("GIC: Unable to register clock notifier\n"); pr_warn("Unable to register clock notifier\n");
} }
/* And finally start the counter */ /* And finally start the counter */
......
/* // SPDX-License-Identifier: GPL-2.0+
* Copyright (C) 2000-2001 Deep Blue Solutions //
* Copyright (C) 2002 Shane Nay (shane@minirl.com) // Copyright (C) 2000-2001 Deep Blue Solutions
* Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) // Copyright (C) 2002 Shane Nay (shane@minirl.com)
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) // Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
* Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. // Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
* // Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/err.h> #include <linux/err.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
......
/* // SPDX-License-Identifier: GPL-2.0+
* linux/arch/arm/plat-mxc/time.c //
* // Copyright (C) 2000-2001 Deep Blue Solutions
* Copyright (C) 2000-2001 Deep Blue Solutions // Copyright (C) 2002 Shane Nay (shane@minirl.com)
* Copyright (C) 2002 Shane Nay (shane@minirl.com) // Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
* Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) // Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
......
/* // SPDX-License-Identifier: GPL-2.0+
* Copyright 2016 Freescale Semiconductor, Inc. //
* Copyright 2017 NXP // Copyright 2016 Freescale Semiconductor, Inc.
* // Copyright 2017 NXP
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*/
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/blkpg.h> #include <linux/blkpg.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/compat.h>
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
#include <asm/schid.h> #include <asm/schid.h>
#include <asm/cmb.h> #include <asm/cmb.h>
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/compat.h>
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
#include <asm/cio.h> #include <asm/cio.h>
#include <asm/ebcdic.h> #include <asm/ebcdic.h>
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <asm/compat.h>
#include <asm/sclp_ctl.h> #include <asm/sclp_ctl.h>
#include <asm/sclp.h> #include <asm/sclp.h>
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/cma.h> #include <linux/cma.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <asm/compat.h>
#include <asm/cpcmd.h> #include <asm/cpcmd.h>
#include <asm/debug.h> #include <asm/debug.h>
#include <asm/vmcp.h> #include <asm/vmcp.h>
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <asm/compat.h>
#include <asm/cio.h> #include <asm/cio.h>
#include <asm/chsc.h> #include <asm/chsc.h>
#include <asm/isc.h> #include <asm/isc.h>
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define KMSG_COMPONENT "qeth" #define KMSG_COMPONENT "qeth"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/compat.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -32,7 +33,6 @@ ...@@ -32,7 +33,6 @@
#include <asm/chpid.h> #include <asm/chpid.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/sysinfo.h> #include <asm/sysinfo.h>
#include <asm/compat.h>
#include <asm/diag.h> #include <asm/diag.h>
#include <asm/cio.h> #include <asm/cio.h>
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
......
/* SPDX-License-Identifier: GPL-2.0 */
/* This is an empty stub for 32-bit-only architectures */
...@@ -7,8 +7,7 @@ ...@@ -7,8 +7,7 @@
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/compat_time.h>
#ifdef CONFIG_COMPAT
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/param.h> /* for HZ */ #include <linux/param.h> /* for HZ */
...@@ -21,8 +20,11 @@ ...@@ -21,8 +20,11 @@
#include <linux/unistd.h> #include <linux/unistd.h>
#include <asm/compat.h> #include <asm/compat.h>
#ifdef CONFIG_COMPAT
#include <asm/siginfo.h> #include <asm/siginfo.h>
#include <asm/signal.h> #include <asm/signal.h>
#endif
#ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER #ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
/* /*
...@@ -83,6 +85,8 @@ ...@@ -83,6 +85,8 @@
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
#endif /* COMPAT_SYSCALL_DEFINEx */ #endif /* COMPAT_SYSCALL_DEFINEx */
#ifdef CONFIG_COMPAT
#ifndef compat_user_stack_pointer #ifndef compat_user_stack_pointer
#define compat_user_stack_pointer() current_user_stack_pointer() #define compat_user_stack_pointer() current_user_stack_pointer()
#endif #endif
...@@ -290,8 +294,6 @@ extern int compat_get_timespec(struct timespec *, const void __user *); ...@@ -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_put_timespec(const struct timespec *, void __user *);
extern int compat_get_timeval(struct timeval *, const 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_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, extern int get_compat_itimerspec64(struct itimerspec64 *its,
const struct compat_itimerspec __user *uits); const struct compat_itimerspec __user *uits);
extern int put_compat_itimerspec64(const struct itimerspec64 *its, extern int put_compat_itimerspec64(const struct itimerspec64 *its,
...@@ -1023,7 +1025,9 @@ static inline struct compat_timeval ns_to_compat_timeval(s64 nsec) ...@@ -1023,7 +1025,9 @@ static inline struct compat_timeval ns_to_compat_timeval(s64 nsec)
#else /* !CONFIG_COMPAT */ #else /* !CONFIG_COMPAT */
#define is_compat_task() (0) #define is_compat_task() (0)
#ifndef in_compat_syscall
static inline bool in_compat_syscall(void) { return false; } static inline bool in_compat_syscall(void) { return false; }
#endif
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
......
/* 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 @@ ...@@ -7,6 +7,7 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/time64.h>
struct timespec; struct timespec;
struct compat_timespec; struct compat_timespec;
...@@ -15,9 +16,7 @@ struct pollfd; ...@@ -15,9 +16,7 @@ struct pollfd;
enum timespec_type { enum timespec_type {
TT_NONE = 0, TT_NONE = 0,
TT_NATIVE = 1, TT_NATIVE = 1,
#ifdef CONFIG_COMPAT
TT_COMPAT = 2, TT_COMPAT = 2,
#endif
}; };
/* /*
...@@ -40,10 +39,8 @@ struct restart_block { ...@@ -40,10 +39,8 @@ struct restart_block {
clockid_t clockid; clockid_t clockid;
enum timespec_type type; enum timespec_type type;
union { union {
struct timespec __user *rmtp; struct __kernel_timespec __user *rmtp;
#ifdef CONFIG_COMPAT
struct compat_timespec __user *compat_rmtp; struct compat_timespec __user *compat_rmtp;
#endif
}; };
u64 expires; u64 expires;
} nanosleep; } nanosleep;
......
...@@ -542,7 +542,8 @@ asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, ...@@ -542,7 +542,8 @@ asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
size_t len); size_t len);
/* kernel/hrtimer.c */ /* 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 */ /* kernel/itimer.c */
asmlinkage long sys_getitimer(int which, struct itimerval __user *value); asmlinkage long sys_getitimer(int which, struct itimerval __user *value);
...@@ -573,14 +574,14 @@ asmlinkage long sys_timer_settime(timer_t timer_id, int flags, ...@@ -573,14 +574,14 @@ asmlinkage long sys_timer_settime(timer_t timer_id, int flags,
struct itimerspec __user *old_setting); struct itimerspec __user *old_setting);
asmlinkage long sys_timer_delete(timer_t timer_id); asmlinkage long sys_timer_delete(timer_t timer_id);
asmlinkage long sys_clock_settime(clockid_t which_clock, 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, 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, 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, asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags,
const struct timespec __user *rqtp, const struct __kernel_timespec __user *rqtp,
struct timespec __user *rmtp); struct __kernel_timespec __user *rmtp);
/* kernel/printk.c */ /* kernel/printk.c */
asmlinkage long sys_syslog(int type, char __user *buf, int len); asmlinkage long sys_syslog(int type, char __user *buf, int len);
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
extern struct timezone sys_tz; extern struct timezone sys_tz;
int get_timespec64(struct timespec64 *ts, int get_timespec64(struct timespec64 *ts,
const struct timespec __user *uts); const struct __kernel_timespec __user *uts);
int put_timespec64(const struct timespec64 *ts, int put_timespec64(const struct timespec64 *ts,
struct timespec __user *uts); struct __kernel_timespec __user *uts);
int get_itimerspec64(struct itimerspec64 *it, int get_itimerspec64(struct itimerspec64 *it,
const struct itimerspec __user *uit); const struct itimerspec __user *uit);
int put_itimerspec64(const struct itimerspec64 *it, int put_itimerspec64(const struct itimerspec64 *it,
......
...@@ -2,12 +2,20 @@ ...@@ -2,12 +2,20 @@
#ifndef _LINUX_TIME64_H #ifndef _LINUX_TIME64_H
#define _LINUX_TIME64_H #define _LINUX_TIME64_H
#include <uapi/linux/time.h>
#include <linux/math64.h> #include <linux/math64.h>
typedef __s64 time64_t; typedef __s64 time64_t;
typedef __u64 timeu64_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 #if __BITS_PER_LONG == 64
/* this trick allows us to optimize out timespec64_to_timespec */ /* this trick allows us to optimize out timespec64_to_timespec */
# define timespec64 timespec # define timespec64 timespec
......
...@@ -87,6 +87,7 @@ typedef struct { ...@@ -87,6 +87,7 @@ typedef struct {
typedef __kernel_long_t __kernel_off_t; typedef __kernel_long_t __kernel_off_t;
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
typedef __kernel_long_t __kernel_time_t; typedef __kernel_long_t __kernel_time_t;
typedef long long __kernel_time64_t;
typedef __kernel_long_t __kernel_clock_t; typedef __kernel_long_t __kernel_clock_t;
typedef int __kernel_timer_t; typedef int __kernel_timer_t;
typedef int __kernel_clockid_t; typedef int __kernel_clockid_t;
......
...@@ -42,6 +42,13 @@ struct itimerval { ...@@ -42,6 +42,13 @@ struct itimerval {
struct timeval it_value; /* current value */ 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 * legacy timeval structure, only embedded in structures that
* traditionally used 'timeval' to pass time intervals (not absolute * traditionally used 'timeval' to pass time intervals (not absolute
......
...@@ -121,50 +121,6 @@ static int __compat_put_timespec(const struct timespec *ts, struct compat_timesp ...@@ -121,50 +121,6 @@ static int __compat_put_timespec(const struct timespec *ts, struct compat_timesp
__put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0; __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) int compat_get_timeval(struct timeval *tv, const void __user *utv)
{ {
if (COMPAT_USE_64BIT_TIME) if (COMPAT_USE_64BIT_TIME)
...@@ -368,6 +324,14 @@ COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t, pid, unsigned int, len, ...@@ -368,6 +324,14 @@ COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t, pid, unsigned int, len,
return ret; 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, int get_compat_itimerspec64(struct itimerspec64 *its,
const struct compat_itimerspec __user *uits) const struct compat_itimerspec __user *uits)
{ {
......
...@@ -129,31 +129,19 @@ static void inline clocksource_watchdog_unlock(unsigned long *flags) ...@@ -129,31 +129,19 @@ static void inline clocksource_watchdog_unlock(unsigned long *flags)
spin_unlock_irqrestore(&watchdog_lock, *flags); spin_unlock_irqrestore(&watchdog_lock, *flags);
} }
static int clocksource_watchdog_kthread(void *data);
static void __clocksource_change_rating(struct clocksource *cs, int rating);
/* /*
* Interval: 0.5sec Threshold: 0.0625s * Interval: 0.5sec Threshold: 0.0625s
*/ */
#define WATCHDOG_INTERVAL (HZ >> 1) #define WATCHDOG_INTERVAL (HZ >> 1)
#define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4) #define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4)
static void clocksource_watchdog_work(struct work_struct *work)
{
/*
* If kthread_run fails the next watchdog scan over the
* watchdog_list will find the unstable clock again.
*/
kthread_run(clocksource_watchdog_kthread, NULL, "kwatchdog");
}
static void __clocksource_unstable(struct clocksource *cs) static void __clocksource_unstable(struct clocksource *cs)
{ {
cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG); cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
cs->flags |= CLOCK_SOURCE_UNSTABLE; cs->flags |= CLOCK_SOURCE_UNSTABLE;
/* /*
* If the clocksource is registered clocksource_watchdog_kthread() will * If the clocksource is registered clocksource_watchdog_work() will
* re-rate and re-select. * re-rate and re-select.
*/ */
if (list_empty(&cs->list)) { if (list_empty(&cs->list)) {
...@@ -164,7 +152,7 @@ static void __clocksource_unstable(struct clocksource *cs) ...@@ -164,7 +152,7 @@ static void __clocksource_unstable(struct clocksource *cs)
if (cs->mark_unstable) if (cs->mark_unstable)
cs->mark_unstable(cs); cs->mark_unstable(cs);
/* kick clocksource_watchdog_kthread() */ /* kick clocksource_watchdog_work() */
if (finished_booting) if (finished_booting)
schedule_work(&watchdog_work); schedule_work(&watchdog_work);
} }
...@@ -174,7 +162,7 @@ static void __clocksource_unstable(struct clocksource *cs) ...@@ -174,7 +162,7 @@ static void __clocksource_unstable(struct clocksource *cs)
* @cs: clocksource to be marked unstable * @cs: clocksource to be marked unstable
* *
* This function is called by the x86 TSC code to mark clocksources as unstable; * This function is called by the x86 TSC code to mark clocksources as unstable;
* it defers demotion and re-selection to a kthread. * it defers demotion and re-selection to a work.
*/ */
void clocksource_mark_unstable(struct clocksource *cs) void clocksource_mark_unstable(struct clocksource *cs)
{ {
...@@ -399,7 +387,9 @@ static void clocksource_dequeue_watchdog(struct clocksource *cs) ...@@ -399,7 +387,9 @@ static void clocksource_dequeue_watchdog(struct clocksource *cs)
} }
} }
static int __clocksource_watchdog_kthread(void) static void __clocksource_change_rating(struct clocksource *cs, int rating);
static int __clocksource_watchdog_work(void)
{ {
struct clocksource *cs, *tmp; struct clocksource *cs, *tmp;
unsigned long flags; unsigned long flags;
...@@ -424,13 +414,12 @@ static int __clocksource_watchdog_kthread(void) ...@@ -424,13 +414,12 @@ static int __clocksource_watchdog_kthread(void)
return select; return select;
} }
static int clocksource_watchdog_kthread(void *data) static void clocksource_watchdog_work(struct work_struct *work)
{ {
mutex_lock(&clocksource_mutex); mutex_lock(&clocksource_mutex);
if (__clocksource_watchdog_kthread()) if (__clocksource_watchdog_work())
clocksource_select(); clocksource_select();
mutex_unlock(&clocksource_mutex); mutex_unlock(&clocksource_mutex);
return 0;
} }
static bool clocksource_is_watchdog(struct clocksource *cs) static bool clocksource_is_watchdog(struct clocksource *cs)
...@@ -449,12 +438,12 @@ static void clocksource_enqueue_watchdog(struct clocksource *cs) ...@@ -449,12 +438,12 @@ static void clocksource_enqueue_watchdog(struct clocksource *cs)
static void clocksource_select_watchdog(bool fallback) { } static void clocksource_select_watchdog(bool fallback) { }
static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { } static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { }
static inline void clocksource_resume_watchdog(void) { } static inline void clocksource_resume_watchdog(void) { }
static inline int __clocksource_watchdog_kthread(void) { return 0; } static inline int __clocksource_watchdog_work(void) { return 0; }
static bool clocksource_is_watchdog(struct clocksource *cs) { return false; } static bool clocksource_is_watchdog(struct clocksource *cs) { return false; }
void clocksource_mark_unstable(struct clocksource *cs) { } void clocksource_mark_unstable(struct clocksource *cs) { }
static void inline clocksource_watchdog_lock(unsigned long *flags) { } static inline void clocksource_watchdog_lock(unsigned long *flags) { }
static void inline clocksource_watchdog_unlock(unsigned long *flags) { } static inline void clocksource_watchdog_unlock(unsigned long *flags) { }
#endif /* CONFIG_CLOCKSOURCE_WATCHDOG */ #endif /* CONFIG_CLOCKSOURCE_WATCHDOG */
...@@ -683,7 +672,7 @@ static int __init clocksource_done_booting(void) ...@@ -683,7 +672,7 @@ static int __init clocksource_done_booting(void)
/* /*
* Run the watchdog first to eliminate unstable clock sources * Run the watchdog first to eliminate unstable clock sources
*/ */
__clocksource_watchdog_kthread(); __clocksource_watchdog_work();
clocksource_select(); clocksource_select();
mutex_unlock(&clocksource_mutex); mutex_unlock(&clocksource_mutex);
return 0; return 0;
......
...@@ -1759,8 +1759,10 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp, ...@@ -1759,8 +1759,10 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp,
return ret; return ret;
} }
SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, #if !defined(CONFIG_64BIT_TIME) || defined(CONFIG_64BIT)
struct timespec __user *, rmtp)
SYSCALL_DEFINE2(nanosleep, struct __kernel_timespec __user *, rqtp,
struct __kernel_timespec __user *, rmtp)
{ {
struct timespec64 tu; struct timespec64 tu;
...@@ -1775,7 +1777,9 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, ...@@ -1775,7 +1777,9 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC); 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, COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
struct compat_timespec __user *, rmtp) struct compat_timespec __user *, rmtp)
......
...@@ -59,7 +59,7 @@ SYS_NI(alarm); ...@@ -59,7 +59,7 @@ SYS_NI(alarm);
*/ */
SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
const struct timespec __user *, tp) const struct __kernel_timespec __user *, tp)
{ {
struct timespec64 new_tp; struct timespec64 new_tp;
...@@ -90,7 +90,7 @@ int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp) ...@@ -90,7 +90,7 @@ int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
return 0; return 0;
} }
SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
struct timespec __user *, tp) struct __kernel_timespec __user *, tp)
{ {
int ret; int ret;
struct timespec64 kernel_tp; struct timespec64 kernel_tp;
...@@ -104,7 +104,7 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, ...@@ -104,7 +104,7 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
return 0; 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 = { struct timespec64 rtn_tp = {
.tv_sec = 0, .tv_sec = 0,
...@@ -124,8 +124,8 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __us ...@@ -124,8 +124,8 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __us
} }
SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
const struct timespec __user *, rqtp, const struct __kernel_timespec __user *, rqtp,
struct timespec __user *, rmtp) struct __kernel_timespec __user *, rmtp)
{ {
struct timespec64 t; struct timespec64 t;
...@@ -158,7 +158,9 @@ COMPAT_SYS_NI(timer_settime); ...@@ -158,7 +158,9 @@ COMPAT_SYS_NI(timer_settime);
COMPAT_SYS_NI(timer_gettime); COMPAT_SYS_NI(timer_gettime);
COMPAT_SYS_NI(getitimer); COMPAT_SYS_NI(getitimer);
COMPAT_SYS_NI(setitimer); COMPAT_SYS_NI(setitimer);
#endif
#ifdef CONFIG_COMPAT_32BIT_TIME
COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, COMPAT_SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
struct compat_timespec __user *, tp) struct compat_timespec __user *, tp)
{ {
......
...@@ -1040,7 +1040,7 @@ void exit_itimers(struct signal_struct *sig) ...@@ -1040,7 +1040,7 @@ void exit_itimers(struct signal_struct *sig)
} }
SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, 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); const struct k_clock *kc = clockid_to_kclock(which_clock);
struct timespec64 new_tp; struct timespec64 new_tp;
...@@ -1055,7 +1055,7 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, ...@@ -1055,7 +1055,7 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
} }
SYSCALL_DEFINE2(clock_gettime, 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); const struct k_clock *kc = clockid_to_kclock(which_clock);
struct timespec64 kernel_tp; struct timespec64 kernel_tp;
...@@ -1096,7 +1096,7 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock, ...@@ -1096,7 +1096,7 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
} }
SYSCALL_DEFINE2(clock_getres, 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); const struct k_clock *kc = clockid_to_kclock(which_clock);
struct timespec64 rtn_tp; struct timespec64 rtn_tp;
...@@ -1113,7 +1113,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, ...@@ -1113,7 +1113,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
return error; return error;
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT_32BIT_TIME
COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock, COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,
struct compat_timespec __user *, tp) struct compat_timespec __user *, tp)
...@@ -1148,6 +1148,10 @@ COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock, ...@@ -1148,6 +1148,10 @@ COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
return err; return err;
} }
#endif
#ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock, COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
struct compat_timex __user *, utp) struct compat_timex __user *, utp)
{ {
...@@ -1172,6 +1176,10 @@ COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock, ...@@ -1172,6 +1176,10 @@ COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
return err; return err;
} }
#endif
#ifdef CONFIG_COMPAT_32BIT_TIME
COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock, COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,
struct compat_timespec __user *, tp) struct compat_timespec __user *, tp)
{ {
...@@ -1203,8 +1211,8 @@ static int common_nsleep(const clockid_t which_clock, int flags, ...@@ -1203,8 +1211,8 @@ static int common_nsleep(const clockid_t which_clock, int flags,
} }
SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
const struct timespec __user *, rqtp, const struct __kernel_timespec __user *, rqtp,
struct timespec __user *, rmtp) struct __kernel_timespec __user *, rmtp)
{ {
const struct k_clock *kc = clockid_to_kclock(which_clock); const struct k_clock *kc = clockid_to_kclock(which_clock);
struct timespec64 t; struct timespec64 t;
...@@ -1227,7 +1235,8 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, ...@@ -1227,7 +1235,8 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
return kc->nsleep(which_clock, flags, &t); 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, COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
struct compat_timespec __user *, rqtp, struct compat_timespec __user *, rqtp,
struct compat_timespec __user *, rmtp) struct compat_timespec __user *, rmtp)
...@@ -1252,6 +1261,7 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags, ...@@ -1252,6 +1261,7 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,
return kc->nsleep(which_clock, flags, &t); return kc->nsleep(which_clock, flags, &t);
} }
#endif #endif
static const struct k_clock clock_realtime = { static const struct k_clock clock_realtime = {
......
...@@ -277,7 +277,8 @@ static bool tick_check_preferred(struct clock_event_device *curdev, ...@@ -277,7 +277,8 @@ static bool tick_check_preferred(struct clock_event_device *curdev,
*/ */
return !curdev || return !curdev ||
newdev->rating > curdev->rating || newdev->rating > curdev->rating ||
!cpumask_equal(curdev->cpumask, newdev->cpumask); (!cpumask_equal(curdev->cpumask, newdev->cpumask) &&
!tick_check_percpu(curdev, newdev, smp_processor_id()));
} }
/* /*
......
...@@ -853,9 +853,9 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs, ...@@ -853,9 +853,9 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
} }
int get_timespec64(struct timespec64 *ts, 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; int ret;
ret = copy_from_user(&kts, uts, sizeof(kts)); ret = copy_from_user(&kts, uts, sizeof(kts));
...@@ -863,6 +863,11 @@ int get_timespec64(struct timespec64 *ts, ...@@ -863,6 +863,11 @@ int get_timespec64(struct timespec64 *ts,
return -EFAULT; return -EFAULT;
ts->tv_sec = kts.tv_sec; 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; ts->tv_nsec = kts.tv_nsec;
return 0; return 0;
...@@ -870,16 +875,61 @@ int get_timespec64(struct timespec64 *ts, ...@@ -870,16 +875,61 @@ int get_timespec64(struct timespec64 *ts,
EXPORT_SYMBOL_GPL(get_timespec64); EXPORT_SYMBOL_GPL(get_timespec64);
int put_timespec64(const struct timespec64 *ts, 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_sec = ts->tv_sec,
.tv_nsec = ts->tv_nsec .tv_nsec = ts->tv_nsec
}; };
return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0; return copy_to_user(uts, &kts, sizeof(kts)) ? -EFAULT : 0;
} }
EXPORT_SYMBOL_GPL(put_timespec64); 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, int get_itimerspec64(struct itimerspec64 *it,
const struct itimerspec __user *uit) const struct itimerspec __user *uit)
{ {
......
...@@ -1251,18 +1251,18 @@ EXPORT_SYMBOL(try_to_del_timer_sync); ...@@ -1251,18 +1251,18 @@ EXPORT_SYMBOL(try_to_del_timer_sync);
* *
* Note: For !irqsafe timers, you must not hold locks that are held in * Note: For !irqsafe timers, you must not hold locks that are held in
* interrupt context while calling this function. Even if the lock has * interrupt context while calling this function. Even if the lock has
* nothing to do with the timer in question. Here's why: * nothing to do with the timer in question. Here's why::
* *
* CPU0 CPU1 * CPU0 CPU1
* ---- ---- * ---- ----
* <SOFTIRQ> * <SOFTIRQ>
* call_timer_fn(); * call_timer_fn();
* base->running_timer = mytimer; * base->running_timer = mytimer;
* spin_lock_irq(somelock); * spin_lock_irq(somelock);
* <IRQ> * <IRQ>
* spin_lock(somelock); * spin_lock(somelock);
* del_timer_sync(mytimer); * del_timer_sync(mytimer);
* while (base->running_timer == mytimer); * while (base->running_timer == mytimer);
* *
* Now del_timer_sync() will never return and never release somelock. * Now del_timer_sync() will never return and never release somelock.
* The interrupt on the other CPU is waiting to grab somelock but * The interrupt on the other CPU is waiting to grab somelock but
......
...@@ -28,8 +28,6 @@ struct timer_list_iter { ...@@ -28,8 +28,6 @@ struct timer_list_iter {
u64 now; u64 now;
}; };
typedef void (*print_fn_t)(struct seq_file *m, unsigned int *classes);
/* /*
* This allows printing both to /proc/timer_list and * This allows printing both to /proc/timer_list and
* to the console (on SysRq-Q): * to the console (on SysRq-Q):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment