From 8ec84f9da9853a4f9f67ce6075cb97fac7e121de Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 Jun 2020 14:29:38 +0200 Subject: [PATCH] add 1 5.7 patch --- ...rovide-sanity-check-for-cycles-again.patch | 77 +++++++++++++++++++ queue-5.7/series | 1 + 2 files changed, 78 insertions(+) create mode 100644 queue-5.7/lib-vdso-provide-sanity-check-for-cycles-again.patch create mode 100644 queue-5.7/series diff --git a/queue-5.7/lib-vdso-provide-sanity-check-for-cycles-again.patch b/queue-5.7/lib-vdso-provide-sanity-check-for-cycles-again.patch new file mode 100644 index 00000000000..9739ebeb991 --- /dev/null +++ b/queue-5.7/lib-vdso-provide-sanity-check-for-cycles-again.patch @@ -0,0 +1,77 @@ +From 72ce778007e57e8996b4bebdec738fc5e1145fd2 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Sat, 6 Jun 2020 23:51:16 +0200 +Subject: lib/vdso: Provide sanity check for cycles (again) + +From: Thomas Gleixner + +commit 72ce778007e57e8996b4bebdec738fc5e1145fd2 upstream. + +The original x86 VDSO implementation checked for the validity of the clock +source read by testing whether the returned signed cycles value is less +than zero. This check was also used by the vdso read function to signal +that the current selected clocksource is not VDSO capable. + +During the rework of the VDSO code the check was removed and replaced with +a check for the clocksource mode being != NONE. + +This turned out to be a mistake because the check is necessary for paravirt +and hyperv clock sources. The reason is that these clock sources have their +own internal sequence counter to validate the clocksource at the point of +reading it. This is necessary because the hypervisor can invalidate the +clocksource asynchronously so a check during the VDSO data update is not +sufficient. Having a separate indicator for the validity is slower than +just validating the cycles value. The check for it being negative turned +out to be the fastest implementation and safe as it would require an uptime +of ~73 years with a 4GHz counter frequency to result in a false positive. + +Add an optional function to validate the cycles with a default +implementation which allows the compiler to optimize it out for +architectures which do not require it. + +Fixes: 5d51bee725cc ("clocksource: Add common vdso clock mode storage") +Reported-by: Miklos Szeredi +Signed-off-by: Thomas Gleixner +Tested-by: Miklos Szeredi +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20200606221531.963970768@linutronix.de +Signed-off-by: Greg Kroah-Hartman + +--- + lib/vdso/gettimeofday.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/lib/vdso/gettimeofday.c ++++ b/lib/vdso/gettimeofday.c +@@ -38,6 +38,13 @@ static inline bool vdso_clocksource_ok(c + } + #endif + ++#ifndef vdso_cycles_ok ++static inline bool vdso_cycles_ok(u64 cycles) ++{ ++ return true; ++} ++#endif ++ + #ifdef CONFIG_TIME_NS + static int do_hres_timens(const struct vdso_data *vdns, clockid_t clk, + struct __kernel_timespec *ts) +@@ -62,6 +69,8 @@ static int do_hres_timens(const struct v + return -1; + + cycles = __arch_get_hw_counter(vd->clock_mode); ++ if (unlikely(!vdso_cycles_ok(cycles))) ++ return -1; + ns = vdso_ts->nsec; + last = vd->cycle_last; + ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult); +@@ -130,6 +139,8 @@ static __always_inline int do_hres(const + return -1; + + cycles = __arch_get_hw_counter(vd->clock_mode); ++ if (unlikely(!vdso_cycles_ok(cycles))) ++ return -1; + ns = vdso_ts->nsec; + last = vd->cycle_last; + ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult); diff --git a/queue-5.7/series b/queue-5.7/series new file mode 100644 index 00000000000..d8f43aca01d --- /dev/null +++ b/queue-5.7/series @@ -0,0 +1 @@ +lib-vdso-provide-sanity-check-for-cycles-again.patch -- 2.47.3