android_kernel_samsung_sm8650/kernel/time
John Stultz ceea5e3771 time: Fix clock->read(clock) race around clocksource changes
In tests, which excercise switching of clocksources, a NULL
pointer dereference can be observed on AMR64 platforms in the
clocksource read() function:

u64 clocksource_mmio_readl_down(struct clocksource *c)
{
	return ~(u64)readl_relaxed(to_mmio_clksrc(c)->reg) & c->mask;
}

This is called from the core timekeeping code via:

	cycle_now = tkr->read(tkr->clock);

tkr->read is the cached tkr->clock->read() function pointer.
When the clocksource is changed then tkr->clock and tkr->read
are updated sequentially. The code above results in a sequential
load operation of tkr->read and tkr->clock as well.

If the store to tkr->clock hits between the loads of tkr->read
and tkr->clock, then the old read() function is called with the
new clock pointer. As a consequence the read() function
dereferences a different data structure and the resulting 'reg'
pointer can point anywhere including NULL.

This problem was introduced when the timekeeping code was
switched over to use struct tk_read_base. Before that, it was
theoretically possible as well when the compiler decided to
reload clock in the code sequence:

     now = tk->clock->read(tk->clock);

Add a helper function which avoids the issue by reading
tk_read_base->clock once into a local variable clk and then issue
the read function via clk->read(clk). This guarantees that the
read() function always gets the proper clocksource pointer handed
in.

Since there is now no use for the tkr.read pointer, this patch
also removes it, and to address stopping the fast timekeeper
during suspend/resume, it introduces a dummy clocksource to use
rather then just a dummy read function.

Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: stable <stable@vger.kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Daniel Mentz <danielmentz@google.com>
Link: http://lkml.kernel.org/r/1496965462-20003-2-git-send-email-john.stultz@linaro.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2017-06-20 10:41:50 +02:00
..
alarmtimer.c alarmtimer: Rate limit periodic intervals 2017-06-04 15:21:18 +02:00
clockevents.c clockevents: Make clockevents_config() static 2017-03-23 12:14:05 -07:00
clocksource.c sched/clock, clocksource: Add optional cs::mark_unstable() method 2017-01-14 11:29:43 +01:00
hrtimer.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2017-05-02 19:09:35 -07:00
itimer.c sched/headers: Prepare to move cputime functionality from <linux/sched.h> into <linux/sched/cputime.h> 2017-03-02 08:42:39 +01:00
jiffies.c jiffies: Revert bogus conversion of NSEC_PER_SEC to TICK_NSEC 2017-03-07 11:03:28 +01:00
Kconfig rcu: Drop RCU_USER_QS in favor of NO_HZ_FULL 2015-07-06 13:52:18 -07:00
Makefile time: Remove CONFIG_TIMER_STATS 2017-02-10 11:15:08 +01:00
ntp_internal.h ntp: Fix second_overflow's input parameter type to be 64bits 2015-12-16 16:50:56 -08:00
ntp.c ktime: Get rid of the union 2016-12-25 17:21:22 +01:00
posix-clock.c time: Change k_clock timer_set() and timer_get() to use timespec64 2017-04-14 21:49:56 +02:00
posix-cpu-timers.c posix-timers: Make signal printks conditional 2017-05-23 23:39:57 +02:00
posix-stubs.c time: Change k_clock nsleep() to use timespec64 2017-04-14 21:49:56 +02:00
posix-timers.c time: Change k_clock nsleep() to use timespec64 2017-04-14 21:49:56 +02:00
sched_clock.c timers, sched_clock: Update timeout for clock wrap 2017-03-23 12:30:27 -07:00
test_udelay.c time: Avoid timespec in udelay_test 2016-06-20 12:47:26 -07:00
tick-broadcast-hrtimer.c ktime: Get rid of the union 2016-12-25 17:21:22 +01:00
tick-broadcast.c tick/broadcast: Make tick_broadcast_setup_oneshot() static 2017-06-12 18:56:01 +02:00
tick-common.c ktime: Cleanup ktime_set() usage 2016-12-25 17:21:22 +01:00
tick-internal.h tick/broadcast: Make tick_broadcast_setup_oneshot() static 2017-06-12 18:56:01 +02:00
tick-oneshot.c ktime: Get rid of the union 2016-12-25 17:21:22 +01:00
tick-sched.c cpufreq: schedutil: Avoid reducing frequency of busy CPUs prematurely 2017-03-23 02:12:14 +01:00
tick-sched.h Revert "nohz: Fix collision between tick and other hrtimers" 2017-02-16 12:19:18 -08:00
time.c time: delete current_fs_time() 2017-05-12 15:57:15 -07:00
timeconst.bc time: Introduce jiffies64_to_nsecs() 2017-02-01 09:13:45 +01:00
timeconv.c time: Add time64_to_tm() 2016-06-20 12:47:15 -07:00
timecounter.c clocksource: Use a plain u64 instead of cycle_t 2016-12-25 11:04:12 +01:00
timekeeping_debug.c timekeeping: Use deferred printk() in debug code 2017-02-15 11:46:08 +01:00
timekeeping_internal.h clocksource: Use a plain u64 instead of cycle_t 2016-12-25 11:04:12 +01:00
timekeeping.c time: Fix clock->read(clock) race around clocksource changes 2017-06-20 10:41:50 +02:00
timekeeping.h timekeeping: Remove unused timekeeping_{get,set}_tai_offset() 2017-01-06 16:47:28 -08:00
timer_list.c sysrq: Reset the watchdog timers while displaying high-resolution timers 2017-03-23 12:46:53 -07:00
timer.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2017-05-02 19:09:35 -07:00