* [PATCH v7 01/25] kernel: Standardize vdso_datapage
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-24 13:56 ` Catalin Marinas
2019-06-21 9:52 ` [PATCH v7 02/25] kernel: Define gettimeofday vdso common code Vincenzo Frascino
` (25 subsequent siblings)
26 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
In an effort to unify the common code for managing the vdso library in
between all the architectures that support it, this patch tries to
provide a common format for the vdso datapage.
As a result of this, this patch generalized the data structures in vgtod.h
from x86 private includes to general includes (include/vdso).
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
include/vdso/datapage.h | 93 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 include/vdso/datapage.h
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
new file mode 100644
index 000000000000..770f40254b08
--- /dev/null
+++ b/include/vdso/datapage.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_DATAPAGE_H
+#define __VDSO_DATAPAGE_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <linux/bits.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#define VDSO_BASES (CLOCK_TAI + 1)
+#define VDSO_HRES (BIT(CLOCK_REALTIME) | \
+ BIT(CLOCK_MONOTONIC) | \
+ BIT(CLOCK_BOOTTIME) | \
+ BIT(CLOCK_TAI))
+#define VDSO_COARSE (BIT(CLOCK_REALTIME_COARSE) | \
+ BIT(CLOCK_MONOTONIC_COARSE))
+#define VDSO_RAW (BIT(CLOCK_MONOTONIC_RAW))
+
+#define CS_HRES_COARSE 0
+#define CS_RAW 1
+#define CS_BASES (CS_RAW + 1)
+
+/**
+ * struct vdso_timestamp - basetime per clock_id
+ * @sec: seconds
+ * @nsec: nanoseconds
+ *
+ * There is one vdso_timestamp object in vvar for each vDSO-accelerated
+ * clock_id. For high-resolution clocks, this encodes the time
+ * corresponding to vdso_data.cycle_last. For coarse clocks this encodes
+ * the actual time.
+ *
+ * To be noticed that for highres clocks nsec is left-shifted by
+ * vdso_data.cs[x].shift.
+ */
+struct vdso_timestamp {
+ u64 sec;
+ u64 nsec;
+};
+
+/**
+ * struct vdso_data - vdso datapage representation
+ * @seq: timebase sequence counter
+ * @clock_mode: clock mode
+ * @cycle_last: timebase at clocksource init
+ * @mask: clocksource mask
+ * @mult: clocksource multiplier
+ * @shift: clocksource shift
+ * @basetime[clock_id]: basetime per clock_id
+ * @tz_minuteswest: minutes west of Greenwich
+ * @tz_dsttime: type of DST correction
+ * @hrtimer_res: hrtimer resolution
+ * @__unused: unused
+ *
+ * vdso_data will be accessed by 64 bit and compat code at the same time
+ * so we should be careful before modifying this structure.
+ */
+struct vdso_data {
+ u32 seq;
+
+ s32 clock_mode;
+ u64 cycle_last;
+ u64 mask;
+ u32 mult;
+ u32 shift;
+
+ struct vdso_timestamp basetime[VDSO_BASES];
+
+ s32 tz_minuteswest;
+ s32 tz_dsttime;
+ u32 hrtimer_res;
+ u32 __unused;
+};
+
+/*
+ * We use the hidden visibility to prevent the compiler from generating a GOT
+ * relocation. Not only is going through a GOT useless (the entry couldn't and
+ * must not be overridden by another library), it does not even work: the linker
+ * cannot generate an absolute address to the data page.
+ *
+ * With the hidden visibility, the compiler simply generates a PC-relative
+ * relocation, and this is what we need.
+ */
+extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __VDSO_DATAPAGE_H */
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 01/25] kernel: Standardize vdso_datapage
2019-06-21 9:52 ` [PATCH v7 01/25] kernel: Standardize vdso_datapage Vincenzo Frascino
@ 2019-06-24 13:56 ` Catalin Marinas
0 siblings, 0 replies; 108+ messages in thread
From: Catalin Marinas @ 2019-06-24 13:56 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
On Fri, Jun 21, 2019 at 10:52:28AM +0100, Vincenzo Frascino wrote:
> In an effort to unify the common code for managing the vdso library in
> between all the architectures that support it, this patch tries to
> provide a common format for the vdso datapage.
>
> As a result of this, this patch generalized the data structures in vgtod.h
> from x86 private includes to general includes (include/vdso).
>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> Tested-by: Shijith Thotton <sthotton@marvell.com>
> Tested-by: Andre Przywara <andre.przywara@arm.com>
Minor clean-up patch (on top of the tip timers/vdso branch):
------------8<------------------------------
From 2e09fa6fca341b3ec7ecaf0b67a313a167bb4ff2 Mon Sep 17 00:00:00 2001
From: Catalin Marinas <catalin.marinas@arm.com>
Date: Mon, 24 Jun 2019 12:19:23 +0100
Subject: [PATCH] vdso: Remove superfluous #ifdef __KERNEL__ in
vdso/datapage.h
With the move to UAPI headers, such #ifdefs are no longer necessary.
Fixes: 361f8aee9b09 ("vdso: Define standardized vdso_datapage")
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
include/vdso/datapage.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index e6eb36c3d54f..2e302c0f41f7 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -2,8 +2,6 @@
#ifndef __VDSO_DATAPAGE_H
#define __VDSO_DATAPAGE_H
-#ifdef __KERNEL__
-
#ifndef __ASSEMBLY__
#include <linux/bits.h>
@@ -88,6 +86,4 @@ extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")
#endif /* !__ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
#endif /* __VDSO_DATAPAGE_H */
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 02/25] kernel: Define gettimeofday vdso common code
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 01/25] kernel: Standardize vdso_datapage Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 03/25] kernel: Unify update_vsyscall implementation Vincenzo Frascino
` (24 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
In the last few years we have seen an explosion in vdso
implementations that mostly share similar code.
Try to unify the gettimeofday vdso implementation introducing
lib/vdso. The code contained in this library can ideally be
reused by all the architectures avoiding, where possible, code
duplication.
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
include/linux/hrtimer.h | 15 +--
include/linux/hrtimer_defs.h | 25 ++++
include/vdso/helpers.h | 56 +++++++++
lib/Kconfig | 5 +
lib/vdso/Kconfig | 36 ++++++
lib/vdso/Makefile | 22 ++++
lib/vdso/gettimeofday.c | 227 +++++++++++++++++++++++++++++++++++
7 files changed, 372 insertions(+), 14 deletions(-)
create mode 100644 include/linux/hrtimer_defs.h
create mode 100644 include/vdso/helpers.h
create mode 100644 lib/vdso/Kconfig
create mode 100644 lib/vdso/Makefile
create mode 100644 lib/vdso/gettimeofday.c
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 2e8957eac4d4..c922ce02e2e6 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -12,6 +12,7 @@
#ifndef _LINUX_HRTIMER_H
#define _LINUX_HRTIMER_H
+#include <linux/hrtimer_defs.h>
#include <linux/rbtree.h>
#include <linux/ktime.h>
#include <linux/init.h>
@@ -298,26 +299,12 @@ struct clock_event_device;
extern void hrtimer_interrupt(struct clock_event_device *dev);
-/*
- * The resolution of the clocks. The resolution value is returned in
- * the clock_getres() system call to give application programmers an
- * idea of the (in)accuracy of timers. Timer values are rounded up to
- * this resolution values.
- */
-# define HIGH_RES_NSEC 1
-# define KTIME_HIGH_RES (HIGH_RES_NSEC)
-# define MONOTONIC_RES_NSEC HIGH_RES_NSEC
-# define KTIME_MONOTONIC_RES KTIME_HIGH_RES
-
extern void clock_was_set_delayed(void);
extern unsigned int hrtimer_resolution;
#else
-# define MONOTONIC_RES_NSEC LOW_RES_NSEC
-# define KTIME_MONOTONIC_RES KTIME_LOW_RES
-
#define hrtimer_resolution (unsigned int)LOW_RES_NSEC
static inline void clock_was_set_delayed(void) { }
diff --git a/include/linux/hrtimer_defs.h b/include/linux/hrtimer_defs.h
new file mode 100644
index 000000000000..7179bfc04115
--- /dev/null
+++ b/include/linux/hrtimer_defs.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_HRTIMER_DEFS_H
+#define _LINUX_HRTIMER_DEFS_H
+
+#ifdef CONFIG_HIGH_RES_TIMERS
+
+/*
+ * The resolution of the clocks. The resolution value is returned in
+ * the clock_getres() system call to give application programmers an
+ * idea of the (in)accuracy of timers. Timer values are rounded up to
+ * this resolution values.
+ */
+# define HIGH_RES_NSEC 1
+# define KTIME_HIGH_RES (HIGH_RES_NSEC)
+# define MONOTONIC_RES_NSEC HIGH_RES_NSEC
+# define KTIME_MONOTONIC_RES KTIME_HIGH_RES
+
+#else
+
+# define MONOTONIC_RES_NSEC LOW_RES_NSEC
+# define KTIME_MONOTONIC_RES KTIME_LOW_RES
+
+#endif
+
+#endif
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h
new file mode 100644
index 000000000000..01641dbb68ef
--- /dev/null
+++ b/include/vdso/helpers.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_HELPERS_H
+#define __VDSO_HELPERS_H
+
+#ifndef __ASSEMBLY__
+
+#include <vdso/datapage.h>
+
+static __always_inline u32 vdso_read_begin(const struct vdso_data *vd)
+{
+ u32 seq;
+
+ while ((seq = READ_ONCE(vd->seq)) & 1)
+ cpu_relax();
+
+ smp_rmb();
+ return seq;
+}
+
+static __always_inline u32 vdso_read_retry(const struct vdso_data *vd,
+ u32 start)
+{
+ u32 seq;
+
+ smp_rmb();
+ seq = READ_ONCE(vd->seq);
+ return seq != start;
+}
+
+static __always_inline void vdso_write_begin(struct vdso_data *vd)
+{
+ /*
+ * WRITE_ONCE it is required otherwise the compiler can validly tear
+ * updates to vd[x].seq and it is possible that the value seen by the
+ * reader it is inconsistent.
+ */
+ WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1);
+ WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1);
+ smp_wmb();
+}
+
+static __always_inline void vdso_write_end(struct vdso_data *vd)
+{
+ smp_wmb();
+ /*
+ * WRITE_ONCE it is required otherwise the compiler can validly tear
+ * updates to vd[x].seq and it is possible that the value seen by the
+ * reader it is inconsistent.
+ */
+ WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1);
+ WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __VDSO_HELPERS_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 90623a0e1942..8c8eefc5e54c 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -576,6 +576,11 @@ config OID_REGISTRY
config UCS2_STRING
tristate
+#
+# generic vdso
+#
+source "lib/vdso/Kconfig"
+
source "lib/fonts/Kconfig"
config SG_SPLIT
diff --git a/lib/vdso/Kconfig b/lib/vdso/Kconfig
new file mode 100644
index 000000000000..cc00364bd2c2
--- /dev/null
+++ b/lib/vdso/Kconfig
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config HAVE_GENERIC_VDSO
+ bool
+
+if HAVE_GENERIC_VDSO
+
+config GENERIC_GETTIMEOFDAY
+ bool
+ help
+ This is a generic implementation of gettimeofday vdso.
+ Each architecture that enables this feature has to
+ provide the fallback implementation.
+
+config GENERIC_VDSO_32
+ bool
+ depends on GENERIC_GETTIMEOFDAY && !64BIT
+ help
+ This config option helps to avoid possible performance issues
+ in 32 bit only architectures.
+
+config GENERIC_COMPAT_VDSO
+ bool
+ help
+ This config option enables the compat VDSO layer.
+
+config CROSS_COMPILE_COMPAT_VDSO
+ string "32 bit Toolchain prefix for compat vDSO"
+ default ""
+ depends on GENERIC_COMPAT_VDSO
+ help
+ Defines the cross-compiler prefix for compiling compat vDSO.
+ If a 64 bit compiler (i.e. x86_64) can compile the VDSO for
+ 32 bit, it does not need to define this parameter.
+
+endif
diff --git a/lib/vdso/Makefile b/lib/vdso/Makefile
new file mode 100644
index 000000000000..c415a685d61b
--- /dev/null
+++ b/lib/vdso/Makefile
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0
+
+GENERIC_VDSO_MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+GENERIC_VDSO_DIR := $(dir $(GENERIC_VDSO_MK_PATH))
+
+c-gettimeofday-$(CONFIG_GENERIC_GETTIMEOFDAY) := $(addprefix $(GENERIC_VDSO_DIR), gettimeofday.c)
+
+# This cmd checks that the vdso library does not contain absolute relocation
+# It has to be called after the linking of the vdso library and requires it
+# as a parameter.
+#
+# $(ARCH_REL_TYPE_ABS) is defined in the arch specific makefile and corresponds
+# to the absolute relocation types printed by "objdump -R" and accepted by the
+# dynamic linker.
+ifndef ARCH_REL_TYPE_ABS
+$(error ARCH_REL_TYPE_ABS is not set)
+endif
+
+quiet_cmd_vdso_check = VDSOCHK $@
+ cmd_vdso_check = if $(OBJDUMP) -R $@ | egrep -h "$(ARCH_REL_TYPE_ABS)"; \
+ then (echo >&2 "$@: dynamic relocations are not supported"; \
+ rm -f $@; /bin/false); fi
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
new file mode 100644
index 000000000000..473e2dda0220
--- /dev/null
+++ b/lib/vdso/gettimeofday.c
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Generic userspace implementations of gettimeofday() and similar.
+ */
+#include <linux/compiler.h>
+#include <linux/math64.h>
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer_defs.h>
+#include <vdso/datapage.h>
+#include <vdso/helpers.h>
+
+/*
+ * The generic vDSO implementation requires that gettimeofday.h
+ * provides:
+ * - __arch_get_vdso_data(): to get the vdso datapage.
+ * - __arch_get_hw_counter(): to get the hw counter based on the
+ * clock_mode.
+ * - gettimeofday_fallback(): fallback for gettimeofday.
+ * - clock_gettime_fallback(): fallback for clock_gettime.
+ * - clock_getres_fallback(): fallback for clock_getres.
+ */
+#include <asm/vdso/gettimeofday.h>
+
+static int do_hres(const struct vdso_data *vd,
+ clockid_t clk,
+ struct __kernel_timespec *ts)
+{
+ const struct vdso_timestamp *vdso_ts = &vd->basetime[clk];
+ u64 cycles, last, sec, ns;
+ u32 seq;
+
+ do {
+ seq = vdso_read_begin(vd);
+ cycles = __arch_get_hw_counter(vd->clock_mode) &
+ vd->mask;
+ ns = vdso_ts->nsec;
+ last = vd->cycle_last;
+ if (unlikely((s64)cycles < 0))
+ return clock_gettime_fallback(clk, ts);
+ if (cycles > last)
+ ns += (cycles - last) * vd->mult;
+ ns >>= vd->shift;
+ sec = vdso_ts->sec;
+ } while (unlikely(vdso_read_retry(vd, seq)));
+
+ /*
+ * Do this outside the loop: a race inside the loop could result
+ * in __iter_div_u64_rem() being extremely slow.
+ */
+ ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
+ ts->tv_nsec = ns;
+
+ return 0;
+}
+
+static void do_coarse(const struct vdso_data *vd,
+ clockid_t clk,
+ struct __kernel_timespec *ts)
+{
+ const struct vdso_timestamp *vdso_ts = &vd->basetime[clk];
+ u32 seq;
+
+ do {
+ seq = vdso_read_begin(vd);
+ ts->tv_sec = vdso_ts->sec;
+ ts->tv_nsec = vdso_ts->nsec;
+ } while (unlikely(vdso_read_retry(vd, seq)));
+}
+
+static __maybe_unused int
+__cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
+{
+ const struct vdso_data *vd = __arch_get_vdso_data();
+ u32 msk;
+
+ /* Check for negative values or invalid clocks */
+ if (unlikely((u32) clock >= MAX_CLOCKS))
+ goto fallback;
+
+ /*
+ * Convert the clockid to a bitmask and use it to check which
+ * clocks are handled in the VDSO directly.
+ */
+ msk = 1U << clock;
+ if (likely(msk & VDSO_HRES)) {
+ return do_hres(&vd[CS_HRES_COARSE], clock, ts);
+ } else if (msk & VDSO_COARSE) {
+ do_coarse(&vd[CS_HRES_COARSE], clock, ts);
+ return 0;
+ } else if (msk & VDSO_RAW) {
+ return do_hres(&vd[CS_RAW], clock, ts);
+ }
+
+fallback:
+ return clock_gettime_fallback(clock, ts);
+}
+
+static __maybe_unused int
+__cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res)
+{
+ struct __kernel_timespec ts;
+ int ret;
+
+ if (res == NULL)
+ goto fallback;
+
+ ret = __cvdso_clock_gettime(clock, &ts);
+
+ if (ret == 0) {
+ res->tv_sec = ts.tv_sec;
+ res->tv_nsec = ts.tv_nsec;
+ }
+
+ return ret;
+
+fallback:
+ return clock_gettime_fallback(clock, (struct __kernel_timespec *)res);
+}
+
+static __maybe_unused int
+__cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
+{
+ const struct vdso_data *vd = __arch_get_vdso_data();
+
+ if (likely(tv != NULL)) {
+ struct __kernel_timespec ts;
+
+ if (do_hres(&vd[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
+ return gettimeofday_fallback(tv, tz);
+
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = (u32)ts.tv_nsec / NSEC_PER_USEC;
+ }
+
+ if (unlikely(tz != NULL)) {
+ tz->tz_minuteswest = vd[CS_HRES_COARSE].tz_minuteswest;
+ tz->tz_dsttime = vd[CS_HRES_COARSE].tz_dsttime;
+ }
+
+ return 0;
+}
+
+#ifdef VDSO_HAS_TIME
+static __maybe_unused time_t __cvdso_time(time_t *time)
+{
+ const struct vdso_data *vd = __arch_get_vdso_data();
+ time_t t = READ_ONCE(vd[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
+
+ if (time)
+ *time = t;
+
+ return t;
+}
+#endif /* VDSO_HAS_TIME */
+
+#ifdef VDSO_HAS_CLOCK_GETRES
+static __maybe_unused
+int __cvdso_clock_getres(clockid_t clock, struct __kernel_timespec *res)
+{
+ const struct vdso_data *vd = __arch_get_vdso_data();
+ u64 ns;
+ u32 msk;
+ u64 hrtimer_res = READ_ONCE(vd[CS_HRES_COARSE].hrtimer_res);
+
+ /* Check for negative values or invalid clocks */
+ if (unlikely((u32) clock >= MAX_CLOCKS))
+ goto fallback;
+
+ /*
+ * Convert the clockid to a bitmask and use it to check which
+ * clocks are handled in the VDSO directly.
+ */
+ msk = 1U << clock;
+ if (msk & VDSO_HRES) {
+ /*
+ * Preserves the behaviour of posix_get_hrtimer_res().
+ */
+ ns = hrtimer_res;
+ } else if (msk & VDSO_COARSE) {
+ /*
+ * Preserves the behaviour of posix_get_coarse_res().
+ */
+ ns = LOW_RES_NSEC;
+ } else if (msk & VDSO_RAW) {
+ /*
+ * Preserves the behaviour of posix_get_hrtimer_res().
+ */
+ ns = hrtimer_res;
+ } else {
+ goto fallback;
+ }
+
+ if (res) {
+ res->tv_sec = 0;
+ res->tv_nsec = ns;
+ }
+
+ return 0;
+
+fallback:
+ return clock_getres_fallback(clock, res);
+}
+
+static __maybe_unused int
+__cvdso_clock_getres_time32(clockid_t clock, struct old_timespec32 *res)
+{
+ struct __kernel_timespec ts;
+ int ret;
+
+ if (res == NULL)
+ goto fallback;
+
+ ret = __cvdso_clock_getres(clock, &ts);
+
+ if (ret == 0) {
+ res->tv_sec = ts.tv_sec;
+ res->tv_nsec = ts.tv_nsec;
+ }
+
+ return ret;
+
+fallback:
+ return clock_getres_fallback(clock, (struct __kernel_timespec *)res);
+}
+#endif /* VDSO_HAS_CLOCK_GETRES */
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 03/25] kernel: Unify update_vsyscall implementation
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 01/25] kernel: Standardize vdso_datapage Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 02/25] kernel: Define gettimeofday vdso common code Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 10:49 ` Huw Davies
2019-06-21 9:52 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Vincenzo Frascino
` (23 subsequent siblings)
26 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
With the definition of the unified vDSO library the implementations of
update_vsyscall and update_vsyscall_tz became quite similar across
architectures.
Define a unified implementation of these two functions in kernel/vdso
and provide the bindings that can be implemented by every architecture
that takes advantage of the unified vDSO library.
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
include/asm-generic/vdso/vsyscall.h | 56 ++++++++++++
include/linux/timekeeper_internal.h | 9 ++
include/vdso/vsyscall.h | 11 +++
kernel/Makefile | 1 +
kernel/vdso/Makefile | 2 +
kernel/vdso/vsyscall.c | 131 ++++++++++++++++++++++++++++
6 files changed, 210 insertions(+)
create mode 100644 include/asm-generic/vdso/vsyscall.h
create mode 100644 include/vdso/vsyscall.h
create mode 100644 kernel/vdso/Makefile
create mode 100644 kernel/vdso/vsyscall.c
diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h
new file mode 100644
index 000000000000..9a4b9fbcc9b6
--- /dev/null
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_GENERIC_VSYSCALL_H
+#define __ASM_GENERIC_VSYSCALL_H
+
+#ifndef __ASSEMBLY__
+
+#ifndef __arch_get_k_vdso_data
+static __always_inline
+struct vdso_data *__arch_get_k_vdso_data(void)
+{
+ return NULL;
+}
+#endif /* __arch_get_k_vdso_data */
+
+#ifndef __arch_update_vdso_data
+static __always_inline
+int __arch_update_vdso_data(void)
+{
+ return 0;
+}
+#endif /* __arch_update_vdso_data */
+
+#ifndef __arch_get_clock_mode
+static __always_inline
+int __arch_get_clock_mode(struct timekeeper *tk)
+{
+ return 0;
+}
+#endif /* __arch_get_clock_mode */
+
+#ifndef __arch_use_vsyscall
+static __always_inline
+int __arch_use_vsyscall(struct vdso_data *vdata)
+{
+ return 1;
+}
+#endif /* __arch_use_vsyscall */
+
+#ifndef __arch_update_vsyscall
+static __always_inline
+void __arch_update_vsyscall(struct vdso_data *vdata,
+ struct timekeeper *tk)
+{
+}
+#endif /* __arch_update_vsyscall */
+
+#ifndef __arch_sync_vdso_data
+static __always_inline
+void __arch_sync_vdso_data(struct vdso_data *vdata)
+{
+}
+#endif /* __arch_sync_vdso_data */
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_GENERIC_VSYSCALL_H */
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index 7acb953298a7..8177e75a71eb 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -135,9 +135,18 @@ struct timekeeper {
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
+#ifdef CONFIG_HAVE_GENERIC_VDSO
+
+void update_vsyscall(struct timekeeper *tk);
+void update_vsyscall_tz(void);
+
+#else
+
extern void update_vsyscall(struct timekeeper *tk);
extern void update_vsyscall_tz(void);
+#endif /* CONFIG_HAVE_GENERIC_VDSO */
+
#else
static inline void update_vsyscall(struct timekeeper *tk)
diff --git a/include/vdso/vsyscall.h b/include/vdso/vsyscall.h
new file mode 100644
index 000000000000..2c6134e0c23d
--- /dev/null
+++ b/include/vdso/vsyscall.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_VSYSCALL_H
+#define __VDSO_VSYSCALL_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/vdso/vsyscall.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __VDSO_VSYSCALL_H */
diff --git a/kernel/Makefile b/kernel/Makefile
index 33824f0385b3..56a98ebb7772 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
obj-$(CONFIG_FREEZER) += freezer.o
obj-$(CONFIG_PROFILING) += profile.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-$(CONFIG_HAVE_GENERIC_VDSO) += vdso/
obj-y += time/
obj-$(CONFIG_FUTEX) += futex.o
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
diff --git a/kernel/vdso/Makefile b/kernel/vdso/Makefile
new file mode 100644
index 000000000000..ad0d3b1a475c
--- /dev/null
+++ b/kernel/vdso/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_HAVE_GENERIC_VDSO) += vsyscall.o
diff --git a/kernel/vdso/vsyscall.c b/kernel/vdso/vsyscall.c
new file mode 100644
index 000000000000..d1e8074e3d10
--- /dev/null
+++ b/kernel/vdso/vsyscall.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 ARM Ltd.
+ *
+ * Generic implementation of update_vsyscall and update_vsyscall_tz.
+ */
+
+#include <linux/hrtimer.h>
+#include <linux/timekeeper_internal.h>
+#include <vdso/datapage.h>
+#include <vdso/helpers.h>
+#include <vdso/vsyscall.h>
+
+static inline void update_vdso_data(struct vdso_data *vdata,
+ struct timekeeper *tk)
+{
+ struct vdso_timestamp *vdso_ts;
+ u64 nsec;
+
+ vdata[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
+ vdata[CS_HRES_COARSE].mask = tk->tkr_mono.mask;
+ vdata[CS_HRES_COARSE].mult = tk->tkr_mono.mult;
+ vdata[CS_HRES_COARSE].shift = tk->tkr_mono.shift;
+ vdata[CS_RAW].cycle_last = tk->tkr_raw.cycle_last;
+ vdata[CS_RAW].mask = tk->tkr_raw.mask;
+ vdata[CS_RAW].mult = tk->tkr_raw.mult;
+ vdata[CS_RAW].shift = tk->tkr_raw.shift;
+
+ /* CLOCK_REALTIME */
+ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
+ vdso_ts->sec = tk->xtime_sec;
+ vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
+
+ /* CLOCK_MONOTONIC */
+ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
+ vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
+
+ nsec = tk->tkr_mono.xtime_nsec;
+ nsec += ((u64)tk->wall_to_monotonic.tv_nsec << tk->tkr_mono.shift);
+ while (nsec >= (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
+ nsec -= (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift);
+ vdso_ts->sec++;
+ }
+ vdso_ts->nsec = nsec;
+
+ /* CLOCK_MONOTONIC_RAW */
+ vdso_ts = &vdata[CS_RAW].basetime[CLOCK_MONOTONIC_RAW];
+ vdso_ts->sec = tk->raw_sec;
+ vdso_ts->nsec = tk->tkr_raw.xtime_nsec;
+
+ /* CLOCK_BOOTTIME */
+ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_BOOTTIME];
+ vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
+ nsec = tk->tkr_mono.xtime_nsec;
+ nsec += ((u64)(tk->wall_to_monotonic.tv_nsec +
+ ktime_to_ns(tk->offs_boot)) << tk->tkr_mono.shift);
+ while (nsec >= (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
+ nsec -= (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift);
+ vdso_ts->sec++;
+ }
+ vdso_ts->nsec = nsec;
+
+ /* CLOCK_TAI */
+ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_TAI];
+ vdso_ts->sec = tk->xtime_sec + (s64)tk->tai_offset;
+ vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
+
+ /*
+ * Read without the seqlock held by clock_getres().
+ * Note: No need to have a second copy.
+ */
+ WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
+}
+
+void update_vsyscall(struct timekeeper *tk)
+{
+ struct vdso_data *vdata = __arch_get_k_vdso_data();
+ struct vdso_timestamp *vdso_ts;
+ u64 nsec;
+
+ if (__arch_update_vdso_data()) {
+ /*
+ * Some architectures might want to skip the update of the
+ * data page.
+ */
+ return;
+ }
+
+ /* copy vsyscall data */
+ vdso_write_begin(vdata);
+
+ vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk);
+ vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk);
+
+ /* CLOCK_REALTIME_COARSE */
+ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE];
+ vdso_ts->sec = tk->xtime_sec;
+ vdso_ts->nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
+
+ /* CLOCK_MONOTONIC_COARSE */
+ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC_COARSE];
+ vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
+ nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
+ nsec = nsec + tk->wall_to_monotonic.tv_nsec;
+ while (nsec >= NSEC_PER_SEC) {
+ nsec = nsec - NSEC_PER_SEC;
+ vdso_ts->sec++;
+ }
+ vdso_ts->nsec = nsec;
+
+ if (__arch_use_vsyscall(vdata))
+ update_vdso_data(vdata, tk);
+
+ __arch_update_vsyscall(vdata, tk);
+
+ vdso_write_end(vdata);
+
+ __arch_sync_vdso_data(vdata);
+}
+
+void update_vsyscall_tz(void)
+{
+ struct vdso_data *vdata = __arch_get_k_vdso_data();
+
+ if (__arch_use_vsyscall(vdata)) {
+ vdata[CS_HRES_COARSE].tz_minuteswest = sys_tz.tz_minuteswest;
+ vdata[CS_HRES_COARSE].tz_dsttime = sys_tz.tz_dsttime;
+ }
+
+ __arch_sync_vdso_data(vdata);
+}
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 03/25] kernel: Unify update_vsyscall implementation
2019-06-21 9:52 ` [PATCH v7 03/25] kernel: Unify update_vsyscall implementation Vincenzo Frascino
@ 2019-06-21 10:49 ` Huw Davies
0 siblings, 0 replies; 108+ messages in thread
From: Huw Davies @ 2019-06-21 10:49 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Shijith Thotton,
Andre Przywara
On Fri, Jun 21, 2019 at 10:52:30AM +0100, Vincenzo Frascino wrote:
> diff --git a/kernel/vdso/vsyscall.c b/kernel/vdso/vsyscall.c
> new file mode 100644
> index 000000000000..d1e8074e3d10
> --- /dev/null
> +++ b/kernel/vdso/vsyscall.c
> +static inline void update_vdso_data(struct vdso_data *vdata,
> + struct timekeeper *tk)
> +{
> + struct vdso_timestamp *vdso_ts;
> + u64 nsec;
> +
> + vdata[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
> + vdata[CS_HRES_COARSE].mask = tk->tkr_mono.mask;
> + vdata[CS_HRES_COARSE].mult = tk->tkr_mono.mult;
> + vdata[CS_HRES_COARSE].shift = tk->tkr_mono.shift;
> + vdata[CS_RAW].cycle_last = tk->tkr_raw.cycle_last;
> + vdata[CS_RAW].mask = tk->tkr_raw.mask;
> + vdata[CS_RAW].mult = tk->tkr_raw.mult;
> + vdata[CS_RAW].shift = tk->tkr_raw.shift;
> +
> + /* CLOCK_REALTIME */
> + vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
There's an extraneous space after the '='. Hopefully Thomas can
fix this up if this patchset is otherwise ok.
> + vdso_ts->sec = tk->xtime_sec;
> + vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
Huw.
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (2 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 03/25] kernel: Unify update_vsyscall implementation Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-24 13:36 ` Will Deacon
` (5 more replies)
2019-06-21 9:52 ` [PATCH v7 05/25] arm64: Build vDSO with -ffixed-x18 Vincenzo Frascino
` (22 subsequent siblings)
26 siblings, 6 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
To take advantage of the commonly defined vdso interface for
gettimeofday the architectural code requires an adaptation.
Re-implement the gettimeofday vdso in C in order to use lib/vdso.
With the new implementation arm64 gains support for CLOCK_BOOTTIME
and CLOCK_TAI.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/Kconfig | 2 +
arch/arm64/include/asm/vdso/gettimeofday.h | 86 ++++++
arch/arm64/include/asm/vdso/vsyscall.h | 53 ++++
arch/arm64/include/asm/vdso_datapage.h | 48 ---
arch/arm64/kernel/asm-offsets.c | 33 +-
arch/arm64/kernel/vdso.c | 51 +---
arch/arm64/kernel/vdso/Makefile | 34 ++-
arch/arm64/kernel/vdso/gettimeofday.S | 334 ---------------------
arch/arm64/kernel/vdso/vgettimeofday.c | 28 ++
9 files changed, 223 insertions(+), 446 deletions(-)
create mode 100644 arch/arm64/include/asm/vdso/gettimeofday.h
create mode 100644 arch/arm64/include/asm/vdso/vsyscall.h
delete mode 100644 arch/arm64/include/asm/vdso_datapage.h
delete mode 100644 arch/arm64/kernel/vdso/gettimeofday.S
create mode 100644 arch/arm64/kernel/vdso/vgettimeofday.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 697ea0510729..952c9f8cf3b8 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -107,6 +107,7 @@ config ARM64
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
+ select GENERIC_GETTIMEOFDAY
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_PCI
@@ -160,6 +161,7 @@ config ARM64
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_KPROBES
select HAVE_KRETPROBES
+ select HAVE_GENERIC_VDSO
select IOMMU_DMA if IOMMU_SUPPORT
select IRQ_DOMAIN
select IRQ_FORCED_THREADING
diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
new file mode 100644
index 000000000000..bc3cb6738051
--- /dev/null
+++ b/arch/arm64/include/asm/vdso/gettimeofday.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 ARM Limited
+ */
+#ifndef __ASM_VDSO_GETTIMEOFDAY_H
+#define __ASM_VDSO_GETTIMEOFDAY_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/unistd.h>
+#include <uapi/linux/time.h>
+
+#define VDSO_HAS_CLOCK_GETRES 1
+
+static __always_inline int gettimeofday_fallback(
+ struct __kernel_old_timeval *_tv,
+ struct timezone *_tz)
+{
+ register struct timezone *tz asm("x1") = _tz;
+ register struct __kernel_old_timeval *tv asm("x0") = _tv;
+ register long ret asm ("x0");
+ register long nr asm("x8") = __NR_gettimeofday;
+
+ asm volatile(
+ " svc #0\n"
+ : "=r" (ret)
+ : "r" (tv), "r" (tz), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static __always_inline long clock_gettime_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ register struct __kernel_timespec *ts asm("x1") = _ts;
+ register clockid_t clkid asm("x0") = _clkid;
+ register long ret asm ("x0");
+ register long nr asm("x8") = __NR_clock_gettime;
+
+ asm volatile(
+ " svc #0\n"
+ : "=r" (ret)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static __always_inline int clock_getres_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ register struct __kernel_timespec *ts asm("x1") = _ts;
+ register clockid_t clkid asm("x0") = _clkid;
+ register long ret asm ("x0");
+ register long nr asm("x8") = __NR_clock_getres;
+
+ asm volatile(
+ " svc #0\n"
+ : "=r" (ret)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
+{
+ u64 res;
+
+ asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
+
+ return res;
+}
+
+static __always_inline
+const struct vdso_data *__arch_get_vdso_data(void)
+{
+ return _vdso_data;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
new file mode 100644
index 000000000000..0c731bfc7c8c
--- /dev/null
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_VDSO_VSYSCALL_H
+#define __ASM_VDSO_VSYSCALL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/timekeeper_internal.h>
+#include <vdso/datapage.h>
+
+#define VDSO_PRECISION_MASK ~(0xFF00ULL<<48)
+
+extern struct vdso_data *vdso_data;
+
+/*
+ * Update the vDSO data page to keep in sync with kernel timekeeping.
+ */
+static __always_inline
+struct vdso_data *__arm64_get_k_vdso_data(void)
+{
+ return vdso_data;
+}
+#define __arch_get_k_vdso_data __arm64_get_k_vdso_data
+
+static __always_inline
+int __arm64_get_clock_mode(struct timekeeper *tk)
+{
+ u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
+
+ return use_syscall;
+}
+#define __arch_get_clock_mode __arm64_get_clock_mode
+
+static __always_inline
+int __arm64_use_vsyscall(struct vdso_data *vdata)
+{
+ return !vdata[CS_HRES_COARSE].clock_mode;
+}
+#define __arch_use_vsyscall __arm64_use_vsyscall
+
+static __always_inline
+void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
+{
+ vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
+ vdata[CS_RAW].mask = VDSO_PRECISION_MASK;
+}
+#define __arch_update_vsyscall __arm64_update_vsyscall
+
+/* The asm-generic header needs to be included after the definitions above */
+#include <asm-generic/vdso/vsyscall.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_VSYSCALL_H */
diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h
deleted file mode 100644
index f89263c8e11a..000000000000
--- a/arch/arm64/include/asm/vdso_datapage.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __ASM_VDSO_DATAPAGE_H
-#define __ASM_VDSO_DATAPAGE_H
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-struct vdso_data {
- __u64 cs_cycle_last; /* Timebase at clocksource init */
- __u64 raw_time_sec; /* Raw time */
- __u64 raw_time_nsec;
- __u64 xtime_clock_sec; /* Kernel time */
- __u64 xtime_clock_nsec;
- __u64 xtime_coarse_sec; /* Coarse time */
- __u64 xtime_coarse_nsec;
- __u64 wtm_clock_sec; /* Wall to monotonic time */
- __u64 wtm_clock_nsec;
- __u32 tb_seq_count; /* Timebase sequence counter */
- /* cs_* members must be adjacent and in this order (ldp accesses) */
- __u32 cs_mono_mult; /* NTP-adjusted clocksource multiplier */
- __u32 cs_shift; /* Clocksource shift (mono = raw) */
- __u32 cs_raw_mult; /* Raw clocksource multiplier */
- __u32 tz_minuteswest; /* Whacky timezone stuff */
- __u32 tz_dsttime;
- __u32 use_syscall;
- __u32 hrtimer_res;
-};
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 947e39896e28..9e4b7ccbab2f 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -25,13 +25,13 @@
#include <linux/kvm_host.h>
#include <linux/preempt.h>
#include <linux/suspend.h>
+#include <vdso/datapage.h>
#include <asm/cpufeature.h>
#include <asm/fixmap.h>
#include <asm/thread_info.h>
#include <asm/memory.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>
-#include <asm/vdso_datapage.h>
#include <linux/kbuild.h>
#include <linux/arm-smccc.h>
@@ -100,17 +100,28 @@ int main(void)
DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
BLANK();
- DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last));
- DEFINE(VDSO_RAW_TIME_SEC, offsetof(struct vdso_data, raw_time_sec));
- DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec));
- DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec));
- DEFINE(VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec));
- DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec));
- DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count));
- DEFINE(VDSO_CS_MONO_MULT, offsetof(struct vdso_data, cs_mono_mult));
- DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift));
+ DEFINE(VDSO_SEQ, offsetof(struct vdso_data, seq));
+ DEFINE(VDSO_CLK_MODE, offsetof(struct vdso_data, clock_mode));
+ DEFINE(VDSO_CYCLE_LAST, offsetof(struct vdso_data, cycle_last));
+ DEFINE(VDSO_MASK, offsetof(struct vdso_data, mask));
+ DEFINE(VDSO_MULT, offsetof(struct vdso_data, mult));
+ DEFINE(VDSO_SHIFT, offsetof(struct vdso_data, shift));
+ DEFINE(VDSO_REALTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].sec));
+ DEFINE(VDSO_REALTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].nsec));
+ DEFINE(VDSO_MONO_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].sec));
+ DEFINE(VDSO_MONO_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].nsec));
+ DEFINE(VDSO_MONO_RAW_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].sec));
+ DEFINE(VDSO_MONO_RAW_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].nsec));
+ DEFINE(VDSO_BOOTTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].sec));
+ DEFINE(VDSO_BOOTTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].nsec));
+ DEFINE(VDSO_TAI_SEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].sec));
+ DEFINE(VDSO_TAI_NSEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].nsec));
+ DEFINE(VDSO_RT_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].sec));
+ DEFINE(VDSO_RT_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].nsec));
+ DEFINE(VDSO_MONO_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].sec));
+ DEFINE(VDSO_MONO_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].nsec));
DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest));
- DEFINE(VDSO_USE_SYSCALL, offsetof(struct vdso_data, use_syscall));
+ DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
BLANK();
DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec));
DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 8074cbd3a3a8..23c38303a52a 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -31,11 +31,13 @@
#include <linux/slab.h>
#include <linux/timekeeper_internal.h>
#include <linux/vmalloc.h>
+#include <vdso/datapage.h>
+#include <vdso/helpers.h>
+#include <vdso/vsyscall.h>
#include <asm/cacheflush.h>
#include <asm/signal32.h>
#include <asm/vdso.h>
-#include <asm/vdso_datapage.h>
extern char vdso_start[], vdso_end[];
static unsigned long vdso_pages __ro_after_init;
@@ -44,10 +46,10 @@ static unsigned long vdso_pages __ro_after_init;
* The vDSO data page.
*/
static union {
- struct vdso_data data;
+ struct vdso_data data[CS_BASES];
u8 page[PAGE_SIZE];
} vdso_data_store __page_aligned_data;
-struct vdso_data *vdso_data = &vdso_data_store.data;
+struct vdso_data *vdso_data = vdso_data_store.data;
#ifdef CONFIG_COMPAT
/*
@@ -280,46 +282,3 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
up_write(&mm->mmap_sem);
return PTR_ERR(ret);
}
-
-/*
- * Update the vDSO data page to keep in sync with kernel timekeeping.
- */
-void update_vsyscall(struct timekeeper *tk)
-{
- u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
-
- ++vdso_data->tb_seq_count;
- smp_wmb();
-
- vdso_data->use_syscall = use_syscall;
- vdso_data->xtime_coarse_sec = tk->xtime_sec;
- vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >>
- tk->tkr_mono.shift;
- vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
- vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
-
- /* Read without the seqlock held by clock_getres() */
- WRITE_ONCE(vdso_data->hrtimer_res, hrtimer_resolution);
-
- if (!use_syscall) {
- /* tkr_mono.cycle_last == tkr_raw.cycle_last */
- vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
- vdso_data->raw_time_sec = tk->raw_sec;
- vdso_data->raw_time_nsec = tk->tkr_raw.xtime_nsec;
- vdso_data->xtime_clock_sec = tk->xtime_sec;
- vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec;
- vdso_data->cs_mono_mult = tk->tkr_mono.mult;
- vdso_data->cs_raw_mult = tk->tkr_raw.mult;
- /* tkr_mono.shift == tkr_raw.shift */
- vdso_data->cs_shift = tk->tkr_mono.shift;
- }
-
- smp_wmb();
- ++vdso_data->tb_seq_count;
-}
-
-void update_vsyscall_tz(void)
-{
- vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
- vdso_data->tz_dsttime = sys_tz.tz_dsttime;
-}
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index fa230ff09aa1..3acfc813e966 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -6,7 +6,12 @@
# Heavily based on the vDSO Makefiles for other archs.
#
-obj-vdso := gettimeofday.o note.o sigreturn.o
+# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+# the inclusion of generic Makefile.
+ARCH_REL_TYPE_ABS := R_AARCH64_JUMP_SLOT|R_AARCH64_GLOB_DAT|R_AARCH64_ABS64
+include $(srctree)/lib/vdso/Makefile
+
+obj-vdso := vgettimeofday.o note.o sigreturn.o
# Build rules
targets := $(obj-vdso) vdso.so vdso.so.dbg
@@ -15,6 +20,24 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \
--build-id -n -T
+ccflags-y := -fno-common -fno-builtin -fno-stack-protector
+ccflags-y += -DDISABLE_BRANCH_PROFILING
+
+VDSO_LDFLAGS := -Bsymbolic
+
+CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
+KBUILD_CFLAGS += $(DISABLE_LTO)
+KASAN_SANITIZE := n
+UBSAN_SANITIZE := n
+OBJECT_FILES_NON_STANDARD := y
+KCOV_INSTRUMENT := n
+
+ifeq ($(c-gettimeofday-y),)
+CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny
+else
+CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -include $(c-gettimeofday-y)
+endif
+
# Disable gcov profiling for VDSO code
GCOV_PROFILE := n
@@ -28,6 +51,7 @@ $(obj)/vdso.o : $(obj)/vdso.so
# Link rule for the .so file, .lds has to be first
$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
$(call if_changed,ld)
+ $(call if_changed,vdso_check)
# Strip rule for the .so file
$(obj)/%.so: OBJCOPYFLAGS := -S
@@ -42,13 +66,9 @@ quiet_cmd_vdsosym = VDSOSYM $@
include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
$(call if_changed,vdsosym)
-# Assembly rules for the .S files
-$(obj-vdso): %.o: %.S FORCE
- $(call if_changed_dep,vdsoas)
-
# Actual build commands
-quiet_cmd_vdsoas = VDSOA $@
- cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
+quiet_cmd_vdsocc = VDSOCC $@
+ cmd_vdsocc = $(CC) $(a_flags) $(c_flags) -c -o $@ $<
# Install commands for the unstripped file
quiet_cmd_vdso_install = INSTALL $@
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
deleted file mode 100644
index 856fee6d3512..000000000000
--- a/arch/arm64/kernel/vdso/gettimeofday.S
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Userspace implementations of gettimeofday() and friends.
- *
- * Copyright (C) 2012 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author: Will Deacon <will.deacon@arm.com>
- */
-
-#include <linux/linkage.h>
-#include <asm/asm-offsets.h>
-#include <asm/unistd.h>
-
-#define NSEC_PER_SEC_LO16 0xca00
-#define NSEC_PER_SEC_HI16 0x3b9a
-
-vdso_data .req x6
-seqcnt .req w7
-w_tmp .req w8
-x_tmp .req x8
-
-/*
- * Conventions for macro arguments:
- * - An argument is write-only if its name starts with "res".
- * - All other arguments are read-only, unless otherwise specified.
- */
-
- .macro seqcnt_acquire
-9999: ldr seqcnt, [vdso_data, #VDSO_TB_SEQ_COUNT]
- tbnz seqcnt, #0, 9999b
- dmb ishld
- .endm
-
- .macro seqcnt_check fail
- dmb ishld
- ldr w_tmp, [vdso_data, #VDSO_TB_SEQ_COUNT]
- cmp w_tmp, seqcnt
- b.ne \fail
- .endm
-
- .macro syscall_check fail
- ldr w_tmp, [vdso_data, #VDSO_USE_SYSCALL]
- cbnz w_tmp, \fail
- .endm
-
- .macro get_nsec_per_sec res
- mov \res, #NSEC_PER_SEC_LO16
- movk \res, #NSEC_PER_SEC_HI16, lsl #16
- .endm
-
- /*
- * Returns the clock delta, in nanoseconds left-shifted by the clock
- * shift.
- */
- .macro get_clock_shifted_nsec res, cycle_last, mult
- /* Read the virtual counter. */
- isb
- mrs x_tmp, cntvct_el0
- /* Calculate cycle delta and convert to ns. */
- sub \res, x_tmp, \cycle_last
- /* We can only guarantee 56 bits of precision. */
- movn x_tmp, #0xff00, lsl #48
- and \res, x_tmp, \res
- mul \res, \res, \mult
- /*
- * Fake address dependency from the value computed from the counter
- * register to subsequent data page accesses so that the sequence
- * locking also orders the read of the counter.
- */
- and x_tmp, \res, xzr
- add vdso_data, vdso_data, x_tmp
- .endm
-
- /*
- * Returns in res_{sec,nsec} the REALTIME timespec, based on the
- * "wall time" (xtime) and the clock_mono delta.
- */
- .macro get_ts_realtime res_sec, res_nsec, \
- clock_nsec, xtime_sec, xtime_nsec, nsec_to_sec
- add \res_nsec, \clock_nsec, \xtime_nsec
- udiv x_tmp, \res_nsec, \nsec_to_sec
- add \res_sec, \xtime_sec, x_tmp
- msub \res_nsec, x_tmp, \nsec_to_sec, \res_nsec
- .endm
-
- /*
- * Returns in res_{sec,nsec} the timespec based on the clock_raw delta,
- * used for CLOCK_MONOTONIC_RAW.
- */
- .macro get_ts_clock_raw res_sec, res_nsec, clock_nsec, nsec_to_sec
- udiv \res_sec, \clock_nsec, \nsec_to_sec
- msub \res_nsec, \res_sec, \nsec_to_sec, \clock_nsec
- .endm
-
- /* sec and nsec are modified in place. */
- .macro add_ts sec, nsec, ts_sec, ts_nsec, nsec_to_sec
- /* Add timespec. */
- add \sec, \sec, \ts_sec
- add \nsec, \nsec, \ts_nsec
-
- /* Normalise the new timespec. */
- cmp \nsec, \nsec_to_sec
- b.lt 9999f
- sub \nsec, \nsec, \nsec_to_sec
- add \sec, \sec, #1
-9999:
- cmp \nsec, #0
- b.ge 9998f
- add \nsec, \nsec, \nsec_to_sec
- sub \sec, \sec, #1
-9998:
- .endm
-
- .macro clock_gettime_return, shift=0
- .if \shift == 1
- lsr x11, x11, x12
- .endif
- stp x10, x11, [x1, #TSPEC_TV_SEC]
- mov x0, xzr
- ret
- .endm
-
- .macro jump_slot jumptable, index, label
- .if (. - \jumptable) != 4 * (\index)
- .error "Jump slot index mismatch"
- .endif
- b \label
- .endm
-
- .text
-
-/* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */
-ENTRY(__kernel_gettimeofday)
- .cfi_startproc
- adr vdso_data, _vdso_data
- /* If tv is NULL, skip to the timezone code. */
- cbz x0, 2f
-
- /* Compute the time of day. */
-1: seqcnt_acquire
- syscall_check fail=4f
- ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
- /* w11 = cs_mono_mult, w12 = cs_shift */
- ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
- ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
-
- get_nsec_per_sec res=x9
- lsl x9, x9, x12
-
- get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
- seqcnt_check fail=1b
- get_ts_realtime res_sec=x10, res_nsec=x11, \
- clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
-
- /* Convert ns to us. */
- mov x13, #1000
- lsl x13, x13, x12
- udiv x11, x11, x13
- stp x10, x11, [x0, #TVAL_TV_SEC]
-2:
- /* If tz is NULL, return 0. */
- cbz x1, 3f
- ldp w4, w5, [vdso_data, #VDSO_TZ_MINWEST]
- stp w4, w5, [x1, #TZ_MINWEST]
-3:
- mov x0, xzr
- ret
-4:
- /* Syscall fallback. */
- mov x8, #__NR_gettimeofday
- svc #0
- ret
- .cfi_endproc
-ENDPROC(__kernel_gettimeofday)
-
-#define JUMPSLOT_MAX CLOCK_MONOTONIC_COARSE
-
-/* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
-ENTRY(__kernel_clock_gettime)
- .cfi_startproc
- cmp w0, #JUMPSLOT_MAX
- b.hi syscall
- adr vdso_data, _vdso_data
- adr x_tmp, jumptable
- add x_tmp, x_tmp, w0, uxtw #2
- br x_tmp
-
- ALIGN
-jumptable:
- jump_slot jumptable, CLOCK_REALTIME, realtime
- jump_slot jumptable, CLOCK_MONOTONIC, monotonic
- b syscall
- b syscall
- jump_slot jumptable, CLOCK_MONOTONIC_RAW, monotonic_raw
- jump_slot jumptable, CLOCK_REALTIME_COARSE, realtime_coarse
- jump_slot jumptable, CLOCK_MONOTONIC_COARSE, monotonic_coarse
-
- .if (. - jumptable) != 4 * (JUMPSLOT_MAX + 1)
- .error "Wrong jumptable size"
- .endif
-
- ALIGN
-realtime:
- seqcnt_acquire
- syscall_check fail=syscall
- ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
- /* w11 = cs_mono_mult, w12 = cs_shift */
- ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
- ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
-
- /* All computations are done with left-shifted nsecs. */
- get_nsec_per_sec res=x9
- lsl x9, x9, x12
-
- get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
- seqcnt_check fail=realtime
- get_ts_realtime res_sec=x10, res_nsec=x11, \
- clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
- clock_gettime_return, shift=1
-
- ALIGN
-monotonic:
- seqcnt_acquire
- syscall_check fail=syscall
- ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
- /* w11 = cs_mono_mult, w12 = cs_shift */
- ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
- ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
- ldp x3, x4, [vdso_data, #VDSO_WTM_CLK_SEC]
-
- /* All computations are done with left-shifted nsecs. */
- lsl x4, x4, x12
- get_nsec_per_sec res=x9
- lsl x9, x9, x12
-
- get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
- seqcnt_check fail=monotonic
- get_ts_realtime res_sec=x10, res_nsec=x11, \
- clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
-
- add_ts sec=x10, nsec=x11, ts_sec=x3, ts_nsec=x4, nsec_to_sec=x9
- clock_gettime_return, shift=1
-
- ALIGN
-monotonic_raw:
- seqcnt_acquire
- syscall_check fail=syscall
- ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
- /* w11 = cs_raw_mult, w12 = cs_shift */
- ldp w12, w11, [vdso_data, #VDSO_CS_SHIFT]
- ldp x13, x14, [vdso_data, #VDSO_RAW_TIME_SEC]
-
- /* All computations are done with left-shifted nsecs. */
- get_nsec_per_sec res=x9
- lsl x9, x9, x12
-
- get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
- seqcnt_check fail=monotonic_raw
- get_ts_clock_raw res_sec=x10, res_nsec=x11, \
- clock_nsec=x15, nsec_to_sec=x9
-
- add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9
- clock_gettime_return, shift=1
-
- ALIGN
-realtime_coarse:
- seqcnt_acquire
- ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC]
- seqcnt_check fail=realtime_coarse
- clock_gettime_return
-
- ALIGN
-monotonic_coarse:
- seqcnt_acquire
- ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC]
- ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC]
- seqcnt_check fail=monotonic_coarse
-
- /* Computations are done in (non-shifted) nsecs. */
- get_nsec_per_sec res=x9
- add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9
- clock_gettime_return
-
- ALIGN
-syscall: /* Syscall fallback. */
- mov x8, #__NR_clock_gettime
- svc #0
- ret
- .cfi_endproc
-ENDPROC(__kernel_clock_gettime)
-
-/* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
-ENTRY(__kernel_clock_getres)
- .cfi_startproc
- cmp w0, #CLOCK_REALTIME
- ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
- ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne
- b.ne 1f
-
- adr vdso_data, _vdso_data
- ldr w2, [vdso_data, #CLOCK_REALTIME_RES]
- b 2f
-1:
- cmp w0, #CLOCK_REALTIME_COARSE
- ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
- b.ne 4f
- ldr x2, 5f
-2:
- cbz x1, 3f
- stp xzr, x2, [x1]
-
-3: /* res == NULL. */
- mov w0, wzr
- ret
-
-4: /* Syscall fallback. */
- mov x8, #__NR_clock_getres
- svc #0
- ret
-5:
- .quad CLOCK_COARSE_RES
- .cfi_endproc
-ENDPROC(__kernel_clock_getres)
diff --git a/arch/arm64/kernel/vdso/vgettimeofday.c b/arch/arm64/kernel/vdso/vgettimeofday.c
new file mode 100644
index 000000000000..3c58f19dbdf4
--- /dev/null
+++ b/arch/arm64/kernel/vdso/vgettimeofday.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM64 userspace implementations of gettimeofday() and similar.
+ *
+ * Copyright (C) 2018 ARM Limited
+ *
+ */
+#include <linux/time.h>
+#include <linux/types.h>
+
+int __kernel_clock_gettime(clockid_t clock,
+ struct __kernel_timespec *ts)
+{
+ return __cvdso_clock_gettime(clock, ts);
+}
+
+int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
+ struct timezone *tz)
+{
+ return __cvdso_gettimeofday(tv, tz);
+}
+
+int __kernel_clock_getres(clockid_t clock_id,
+ struct __kernel_timespec *res)
+{
+ return __cvdso_clock_getres(clock_id, res);
+}
+
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-21 9:52 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Vincenzo Frascino
@ 2019-06-24 13:36 ` Will Deacon
2019-06-24 13:59 ` Vincenzo Frascino
2019-06-25 16:18 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Vincenzo Frascino
2019-06-24 13:58 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Catalin Marinas
` (4 subsequent siblings)
5 siblings, 2 replies; 108+ messages in thread
From: Will Deacon @ 2019-06-24 13:36 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
Hi Vincenzo,
On Fri, Jun 21, 2019 at 10:52:31AM +0100, Vincenzo Frascino wrote:
> To take advantage of the commonly defined vdso interface for
> gettimeofday the architectural code requires an adaptation.
>
> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>
> With the new implementation arm64 gains support for CLOCK_BOOTTIME
> and CLOCK_TAI.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> Tested-by: Shijith Thotton <sthotton@marvell.com>
> Tested-by: Andre Przywara <andre.przywara@arm.com>
> ---
> arch/arm64/Kconfig | 2 +
> arch/arm64/include/asm/vdso/gettimeofday.h | 86 ++++++
> arch/arm64/include/asm/vdso/vsyscall.h | 53 ++++
> arch/arm64/include/asm/vdso_datapage.h | 48 ---
> arch/arm64/kernel/asm-offsets.c | 33 +-
> arch/arm64/kernel/vdso.c | 51 +---
> arch/arm64/kernel/vdso/Makefile | 34 ++-
> arch/arm64/kernel/vdso/gettimeofday.S | 334 ---------------------
> arch/arm64/kernel/vdso/vgettimeofday.c | 28 ++
I'm concerned about an apparent semantic change introduced by your patch:
> +static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
> +{
> + u64 res;
> +
> + asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
> +
> + return res;
> +}
vs:
> - .macro get_clock_shifted_nsec res, cycle_last, mult
> - /* Read the virtual counter. */
> - isb
> - mrs x_tmp, cntvct_el0
> - /* Calculate cycle delta and convert to ns. */
> - sub \res, x_tmp, \cycle_last
> - /* We can only guarantee 56 bits of precision. */
> - movn x_tmp, #0xff00, lsl #48
> - and \res, x_tmp, \res
> - mul \res, \res, \mult
> - /*
> - * Fake address dependency from the value computed from the counter
> - * register to subsequent data page accesses so that the sequence
> - * locking also orders the read of the counter.
> - */
> - and x_tmp, \res, xzr
> - add vdso_data, vdso_data, x_tmp
> - .endm
It looks like you're dropping both the preceding ISB (allowing the counter
value to be speculated) and also the subsequent dependency (allowing the
seq lock to be speculated). If I've missed them, apologies, but I couldn't
spot them elsewhere in this patch.
__arch_get_hw_counter should probably be identical to __arch_counter_get_cntvct
to avoid these problems. I guess we don't need to care about the case where
the counter is unstable, since we'll just disable the vDSO altogether on
such systems?
Will
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-24 13:36 ` Will Deacon
@ 2019-06-24 13:59 ` Vincenzo Frascino
2019-06-25 16:18 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Vincenzo Frascino
1 sibling, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-24 13:59 UTC (permalink / raw)
To: Will Deacon
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
On 24/06/2019 14:36, Will Deacon wrote:
> Hi Vincenzo,
>
> On Fri, Jun 21, 2019 at 10:52:31AM +0100, Vincenzo Frascino wrote:
>> To take advantage of the commonly defined vdso interface for
>> gettimeofday the architectural code requires an adaptation.
>>
>> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>>
>> With the new implementation arm64 gains support for CLOCK_BOOTTIME
>> and CLOCK_TAI.
>>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>> Tested-by: Shijith Thotton <sthotton@marvell.com>
>> Tested-by: Andre Przywara <andre.przywara@arm.com>
>> ---
>> arch/arm64/Kconfig | 2 +
>> arch/arm64/include/asm/vdso/gettimeofday.h | 86 ++++++
>> arch/arm64/include/asm/vdso/vsyscall.h | 53 ++++
>> arch/arm64/include/asm/vdso_datapage.h | 48 ---
>> arch/arm64/kernel/asm-offsets.c | 33 +-
>> arch/arm64/kernel/vdso.c | 51 +---
>> arch/arm64/kernel/vdso/Makefile | 34 ++-
>> arch/arm64/kernel/vdso/gettimeofday.S | 334 ---------------------
>> arch/arm64/kernel/vdso/vgettimeofday.c | 28 ++
>
> I'm concerned about an apparent semantic change introduced by your patch:
>
>> +static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
>> +{
>> + u64 res;
>> +
>> + asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
>> +
>> + return res;
>> +}
>
> vs:
>
>> - .macro get_clock_shifted_nsec res, cycle_last, mult
>> - /* Read the virtual counter. */
>> - isb
>> - mrs x_tmp, cntvct_el0
>> - /* Calculate cycle delta and convert to ns. */
>> - sub \res, x_tmp, \cycle_last
>> - /* We can only guarantee 56 bits of precision. */
>> - movn x_tmp, #0xff00, lsl #48
>> - and \res, x_tmp, \res
>> - mul \res, \res, \mult
>> - /*
>> - * Fake address dependency from the value computed from the counter
>> - * register to subsequent data page accesses so that the sequence
>> - * locking also orders the read of the counter.
>> - */
>> - and x_tmp, \res, xzr
>> - add vdso_data, vdso_data, x_tmp
>> - .endm
>
> It looks like you're dropping both the preceding ISB (allowing the counter
> value to be speculated) and also the subsequent dependency (allowing the
> seq lock to be speculated). If I've missed them, apologies, but I couldn't
> spot them elsewhere in this patch.
>
> __arch_get_hw_counter should probably be identical to __arch_counter_get_cntvct
> to avoid these problems. I guess we don't need to care about the case where
> the counter is unstable, since we'll just disable the vDSO altogether on
> such systems?
>
Oops, I forgot to mirror your patch that introduces this change. I will post a
fix in reply to this email.
> Will
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH 1/3] lib/vdso: Delay mask application in do_hres()
2019-06-24 13:36 ` Will Deacon
2019-06-24 13:59 ` Vincenzo Frascino
@ 2019-06-25 16:18 ` Vincenzo Frascino
2019-06-25 16:18 ` [PATCH 2/3] arm64: Fix __arch_get_hw_counter() implementation Vincenzo Frascino
` (2 more replies)
1 sibling, 3 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-25 16:18 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara
do_hres() in the vDSO generic library masks the hw counter value
immediately after reading it.
Postpone the mask application after checking if the syscall fallback is
enabled, in order to be able to detect a possible fallback for the
architectures that have masks smaller than ULLONG_MAX.
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
lib/vdso/gettimeofday.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index ef28cc5d7bff..ee1221ba1d32 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -35,12 +35,12 @@ static int do_hres(const struct vdso_data *vd, clockid_t clk,
do {
seq = vdso_read_begin(vd);
- cycles = __arch_get_hw_counter(vd->clock_mode) &
- vd->mask;
+ cycles = __arch_get_hw_counter(vd->clock_mode);
ns = vdso_ts->nsec;
last = vd->cycle_last;
if (unlikely((s64)cycles < 0))
return clock_gettime_fallback(clk, ts);
+ cycles &= vd->mask;
if (cycles > last)
ns += (cycles - last) * vd->mult;
ns >>= vd->shift;
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH 2/3] arm64: Fix __arch_get_hw_counter() implementation
2019-06-25 16:18 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Vincenzo Frascino
@ 2019-06-25 16:18 ` Vincenzo Frascino
2019-06-25 16:18 ` [PATCH 3/3] arm64: compat: " Vincenzo Frascino
2019-06-25 17:02 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Thomas Gleixner
2 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-25 16:18 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara
Provide the following fixes for the __arch_get_hw_counter()
implementation on arm64:
- Fallback on syscall when an unstable counter is detected.
- Introduce isb()s before and after the counter read to avoid
speculation of the counter value and of the seq lock
respectively.
The second isb() is a temporary solution that will be revisited
in 5.3-rc1.
These fixes restore the semantics that __arch_counter_get_cntvct()
had on arm64.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/arm64/include/asm/vdso/gettimeofday.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
index 447ef417de45..b08f476b72b4 100644
--- a/arch/arm64/include/asm/vdso/gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/gettimeofday.h
@@ -10,6 +10,8 @@
#include <asm/unistd.h>
#include <uapi/linux/time.h>
+#define __VDSO_USE_SYSCALL ULLONG_MAX
+
#define VDSO_HAS_CLOCK_GETRES 1
static __always_inline
@@ -68,7 +70,24 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
{
u64 res;
+ /*
+ * clock_mode == 0 implies that vDSO are enabled otherwise
+ * fallback on syscall.
+ */
+ if (clock_mode)
+ return __VDSO_USE_SYSCALL;
+
+ /*
+ * This isb() is required to prevent that the counter value
+ * is speculated.
+ */
+ isb();
asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
+ /*
+ * This isb() is required to prevent that the seq lock is
+ * speculated.#
+ */
+ isb();
return res;
}
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH 3/3] arm64: compat: Fix __arch_get_hw_counter() implementation
2019-06-25 16:18 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Vincenzo Frascino
2019-06-25 16:18 ` [PATCH 2/3] arm64: Fix __arch_get_hw_counter() implementation Vincenzo Frascino
@ 2019-06-25 16:18 ` Vincenzo Frascino
2019-06-25 17:02 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Thomas Gleixner
2 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-25 16:18 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara
Provide the following fixes for the __arch_get_hw_counter()
implementation on arm64:
- Fallback on syscall when an unstable counter is detected.
- Introduce isb()s before and after the counter read to avoid
speculation of the counter value and of the seq lock
respectively.
The second isb() is a temporary solution that will be revisited
in 5.3-rc1.
These fixes restore the semantics that __arch_counter_get_cntvct()
had on arm64.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
.../include/asm/vdso/compat_gettimeofday.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
index 93dbd935b66d..f4812777f5c5 100644
--- a/arch/arm64/include/asm/vdso/compat_gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -12,6 +12,8 @@
#include <asm/vdso/compat_barrier.h>
+#define __VDSO_USE_SYSCALL ULLONG_MAX
+
#define VDSO_HAS_CLOCK_GETRES 1
static __always_inline
@@ -74,8 +76,24 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
{
u64 res;
+ /*
+ * clock_mode == 0 implies that vDSO are enabled otherwise
+ * fallback on syscall.
+ */
+ if (clock_mode)
+ return __VDSO_USE_SYSCALL;
+
+ /*
+ * This isb() is required to prevent that the counter value
+ * is speculated.
+ */
isb();
asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (res));
+ /*
+ * This isb() is required to prevent that the seq lock is
+ * speculated.
+ */
+ isb();
return res;
}
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH 1/3] lib/vdso: Delay mask application in do_hres()
2019-06-25 16:18 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Vincenzo Frascino
2019-06-25 16:18 ` [PATCH 2/3] arm64: Fix __arch_get_hw_counter() implementation Vincenzo Frascino
2019-06-25 16:18 ` [PATCH 3/3] arm64: compat: " Vincenzo Frascino
@ 2019-06-25 17:02 ` Thomas Gleixner
2019-06-25 18:27 ` Thomas Gleixner
2019-06-26 6:38 ` Thomas Gleixner
2 siblings, 2 replies; 108+ messages in thread
From: Thomas Gleixner @ 2019-06-25 17:02 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
catalin.marinas, Will Deacon, Arnd Bergmann, linux, Ralf Baechle,
paul.burton, Daniel Lezcano, salyzyn, pcc, shuah, 0x7f454c46,
linux, huw, sthotton, andre.przywara, Andy Lutomirski
On Tue, 25 Jun 2019, Vincenzo Frascino wrote:
CC+ Andy
> do_hres() in the vDSO generic library masks the hw counter value
> immediately after reading it.
>
> Postpone the mask application after checking if the syscall fallback is
> enabled, in order to be able to detect a possible fallback for the
> architectures that have masks smaller than ULLONG_MAX.
Right. This only worked on x86 because the mask is there ULLONG_MAX for all
VDSO capable clocksources, i.e. that ever worked just by chance.
As we talked about that already yesterday, I tested this on a couple of
machines and as expected the outcome is uarch dependent. Minimal deviations
to both sides and some machines do not show any change at all. I doubt it's
possible to come up with a solution which makes all uarchs go faster
magically.
Though, thinking about it, we could remove the mask operation completely on
X86. /me runs tests
Thanks,
tglx
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> ---
> lib/vdso/gettimeofday.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> index ef28cc5d7bff..ee1221ba1d32 100644
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -35,12 +35,12 @@ static int do_hres(const struct vdso_data *vd, clockid_t clk,
>
> do {
> seq = vdso_read_begin(vd);
> - cycles = __arch_get_hw_counter(vd->clock_mode) &
> - vd->mask;
> + cycles = __arch_get_hw_counter(vd->clock_mode);
> ns = vdso_ts->nsec;
> last = vd->cycle_last;
> if (unlikely((s64)cycles < 0))
> return clock_gettime_fallback(clk, ts);
> + cycles &= vd->mask;
> if (cycles > last)
> ns += (cycles - last) * vd->mult;
> ns >>= vd->shift;
> --
> 2.22.0
>
>
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH 1/3] lib/vdso: Delay mask application in do_hres()
2019-06-25 17:02 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Thomas Gleixner
@ 2019-06-25 18:27 ` Thomas Gleixner
2019-06-25 20:15 ` Andy Lutomirski
2019-06-26 6:38 ` Thomas Gleixner
1 sibling, 1 reply; 108+ messages in thread
From: Thomas Gleixner @ 2019-06-25 18:27 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
catalin.marinas, Will Deacon, Arnd Bergmann, linux, Ralf Baechle,
paul.burton, Daniel Lezcano, salyzyn, pcc, shuah, 0x7f454c46,
linux, huw, sthotton, andre.przywara, Andy Lutomirski,
Peter Zijlstra
On Tue, 25 Jun 2019, Thomas Gleixner wrote:
> On Tue, 25 Jun 2019, Vincenzo Frascino wrote:
>
> CC+ Andy
>
> > do_hres() in the vDSO generic library masks the hw counter value
> > immediately after reading it.
> >
> > Postpone the mask application after checking if the syscall fallback is
> > enabled, in order to be able to detect a possible fallback for the
> > architectures that have masks smaller than ULLONG_MAX.
>
> Right. This only worked on x86 because the mask is there ULLONG_MAX for all
> VDSO capable clocksources, i.e. that ever worked just by chance.
>
> As we talked about that already yesterday, I tested this on a couple of
> machines and as expected the outcome is uarch dependent. Minimal deviations
> to both sides and some machines do not show any change at all. I doubt it's
> possible to come up with a solution which makes all uarchs go faster
> magically.
>
> Though, thinking about it, we could remove the mask operation completely on
> X86. /me runs tests
Unsurprisingly the results vary. Two uarchs do not care, but they did not
care about moving the mask either. The other two gain performance and the
last one falls back to the state before moving the mask. So in general it
looks like a worthwhile optimization.
Thanks,
tglx
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH 1/3] lib/vdso: Delay mask application in do_hres()
2019-06-25 18:27 ` Thomas Gleixner
@ 2019-06-25 20:15 ` Andy Lutomirski
2019-06-25 22:24 ` Thomas Gleixner
0 siblings, 1 reply; 108+ messages in thread
From: Andy Lutomirski @ 2019-06-25 20:15 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Vincenzo Frascino, linux-arch, LAK, LKML, linux-mips,
open list:KERNEL SELFTEST FRAMEWORK, Catalin Marinas,
Will Deacon, Arnd Bergmann, Russell King, Ralf Baechle,
Paul Burton, Daniel Lezcano, Mark Salyzyn, Peter Collingbourne,
Shuah Khan, Dmitry Safonov, Rasmus Villemoes, Huw Davies,
Shijith Thotton, Andre Przywara, Andy Lutomirski, Peter Zijlstra
On Tue, Jun 25, 2019 at 11:27 AM Thomas Gleixner <tglx@linutronix.de> wrote:
>
> On Tue, 25 Jun 2019, Thomas Gleixner wrote:
>
> > On Tue, 25 Jun 2019, Vincenzo Frascino wrote:
> >
> > CC+ Andy
> >
> > > do_hres() in the vDSO generic library masks the hw counter value
> > > immediately after reading it.
> > >
> > > Postpone the mask application after checking if the syscall fallback is
> > > enabled, in order to be able to detect a possible fallback for the
> > > architectures that have masks smaller than ULLONG_MAX.
> >
> > Right. This only worked on x86 because the mask is there ULLONG_MAX for all
> > VDSO capable clocksources, i.e. that ever worked just by chance.
> >
> > As we talked about that already yesterday, I tested this on a couple of
> > machines and as expected the outcome is uarch dependent. Minimal deviations
> > to both sides and some machines do not show any change at all. I doubt it's
> > possible to come up with a solution which makes all uarchs go faster
> > magically.
> >
> > Though, thinking about it, we could remove the mask operation completely on
> > X86. /me runs tests
>
> Unsurprisingly the results vary. Two uarchs do not care, but they did not
> care about moving the mask either. The other two gain performance and the
> last one falls back to the state before moving the mask. So in general it
> looks like a worthwhile optimization.
>
At one point, I contemplated a different approach: have the "get the
counter" routine return 0 and then do if (unlikely(cycles <= last))
goto fallback. This will remove one branch from the hot path. I got
dubious results when I tried benchmarking it, probably because the
branch in question was always correctly predicted.
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH 1/3] lib/vdso: Delay mask application in do_hres()
2019-06-25 20:15 ` Andy Lutomirski
@ 2019-06-25 22:24 ` Thomas Gleixner
0 siblings, 0 replies; 108+ messages in thread
From: Thomas Gleixner @ 2019-06-25 22:24 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Vincenzo Frascino, linux-arch, LAK, LKML, linux-mips,
open list:KERNEL SELFTEST FRAMEWORK, Catalin Marinas,
Will Deacon, Arnd Bergmann, Russell King, Ralf Baechle,
Paul Burton, Daniel Lezcano, Mark Salyzyn, Peter Collingbourne,
Shuah Khan, Dmitry Safonov, Rasmus Villemoes, Huw Davies,
Shijith Thotton, Andre Przywara, Peter Zijlstra
On Tue, 25 Jun 2019, Andy Lutomirski wrote:
> On Tue, Jun 25, 2019 at 11:27 AM Thomas Gleixner <tglx@linutronix.de> wrote:
> >
> > On Tue, 25 Jun 2019, Thomas Gleixner wrote:
> >
> > > On Tue, 25 Jun 2019, Vincenzo Frascino wrote:
> > >
> > > CC+ Andy
> > >
> > > > do_hres() in the vDSO generic library masks the hw counter value
> > > > immediately after reading it.
> > > >
> > > > Postpone the mask application after checking if the syscall fallback is
> > > > enabled, in order to be able to detect a possible fallback for the
> > > > architectures that have masks smaller than ULLONG_MAX.
> > >
> > > Right. This only worked on x86 because the mask is there ULLONG_MAX for all
> > > VDSO capable clocksources, i.e. that ever worked just by chance.
> > >
> > > As we talked about that already yesterday, I tested this on a couple of
> > > machines and as expected the outcome is uarch dependent. Minimal deviations
> > > to both sides and some machines do not show any change at all. I doubt it's
> > > possible to come up with a solution which makes all uarchs go faster
> > > magically.
> > >
> > > Though, thinking about it, we could remove the mask operation completely on
> > > X86. /me runs tests
> >
> > Unsurprisingly the results vary. Two uarchs do not care, but they did not
> > care about moving the mask either. The other two gain performance and the
> > last one falls back to the state before moving the mask. So in general it
> > looks like a worthwhile optimization.
> >
>
> At one point, I contemplated a different approach: have the "get the
> counter" routine return 0 and then do if (unlikely(cycles <= last))
> goto fallback. This will remove one branch from the hot path. I got
> dubious results when I tried benchmarking it, probably because the
> branch in question was always correctly predicted.
Just tried and it's the same thing. One drops, one does not care and one
gains. Did not test the other two as they are asleep already. There is no
universal cure for this I fear. I even tried a uarch optimized build a few
days ago which came out worse than the generic one...
The issue in that code path is the fencing of the TSC read. That seems to
screw up every uarch in a different way.
If you have no objections I'll queue this change (moving the mask) along
with the other two ARM64 ones to unbreak the fallback path for these errata
inflicted machines.
Thanks,
tglx
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH 1/3] lib/vdso: Delay mask application in do_hres()
2019-06-25 17:02 ` [PATCH 1/3] lib/vdso: Delay mask application in do_hres() Thomas Gleixner
2019-06-25 18:27 ` Thomas Gleixner
@ 2019-06-26 6:38 ` Thomas Gleixner
2019-06-26 9:25 ` Vincenzo Frascino
1 sibling, 1 reply; 108+ messages in thread
From: Thomas Gleixner @ 2019-06-26 6:38 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
catalin.marinas, Will Deacon, Arnd Bergmann, linux, Ralf Baechle,
paul.burton, Daniel Lezcano, salyzyn, pcc, shuah, 0x7f454c46,
linux, huw, sthotton, andre.przywara, Andy Lutomirski
On Tue, 25 Jun 2019, Thomas Gleixner wrote:
> On Tue, 25 Jun 2019, Vincenzo Frascino wrote:
> > do_hres() in the vDSO generic library masks the hw counter value
> > immediately after reading it.
> >
> > Postpone the mask application after checking if the syscall fallback is
> > enabled, in order to be able to detect a possible fallback for the
> > architectures that have masks smaller than ULLONG_MAX.
>
> Right. This only worked on x86 because the mask is there ULLONG_MAX for all
> VDSO capable clocksources, i.e. that ever worked just by chance.
But it's actually worse than that:
> > + cycles &= vd->mask;
> > if (cycles > last)
> > ns += (cycles - last) * vd->mult;
> > ns >>= vd->shift;
This is broken for any clocksource which can legitimately wrap around. The
core timekeeping does the right thing:
(cycles - last) & mask
That makes sure that a wraparound is correctly handled. With the above the
wrap around would be ignored due to
if (cycles > last)
Stupid me. I should have added big fat comments to the x86 vdso why this
all works correctly and only correctly for the x86 crud. That was part of
squeezing the last cycles out of the vdso.
Sorry for not noticing earlier. Working on a fix.
Thanks,
tglx
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH 1/3] lib/vdso: Delay mask application in do_hres()
2019-06-26 6:38 ` Thomas Gleixner
@ 2019-06-26 9:25 ` Vincenzo Frascino
2019-06-26 10:02 ` lib/vdso: Make delta calculation work correctly Thomas Gleixner
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-26 9:25 UTC (permalink / raw)
To: Thomas Gleixner
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
catalin.marinas, Will Deacon, Arnd Bergmann, linux, Ralf Baechle,
paul.burton, Daniel Lezcano, salyzyn, pcc, shuah, 0x7f454c46,
linux, huw, sthotton, andre.przywara, Andy Lutomirski
Hi Thomas,
On 26/06/2019 07:38, Thomas Gleixner wrote:
> On Tue, 25 Jun 2019, Thomas Gleixner wrote:
>> On Tue, 25 Jun 2019, Vincenzo Frascino wrote:
>>> do_hres() in the vDSO generic library masks the hw counter value
>>> immediately after reading it.
>>>
>>> Postpone the mask application after checking if the syscall fallback is
>>> enabled, in order to be able to detect a possible fallback for the
>>> architectures that have masks smaller than ULLONG_MAX.
>>
>> Right. This only worked on x86 because the mask is there ULLONG_MAX for all
>> VDSO capable clocksources, i.e. that ever worked just by chance.
>
> But it's actually worse than that:
>
>>> + cycles &= vd->mask;
>>> if (cycles > last)
>>> ns += (cycles - last) * vd->mult;
>>> ns >>= vd->shift;
>
> This is broken for any clocksource which can legitimately wrap around. The
> core timekeeping does the right thing:
>
> (cycles - last) & mask
>
> That makes sure that a wraparound is correctly handled. With the above the
> wrap around would be ignored due to
>
> if (cycles > last)
>
You are right. Thanks for spotting it.
...
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* lib/vdso: Make delta calculation work correctly
2019-06-26 9:25 ` Vincenzo Frascino
@ 2019-06-26 10:02 ` Thomas Gleixner
2019-06-26 11:08 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Thomas Gleixner @ 2019-06-26 10:02 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
catalin.marinas, Will Deacon, Arnd Bergmann, linux, Ralf Baechle,
paul.burton, Daniel Lezcano, salyzyn, pcc, shuah, 0x7f454c46,
linux, huw, sthotton, andre.przywara, Andy Lutomirski
The x86 vdso implementation on which the generic vdso library is based on
has subtle (unfortunately undocumented) twists:
1) The code assumes that the clocksource mask is U64_MAX which means that
no bits are masked. Which is true for any valid x86 VDSO clocksource.
Stupidly it still did the mask operation for no reason and at the wrong
place right after reading the clocksource.
2) It contains a sanity check to catch the case where slightly
unsynchronized TSC values can be overserved which would cause the delta
calculation to make a huge jump. It therefore checks whether the
current TSC value is larger than the value on which the current
conversion is based on. If it's not larger the base value is used to
prevent time jumps.
#1 Is not only stupid for the X86 case because it does the masking for no
reason it is also completely wrong for clocksources with a smaller mask
which can legitimately wrap around during a conversion period. The core
timekeeping code does it correct by applying the mask after the delta
calculation:
(now - base) & mask
#2 is equally broken for clocksources which have smaller masks and can wrap
around during a conversion period because there the now > base check is
just wrong and causes stale time stamps and time going backwards issues.
Unbreak it by:
1) Removing the mask operation from the clocksource read which makes the
fallback detection work for all clocksources
2) Replacing the conditional delta calculation with a overrideable inline
function.
#2 could reuse clocksource_delta() from the timekeeping code but that
results in a significant performance hit for the x86 VSDO. The timekeeping
core code must have the non optimized version as it has to operate
correctly with clocksources which have smaller masks as well to handle the
case where TSC is discarded as timekeeper clocksource and replaced by HPET
or pmtimer. For the VDSO there is no replacement clocksource. If TSC is
unusable the syscall is enforced which does the right thing.
To accomodate to the needs of various architectures provide an overrideable
inline function which defaults to the regular delta calculation with
masking:
(now - base) & mask
Override it for x86 with the non-masking and checking version.
This unbreaks the ARM64 syscall fallback operation, allows to use
clocksources with arbitrary width and preserves the performance
optimization for x86.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/vdso/gettimeofday.h | 27 +++++++++++++++++++++++++++
lib/vdso/gettimeofday.c | 19 +++++++++++++++----
2 files changed, 42 insertions(+), 4 deletions(-)
--- a/arch/x86/include/asm/vdso/gettimeofday.h
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -229,6 +229,33 @@ static __always_inline const struct vdso
return __vdso_data;
}
+/*
+ * x86 specific delta calculation.
+ *
+ * The regular implementation assumes that clocksource reads are globally
+ * monotonic. The TSC can be slightly off across sockets which can cause
+ * the regular delta calculation (@cycles - @last) to return a huge time
+ * jump.
+ *
+ * Therefore it needs to be verified that @cycles are greater than
+ * @last. If not then use @last, which is the base time of the current
+ * conversion period.
+ *
+ * This variant also removes the masking of the subtraction because the
+ * clocksource mask of all VDSO capable clocksources on x86 is U64_MAX
+ * which would result in a pointless operation. The compiler cannot
+ * optimize it away as the mask comes from the vdso data and is not compile
+ * time constant.
+ */
+static __always_inline
+u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
+{
+ if (cycles > last)
+ return (cycles - last) * mult;
+ return 0;
+}
+#define vdso_calc_delta vdso_calc_delta
+
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -26,6 +26,18 @@
#include <asm/vdso/gettimeofday.h>
#endif /* ENABLE_COMPAT_VDSO */
+#ifndef vdso_calc_delta
+/*
+ * Default implementation which works for all sane clocksources. That
+ * obviously excludes x86/TSC.
+ */
+static __always_inline
+u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
+{
+ return ((cyles - last) & mask) * mult;
+}
+#endif
+
static int do_hres(const struct vdso_data *vd, clockid_t clk,
struct __kernel_timespec *ts)
{
@@ -35,14 +47,13 @@ static int do_hres(const struct vdso_dat
do {
seq = vdso_read_begin(vd);
- cycles = __arch_get_hw_counter(vd->clock_mode) &
- vd->mask;
+ cycles = __arch_get_hw_counter(vd->clock_mode);
ns = vdso_ts->nsec;
last = vd->cycle_last;
if (unlikely((s64)cycles < 0))
return clock_gettime_fallback(clk, ts);
- if (cycles > last)
- ns += (cycles - last) * vd->mult;
+
+ ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
ns >>= vd->shift;
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vd, seq)));
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: lib/vdso: Make delta calculation work correctly
2019-06-26 10:02 ` lib/vdso: Make delta calculation work correctly Thomas Gleixner
@ 2019-06-26 11:08 ` Vincenzo Frascino
0 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-26 11:08 UTC (permalink / raw)
To: Thomas Gleixner
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
catalin.marinas, Will Deacon, Arnd Bergmann, linux, Ralf Baechle,
paul.burton, Daniel Lezcano, salyzyn, pcc, shuah, 0x7f454c46,
linux, huw, sthotton, andre.przywara, Andy Lutomirski
Hi Thomas,
On 26/06/2019 11:02, Thomas Gleixner wrote:
> The x86 vdso implementation on which the generic vdso library is based on
> has subtle (unfortunately undocumented) twists:
>
> 1) The code assumes that the clocksource mask is U64_MAX which means that
> no bits are masked. Which is true for any valid x86 VDSO clocksource.
> Stupidly it still did the mask operation for no reason and at the wrong
> place right after reading the clocksource.
>
> 2) It contains a sanity check to catch the case where slightly
> unsynchronized TSC values can be overserved which would cause the delta
> calculation to make a huge jump. It therefore checks whether the
> current TSC value is larger than the value on which the current
> conversion is based on. If it's not larger the base value is used to
> prevent time jumps.
>
> #1 Is not only stupid for the X86 case because it does the masking for no
> reason it is also completely wrong for clocksources with a smaller mask
> which can legitimately wrap around during a conversion period. The core
> timekeeping code does it correct by applying the mask after the delta
> calculation:
>
> (now - base) & mask
>
> #2 is equally broken for clocksources which have smaller masks and can wrap
> around during a conversion period because there the now > base check is
> just wrong and causes stale time stamps and time going backwards issues.
>
> Unbreak it by:
>
> 1) Removing the mask operation from the clocksource read which makes the
> fallback detection work for all clocksources
>
> 2) Replacing the conditional delta calculation with a overrideable inline
> function.
>
> #2 could reuse clocksource_delta() from the timekeeping code but that
> results in a significant performance hit for the x86 VSDO. The timekeeping
> core code must have the non optimized version as it has to operate
> correctly with clocksources which have smaller masks as well to handle the
> case where TSC is discarded as timekeeper clocksource and replaced by HPET
> or pmtimer. For the VDSO there is no replacement clocksource. If TSC is
> unusable the syscall is enforced which does the right thing.
>
> To accomodate to the needs of various architectures provide an overrideable
> inline function which defaults to the regular delta calculation with
> masking:
>
> (now - base) & mask
>
> Override it for x86 with the non-masking and checking version.
>
> This unbreaks the ARM64 syscall fallback operation, allows to use
> clocksources with arbitrary width and preserves the performance
> optimization for x86.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
A part a typo that leads to compilation errors on non-x86 platforms the rest
looks fine by me.
I tested it on arm64 and behaves correctly.
With this:
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> ---
> arch/x86/include/asm/vdso/gettimeofday.h | 27 +++++++++++++++++++++++++++
> lib/vdso/gettimeofday.c | 19 +++++++++++++++----
> 2 files changed, 42 insertions(+), 4 deletions(-)
>
> --- a/arch/x86/include/asm/vdso/gettimeofday.h
> +++ b/arch/x86/include/asm/vdso/gettimeofday.h
> @@ -229,6 +229,33 @@ static __always_inline const struct vdso
> return __vdso_data;
> }
>
> +/*
> + * x86 specific delta calculation.
> + *
> + * The regular implementation assumes that clocksource reads are globally
> + * monotonic. The TSC can be slightly off across sockets which can cause
> + * the regular delta calculation (@cycles - @last) to return a huge time
> + * jump.
> + *
> + * Therefore it needs to be verified that @cycles are greater than
> + * @last. If not then use @last, which is the base time of the current
> + * conversion period.
> + *
> + * This variant also removes the masking of the subtraction because the
> + * clocksource mask of all VDSO capable clocksources on x86 is U64_MAX
> + * which would result in a pointless operation. The compiler cannot
> + * optimize it away as the mask comes from the vdso data and is not compile
> + * time constant.
> + */
> +static __always_inline
> +u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
> +{
> + if (cycles > last)
> + return (cycles - last) * mult;
> + return 0;
> +}
> +#define vdso_calc_delta vdso_calc_delta
> +
> #endif /* !__ASSEMBLY__ */
>
> #endif /* __ASM_VDSO_GETTIMEOFDAY_H */
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -26,6 +26,18 @@
> #include <asm/vdso/gettimeofday.h>
> #endif /* ENABLE_COMPAT_VDSO */
>
> +#ifndef vdso_calc_delta
> +/*
> + * Default implementation which works for all sane clocksources. That
> + * obviously excludes x86/TSC.
> + */
> +static __always_inline
> +u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
> +{
> + return ((cyles - last) & mask) * mult;
Typo here:
s/cyles/cycles/
> +}
> +#endif
> +
> static int do_hres(const struct vdso_data *vd, clockid_t clk,
> struct __kernel_timespec *ts)
> {
> @@ -35,14 +47,13 @@ static int do_hres(const struct vdso_dat
>
> do {
> seq = vdso_read_begin(vd);
> - cycles = __arch_get_hw_counter(vd->clock_mode) &
> - vd->mask;
> + cycles = __arch_get_hw_counter(vd->clock_mode);
> ns = vdso_ts->nsec;
> last = vd->cycle_last;
> if (unlikely((s64)cycles < 0))
> return clock_gettime_fallback(clk, ts);
> - if (cycles > last)
> - ns += (cycles - last) * vd->mult;
> +
> + ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
> ns >>= vd->shift;
> sec = vdso_ts->sec;
> } while (unlikely(vdso_read_retry(vd, seq)));
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-21 9:52 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Vincenzo Frascino
2019-06-24 13:36 ` Will Deacon
@ 2019-06-24 13:58 ` Catalin Marinas
2019-06-25 15:33 ` Dave Martin
` (3 subsequent siblings)
5 siblings, 0 replies; 108+ messages in thread
From: Catalin Marinas @ 2019-06-24 13:58 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
On Fri, Jun 21, 2019 at 10:52:31AM +0100, Vincenzo Frascino wrote:
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index 947e39896e28..9e4b7ccbab2f 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -25,13 +25,13 @@
> #include <linux/kvm_host.h>
> #include <linux/preempt.h>
> #include <linux/suspend.h>
> +#include <vdso/datapage.h>
> #include <asm/cpufeature.h>
> #include <asm/fixmap.h>
> #include <asm/thread_info.h>
> #include <asm/memory.h>
> #include <asm/smp_plat.h>
> #include <asm/suspend.h>
> -#include <asm/vdso_datapage.h>
> #include <linux/kbuild.h>
> #include <linux/arm-smccc.h>
>
> @@ -100,17 +100,28 @@ int main(void)
> DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
> DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
> BLANK();
> - DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last));
> - DEFINE(VDSO_RAW_TIME_SEC, offsetof(struct vdso_data, raw_time_sec));
> - DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec));
> - DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec));
> - DEFINE(VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec));
> - DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec));
> - DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count));
> - DEFINE(VDSO_CS_MONO_MULT, offsetof(struct vdso_data, cs_mono_mult));
> - DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift));
> + DEFINE(VDSO_SEQ, offsetof(struct vdso_data, seq));
> + DEFINE(VDSO_CLK_MODE, offsetof(struct vdso_data, clock_mode));
> + DEFINE(VDSO_CYCLE_LAST, offsetof(struct vdso_data, cycle_last));
> + DEFINE(VDSO_MASK, offsetof(struct vdso_data, mask));
> + DEFINE(VDSO_MULT, offsetof(struct vdso_data, mult));
> + DEFINE(VDSO_SHIFT, offsetof(struct vdso_data, shift));
> + DEFINE(VDSO_REALTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].sec));
> + DEFINE(VDSO_REALTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].nsec));
> + DEFINE(VDSO_MONO_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].sec));
> + DEFINE(VDSO_MONO_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].nsec));
> + DEFINE(VDSO_MONO_RAW_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].sec));
> + DEFINE(VDSO_MONO_RAW_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].nsec));
> + DEFINE(VDSO_BOOTTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].sec));
> + DEFINE(VDSO_BOOTTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].nsec));
> + DEFINE(VDSO_TAI_SEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].sec));
> + DEFINE(VDSO_TAI_NSEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].nsec));
> + DEFINE(VDSO_RT_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].sec));
> + DEFINE(VDSO_RT_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].nsec));
> + DEFINE(VDSO_MONO_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].sec));
> + DEFINE(VDSO_MONO_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].nsec));
> DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest));
> - DEFINE(VDSO_USE_SYSCALL, offsetof(struct vdso_data, use_syscall));
> + DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
> BLANK();
> DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec));
> DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
Now that we are moving this to C, do we actually need the asm-offsets?
If not, here's a clean-up patch:
---------------8<--------------------------------------
From 7e818178a8b225b522fe547cf00ba8508d4cdcf0 Mon Sep 17 00:00:00 2001
From: Catalin Marinas <catalin.marinas@arm.com>
Date: Mon, 24 Jun 2019 14:12:48 +0100
Subject: [PATCH] arm64: vdso: Remove unnecessary asm-offsets.c definitions
Since the VDSO code is moving to C from assembly, there is no need to
define and maintain the corresponding asm offsets.
Fixes: 28b1a824a4f4 ("arm64: vdso: Substitute gettimeofday() with C implementation")
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/asm-offsets.c | 39 ---------------------------------
1 file changed, 39 deletions(-)
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index e6f7409a78a4..214685760e1c 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -14,7 +14,6 @@
#include <linux/kvm_host.h>
#include <linux/preempt.h>
#include <linux/suspend.h>
-#include <vdso/datapage.h>
#include <asm/cpufeature.h>
#include <asm/fixmap.h>
#include <asm/thread_info.h>
@@ -86,44 +85,6 @@ int main(void)
BLANK();
DEFINE(PREEMPT_DISABLE_OFFSET, PREEMPT_DISABLE_OFFSET);
BLANK();
- DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
- DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
- DEFINE(CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_RAW);
- DEFINE(CLOCK_REALTIME_RES, offsetof(struct vdso_data, hrtimer_res));
- DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
- DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE);
- DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
- DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
- BLANK();
- DEFINE(VDSO_SEQ, offsetof(struct vdso_data, seq));
- DEFINE(VDSO_CLK_MODE, offsetof(struct vdso_data, clock_mode));
- DEFINE(VDSO_CYCLE_LAST, offsetof(struct vdso_data, cycle_last));
- DEFINE(VDSO_MASK, offsetof(struct vdso_data, mask));
- DEFINE(VDSO_MULT, offsetof(struct vdso_data, mult));
- DEFINE(VDSO_SHIFT, offsetof(struct vdso_data, shift));
- DEFINE(VDSO_REALTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].sec));
- DEFINE(VDSO_REALTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].nsec));
- DEFINE(VDSO_MONO_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].sec));
- DEFINE(VDSO_MONO_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].nsec));
- DEFINE(VDSO_MONO_RAW_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].sec));
- DEFINE(VDSO_MONO_RAW_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].nsec));
- DEFINE(VDSO_BOOTTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].sec));
- DEFINE(VDSO_BOOTTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].nsec));
- DEFINE(VDSO_TAI_SEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].sec));
- DEFINE(VDSO_TAI_NSEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].nsec));
- DEFINE(VDSO_RT_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].sec));
- DEFINE(VDSO_RT_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].nsec));
- DEFINE(VDSO_MONO_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].sec));
- DEFINE(VDSO_MONO_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].nsec));
- DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest));
- DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
- BLANK();
- DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec));
- DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
- BLANK();
- DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
- DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
- BLANK();
DEFINE(CPU_BOOT_STACK, offsetof(struct secondary_data, stack));
DEFINE(CPU_BOOT_TASK, offsetof(struct secondary_data, task));
BLANK();
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-21 9:52 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Vincenzo Frascino
2019-06-24 13:36 ` Will Deacon
2019-06-24 13:58 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Catalin Marinas
@ 2019-06-25 15:33 ` Dave Martin
2019-06-26 13:27 ` Vincenzo Frascino
2019-06-25 17:43 ` [PATCH] arm64: vdso: Fix compilation with clang < 8 Vincenzo Frascino
` (2 subsequent siblings)
5 siblings, 1 reply; 108+ messages in thread
From: Dave Martin @ 2019-06-25 15:33 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Shuah Khan, Andre Przywara, Arnd Bergmann,
Huw Davies, Catalin Marinas, Daniel Lezcano, Will Deacon,
Russell King, Ralf Baechle, Mark Salyzyn, Paul Burton,
Dmitry Safonov, Rasmus Villemoes, Thomas Gleixner,
Shijith Thotton, Peter Collingbourne
On Fri, Jun 21, 2019 at 10:52:31AM +0100, Vincenzo Frascino wrote:
> To take advantage of the commonly defined vdso interface for
> gettimeofday the architectural code requires an adaptation.
>
> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>
> With the new implementation arm64 gains support for CLOCK_BOOTTIME
> and CLOCK_TAI.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> Tested-by: Shijith Thotton <sthotton@marvell.com>
> Tested-by: Andre Przywara <andre.przywara@arm.com>
[...]
> diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
> new file mode 100644
> index 000000000000..bc3cb6738051
> --- /dev/null
> +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
> @@ -0,0 +1,86 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2018 ARM Limited
> + */
> +#ifndef __ASM_VDSO_GETTIMEOFDAY_H
> +#define __ASM_VDSO_GETTIMEOFDAY_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#include <asm/unistd.h>
> +#include <uapi/linux/time.h>
> +
> +#define VDSO_HAS_CLOCK_GETRES 1
> +
> +static __always_inline int gettimeofday_fallback(
> + struct __kernel_old_timeval *_tv,
> + struct timezone *_tz)
Out of interest, does this need to be __always_inline?
> +{
> + register struct timezone *tz asm("x1") = _tz;
> + register struct __kernel_old_timeval *tv asm("x0") = _tv;
> + register long ret asm ("x0");
> + register long nr asm("x8") = __NR_gettimeofday;
> +
> + asm volatile(
> + " svc #0\n"
Can inlining of this function result in non-trivial expressions being
substituted for _tz or _tv?
A function call can clobber register asm vars that are assigned to the
caller-save registers or that the PCS uses for function arguments, and
the situations where this can happen are poorly defined AFAICT. There's
also no reliable way to detect at build time whether the compiler has
done this, and no robust way to stop if happening.
(IMHO the compiler is wrong to do this, but it's been that way for ever,
and I think I saw GCC 9 show this behaviour recently when I was
investigating something related.)
To be safe, it's better to put this out of line, or remove the reg asm()
specifiers, mark x0-x18 and lr as clobbered here (so that the compiler
doesn't map arguments to them), and put movs in the asm to move things
into the right registers. The syscall number can be passed with an "i"
constraint. (And yes, this sucks.)
If the code this is inlined in is simple enough though, we can be fairly
confident of getting away with it.
[...]
Cheers
---Dave
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-25 15:33 ` Dave Martin
@ 2019-06-26 13:27 ` Vincenzo Frascino
2019-06-26 16:14 ` Dave Martin
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-26 13:27 UTC (permalink / raw)
To: Dave Martin
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Shuah Khan, Andre Przywara, Arnd Bergmann,
Huw Davies, Catalin Marinas, Daniel Lezcano, Will Deacon,
Russell King, Ralf Baechle, Mark Salyzyn, Paul Burton,
Dmitry Safonov, Rasmus Villemoes, Thomas Gleixner,
Shijith Thotton, Peter Collingbourne
Hi Dave,
On 25/06/2019 16:33, Dave Martin wrote:
> On Fri, Jun 21, 2019 at 10:52:31AM +0100, Vincenzo Frascino wrote:
>> To take advantage of the commonly defined vdso interface for
>> gettimeofday the architectural code requires an adaptation.
>>
>> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>>
>> With the new implementation arm64 gains support for CLOCK_BOOTTIME
>> and CLOCK_TAI.
>>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>> Tested-by: Shijith Thotton <sthotton@marvell.com>
>> Tested-by: Andre Przywara <andre.przywara@arm.com>
>
> [...]
>
>> diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
>> new file mode 100644
>> index 000000000000..bc3cb6738051
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
>> @@ -0,0 +1,86 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Copyright (C) 2018 ARM Limited
>> + */
>> +#ifndef __ASM_VDSO_GETTIMEOFDAY_H
>> +#define __ASM_VDSO_GETTIMEOFDAY_H
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +#include <asm/unistd.h>
>> +#include <uapi/linux/time.h>
>> +
>> +#define VDSO_HAS_CLOCK_GETRES 1
>> +
>> +static __always_inline int gettimeofday_fallback(
>> + struct __kernel_old_timeval *_tv,
>> + struct timezone *_tz)
>
> Out of interest, does this need to be __always_inline?
>
It is a design choice. Philosophically, I prefer to control and reduce the scope
of the decisions the compiler has to make in order to not have surprises.
>> +{
>> + register struct timezone *tz asm("x1") = _tz;
>> + register struct __kernel_old_timeval *tv asm("x0") = _tv;
>> + register long ret asm ("x0");
>> + register long nr asm("x8") = __NR_gettimeofday;
>> +
>> + asm volatile(
>> + " svc #0\n"
>
> Can inlining of this function result in non-trivial expressions being
> substituted for _tz or _tv?
>
> A function call can clobber register asm vars that are assigned to the
> caller-save registers or that the PCS uses for function arguments, and
> the situations where this can happen are poorly defined AFAICT. There's
> also no reliable way to detect at build time whether the compiler has
> done this, and no robust way to stop if happening.
>
> (IMHO the compiler is wrong to do this, but it's been that way for ever,
> and I think I saw GCC 9 show this behaviour recently when I was
> investigating something related.)
>
>
> To be safe, it's better to put this out of line, or remove the reg asm()
> specifiers, mark x0-x18 and lr as clobbered here (so that the compiler
> doesn't map arguments to them), and put movs in the asm to move things
> into the right registers. The syscall number can be passed with an "i"
> constraint. (And yes, this sucks.)
>
> If the code this is inlined in is simple enough though, we can be fairly
> confident of getting away with it.
>
I took very seriously what you are mentioning here because I think that
robustness of the code comes before than everything especially in the kernel and
I carried on some experiments to try to verify if in this case is safe to assume
that the compiler is doing the right thing.
Based on my investigation and on previous observations of the generation of the
vDSO library, I can conclude that the approach seems safe due to the fact that
the usage of this code is very limited, the code itself is simple enough and
that gcc would inline this code anyway based on the current compilation options.
The experiment that I did was to define some self-contained code that tries to
mimic what you are describing and compile it with 3 different versions of gcc
(6.4, 8.1 and 8.3) and in all the tree cases the behavior seems correct.
Code:
=====
typedef int ssize_t;
typedef int size_t;
static int my_strlen(const char *s)
{
int i = 0;
while (s[i] == '\0')
i++;
return i;
}
static inline ssize_t my_syscall(int fd, const void *buf, size_t count)
{
register ssize_t arg1 asm ("x0") = fd;
register const void *arg2 asm ("x1") = buf;
register size_t arg3 asm ("x2") = count;
__asm__ volatile (
"mov x8, #64\n"
"svc #0\n"
: "=&r" (arg1)
: "r" (arg2), "r" (arg3)
: "x8"
);
return arg1;
}
void sys_caller(const char *s)
{
my_syscall(1, s, my_strlen(s));
}
GCC 8.3.0:
==========
main.8.3.0.o: file format elf64-littleaarch64
Disassembly of section .text:
0000000000000000 <sys_caller>:
0: 39400001 ldrb w1, [x0]
4: 35000161 cbnz w1, 30 <sys_caller+0x30>
8: d2800023 mov x3, #0x1 // #1
c: d1000404 sub x4, x0, #0x1
10: 2a0303e2 mov w2, w3
14: 91000463 add x3, x3, #0x1
18: 38636881 ldrb w1, [x4, x3]
1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
20: aa0003e1 mov x1, x0
24: d2800808 mov x8, #0x40 // #64
28: d4000001 svc #0x0
2c: d65f03c0 ret
30: 52800002 mov w2, #0x0 // #0
34: 17fffffb b 20 <sys_caller+0x20>
GCC 8.1.0:
==========
main.8.1.0.o: file format elf64-littleaarch64
Disassembly of section .text:
0000000000000000 <sys_caller>:
0: 39400001 ldrb w1, [x0]
4: 35000161 cbnz w1, 30 <sys_caller+0x30>
8: d2800023 mov x3, #0x1 // #1
c: d1000404 sub x4, x0, #0x1
10: 2a0303e2 mov w2, w3
14: 91000463 add x3, x3, #0x1
18: 38636881 ldrb w1, [x4, x3]
1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
20: aa0003e1 mov x1, x0
24: d2800808 mov x8, #0x40 // #64
28: d4000001 svc #0x0
2c: d65f03c0 ret
30: 52800002 mov w2, #0x0 // #0
34: 17fffffb b 20 <sys_caller+0x20>
GCC 6.4.0:
==========
main.6.4.0.o: file format elf64-littleaarch64
Disassembly of section .text:
0000000000000000 <sys_caller>:
0: 39400001 ldrb w1, [x0]
4: 35000161 cbnz w1, 30 <sys_caller+0x30>
8: d2800023 mov x3, #0x1 // #1
c: d1000404 sub x4, x0, #0x1
10: 2a0303e2 mov w2, w3
14: 91000463 add x3, x3, #0x1
18: 38636881 ldrb w1, [x4, x3]
1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
20: aa0003e1 mov x1, x0
24: d2800808 mov x8, #0x40 // #64
28: d4000001 svc #0x0
2c: d65f03c0 ret
30: 52800002 mov w2, #0x0 // #0
34: 17fffffb b 20 <sys_caller+0x20>
> [...]
>
> Cheers
> ---Dave
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-26 13:27 ` Vincenzo Frascino
@ 2019-06-26 16:14 ` Dave Martin
2019-06-26 19:01 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Dave Martin @ 2019-06-26 16:14 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, Shijith Thotton, Peter Collingbourne, Arnd Bergmann,
Huw Davies, Andre Przywara, Daniel Lezcano, Will Deacon,
linux-kernel, Ralf Baechle, linux-mips, Paul Burton,
Rasmus Villemoes, linux-kselftest, Catalin Marinas, Russell King,
Dmitry Safonov, Mark Salyzyn, Shuah Khan, Thomas Gleixner,
linux-arm-kernel
On Wed, Jun 26, 2019 at 02:27:59PM +0100, Vincenzo Frascino wrote:
> Hi Dave,
>
> On 25/06/2019 16:33, Dave Martin wrote:
> > On Fri, Jun 21, 2019 at 10:52:31AM +0100, Vincenzo Frascino wrote:
> >> To take advantage of the commonly defined vdso interface for
> >> gettimeofday the architectural code requires an adaptation.
> >>
> >> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
> >>
> >> With the new implementation arm64 gains support for CLOCK_BOOTTIME
> >> and CLOCK_TAI.
> >>
> >> Cc: Catalin Marinas <catalin.marinas@arm.com>
> >> Cc: Will Deacon <will.deacon@arm.com>
> >> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> >> Tested-by: Shijith Thotton <sthotton@marvell.com>
> >> Tested-by: Andre Przywara <andre.przywara@arm.com>
> >
> > [...]
> >
> >> diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
> >> new file mode 100644
> >> index 000000000000..bc3cb6738051
> >> --- /dev/null
> >> +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
> >> @@ -0,0 +1,86 @@
> >> +/* SPDX-License-Identifier: GPL-2.0 */
> >> +/*
> >> + * Copyright (C) 2018 ARM Limited
> >> + */
> >> +#ifndef __ASM_VDSO_GETTIMEOFDAY_H
> >> +#define __ASM_VDSO_GETTIMEOFDAY_H
> >> +
> >> +#ifndef __ASSEMBLY__
> >> +
> >> +#include <asm/unistd.h>
> >> +#include <uapi/linux/time.h>
> >> +
> >> +#define VDSO_HAS_CLOCK_GETRES 1
> >> +
> >> +static __always_inline int gettimeofday_fallback(
> >> + struct __kernel_old_timeval *_tv,
> >> + struct timezone *_tz)
> >
> > Out of interest, does this need to be __always_inline?
> >
>
> It is a design choice. Philosophically, I prefer to control and reduce the scope
> of the decisions the compiler has to make in order to not have surprises.
>
> >> +{
> >> + register struct timezone *tz asm("x1") = _tz;
> >> + register struct __kernel_old_timeval *tv asm("x0") = _tv;
> >> + register long ret asm ("x0");
> >> + register long nr asm("x8") = __NR_gettimeofday;
> >> +
> >> + asm volatile(
> >> + " svc #0\n"
> >
> > Can inlining of this function result in non-trivial expressions being
> > substituted for _tz or _tv?
> >
> > A function call can clobber register asm vars that are assigned to the
> > caller-save registers or that the PCS uses for function arguments, and
> > the situations where this can happen are poorly defined AFAICT. There's
> > also no reliable way to detect at build time whether the compiler has
> > done this, and no robust way to stop if happening.
> >
> > (IMHO the compiler is wrong to do this, but it's been that way for ever,
> > and I think I saw GCC 9 show this behaviour recently when I was
> > investigating something related.)
> >
> >
> > To be safe, it's better to put this out of line, or remove the reg asm()
> > specifiers, mark x0-x18 and lr as clobbered here (so that the compiler
> > doesn't map arguments to them), and put movs in the asm to move things
> > into the right registers. The syscall number can be passed with an "i"
> > constraint. (And yes, this sucks.)
> >
> > If the code this is inlined in is simple enough though, we can be fairly
> > confident of getting away with it.
> >
>
> I took very seriously what you are mentioning here because I think
> that robustness of the code comes before than everything especially
> in the kernel and I carried on some experiments to try to verify if
> in this case is safe to assume that the compiler is doing the right
> thing.
>
> Based on my investigation and on previous observations of the
> generation of the vDSO library, I can conclude that the approach
> seems safe due to the fact that the usage of this code is very
> limited, the code itself is simple enough and that gcc would inline
> this code anyway based on the current compilation options.
I'd caution about "seems safe". A lot of subtly wrong code not only
seems safe, but _is_ safe in its original context, in practice. Add
some code to the vdso over time though, or tweak the compilation options
at some point in the future, or use a different compiler, and things
could still go wrong.
(Further comments below.)
> The experiment that I did was to define some self-contained code that
> tries to mimic what you are describing and compile it with 3
> different versions of gcc (6.4, 8.1 and 8.3) and in all the tree
> cases the behavior seems correct.
>
> Code:
> =====
>
> typedef int ssize_t;
> typedef int size_t;
>
> static int my_strlen(const char *s)
> {
> int i = 0;
>
> while (s[i] == '\0')
> i++;
>
> return i;
> }
>
> static inline ssize_t my_syscall(int fd, const void *buf, size_t count)
> {
> register ssize_t arg1 asm ("x0") = fd;
> register const void *arg2 asm ("x1") = buf;
> register size_t arg3 asm ("x2") = count;
>
> __asm__ volatile (
> "mov x8, #64\n"
> "svc #0\n"
> : "=&r" (arg1)
> : "r" (arg2), "r" (arg3)
> : "x8"
> );
>
> return arg1;
> }
>
> void sys_caller(const char *s)
> {
> my_syscall(1, s, my_strlen(s));
> }
>
>
> GCC 8.3.0:
> ==========
>
> main.8.3.0.o: file format elf64-littleaarch64
>
>
> Disassembly of section .text:
>
> 0000000000000000 <sys_caller>:
> 0: 39400001 ldrb w1, [x0]
> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
> 8: d2800023 mov x3, #0x1 // #1
> c: d1000404 sub x4, x0, #0x1
> 10: 2a0303e2 mov w2, w3
> 14: 91000463 add x3, x3, #0x1
> 18: 38636881 ldrb w1, [x4, x3]
> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
> 20: aa0003e1 mov x1, x0
> 24: d2800808 mov x8, #0x40 // #64
> 28: d4000001 svc #0x0
> 2c: d65f03c0 ret
> 30: 52800002 mov w2, #0x0 // #0
> 34: 17fffffb b 20 <sys_caller+0x20>
>
>
> GCC 8.1.0:
> ==========
>
> main.8.1.0.o: file format elf64-littleaarch64
>
>
> Disassembly of section .text:
>
> 0000000000000000 <sys_caller>:
> 0: 39400001 ldrb w1, [x0]
> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
> 8: d2800023 mov x3, #0x1 // #1
> c: d1000404 sub x4, x0, #0x1
> 10: 2a0303e2 mov w2, w3
> 14: 91000463 add x3, x3, #0x1
> 18: 38636881 ldrb w1, [x4, x3]
> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
> 20: aa0003e1 mov x1, x0
> 24: d2800808 mov x8, #0x40 // #64
> 28: d4000001 svc #0x0
> 2c: d65f03c0 ret
> 30: 52800002 mov w2, #0x0 // #0
> 34: 17fffffb b 20 <sys_caller+0x20>
>
>
>
> GCC 6.4.0:
> ==========
>
> main.6.4.0.o: file format elf64-littleaarch64
>
>
> Disassembly of section .text:
>
> 0000000000000000 <sys_caller>:
> 0: 39400001 ldrb w1, [x0]
> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
> 8: d2800023 mov x3, #0x1 // #1
> c: d1000404 sub x4, x0, #0x1
> 10: 2a0303e2 mov w2, w3
> 14: 91000463 add x3, x3, #0x1
> 18: 38636881 ldrb w1, [x4, x3]
> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
> 20: aa0003e1 mov x1, x0
> 24: d2800808 mov x8, #0x40 // #64
> 28: d4000001 svc #0x0
> 2c: d65f03c0 ret
> 30: 52800002 mov w2, #0x0 // #0
> 34: 17fffffb b 20 <sys_caller+0x20>
Thanks for having a go at this. If the compiler can show the
problematic behaviour, it looks like your could could probably trigger
it, and as you observe, it doesn't trigger.
I am sure I have seen it in the past, but today I am struggling
to tickle the compiler in the right way. My original reproducer may
have involved LTO, but either way I don't still have it :(
The classic example of this (triggered directly and not due to inlining)
would be something like:
int bar(int, int);
void foo(int x, int y)
{
register int x_ asm("r0") = x;
register int y_ asm("r1") = bar(x, y);
asm volatile (
"svc #0"
:: "r" (x_), "r" (y_)
: "memory"
);
}
->
0000000000000000 <foo>:
0: a9bf7bfd stp x29, x30, [sp, #-16]!
4: 910003fd mov x29, sp
8: 94000000 bl 0 <bar>
c: 2a0003e1 mov w1, w0
10: d4000001 svc #0x0
14: a8c17bfd ldp x29, x30, [sp], #16
18: d65f03c0 ret
The gcc documentation is vague and ambiguous about precisely whan this
can happen and about how to avoid it.
The case where this behaviour is triggered by inlining an expression
that involves a (possibly implicit) function call seems hard to
reproduce.
However, the workaround is cheap, and to avoid the chance of subtle
intermittent code gen bugs it may be worth it:
void foo(int x, int y)
{
asm volatile (
"mov x0, %0\n\t"
"mov x1, %1\n\t"
"svc #0"
:: "r" (x), "r" (bar(x, y))
: "r0", "r1", "memory"
);
}
->
0000000000000000 <foo>:
0: a9be7bfd stp x29, x30, [sp, #-32]!
4: 910003fd mov x29, sp
8: f9000bf3 str x19, [sp, #16]
c: 2a0003f3 mov w19, w0
10: 94000000 bl 0 <bar>
14: 2a0003e2 mov w2, w0
18: aa1303e0 mov x0, x19
1c: aa0203e1 mov x1, x2
20: d4000001 svc #0x0
24: f9400bf3 ldr x19, [sp, #16]
28: a8c27bfd ldp x29, x30, [sp], #32
2c: d65f03c0 ret
What do you think?
Cheers
---Dave
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-26 16:14 ` Dave Martin
@ 2019-06-26 19:01 ` Vincenzo Frascino
2019-06-27 10:01 ` Dave Martin
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-26 19:01 UTC (permalink / raw)
To: Dave Martin
Cc: linux-arch, Shijith Thotton, Peter Collingbourne, Arnd Bergmann,
Huw Davies, Andre Przywara, Daniel Lezcano, Will Deacon,
linux-kernel, Ralf Baechle, linux-mips, Paul Burton,
Rasmus Villemoes, linux-kselftest, Catalin Marinas, Russell King,
Dmitry Safonov, Mark Salyzyn, Shuah Khan, Thomas Gleixner,
linux-arm-kernel
Hi Dave,
thank you for the quick turn around.
On 6/26/19 5:14 PM, Dave Martin wrote:
> On Wed, Jun 26, 2019 at 02:27:59PM +0100, Vincenzo Frascino wrote:
>> Hi Dave,
>>
>> On 25/06/2019 16:33, Dave Martin wrote:
>>> On Fri, Jun 21, 2019 at 10:52:31AM +0100, Vincenzo Frascino wrote:
>>>> To take advantage of the commonly defined vdso interface for
>>>> gettimeofday the architectural code requires an adaptation.
>>>>
>>>> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>>>>
>>>> With the new implementation arm64 gains support for CLOCK_BOOTTIME
>>>> and CLOCK_TAI.
>>>>
>>>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>>>> Cc: Will Deacon <will.deacon@arm.com>
>>>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>>>> Tested-by: Shijith Thotton <sthotton@marvell.com>
>>>> Tested-by: Andre Przywara <andre.przywara@arm.com>
>>>
>>> [...]
>>>
>>>> diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
>>>> new file mode 100644
>>>> index 000000000000..bc3cb6738051
>>>> --- /dev/null
>>>> +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
>>>> @@ -0,0 +1,86 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>> +/*
>>>> + * Copyright (C) 2018 ARM Limited
>>>> + */
>>>> +#ifndef __ASM_VDSO_GETTIMEOFDAY_H
>>>> +#define __ASM_VDSO_GETTIMEOFDAY_H
>>>> +
>>>> +#ifndef __ASSEMBLY__
>>>> +
>>>> +#include <asm/unistd.h>
>>>> +#include <uapi/linux/time.h>
>>>> +
>>>> +#define VDSO_HAS_CLOCK_GETRES 1
>>>> +
>>>> +static __always_inline int gettimeofday_fallback(
>>>> + struct __kernel_old_timeval *_tv,
>>>> + struct timezone *_tz)
>>>
>>> Out of interest, does this need to be __always_inline?
>>>
>>
>> It is a design choice. Philosophically, I prefer to control and reduce the scope
>> of the decisions the compiler has to make in order to not have surprises.
>>
>>>> +{
>>>> + register struct timezone *tz asm("x1") = _tz;
>>>> + register struct __kernel_old_timeval *tv asm("x0") = _tv;
>>>> + register long ret asm ("x0");
>>>> + register long nr asm("x8") = __NR_gettimeofday;
>>>> +
>>>> + asm volatile(
>>>> + " svc #0\n"
>>>
>>> Can inlining of this function result in non-trivial expressions being
>>> substituted for _tz or _tv?
>>>
>>> A function call can clobber register asm vars that are assigned to the
>>> caller-save registers or that the PCS uses for function arguments, and
>>> the situations where this can happen are poorly defined AFAICT. There's
>>> also no reliable way to detect at build time whether the compiler has
>>> done this, and no robust way to stop if happening.
>>>
>>> (IMHO the compiler is wrong to do this, but it's been that way for ever,
>>> and I think I saw GCC 9 show this behaviour recently when I was
>>> investigating something related.)
>>>
>>>
>>> To be safe, it's better to put this out of line, or remove the reg asm()
>>> specifiers, mark x0-x18 and lr as clobbered here (so that the compiler
>>> doesn't map arguments to them), and put movs in the asm to move things
>>> into the right registers. The syscall number can be passed with an "i"
>>> constraint. (And yes, this sucks.)
>>>
>>> If the code this is inlined in is simple enough though, we can be fairly
>>> confident of getting away with it.
>>>
>>
>> I took very seriously what you are mentioning here because I think
>> that robustness of the code comes before than everything especially
>> in the kernel and I carried on some experiments to try to verify if
>> in this case is safe to assume that the compiler is doing the right
>> thing.
>>
>> Based on my investigation and on previous observations of the
>> generation of the vDSO library, I can conclude that the approach
>> seems safe due to the fact that the usage of this code is very
>> limited, the code itself is simple enough and that gcc would inline
>> this code anyway based on the current compilation options.
>
> I'd caution about "seems safe". A lot of subtly wrong code not only
> seems safe, but _is_ safe in its original context, in practice. Add
> some code to the vdso over time though, or tweak the compilation options
> at some point in the future, or use a different compiler, and things
> could still go wrong.
>
> (Further comments below.)
>
Allow me to provide a clarification on "seems safe" vs "is safe": my approach
"seems safe" because I am providing empirical evidence to support my thesis, but
I guess we both know that there is no simple way to prove in one way or another
that the problem has a complete solution.
The proposed problem involves suppositions on potential future code additions
and changes of behavior of the compiler that I can't either control or prevent.
In other words, I can comment and propose solutions only based on the current
status of the things, and it is what my analysis targets, not on what will
happen in future.
I will reply point by point below.
>> The experiment that I did was to define some self-contained code that
>> tries to mimic what you are describing and compile it with 3
>> different versions of gcc (6.4, 8.1 and 8.3) and in all the tree
>> cases the behavior seems correct.
>>
>> Code:
>> =====
>>
>> typedef int ssize_t;
>> typedef int size_t;
>>
>> static int my_strlen(const char *s)
>> {
>> int i = 0;
>>
>> while (s[i] == '\0')
>> i++;
>>
>> return i;
>> }
>>
>> static inline ssize_t my_syscall(int fd, const void *buf, size_t count)
>> {
>> register ssize_t arg1 asm ("x0") = fd;
>> register const void *arg2 asm ("x1") = buf;
>> register size_t arg3 asm ("x2") = count;
>>
>> __asm__ volatile (
>> "mov x8, #64\n"
>> "svc #0\n"
>> : "=&r" (arg1)
>> : "r" (arg2), "r" (arg3)
>> : "x8"
>> );
>>
>> return arg1;
>> }
>>
>> void sys_caller(const char *s)
>> {
>> my_syscall(1, s, my_strlen(s));
>> }
>>
>>
>> GCC 8.3.0:
>> ==========
>>
>> main.8.3.0.o: file format elf64-littleaarch64
>>
>>
>> Disassembly of section .text:
>>
>> 0000000000000000 <sys_caller>:
>> 0: 39400001 ldrb w1, [x0]
>> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
>> 8: d2800023 mov x3, #0x1 // #1
>> c: d1000404 sub x4, x0, #0x1
>> 10: 2a0303e2 mov w2, w3
>> 14: 91000463 add x3, x3, #0x1
>> 18: 38636881 ldrb w1, [x4, x3]
>> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
>> 20: aa0003e1 mov x1, x0
>> 24: d2800808 mov x8, #0x40 // #64
>> 28: d4000001 svc #0x0
>> 2c: d65f03c0 ret
>> 30: 52800002 mov w2, #0x0 // #0
>> 34: 17fffffb b 20 <sys_caller+0x20>
>>
>>
>> GCC 8.1.0:
>> ==========
>>
>> main.8.1.0.o: file format elf64-littleaarch64
>>
>>
>> Disassembly of section .text:
>>
>> 0000000000000000 <sys_caller>:
>> 0: 39400001 ldrb w1, [x0]
>> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
>> 8: d2800023 mov x3, #0x1 // #1
>> c: d1000404 sub x4, x0, #0x1
>> 10: 2a0303e2 mov w2, w3
>> 14: 91000463 add x3, x3, #0x1
>> 18: 38636881 ldrb w1, [x4, x3]
>> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
>> 20: aa0003e1 mov x1, x0
>> 24: d2800808 mov x8, #0x40 // #64
>> 28: d4000001 svc #0x0
>> 2c: d65f03c0 ret
>> 30: 52800002 mov w2, #0x0 // #0
>> 34: 17fffffb b 20 <sys_caller+0x20>
>>
>>
>>
>> GCC 6.4.0:
>> ==========
>>
>> main.6.4.0.o: file format elf64-littleaarch64
>>
>>
>> Disassembly of section .text:
>>
>> 0000000000000000 <sys_caller>:
>> 0: 39400001 ldrb w1, [x0]
>> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
>> 8: d2800023 mov x3, #0x1 // #1
>> c: d1000404 sub x4, x0, #0x1
>> 10: 2a0303e2 mov w2, w3
>> 14: 91000463 add x3, x3, #0x1
>> 18: 38636881 ldrb w1, [x4, x3]
>> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
>> 20: aa0003e1 mov x1, x0
>> 24: d2800808 mov x8, #0x40 // #64
>> 28: d4000001 svc #0x0
>> 2c: d65f03c0 ret
>> 30: 52800002 mov w2, #0x0 // #0
>> 34: 17fffffb b 20 <sys_caller+0x20>
>
> Thanks for having a go at this. If the compiler can show the
> problematic behaviour, it looks like your could could probably trigger
> it, and as you observe, it doesn't trigger.
>
> I am sure I have seen it in the past, but today I am struggling
> to tickle the compiler in the right way. My original reproducer may
> have involved LTO, but either way I don't still have it :(
>
vDSO library is a shared object not compiled with LTO as far as I can see, hence
if this involved LTO should not applicable in this case.
>
> The classic example of this (triggered directly and not due to inlining)
> would be something like:
>
> int bar(int, int);
>
> void foo(int x, int y)
> {
> register int x_ asm("r0") = x;
> register int y_ asm("r1") = bar(x, y);
>
> asm volatile (
> "svc #0"
> :: "r" (x_), "r" (y_)
> : "memory"
> );
> }
>
> ->
>
> 0000000000000000 <foo>:
> 0: a9bf7bfd stp x29, x30, [sp, #-16]!
> 4: 910003fd mov x29, sp
> 8: 94000000 bl 0 <bar>
> c: 2a0003e1 mov w1, w0
> 10: d4000001 svc #0x0
> 14: a8c17bfd ldp x29, x30, [sp], #16
> 18: d65f03c0 ret
>
Contextualized to what my vdso fallback functions do, this should not be a
concern because in no case a function result is directly set to a variable
declared as register.
Since the vdso fallback functions serve a very specific and limited purpose, I
do not expect that that code is going to change much in future.
The only thing that can happen is something similar to what I wrote in my
example, which as I empirically proved does not trigger the problematic behavior.
>
> The gcc documentation is vague and ambiguous about precisely whan this
> can happen and about how to avoid it.
>
On this I agree, it is not very clear, but this seems more something to raise
with the gcc folks in order to have a more "explicit" description that leaves no
room to the interpretation.
...
>
> However, the workaround is cheap, and to avoid the chance of subtle
> intermittent code gen bugs it may be worth it:
>
> void foo(int x, int y)
> {
> asm volatile (
> "mov x0, %0\n\t"
> "mov x1, %1\n\t"
> "svc #0"
> :: "r" (x), "r" (bar(x, y))
> : "r0", "r1", "memory"
> );
> }
>
> ->
>
> 0000000000000000 <foo>:
> 0: a9be7bfd stp x29, x30, [sp, #-32]!
> 4: 910003fd mov x29, sp
> 8: f9000bf3 str x19, [sp, #16]
> c: 2a0003f3 mov w19, w0
> 10: 94000000 bl 0 <bar>
> 14: 2a0003e2 mov w2, w0
> 18: aa1303e0 mov x0, x19
> 1c: aa0203e1 mov x1, x2
> 20: d4000001 svc #0x0
> 24: f9400bf3 ldr x19, [sp, #16]
> 28: a8c27bfd ldp x29, x30, [sp], #32
> 2c: d65f03c0 ret
>
>
> What do you think?
>
The solution seems ok, thanks for providing it, but IMHO I think we should find
a workaround for something that is broken, which, unless I am missing something
major, this seems not the case.
> Cheers
> ---Dave
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-26 19:01 ` Vincenzo Frascino
@ 2019-06-27 10:01 ` Dave Martin
2019-06-27 10:57 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Dave Martin @ 2019-06-27 10:01 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, Shuah Khan, Catalin Marinas, Arnd Bergmann,
Mark Salyzyn, Huw Davies, Andre Przywara, Daniel Lezcano,
Will Deacon, linux-kernel, Ralf Baechle, linux-mips, Paul Burton,
linux-kselftest, Rasmus Villemoes, Russell King, Dmitry Safonov,
Shijith Thotton, Peter Collingbourne, Thomas Gleixner,
linux-arm-kernel
On Wed, Jun 26, 2019 at 08:01:58PM +0100, Vincenzo Frascino wrote:
[...]
> On 6/26/19 5:14 PM, Dave Martin wrote:
> > On Wed, Jun 26, 2019 at 02:27:59PM +0100, Vincenzo Frascino wrote:
> >> Hi Dave,
> >>
> >> On 25/06/2019 16:33, Dave Martin wrote:
> >>> On Fri, Jun 21, 2019 at 10:52:31AM +0100, Vincenzo Frascino wrote:
> >>>> To take advantage of the commonly defined vdso interface for
> >>>> gettimeofday the architectural code requires an adaptation.
> >>>>
> >>>> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
> >>>>
> >>>> With the new implementation arm64 gains support for CLOCK_BOOTTIME
> >>>> and CLOCK_TAI.
> >>>>
> >>>> Cc: Catalin Marinas <catalin.marinas@arm.com>
> >>>> Cc: Will Deacon <will.deacon@arm.com>
> >>>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> >>>> Tested-by: Shijith Thotton <sthotton@marvell.com>
> >>>> Tested-by: Andre Przywara <andre.przywara@arm.com>
> >>>
> >>> [...]
> >>>
> >>>> diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
> >>>> new file mode 100644
> >>>> index 000000000000..bc3cb6738051
> >>>> --- /dev/null
> >>>> +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
> >>>> @@ -0,0 +1,86 @@
> >>>> +/* SPDX-License-Identifier: GPL-2.0 */
> >>>> +/*
> >>>> + * Copyright (C) 2018 ARM Limited
> >>>> + */
> >>>> +#ifndef __ASM_VDSO_GETTIMEOFDAY_H
> >>>> +#define __ASM_VDSO_GETTIMEOFDAY_H
> >>>> +
> >>>> +#ifndef __ASSEMBLY__
> >>>> +
> >>>> +#include <asm/unistd.h>
> >>>> +#include <uapi/linux/time.h>
> >>>> +
> >>>> +#define VDSO_HAS_CLOCK_GETRES 1
> >>>> +
> >>>> +static __always_inline int gettimeofday_fallback(
> >>>> + struct __kernel_old_timeval *_tv,
> >>>> + struct timezone *_tz)
> >>>
> >>> Out of interest, does this need to be __always_inline?
> >>>
> >>
> >> It is a design choice. Philosophically, I prefer to control and reduce the scope
> >> of the decisions the compiler has to make in order to not have surprises.
> >>
> >>>> +{
> >>>> + register struct timezone *tz asm("x1") = _tz;
> >>>> + register struct __kernel_old_timeval *tv asm("x0") = _tv;
> >>>> + register long ret asm ("x0");
> >>>> + register long nr asm("x8") = __NR_gettimeofday;
> >>>> +
> >>>> + asm volatile(
> >>>> + " svc #0\n"
> >>>
> >>> Can inlining of this function result in non-trivial expressions being
> >>> substituted for _tz or _tv?
> >>>
> >>> A function call can clobber register asm vars that are assigned to the
> >>> caller-save registers or that the PCS uses for function arguments, and
> >>> the situations where this can happen are poorly defined AFAICT. There's
> >>> also no reliable way to detect at build time whether the compiler has
> >>> done this, and no robust way to stop if happening.
> >>>
> >>> (IMHO the compiler is wrong to do this, but it's been that way for ever,
> >>> and I think I saw GCC 9 show this behaviour recently when I was
> >>> investigating something related.)
> >>>
> >>>
> >>> To be safe, it's better to put this out of line, or remove the reg asm()
> >>> specifiers, mark x0-x18 and lr as clobbered here (so that the compiler
> >>> doesn't map arguments to them), and put movs in the asm to move things
> >>> into the right registers. The syscall number can be passed with an "i"
> >>> constraint. (And yes, this sucks.)
> >>>
> >>> If the code this is inlined in is simple enough though, we can be fairly
> >>> confident of getting away with it.
> >>>
> >>
> >> I took very seriously what you are mentioning here because I think
> >> that robustness of the code comes before than everything especially
> >> in the kernel and I carried on some experiments to try to verify if
> >> in this case is safe to assume that the compiler is doing the right
> >> thing.
> >>
> >> Based on my investigation and on previous observations of the
> >> generation of the vDSO library, I can conclude that the approach
> >> seems safe due to the fact that the usage of this code is very
> >> limited, the code itself is simple enough and that gcc would inline
> >> this code anyway based on the current compilation options.
> >
> > I'd caution about "seems safe". A lot of subtly wrong code not only
> > seems safe, but _is_ safe in its original context, in practice. Add
> > some code to the vdso over time though, or tweak the compilation options
> > at some point in the future, or use a different compiler, and things
> > could still go wrong.
> >
> > (Further comments below.)
> >
>
> Allow me to provide a clarification on "seems safe" vs "is safe": my approach
> "seems safe" because I am providing empirical evidence to support my thesis, but
> I guess we both know that there is no simple way to prove in one way or another
> that the problem has a complete solution.
> The proposed problem involves suppositions on potential future code additions
> and changes of behavior of the compiler that I can't either control or prevent.
> In other words, I can comment and propose solutions only based on the current
> status of the things, and it is what my analysis targets, not on what will
> happen in future.
>
> I will reply point by point below.
>
> >> The experiment that I did was to define some self-contained code that
> >> tries to mimic what you are describing and compile it with 3
> >> different versions of gcc (6.4, 8.1 and 8.3) and in all the tree
> >> cases the behavior seems correct.
> >>
> >> Code:
> >> =====
> >>
> >> typedef int ssize_t;
> >> typedef int size_t;
> >>
> >> static int my_strlen(const char *s)
> >> {
> >> int i = 0;
> >>
> >> while (s[i] == '\0')
> >> i++;
> >>
> >> return i;
> >> }
> >>
> >> static inline ssize_t my_syscall(int fd, const void *buf, size_t count)
> >> {
> >> register ssize_t arg1 asm ("x0") = fd;
> >> register const void *arg2 asm ("x1") = buf;
> >> register size_t arg3 asm ("x2") = count;
> >>
> >> __asm__ volatile (
> >> "mov x8, #64\n"
> >> "svc #0\n"
> >> : "=&r" (arg1)
> >> : "r" (arg2), "r" (arg3)
> >> : "x8"
> >> );
> >>
> >> return arg1;
> >> }
> >>
> >> void sys_caller(const char *s)
> >> {
> >> my_syscall(1, s, my_strlen(s));
> >> }
> >>
> >>
> >> GCC 8.3.0:
> >> ==========
> >>
> >> main.8.3.0.o: file format elf64-littleaarch64
> >>
> >>
> >> Disassembly of section .text:
> >>
> >> 0000000000000000 <sys_caller>:
> >> 0: 39400001 ldrb w1, [x0]
> >> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
> >> 8: d2800023 mov x3, #0x1 // #1
> >> c: d1000404 sub x4, x0, #0x1
> >> 10: 2a0303e2 mov w2, w3
> >> 14: 91000463 add x3, x3, #0x1
> >> 18: 38636881 ldrb w1, [x4, x3]
> >> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
> >> 20: aa0003e1 mov x1, x0
> >> 24: d2800808 mov x8, #0x40 // #64
> >> 28: d4000001 svc #0x0
> >> 2c: d65f03c0 ret
> >> 30: 52800002 mov w2, #0x0 // #0
> >> 34: 17fffffb b 20 <sys_caller+0x20>
> >>
> >>
> >> GCC 8.1.0:
> >> ==========
> >>
> >> main.8.1.0.o: file format elf64-littleaarch64
> >>
> >>
> >> Disassembly of section .text:
> >>
> >> 0000000000000000 <sys_caller>:
> >> 0: 39400001 ldrb w1, [x0]
> >> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
> >> 8: d2800023 mov x3, #0x1 // #1
> >> c: d1000404 sub x4, x0, #0x1
> >> 10: 2a0303e2 mov w2, w3
> >> 14: 91000463 add x3, x3, #0x1
> >> 18: 38636881 ldrb w1, [x4, x3]
> >> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
> >> 20: aa0003e1 mov x1, x0
> >> 24: d2800808 mov x8, #0x40 // #64
> >> 28: d4000001 svc #0x0
> >> 2c: d65f03c0 ret
> >> 30: 52800002 mov w2, #0x0 // #0
> >> 34: 17fffffb b 20 <sys_caller+0x20>
> >>
> >>
> >>
> >> GCC 6.4.0:
> >> ==========
> >>
> >> main.6.4.0.o: file format elf64-littleaarch64
> >>
> >>
> >> Disassembly of section .text:
> >>
> >> 0000000000000000 <sys_caller>:
> >> 0: 39400001 ldrb w1, [x0]
> >> 4: 35000161 cbnz w1, 30 <sys_caller+0x30>
> >> 8: d2800023 mov x3, #0x1 // #1
> >> c: d1000404 sub x4, x0, #0x1
> >> 10: 2a0303e2 mov w2, w3
> >> 14: 91000463 add x3, x3, #0x1
> >> 18: 38636881 ldrb w1, [x4, x3]
> >> 1c: 34ffffa1 cbz w1, 10 <sys_caller+0x10>
> >> 20: aa0003e1 mov x1, x0
> >> 24: d2800808 mov x8, #0x40 // #64
> >> 28: d4000001 svc #0x0
> >> 2c: d65f03c0 ret
> >> 30: 52800002 mov w2, #0x0 // #0
> >> 34: 17fffffb b 20 <sys_caller+0x20>
> >
> > Thanks for having a go at this. If the compiler can show the
> > problematic behaviour, it looks like your could could probably trigger
> > it, and as you observe, it doesn't trigger.
> >
> > I am sure I have seen it in the past, but today I am struggling
> > to tickle the compiler in the right way. My original reproducer may
> > have involved LTO, but either way I don't still have it :(
> >
>
> vDSO library is a shared object not compiled with LTO as far as I can
> see, hence if this involved LTO should not applicable in this case.
That turned to be a spurious hypothesis on my part -- LTO isn't the
smoking gun. (See below.)
> > The classic example of this (triggered directly and not due to inlining)
> > would be something like:
> >
> > int bar(int, int);
> >
> > void foo(int x, int y)
> > {
> > register int x_ asm("r0") = x;
> > register int y_ asm("r1") = bar(x, y);
> >
> > asm volatile (
> > "svc #0"
> > :: "r" (x_), "r" (y_)
> > : "memory"
> > );
> > }
> >
> > ->
> >
> > 0000000000000000 <foo>:
> > 0: a9bf7bfd stp x29, x30, [sp, #-16]!
> > 4: 910003fd mov x29, sp
> > 8: 94000000 bl 0 <bar>
> > c: 2a0003e1 mov w1, w0
> > 10: d4000001 svc #0x0
> > 14: a8c17bfd ldp x29, x30, [sp], #16
> > 18: d65f03c0 ret
> >
>
> Contextualized to what my vdso fallback functions do, this should not be a
> concern because in no case a function result is directly set to a variable
> declared as register.
>
> Since the vdso fallback functions serve a very specific and limited purpose, I
> do not expect that that code is going to change much in future.
>
> The only thing that can happen is something similar to what I wrote in my
> example, which as I empirically proved does not trigger the problematic behavior.
>
> >
> > The gcc documentation is vague and ambiguous about precisely whan this
> > can happen and about how to avoid it.
> >
>
> On this I agree, it is not very clear, but this seems more something to raise
> with the gcc folks in order to have a more "explicit" description that leaves no
> room to the interpretation.
>
> ...
>
> >
> > However, the workaround is cheap, and to avoid the chance of subtle
> > intermittent code gen bugs it may be worth it:
> >
> > void foo(int x, int y)
> > {
> > asm volatile (
> > "mov x0, %0\n\t"
> > "mov x1, %1\n\t"
> > "svc #0"
> > :: "r" (x), "r" (bar(x, y))
> > : "r0", "r1", "memory"
> > );
> > }
> >
> > ->
> >
> > 0000000000000000 <foo>:
> > 0: a9be7bfd stp x29, x30, [sp, #-32]!
> > 4: 910003fd mov x29, sp
> > 8: f9000bf3 str x19, [sp, #16]
> > c: 2a0003f3 mov w19, w0
> > 10: 94000000 bl 0 <bar>
> > 14: 2a0003e2 mov w2, w0
> > 18: aa1303e0 mov x0, x19
> > 1c: aa0203e1 mov x1, x2
> > 20: d4000001 svc #0x0
> > 24: f9400bf3 ldr x19, [sp, #16]
> > 28: a8c27bfd ldp x29, x30, [sp], #32
> > 2c: d65f03c0 ret
> >
> >
> > What do you think?
> >
>
> The solution seems ok, thanks for providing it, but IMHO I think we
> should find a workaround for something that is broken, which, unless
> I am missing something major, this seems not the case.
So, after a bit of further experimentation, I found that I could trigger
it with implicit function calls on an older compiler. I couldn't show
it with explicit function calls (as in your example).
With the following code, inlining if an expression that causes an
implicit call to a libgcc helper can trigger this issue, but I had to
try an older compiler:
int foo(int x, int y)
{
register int res asm("r0");
register const int x_ asm("r0") = x;
register const int y_ asm("r1") = y;
asm volatile (
"svc #0"
: "=r" (res)
: "r" (x_), "r" (y_)
: "memory"
);
return res;
}
int bar(int x, int y)
{
return foo(x, x / y);
}
-> (arm-linux-gnueabihf-gcc 9.1 -O2)
00000000 <foo>:
0: df00 svc 0
2: 4770 bx lr
00000004 <bar>:
4: b510 push {r4, lr}
6: 4604 mov r4, r0
8: f7ff fffe bl 0 <__aeabi_idiv>
c: 4601 mov r1, r0
e: 4620 mov r0, r4
10: df00 svc 0
12: bd10 pop {r4, pc}
-> (arm-linux-gnueabihf-gcc 5.1 -O2)
00000000 <foo>:
0: df00 svc 0
2: 4770 bx lr
00000004 <bar>:
4: b508 push {r3, lr}
6: f7ff fffe bl 0 <__aeabi_idiv>
a: 4601 mov r1, r0
c: df00 svc 0
e: bd08 pop {r3, pc}
I was struggling to find a way to emit an implicit function call for
AArch64, except for 128-bit divide, which would complicate things since
uint128_t doesn't fit in a single register anyway.
Maybe this was considered a bug and fixed sometime after GCC 5, but I
think the GCC documentation is still quite unclear on the semantics of
register asm vars that alias call-clobbered registers in the PCS.
If we can get a promise out of the GCC folks that this will not happen
with any future compiler, then maybe we could just require a new enough
compiler to be used.
Then of course there is clang.
Cheers
---Dave
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-27 10:01 ` Dave Martin
@ 2019-06-27 10:57 ` Vincenzo Frascino
2019-06-27 11:27 ` Dave Martin
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-27 10:57 UTC (permalink / raw)
To: Dave Martin
Cc: linux-arch, Shuah Khan, Catalin Marinas, Arnd Bergmann,
Mark Salyzyn, Huw Davies, Andre Przywara, Daniel Lezcano,
Will Deacon, linux-kernel, Ralf Baechle, linux-mips, Paul Burton,
linux-kselftest, Rasmus Villemoes, Russell King, Dmitry Safonov,
Shijith Thotton, Peter Collingbourne, Thomas Gleixner,
linux-arm-kernel
Hi Dave,
Overall, I want to thank you for bringing out the topic. It helped me to
question some decisions and make sure that we have no holes left in the approach.
[...]
>>
>> vDSO library is a shared object not compiled with LTO as far as I can
>> see, hence if this involved LTO should not applicable in this case.
>
> That turned to be a spurious hypothesis on my part -- LTO isn't the
> smoking gun. (See below.)
>
Ok.
>>> The classic example of this (triggered directly and not due to inlining)
>>> would be something like:
>>>
>>> int bar(int, int);
>>>
>>> void foo(int x, int y)
>>> {
>>> register int x_ asm("r0") = x;
>>> register int y_ asm("r1") = bar(x, y);
>>>
>>> asm volatile (
>>> "svc #0"
>>> :: "r" (x_), "r" (y_)
>>> : "memory"
>>> );
>>> }
>>>
>>> ->
>>>
>>> 0000000000000000 <foo>:
>>> 0: a9bf7bfd stp x29, x30, [sp, #-16]!
>>> 4: 910003fd mov x29, sp
>>> 8: 94000000 bl 0 <bar>
>>> c: 2a0003e1 mov w1, w0
>>> 10: d4000001 svc #0x0
>>> 14: a8c17bfd ldp x29, x30, [sp], #16
>>> 18: d65f03c0 ret
>>>
>>
>> Contextualized to what my vdso fallback functions do, this should not be a
>> concern because in no case a function result is directly set to a variable
>> declared as register.
>>
>> Since the vdso fallback functions serve a very specific and limited purpose, I
>> do not expect that that code is going to change much in future.
>>
>> The only thing that can happen is something similar to what I wrote in my
>> example, which as I empirically proved does not trigger the problematic behavior.
>>
>>>
>>> The gcc documentation is vague and ambiguous about precisely whan this
>>> can happen and about how to avoid it.
>>>
>>
>> On this I agree, it is not very clear, but this seems more something to raise
>> with the gcc folks in order to have a more "explicit" description that leaves no
>> room to the interpretation.
>>
>> ...
>>
>>>
>>> However, the workaround is cheap, and to avoid the chance of subtle
>>> intermittent code gen bugs it may be worth it:
>>>
>>> void foo(int x, int y)
>>> {
>>> asm volatile (
>>> "mov x0, %0\n\t"
>>> "mov x1, %1\n\t"
>>> "svc #0"
>>> :: "r" (x), "r" (bar(x, y))
>>> : "r0", "r1", "memory"
>>> );
>>> }
>>>
>>> ->
>>>
>>> 0000000000000000 <foo>:
>>> 0: a9be7bfd stp x29, x30, [sp, #-32]!
>>> 4: 910003fd mov x29, sp
>>> 8: f9000bf3 str x19, [sp, #16]
>>> c: 2a0003f3 mov w19, w0
>>> 10: 94000000 bl 0 <bar>
>>> 14: 2a0003e2 mov w2, w0
>>> 18: aa1303e0 mov x0, x19
>>> 1c: aa0203e1 mov x1, x2
>>> 20: d4000001 svc #0x0
>>> 24: f9400bf3 ldr x19, [sp, #16]
>>> 28: a8c27bfd ldp x29, x30, [sp], #32
>>> 2c: d65f03c0 ret
>>>
>>>
>>> What do you think?
>>>
>>
>> The solution seems ok, thanks for providing it, but IMHO I think we
>> should find a workaround for something that is broken, which, unless
>> I am missing something major, this seems not the case.
>
> So, after a bit of further experimentation, I found that I could trigger
> it with implicit function calls on an older compiler. I couldn't show
> it with explicit function calls (as in your example).
>
> With the following code, inlining if an expression that causes an
> implicit call to a libgcc helper can trigger this issue, but I had to
> try an older compiler:
>
> int foo(int x, int y)
> {
> register int res asm("r0");
> register const int x_ asm("r0") = x;
> register const int y_ asm("r1") = y;
>
> asm volatile (
> "svc #0"
> : "=r" (res)
> : "r" (x_), "r" (y_)
> : "memory"
> );
>
> return res;
> }
>
> int bar(int x, int y)
> {
> return foo(x, x / y);
> }
>
> -> (arm-linux-gnueabihf-gcc 9.1 -O2)
>
> 00000000 <foo>:
> 0: df00 svc 0
> 2: 4770 bx lr
>
> 00000004 <bar>:
> 4: b510 push {r4, lr}
> 6: 4604 mov r4, r0
> 8: f7ff fffe bl 0 <__aeabi_idiv>
> c: 4601 mov r1, r0
> e: 4620 mov r0, r4
> 10: df00 svc 0
> 12: bd10 pop {r4, pc}
>
> -> (arm-linux-gnueabihf-gcc 5.1 -O2)
>
> 00000000 <foo>:
> 0: df00 svc 0
> 2: 4770 bx lr
>
> 00000004 <bar>:
> 4: b508 push {r3, lr}
> 6: f7ff fffe bl 0 <__aeabi_idiv>
> a: 4601 mov r1, r0
> c: df00 svc 0
> e: bd08 pop {r3, pc}
>
Thanks for reporting this. I had a go with gcc-5.1 on the vDSO library and seems
Ok, but it was worth trying.
For obvious reasons I am not reporting the objdump here :)
> I was struggling to find a way to emit an implicit function call for
> AArch64, except for 128-bit divide, which would complicate things since
> uint128_t doesn't fit in a single register anyway.
>
> Maybe this was considered a bug and fixed sometime after GCC 5, but I
> think the GCC documentation is still quite unclear on the semantics of
> register asm vars that alias call-clobbered registers in the PCS.
>
> If we can get a promise out of the GCC folks that this will not happen
> with any future compiler, then maybe we could just require a new enough
> compiler to be used.
>
On this I fully agree, the compiler should never change an "expected" behavior.
If the issue comes from a gray area in the documentation, we have to address it
and have it fixed there.
The minimum version of the compiler from linux-4.19 is 4.6, hence I had to try
that the vDSO lib does not break with 5.1 [1].
[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cafa0010cd51fb711fdcb50fc55f394c5f167a0a
> Then of course there is clang.
>
I could not help myself and I tried clang.8 and clang.7 as well with my example,
just to make sure that we are fine even in that case. Please find below the
results (pretty identical).
main.clang.7.o: file format ELF64-aarch64-little
Disassembly of section .text:
0000000000000000 show_it:
0: e8 03 1f aa mov x8, xzr
4: 09 68 68 38 ldrb w9, [x0, x8]
8: 08 05 00 91 add x8, x8, #1
c: c9 ff ff 34 cbz w9, #-8 <show_it+0x4>
10: 02 05 00 51 sub w2, w8, #1
14: e1 03 00 aa mov x1, x0
18: 08 08 80 d2 mov x8, #64
1c: 01 00 00 d4 svc #0
20: c0 03 5f d6 ret
main.clang.8.o: file format ELF64-aarch64-little
Disassembly of section .text:
0000000000000000 show_it:
0: e8 03 1f aa mov x8, xzr
4: 09 68 68 38 ldrb w9, [x0, x8]
8: 08 05 00 91 add x8, x8, #1
c: c9 ff ff 34 cbz w9, #-8 <show_it+0x4>
10: 02 05 00 51 sub w2, w8, #1
14: e1 03 00 aa mov x1, x0
18: 08 08 80 d2 mov x8, #64
1c: 01 00 00 d4 svc #0
20: c0 03 5f d6 ret
Commands used:
$ clang -target aarch64-linux-gnueabi main.c -O -c -o main.clang.<x>.o
$ llvm-objdump -d main.clang.<x>.o
> Cheers
> ---Dave
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-27 10:57 ` Vincenzo Frascino
@ 2019-06-27 11:27 ` Dave Martin
2019-06-27 11:59 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Dave Martin @ 2019-06-27 11:27 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, Shijith Thotton, Peter Collingbourne, Arnd Bergmann,
Huw Davies, Catalin Marinas, Daniel Lezcano, Will Deacon,
linux-kernel, Ralf Baechle, Mark Salyzyn, Paul Burton,
Rasmus Villemoes, linux-kselftest, Andre Przywara, Russell King,
Dmitry Safonov, linux-mips, Shuah Khan, Thomas Gleixner,
linux-arm-kernel
On Thu, Jun 27, 2019 at 11:57:36AM +0100, Vincenzo Frascino wrote:
> Hi Dave,
>
> Overall, I want to thank you for bringing out the topic. It helped me to
> question some decisions and make sure that we have no holes left in
> the approach.
Fair enough.
This is really just a nasty compiler corner-case... the validity of the
overall approach isn't affected.
> >>
> >> vDSO library is a shared object not compiled with LTO as far as I can
> >> see, hence if this involved LTO should not applicable in this case.
> >
> > That turned to be a spurious hypothesis on my part -- LTO isn't the
> > smoking gun. (See below.)
> >
>
> Ok.
>
> >>> The classic example of this (triggered directly and not due to inlining)
> >>> would be something like:
> >>>
> >>> int bar(int, int);
> >>>
> >>> void foo(int x, int y)
> >>> {
> >>> register int x_ asm("r0") = x;
> >>> register int y_ asm("r1") = bar(x, y);
> >>>
> >>> asm volatile (
> >>> "svc #0"
> >>> :: "r" (x_), "r" (y_)
> >>> : "memory"
> >>> );
> >>> }
> >>>
> >>> ->
> >>>
> >>> 0000000000000000 <foo>:
> >>> 0: a9bf7bfd stp x29, x30, [sp, #-16]!
> >>> 4: 910003fd mov x29, sp
> >>> 8: 94000000 bl 0 <bar>
> >>> c: 2a0003e1 mov w1, w0
> >>> 10: d4000001 svc #0x0
> >>> 14: a8c17bfd ldp x29, x30, [sp], #16
> >>> 18: d65f03c0 ret
> >>>
> >>
> >> Contextualized to what my vdso fallback functions do, this should not be a
> >> concern because in no case a function result is directly set to a variable
> >> declared as register.
> >>
> >> Since the vdso fallback functions serve a very specific and limited purpose, I
> >> do not expect that that code is going to change much in future.
> >>
> >> The only thing that can happen is something similar to what I wrote in my
> >> example, which as I empirically proved does not trigger the problematic behavior.
> >>
> >>>
> >>> The gcc documentation is vague and ambiguous about precisely whan this
> >>> can happen and about how to avoid it.
> >>>
> >>
> >> On this I agree, it is not very clear, but this seems more something to raise
> >> with the gcc folks in order to have a more "explicit" description that leaves no
> >> room to the interpretation.
> >>
> >> ...
> >>
> >>>
> >>> However, the workaround is cheap, and to avoid the chance of subtle
> >>> intermittent code gen bugs it may be worth it:
> >>>
> >>> void foo(int x, int y)
> >>> {
> >>> asm volatile (
> >>> "mov x0, %0\n\t"
> >>> "mov x1, %1\n\t"
> >>> "svc #0"
> >>> :: "r" (x), "r" (bar(x, y))
> >>> : "r0", "r1", "memory"
> >>> );
> >>> }
> >>>
> >>> ->
> >>>
> >>> 0000000000000000 <foo>:
> >>> 0: a9be7bfd stp x29, x30, [sp, #-32]!
> >>> 4: 910003fd mov x29, sp
> >>> 8: f9000bf3 str x19, [sp, #16]
> >>> c: 2a0003f3 mov w19, w0
> >>> 10: 94000000 bl 0 <bar>
> >>> 14: 2a0003e2 mov w2, w0
> >>> 18: aa1303e0 mov x0, x19
> >>> 1c: aa0203e1 mov x1, x2
> >>> 20: d4000001 svc #0x0
> >>> 24: f9400bf3 ldr x19, [sp, #16]
> >>> 28: a8c27bfd ldp x29, x30, [sp], #32
> >>> 2c: d65f03c0 ret
> >>>
> >>>
> >>> What do you think?
> >>>
> >>
> >> The solution seems ok, thanks for providing it, but IMHO I think we
> >> should find a workaround for something that is broken, which, unless
> >> I am missing something major, this seems not the case.
> >
> > So, after a bit of further experimentation, I found that I could trigger
> > it with implicit function calls on an older compiler. I couldn't show
> > it with explicit function calls (as in your example).
> >
> > With the following code, inlining if an expression that causes an
> > implicit call to a libgcc helper can trigger this issue, but I had to
> > try an older compiler:
> >
> > int foo(int x, int y)
> > {
> > register int res asm("r0");
> > register const int x_ asm("r0") = x;
> > register const int y_ asm("r1") = y;
> >
> > asm volatile (
> > "svc #0"
> > : "=r" (res)
> > : "r" (x_), "r" (y_)
> > : "memory"
> > );
> >
> > return res;
> > }
> >
> > int bar(int x, int y)
> > {
> > return foo(x, x / y);
> > }
> >
> > -> (arm-linux-gnueabihf-gcc 9.1 -O2)
> >
> > 00000000 <foo>:
> > 0: df00 svc 0
> > 2: 4770 bx lr
> >
> > 00000004 <bar>:
> > 4: b510 push {r4, lr}
> > 6: 4604 mov r4, r0
> > 8: f7ff fffe bl 0 <__aeabi_idiv>
> > c: 4601 mov r1, r0
> > e: 4620 mov r0, r4
> > 10: df00 svc 0
> > 12: bd10 pop {r4, pc}
> >
> > -> (arm-linux-gnueabihf-gcc 5.1 -O2)
> >
> > 00000000 <foo>:
> > 0: df00 svc 0
> > 2: 4770 bx lr
> >
> > 00000004 <bar>:
> > 4: b508 push {r3, lr}
> > 6: f7ff fffe bl 0 <__aeabi_idiv>
> > a: 4601 mov r1, r0
> > c: df00 svc 0
> > e: bd08 pop {r3, pc}
> >
>
> Thanks for reporting this. I had a go with gcc-5.1 on the vDSO library and seems
> Ok, but it was worth trying.
>
> For obvious reasons I am not reporting the objdump here :)
>
> > I was struggling to find a way to emit an implicit function call for
> > AArch64, except for 128-bit divide, which would complicate things since
> > uint128_t doesn't fit in a single register anyway.
> >
> > Maybe this was considered a bug and fixed sometime after GCC 5, but I
> > think the GCC documentation is still quite unclear on the semantics of
> > register asm vars that alias call-clobbered registers in the PCS.
> >
> > If we can get a promise out of the GCC folks that this will not happen
> > with any future compiler, then maybe we could just require a new enough
> > compiler to be used.
> >
>
> On this I fully agree, the compiler should never change an "expected" behavior.
>
> If the issue comes from a gray area in the documentation, we have to address it
> and have it fixed there.
>
> The minimum version of the compiler from linux-4.19 is 4.6, hence I had to try
> that the vDSO lib does not break with 5.1 [1].
>
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cafa0010cd51fb711fdcb50fc55f394c5f167a0a
OK
> > Then of course there is clang.
> >
>
> I could not help myself and I tried clang.8 and clang.7 as well with my example,
> just to make sure that we are fine even in that case. Please find below the
> results (pretty identical).
>
> main.clang.7.o: file format ELF64-aarch64-little
>
> Disassembly of section .text:
> 0000000000000000 show_it:
> 0: e8 03 1f aa mov x8, xzr
> 4: 09 68 68 38 ldrb w9, [x0, x8]
> 8: 08 05 00 91 add x8, x8, #1
> c: c9 ff ff 34 cbz w9, #-8 <show_it+0x4>
> 10: 02 05 00 51 sub w2, w8, #1
> 14: e1 03 00 aa mov x1, x0
> 18: 08 08 80 d2 mov x8, #64
> 1c: 01 00 00 d4 svc #0
> 20: c0 03 5f d6 ret
>
> main.clang.8.o: file format ELF64-aarch64-little
>
> Disassembly of section .text:
> 0000000000000000 show_it:
> 0: e8 03 1f aa mov x8, xzr
> 4: 09 68 68 38 ldrb w9, [x0, x8]
> 8: 08 05 00 91 add x8, x8, #1
> c: c9 ff ff 34 cbz w9, #-8 <show_it+0x4>
> 10: 02 05 00 51 sub w2, w8, #1
> 14: e1 03 00 aa mov x1, x0
> 18: 08 08 80 d2 mov x8, #64
> 1c: 01 00 00 d4 svc #0
> 20: c0 03 5f d6 ret
>
> Commands used:
>
> $ clang -target aarch64-linux-gnueabi main.c -O -c -o main.clang.<x>.o
> $ llvm-objdump -d main.clang.<x>.o
Actually, I'm not sure this is comparable with the reproducer I quoted
in my last reply.
The compiler can see the definition of strlen and fully inlines it.
I only ever saw the problem when the compiler emits an out-of-line
implicit function call.
What does clang do with my example on 32-bit?
Cheers
---Dave
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-27 11:27 ` Dave Martin
@ 2019-06-27 11:59 ` Vincenzo Frascino
2019-06-27 14:38 ` Dave Martin
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-27 11:59 UTC (permalink / raw)
To: Dave Martin
Cc: linux-arch, Shuah Khan, linux-mips, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, linux-kernel, Ralf Baechle, Mark Salyzyn,
Paul Burton, linux-kselftest, Rasmus Villemoes, Russell King,
Dmitry Safonov, Shijith Thotton, Peter Collingbourne,
Thomas Gleixner, linux-arm-kernel
On 6/27/19 12:27 PM, Dave Martin wrote:
> On Thu, Jun 27, 2019 at 11:57:36AM +0100, Vincenzo Frascino wrote:
>> Hi Dave,
>>
>> Overall, I want to thank you for bringing out the topic. It helped me to
>> question some decisions and make sure that we have no holes left in
>> the approach.
>
> Fair enough.
>
> This is really just a nasty compiler corner-case... the validity of the
> overall approach isn't affected.
>
>>>>
>>>> vDSO library is a shared object not compiled with LTO as far as I can
>>>> see, hence if this involved LTO should not applicable in this case.
>>>
>>> That turned to be a spurious hypothesis on my part -- LTO isn't the
>>> smoking gun. (See below.)
>>>
>>
>> Ok.
>>
>>>>> The classic example of this (triggered directly and not due to inlining)
>>>>> would be something like:
>>>>>
>>>>> int bar(int, int);
>>>>>
>>>>> void foo(int x, int y)
>>>>> {
>>>>> register int x_ asm("r0") = x;
>>>>> register int y_ asm("r1") = bar(x, y);
>>>>>
>>>>> asm volatile (
>>>>> "svc #0"
>>>>> :: "r" (x_), "r" (y_)
>>>>> : "memory"
>>>>> );
>>>>> }
>>>>>
>>>>> ->
>>>>>
>>>>> 0000000000000000 <foo>:
>>>>> 0: a9bf7bfd stp x29, x30, [sp, #-16]!
>>>>> 4: 910003fd mov x29, sp
>>>>> 8: 94000000 bl 0 <bar>
>>>>> c: 2a0003e1 mov w1, w0
>>>>> 10: d4000001 svc #0x0
>>>>> 14: a8c17bfd ldp x29, x30, [sp], #16
>>>>> 18: d65f03c0 ret
>>>>>
>>>>
>>>> Contextualized to what my vdso fallback functions do, this should not be a
>>>> concern because in no case a function result is directly set to a variable
>>>> declared as register.
>>>>
>>>> Since the vdso fallback functions serve a very specific and limited purpose, I
>>>> do not expect that that code is going to change much in future.
>>>>
>>>> The only thing that can happen is something similar to what I wrote in my
>>>> example, which as I empirically proved does not trigger the problematic behavior.
>>>>
>>>>>
>>>>> The gcc documentation is vague and ambiguous about precisely whan this
>>>>> can happen and about how to avoid it.
>>>>>
>>>>
>>>> On this I agree, it is not very clear, but this seems more something to raise
>>>> with the gcc folks in order to have a more "explicit" description that leaves no
>>>> room to the interpretation.
>>>>
>>>> ...
>>>>
>>>>>
>>>>> However, the workaround is cheap, and to avoid the chance of subtle
>>>>> intermittent code gen bugs it may be worth it:
>>>>>
>>>>> void foo(int x, int y)
>>>>> {
>>>>> asm volatile (
>>>>> "mov x0, %0\n\t"
>>>>> "mov x1, %1\n\t"
>>>>> "svc #0"
>>>>> :: "r" (x), "r" (bar(x, y))
>>>>> : "r0", "r1", "memory"
>>>>> );
>>>>> }
>>>>>
>>>>> ->
>>>>>
>>>>> 0000000000000000 <foo>:
>>>>> 0: a9be7bfd stp x29, x30, [sp, #-32]!
>>>>> 4: 910003fd mov x29, sp
>>>>> 8: f9000bf3 str x19, [sp, #16]
>>>>> c: 2a0003f3 mov w19, w0
>>>>> 10: 94000000 bl 0 <bar>
>>>>> 14: 2a0003e2 mov w2, w0
>>>>> 18: aa1303e0 mov x0, x19
>>>>> 1c: aa0203e1 mov x1, x2
>>>>> 20: d4000001 svc #0x0
>>>>> 24: f9400bf3 ldr x19, [sp, #16]
>>>>> 28: a8c27bfd ldp x29, x30, [sp], #32
>>>>> 2c: d65f03c0 ret
>>>>>
>>>>>
>>>>> What do you think?
>>>>>
>>>>
>>>> The solution seems ok, thanks for providing it, but IMHO I think we
>>>> should find a workaround for something that is broken, which, unless
>>>> I am missing something major, this seems not the case.
>>>
>>> So, after a bit of further experimentation, I found that I could trigger
>>> it with implicit function calls on an older compiler. I couldn't show
>>> it with explicit function calls (as in your example).
>>>
>>> With the following code, inlining if an expression that causes an
>>> implicit call to a libgcc helper can trigger this issue, but I had to
>>> try an older compiler:
>>>
>>> int foo(int x, int y)
>>> {
>>> register int res asm("r0");
>>> register const int x_ asm("r0") = x;
>>> register const int y_ asm("r1") = y;
>>>
>>> asm volatile (
>>> "svc #0"
>>> : "=r" (res)
>>> : "r" (x_), "r" (y_)
>>> : "memory"
>>> );
>>>
>>> return res;
>>> }
>>>
>>> int bar(int x, int y)
>>> {
>>> return foo(x, x / y);
>>> }
>>>
>>> -> (arm-linux-gnueabihf-gcc 9.1 -O2)
>>>
>>> 00000000 <foo>:
>>> 0: df00 svc 0
>>> 2: 4770 bx lr
>>>
>>> 00000004 <bar>:
>>> 4: b510 push {r4, lr}
>>> 6: 4604 mov r4, r0
>>> 8: f7ff fffe bl 0 <__aeabi_idiv>
>>> c: 4601 mov r1, r0
>>> e: 4620 mov r0, r4
>>> 10: df00 svc 0
>>> 12: bd10 pop {r4, pc}
>>>
>>> -> (arm-linux-gnueabihf-gcc 5.1 -O2)
>>>
>>> 00000000 <foo>:
>>> 0: df00 svc 0
>>> 2: 4770 bx lr
>>>
>>> 00000004 <bar>:
>>> 4: b508 push {r3, lr}
>>> 6: f7ff fffe bl 0 <__aeabi_idiv>
>>> a: 4601 mov r1, r0
>>> c: df00 svc 0
>>> e: bd08 pop {r3, pc}
>>>
>>
>> Thanks for reporting this. I had a go with gcc-5.1 on the vDSO library and seems
>> Ok, but it was worth trying.
>>
>> For obvious reasons I am not reporting the objdump here :)
>>
>>> I was struggling to find a way to emit an implicit function call for
>>> AArch64, except for 128-bit divide, which would complicate things since
>>> uint128_t doesn't fit in a single register anyway.
>>>
>>> Maybe this was considered a bug and fixed sometime after GCC 5, but I
>>> think the GCC documentation is still quite unclear on the semantics of
>>> register asm vars that alias call-clobbered registers in the PCS.
>>>
>>> If we can get a promise out of the GCC folks that this will not happen
>>> with any future compiler, then maybe we could just require a new enough
>>> compiler to be used.
>>>
>>
>> On this I fully agree, the compiler should never change an "expected" behavior.
>>
>> If the issue comes from a gray area in the documentation, we have to address it
>> and have it fixed there.
>>
>> The minimum version of the compiler from linux-4.19 is 4.6, hence I had to try
>> that the vDSO lib does not break with 5.1 [1].
>>
>> [1]
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cafa0010cd51fb711fdcb50fc55f394c5f167a0a
>
> OK
>
>>> Then of course there is clang.
>>>
>>
>> I could not help myself and I tried clang.8 and clang.7 as well with my example,
>> just to make sure that we are fine even in that case. Please find below the
>> results (pretty identical).
>>
>> main.clang.7.o: file format ELF64-aarch64-little
>>
>> Disassembly of section .text:
>> 0000000000000000 show_it:
>> 0: e8 03 1f aa mov x8, xzr
>> 4: 09 68 68 38 ldrb w9, [x0, x8]
>> 8: 08 05 00 91 add x8, x8, #1
>> c: c9 ff ff 34 cbz w9, #-8 <show_it+0x4>
>> 10: 02 05 00 51 sub w2, w8, #1
>> 14: e1 03 00 aa mov x1, x0
>> 18: 08 08 80 d2 mov x8, #64
>> 1c: 01 00 00 d4 svc #0
>> 20: c0 03 5f d6 ret
>>
>> main.clang.8.o: file format ELF64-aarch64-little
>>
>> Disassembly of section .text:
>> 0000000000000000 show_it:
>> 0: e8 03 1f aa mov x8, xzr
>> 4: 09 68 68 38 ldrb w9, [x0, x8]
>> 8: 08 05 00 91 add x8, x8, #1
>> c: c9 ff ff 34 cbz w9, #-8 <show_it+0x4>
>> 10: 02 05 00 51 sub w2, w8, #1
>> 14: e1 03 00 aa mov x1, x0
>> 18: 08 08 80 d2 mov x8, #64
>> 1c: 01 00 00 d4 svc #0
>> 20: c0 03 5f d6 ret
>>
>> Commands used:
>>
>> $ clang -target aarch64-linux-gnueabi main.c -O -c -o main.clang.<x>.o
>> $ llvm-objdump -d main.clang.<x>.o
>
> Actually, I'm not sure this is comparable with the reproducer I quoted
> in my last reply.
>
As explained in my previous email, this is the only case that can realistically
happen. vDSO has no dependency on any other library (i.e. libgcc you were
mentioning) and we are referring to the fallbacks which fall in this category.
> The compiler can see the definition of strlen and fully inlines it.
> I only ever saw the problem when the compiler emits an out-of-line
> implicit function call.
> > What does clang do with my example on 32-bit?
When clang is selected compat vDSOs are currently disabled on arm64, will be
introduced with a future patch series.
Anyway since I am curious as well, this is what happens with your example with
clang.8 target=arm-linux-gnueabihf:
dave-code.clang.8.o: file format ELF32-arm-little
Disassembly of section .text:
0000000000000000 foo:
0: 00 00 00 ef svc #0
4: 1e ff 2f e1 bx lr
0000000000000008 bar:
8: 10 4c 2d e9 push {r4, r10, r11, lr}
c: 08 b0 8d e2 add r11, sp, #8
10: 00 40 a0 e1 mov r4, r0
14: fe ff ff eb bl #-8 <bar+0xc>
18: 00 10 a0 e1 mov r1, r0
1c: 04 00 a0 e1 mov r0, r4
20: 00 00 00 ef svc #0
24: 10 8c bd e8 pop {r4, r10, r11, pc}
Compiled with -O2, -O3, -Os never inlines.
Same thing happens for aarch64-linux-gnueabi:
dave-code.clang.8.o: file format ELF64-aarch64-little
Disassembly of section .text:
0000000000000000 foo:
0: e0 03 00 2a mov w0, w0
4: e1 03 01 2a mov w1, w1
8: 01 00 00 d4 svc #0
c: c0 03 5f d6 ret
0000000000000010 bar:
10: 01 0c c1 1a sdiv w1, w0, w1
14: e0 03 00 2a mov w0, w0
18: 01 00 00 d4 svc #0
1c: c0 03 5f d6 ret
Based on this I think we can conclude our investigation.
>
> Cheers
> ---Dave
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-27 11:59 ` Vincenzo Frascino
@ 2019-06-27 14:38 ` Dave Martin
2019-06-27 15:34 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Dave Martin @ 2019-06-27 14:38 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, Shijith Thotton, Peter Collingbourne, Arnd Bergmann,
Huw Davies, Andre Przywara, Daniel Lezcano, Will Deacon,
linux-mips, Ralf Baechle, linux-kernel, Paul Burton,
Rasmus Villemoes, linux-kselftest, Catalin Marinas, Russell King,
Dmitry Safonov, Mark Salyzyn, Shuah Khan, Thomas Gleixner,
linux-arm-kernel
On Thu, Jun 27, 2019 at 12:59:07PM +0100, Vincenzo Frascino wrote:
> On 6/27/19 12:27 PM, Dave Martin wrote:
> > On Thu, Jun 27, 2019 at 11:57:36AM +0100, Vincenzo Frascino wrote:
[...]
> >> Disassembly of section .text:
> >> 0000000000000000 show_it:
> >> 0: e8 03 1f aa mov x8, xzr
> >> 4: 09 68 68 38 ldrb w9, [x0, x8]
> >> 8: 08 05 00 91 add x8, x8, #1
> >> c: c9 ff ff 34 cbz w9, #-8 <show_it+0x4>
> >> 10: 02 05 00 51 sub w2, w8, #1
> >> 14: e1 03 00 aa mov x1, x0
> >> 18: 08 08 80 d2 mov x8, #64
> >> 1c: 01 00 00 d4 svc #0
> >> 20: c0 03 5f d6 ret
> >>
> >> Commands used:
> >>
> >> $ clang -target aarch64-linux-gnueabi main.c -O -c -o main.clang.<x>.o
> >> $ llvm-objdump -d main.clang.<x>.o
> >
> > Actually, I'm not sure this is comparable with the reproducer I quoted
> > in my last reply.
> >
>
> As explained in my previous email, this is the only case that can realistically
> happen. vDSO has no dependency on any other library (i.e. libgcc you were
> mentioning) and we are referring to the fallbacks which fall in this category.
Outlining could also introduce a local function call where none exists
explicitly in the program IIUC.
My point is that the interaction between asm reg vars and machine-level
procedure calls is at best ill-defined, and it is largely up to the
compiler when to introduce such a call, even without LTO etc.
So we should not be surprised to see variations in behaviour depending
on compiler, compiler version and compiler flags.
> > The compiler can see the definition of strlen and fully inlines it.
> > I only ever saw the problem when the compiler emits an out-of-line
> > implicit function call.
> > > What does clang do with my example on 32-bit?
>
> When clang is selected compat vDSOs are currently disabled on arm64, will be
> introduced with a future patch series.
>
> Anyway since I am curious as well, this is what happens with your example with
> clang.8 target=arm-linux-gnueabihf:
>
> dave-code.clang.8.o: file format ELF32-arm-little
>
> Disassembly of section .text:
> 0000000000000000 foo:
> 0: 00 00 00 ef svc #0
> 4: 1e ff 2f e1 bx lr
>
> 0000000000000008 bar:
> 8: 10 4c 2d e9 push {r4, r10, r11, lr}
> c: 08 b0 8d e2 add r11, sp, #8
> 10: 00 40 a0 e1 mov r4, r0
> 14: fe ff ff eb bl #-8 <bar+0xc>
> 18: 00 10 a0 e1 mov r1, r0
> 1c: 04 00 a0 e1 mov r0, r4
> 20: 00 00 00 ef svc #0
> 24: 10 8c bd e8 pop {r4, r10, r11, pc}
> Compiled with -O2, -O3, -Os never inlines.
Looks sane, and is the behaviour we want.
> Same thing happens for aarch64-linux-gnueabi:
>
> dave-code.clang.8.o: file format ELF64-aarch64-little
>
> Disassembly of section .text:
> 0000000000000000 foo:
> 0: e0 03 00 2a mov w0, w0
> 4: e1 03 01 2a mov w1, w1
> 8: 01 00 00 d4 svc #0
> c: c0 03 5f d6 ret
>
> 0000000000000010 bar:
> 10: 01 0c c1 1a sdiv w1, w0, w1
> 14: e0 03 00 2a mov w0, w0
> 18: 01 00 00 d4 svc #0
> 1c: c0 03 5f d6 ret
Curious, clang seems to be inserting some seemingly redundant moves
of its own here, though this shouldn't break anything.
I suspect that clang might require an X-reg holding an int to have its
top 32 bits zeroed for passing to an asm, whereas GCC does not. I think
this comes under "we should not be surprised to see variations".
GCC 9 does this instead:
0000000000000000 <foo>:
0: d4000001 svc #0x0
4: d65f03c0 ret
0000000000000008 <bar>:
8: 1ac10c01 sdiv w1, w0, w1
c: d4000001 svc #0x0
10: d65f03c0 ret
> Based on this I think we can conclude our investigation.
So we use non-reg vars and use the asm clobber list and explicit moves
to get things into / out of the right registers?
Cheers
---Dave
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-27 14:38 ` Dave Martin
@ 2019-06-27 15:34 ` Vincenzo Frascino
0 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-27 15:34 UTC (permalink / raw)
To: Dave Martin
Cc: linux-arch, Shijith Thotton, Peter Collingbourne, Arnd Bergmann,
Huw Davies, Andre Przywara, Daniel Lezcano, Will Deacon,
linux-mips, Ralf Baechle, linux-kernel, Paul Burton,
Rasmus Villemoes, linux-kselftest, Catalin Marinas, Russell King,
Dmitry Safonov, Mark Salyzyn, Shuah Khan, Thomas Gleixner,
linux-arm-kernel
Hi Dave,
On 6/27/19 3:38 PM, Dave Martin wrote:
> On Thu, Jun 27, 2019 at 12:59:07PM +0100, Vincenzo Frascino wrote:
>> On 6/27/19 12:27 PM, Dave Martin wrote:
>>> On Thu, Jun 27, 2019 at 11:57:36AM +0100, Vincenzo Frascino wrote:
>
> [...]
>
>>>> Disassembly of section .text:
>>>> 0000000000000000 show_it:
>>>> 0: e8 03 1f aa mov x8, xzr
>>>> 4: 09 68 68 38 ldrb w9, [x0, x8]
>>>> 8: 08 05 00 91 add x8, x8, #1
>>>> c: c9 ff ff 34 cbz w9, #-8 <show_it+0x4>
>>>> 10: 02 05 00 51 sub w2, w8, #1
>>>> 14: e1 03 00 aa mov x1, x0
>>>> 18: 08 08 80 d2 mov x8, #64
>>>> 1c: 01 00 00 d4 svc #0
>>>> 20: c0 03 5f d6 ret
>>>>
>>>> Commands used:
>>>>
>>>> $ clang -target aarch64-linux-gnueabi main.c -O -c -o main.clang.<x>.o
>>>> $ llvm-objdump -d main.clang.<x>.o
>>>
>>> Actually, I'm not sure this is comparable with the reproducer I quoted
>>> in my last reply.
>>>
>>
>> As explained in my previous email, this is the only case that can realistically
>> happen. vDSO has no dependency on any other library (i.e. libgcc you were
>> mentioning) and we are referring to the fallbacks which fall in this category.
>
> Outlining could also introduce a local function call where none exists
> explicitly in the program IIUC.
>
> My point is that the interaction between asm reg vars and machine-level
> procedure calls is at best ill-defined, and it is largely up to the
> compiler when to introduce such a call, even without LTO etc.
>
> So we should not be surprised to see variations in behaviour depending
> on compiler, compiler version and compiler flags.
>
I tested 10 version of the compiler and a part gcc-5.1 that triggers the issue
in a specific case and not in the vdso library, I could not find evidence of the
problem.
>>> The compiler can see the definition of strlen and fully inlines it.
>>> I only ever saw the problem when the compiler emits an out-of-line
>>> implicit function call.
>>>> What does clang do with my example on 32-bit?
>>
>> When clang is selected compat vDSOs are currently disabled on arm64, will be
>> introduced with a future patch series.
>>
>> Anyway since I am curious as well, this is what happens with your example with
>> clang.8 target=arm-linux-gnueabihf:
>>
>> dave-code.clang.8.o: file format ELF32-arm-little
>>
>> Disassembly of section .text:
>> 0000000000000000 foo:
>> 0: 00 00 00 ef svc #0
>> 4: 1e ff 2f e1 bx lr
>>
>> 0000000000000008 bar:
>> 8: 10 4c 2d e9 push {r4, r10, r11, lr}
>> c: 08 b0 8d e2 add r11, sp, #8
>> 10: 00 40 a0 e1 mov r4, r0
>> 14: fe ff ff eb bl #-8 <bar+0xc>
>> 18: 00 10 a0 e1 mov r1, r0
>> 1c: 04 00 a0 e1 mov r0, r4
>> 20: 00 00 00 ef svc #0
>> 24: 10 8c bd e8 pop {r4, r10, r11, pc}
>
>> Compiled with -O2, -O3, -Os never inlines.
>
> Looks sane, and is the behaviour we want.
>
>> Same thing happens for aarch64-linux-gnueabi:
>>
>> dave-code.clang.8.o: file format ELF64-aarch64-little
>>
>> Disassembly of section .text:
>> 0000000000000000 foo:
>> 0: e0 03 00 2a mov w0, w0
>> 4: e1 03 01 2a mov w1, w1
>> 8: 01 00 00 d4 svc #0
>> c: c0 03 5f d6 ret
>>
>> 0000000000000010 bar:
>> 10: 01 0c c1 1a sdiv w1, w0, w1
>> 14: e0 03 00 2a mov w0, w0
>> 18: 01 00 00 d4 svc #0
>> 1c: c0 03 5f d6 ret
>
> Curious, clang seems to be inserting some seemingly redundant moves
> of its own here, though this shouldn't break anything.
>
> I suspect that clang might require an X-reg holding an int to have its
> top 32 bits zeroed for passing to an asm, whereas GCC does not. I think
> this comes under "we should not be surprised to see variations".
>
> GCC 9 does this instead:
>
> 0000000000000000 <foo>:
> 0: d4000001 svc #0x0
> 4: d65f03c0 ret
>
> 0000000000000008 <bar>:
> 8: 1ac10c01 sdiv w1, w0, w1
> c: d4000001 svc #0x0
> 10: d65f03c0 ret
>
>
>> Based on this I think we can conclude our investigation.
>
> So we use non-reg vars and use the asm clobber list and explicit moves
> to get things into / out of the right registers?
>
Since I managed to provide enough evidence, based on the behavior of various
versions of the compilers, that the library as it stands is consistent and does
not suffer any of the issues you reported I think I will keep my code as is at
least for this release, I will revisit it in future if something happens.
If you manage to prove that my library as it stands (no code additions or source
modifications) has the issues you mentioned based on some version of the
compiler, this changes everything.
Happy to hear from you.
> Cheers
> ---Dave
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH] arm64: vdso: Fix compilation with clang < 8
2019-06-21 9:52 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Vincenzo Frascino
` (2 preceding siblings ...)
2019-06-25 15:33 ` Dave Martin
@ 2019-06-25 17:43 ` Vincenzo Frascino
2019-06-26 11:36 ` [PATCH v2] arm64: vdso: Fix compilation with clang older then 8 Vincenzo Frascino
[not found] ` <CGME20190628130921eucas1p239935b0771032c331911eacc1a69dd2e@eucas1p2.samsung.com>
5 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-25 17:43 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara, luto, Qian Cai
clang versions previous to 8 do not support -mcmodel=tiny.
Add a check to the vDSO Makefile for arm64 to remove the flag when these
versions of the compiler are detected.
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Reported-by: Qian Cai <cai@lca.pw>
Tested-by: Qian Cai <cai@lca.pw>
---
arch/arm64/kernel/vdso/Makefile | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index ec81d28aeb5d..5154f50aff2d 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -38,6 +38,11 @@ else
CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -include $(c-gettimeofday-y)
endif
+# Clang versions less than 8 do not support -mcmodel=tiny
+ifeq ($(shell test $(CONFIG_CLANG_VERSION) -lt 80000; echo $$?),0)
+CFLAGS_REMOVE_vgettimeofday.o += -mcmodel=tiny
+endif
+
# Disable gcov profiling for VDSO code
GCOV_PROFILE := n
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v2] arm64: vdso: Fix compilation with clang older then 8
2019-06-21 9:52 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Vincenzo Frascino
` (3 preceding siblings ...)
2019-06-25 17:43 ` [PATCH] arm64: vdso: Fix compilation with clang < 8 Vincenzo Frascino
@ 2019-06-26 11:36 ` Vincenzo Frascino
[not found] ` <CGME20190628130921eucas1p239935b0771032c331911eacc1a69dd2e@eucas1p2.samsung.com>
5 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-26 11:36 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara, luto, Qian Cai
clang versions older then 8 do not support -mcmodel=tiny.
Add a check to the vDSO Makefile for arm64 to remove the flag when
these versions of the compiler are detected.
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Reported-by: Qian Cai <cai@lca.pw>
Tested-by: Qian Cai <cai@lca.pw>
---
arch/arm64/kernel/vdso/Makefile | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index ec81d28aeb5d..4ab863045188 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -38,6 +38,13 @@ else
CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -include $(c-gettimeofday-y)
endif
+# Clang versions less than 8 do not support -mcmodel=tiny
+ifeq ($(CONFIG_CC_IS_CLANG), y)
+ ifeq ($(shell test $(CONFIG_CLANG_VERSION) -lt 80000; echo $$?),0)
+ CFLAGS_REMOVE_vgettimeofday.o += -mcmodel=tiny
+ endif
+endif
+
# Disable gcov profiling for VDSO code
GCOV_PROFILE := n
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
[parent not found: <CGME20190628130921eucas1p239935b0771032c331911eacc1a69dd2e@eucas1p2.samsung.com>]
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
[not found] ` <CGME20190628130921eucas1p239935b0771032c331911eacc1a69dd2e@eucas1p2.samsung.com>
@ 2019-06-28 13:09 ` Marek Szyprowski
2019-06-28 14:32 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Marek Szyprowski @ 2019-06-28 13:09 UTC (permalink / raw)
To: Vincenzo Frascino, linux-arch, linux-arm-kernel, linux-kernel,
linux-mips, linux-kselftest
Cc: Shuah Khan, Andre Przywara, Arnd Bergmann, Huw Davies,
Catalin Marinas, Daniel Lezcano, Will Deacon, Russell King,
Ralf Baechle, Mark Salyzyn, Paul Burton, Dmitry Safonov,
Rasmus Villemoes, Thomas Gleixner, Shijith Thotton,
Peter Collingbourne, Sylwester Nawrocki
Dear All,
On 2019-06-21 11:52, Vincenzo Frascino wrote:
> To take advantage of the commonly defined vdso interface for
> gettimeofday the architectural code requires an adaptation.
>
> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>
> With the new implementation arm64 gains support for CLOCK_BOOTTIME
> and CLOCK_TAI.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> Tested-by: Shijith Thotton <sthotton@marvell.com>
> Tested-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This patch causes serious regression on Samsung Exynos5433 SoC based
TM2(e) boards. The time in userspace is always set to begin of the epoch:
# date 062813152019
Fri Jun 28 13:15:00 UTC 2019
# date
Thu Jan 1 00:00:00 UTC 1970
# date
Thu Jan 1 00:00:00 UTC 1970
I've noticed that since the patch landed in Linux next-20190625 and
bisect indeed pointed to this patch.
> ---
> arch/arm64/Kconfig | 2 +
> arch/arm64/include/asm/vdso/gettimeofday.h | 86 ++++++
> arch/arm64/include/asm/vdso/vsyscall.h | 53 ++++
> arch/arm64/include/asm/vdso_datapage.h | 48 ---
> arch/arm64/kernel/asm-offsets.c | 33 +-
> arch/arm64/kernel/vdso.c | 51 +---
> arch/arm64/kernel/vdso/Makefile | 34 ++-
> arch/arm64/kernel/vdso/gettimeofday.S | 334 ---------------------
> arch/arm64/kernel/vdso/vgettimeofday.c | 28 ++
> 9 files changed, 223 insertions(+), 446 deletions(-)
> create mode 100644 arch/arm64/include/asm/vdso/gettimeofday.h
> create mode 100644 arch/arm64/include/asm/vdso/vsyscall.h
> delete mode 100644 arch/arm64/include/asm/vdso_datapage.h
> delete mode 100644 arch/arm64/kernel/vdso/gettimeofday.S
> create mode 100644 arch/arm64/kernel/vdso/vgettimeofday.c
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 697ea0510729..952c9f8cf3b8 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -107,6 +107,7 @@ config ARM64
> select GENERIC_STRNCPY_FROM_USER
> select GENERIC_STRNLEN_USER
> select GENERIC_TIME_VSYSCALL
> + select GENERIC_GETTIMEOFDAY
> select HANDLE_DOMAIN_IRQ
> select HARDIRQS_SW_RESEND
> select HAVE_PCI
> @@ -160,6 +161,7 @@ config ARM64
> select HAVE_SYSCALL_TRACEPOINTS
> select HAVE_KPROBES
> select HAVE_KRETPROBES
> + select HAVE_GENERIC_VDSO
> select IOMMU_DMA if IOMMU_SUPPORT
> select IRQ_DOMAIN
> select IRQ_FORCED_THREADING
> diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
> new file mode 100644
> index 000000000000..bc3cb6738051
> --- /dev/null
> +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
> @@ -0,0 +1,86 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2018 ARM Limited
> + */
> +#ifndef __ASM_VDSO_GETTIMEOFDAY_H
> +#define __ASM_VDSO_GETTIMEOFDAY_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#include <asm/unistd.h>
> +#include <uapi/linux/time.h>
> +
> +#define VDSO_HAS_CLOCK_GETRES 1
> +
> +static __always_inline int gettimeofday_fallback(
> + struct __kernel_old_timeval *_tv,
> + struct timezone *_tz)
> +{
> + register struct timezone *tz asm("x1") = _tz;
> + register struct __kernel_old_timeval *tv asm("x0") = _tv;
> + register long ret asm ("x0");
> + register long nr asm("x8") = __NR_gettimeofday;
> +
> + asm volatile(
> + " svc #0\n"
> + : "=r" (ret)
> + : "r" (tv), "r" (tz), "r" (nr)
> + : "memory");
> +
> + return ret;
> +}
> +
> +static __always_inline long clock_gettime_fallback(
> + clockid_t _clkid,
> + struct __kernel_timespec *_ts)
> +{
> + register struct __kernel_timespec *ts asm("x1") = _ts;
> + register clockid_t clkid asm("x0") = _clkid;
> + register long ret asm ("x0");
> + register long nr asm("x8") = __NR_clock_gettime;
> +
> + asm volatile(
> + " svc #0\n"
> + : "=r" (ret)
> + : "r" (clkid), "r" (ts), "r" (nr)
> + : "memory");
> +
> + return ret;
> +}
> +
> +static __always_inline int clock_getres_fallback(
> + clockid_t _clkid,
> + struct __kernel_timespec *_ts)
> +{
> + register struct __kernel_timespec *ts asm("x1") = _ts;
> + register clockid_t clkid asm("x0") = _clkid;
> + register long ret asm ("x0");
> + register long nr asm("x8") = __NR_clock_getres;
> +
> + asm volatile(
> + " svc #0\n"
> + : "=r" (ret)
> + : "r" (clkid), "r" (ts), "r" (nr)
> + : "memory");
> +
> + return ret;
> +}
> +
> +static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
> +{
> + u64 res;
> +
> + asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
> +
> + return res;
> +}
> +
> +static __always_inline
> +const struct vdso_data *__arch_get_vdso_data(void)
> +{
> + return _vdso_data;
> +}
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
> diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
> new file mode 100644
> index 000000000000..0c731bfc7c8c
> --- /dev/null
> +++ b/arch/arm64/include/asm/vdso/vsyscall.h
> @@ -0,0 +1,53 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ASM_VDSO_VSYSCALL_H
> +#define __ASM_VDSO_VSYSCALL_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#include <linux/timekeeper_internal.h>
> +#include <vdso/datapage.h>
> +
> +#define VDSO_PRECISION_MASK ~(0xFF00ULL<<48)
> +
> +extern struct vdso_data *vdso_data;
> +
> +/*
> + * Update the vDSO data page to keep in sync with kernel timekeeping.
> + */
> +static __always_inline
> +struct vdso_data *__arm64_get_k_vdso_data(void)
> +{
> + return vdso_data;
> +}
> +#define __arch_get_k_vdso_data __arm64_get_k_vdso_data
> +
> +static __always_inline
> +int __arm64_get_clock_mode(struct timekeeper *tk)
> +{
> + u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
> +
> + return use_syscall;
> +}
> +#define __arch_get_clock_mode __arm64_get_clock_mode
> +
> +static __always_inline
> +int __arm64_use_vsyscall(struct vdso_data *vdata)
> +{
> + return !vdata[CS_HRES_COARSE].clock_mode;
> +}
> +#define __arch_use_vsyscall __arm64_use_vsyscall
> +
> +static __always_inline
> +void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
> +{
> + vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
> + vdata[CS_RAW].mask = VDSO_PRECISION_MASK;
> +}
> +#define __arch_update_vsyscall __arm64_update_vsyscall
> +
> +/* The asm-generic header needs to be included after the definitions above */
> +#include <asm-generic/vdso/vsyscall.h>
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __ASM_VDSO_VSYSCALL_H */
> diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h
> deleted file mode 100644
> index f89263c8e11a..000000000000
> --- a/arch/arm64/include/asm/vdso_datapage.h
> +++ /dev/null
> @@ -1,48 +0,0 @@
> -/*
> - * Copyright (C) 2012 ARM Limited
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - *
> - * 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, see <http://www.gnu.org/licenses/>.
> - */
> -#ifndef __ASM_VDSO_DATAPAGE_H
> -#define __ASM_VDSO_DATAPAGE_H
> -
> -#ifdef __KERNEL__
> -
> -#ifndef __ASSEMBLY__
> -
> -struct vdso_data {
> - __u64 cs_cycle_last; /* Timebase at clocksource init */
> - __u64 raw_time_sec; /* Raw time */
> - __u64 raw_time_nsec;
> - __u64 xtime_clock_sec; /* Kernel time */
> - __u64 xtime_clock_nsec;
> - __u64 xtime_coarse_sec; /* Coarse time */
> - __u64 xtime_coarse_nsec;
> - __u64 wtm_clock_sec; /* Wall to monotonic time */
> - __u64 wtm_clock_nsec;
> - __u32 tb_seq_count; /* Timebase sequence counter */
> - /* cs_* members must be adjacent and in this order (ldp accesses) */
> - __u32 cs_mono_mult; /* NTP-adjusted clocksource multiplier */
> - __u32 cs_shift; /* Clocksource shift (mono = raw) */
> - __u32 cs_raw_mult; /* Raw clocksource multiplier */
> - __u32 tz_minuteswest; /* Whacky timezone stuff */
> - __u32 tz_dsttime;
> - __u32 use_syscall;
> - __u32 hrtimer_res;
> -};
> -
> -#endif /* !__ASSEMBLY__ */
> -
> -#endif /* __KERNEL__ */
> -
> -#endif /* __ASM_VDSO_DATAPAGE_H */
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index 947e39896e28..9e4b7ccbab2f 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -25,13 +25,13 @@
> #include <linux/kvm_host.h>
> #include <linux/preempt.h>
> #include <linux/suspend.h>
> +#include <vdso/datapage.h>
> #include <asm/cpufeature.h>
> #include <asm/fixmap.h>
> #include <asm/thread_info.h>
> #include <asm/memory.h>
> #include <asm/smp_plat.h>
> #include <asm/suspend.h>
> -#include <asm/vdso_datapage.h>
> #include <linux/kbuild.h>
> #include <linux/arm-smccc.h>
>
> @@ -100,17 +100,28 @@ int main(void)
> DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
> DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
> BLANK();
> - DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last));
> - DEFINE(VDSO_RAW_TIME_SEC, offsetof(struct vdso_data, raw_time_sec));
> - DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec));
> - DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec));
> - DEFINE(VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec));
> - DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec));
> - DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count));
> - DEFINE(VDSO_CS_MONO_MULT, offsetof(struct vdso_data, cs_mono_mult));
> - DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift));
> + DEFINE(VDSO_SEQ, offsetof(struct vdso_data, seq));
> + DEFINE(VDSO_CLK_MODE, offsetof(struct vdso_data, clock_mode));
> + DEFINE(VDSO_CYCLE_LAST, offsetof(struct vdso_data, cycle_last));
> + DEFINE(VDSO_MASK, offsetof(struct vdso_data, mask));
> + DEFINE(VDSO_MULT, offsetof(struct vdso_data, mult));
> + DEFINE(VDSO_SHIFT, offsetof(struct vdso_data, shift));
> + DEFINE(VDSO_REALTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].sec));
> + DEFINE(VDSO_REALTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].nsec));
> + DEFINE(VDSO_MONO_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].sec));
> + DEFINE(VDSO_MONO_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].nsec));
> + DEFINE(VDSO_MONO_RAW_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].sec));
> + DEFINE(VDSO_MONO_RAW_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].nsec));
> + DEFINE(VDSO_BOOTTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].sec));
> + DEFINE(VDSO_BOOTTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].nsec));
> + DEFINE(VDSO_TAI_SEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].sec));
> + DEFINE(VDSO_TAI_NSEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].nsec));
> + DEFINE(VDSO_RT_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].sec));
> + DEFINE(VDSO_RT_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].nsec));
> + DEFINE(VDSO_MONO_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].sec));
> + DEFINE(VDSO_MONO_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].nsec));
> DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest));
> - DEFINE(VDSO_USE_SYSCALL, offsetof(struct vdso_data, use_syscall));
> + DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
> BLANK();
> DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec));
> DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index 8074cbd3a3a8..23c38303a52a 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -31,11 +31,13 @@
> #include <linux/slab.h>
> #include <linux/timekeeper_internal.h>
> #include <linux/vmalloc.h>
> +#include <vdso/datapage.h>
> +#include <vdso/helpers.h>
> +#include <vdso/vsyscall.h>
>
> #include <asm/cacheflush.h>
> #include <asm/signal32.h>
> #include <asm/vdso.h>
> -#include <asm/vdso_datapage.h>
>
> extern char vdso_start[], vdso_end[];
> static unsigned long vdso_pages __ro_after_init;
> @@ -44,10 +46,10 @@ static unsigned long vdso_pages __ro_after_init;
> * The vDSO data page.
> */
> static union {
> - struct vdso_data data;
> + struct vdso_data data[CS_BASES];
> u8 page[PAGE_SIZE];
> } vdso_data_store __page_aligned_data;
> -struct vdso_data *vdso_data = &vdso_data_store.data;
> +struct vdso_data *vdso_data = vdso_data_store.data;
>
> #ifdef CONFIG_COMPAT
> /*
> @@ -280,46 +282,3 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
> up_write(&mm->mmap_sem);
> return PTR_ERR(ret);
> }
> -
> -/*
> - * Update the vDSO data page to keep in sync with kernel timekeeping.
> - */
> -void update_vsyscall(struct timekeeper *tk)
> -{
> - u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
> -
> - ++vdso_data->tb_seq_count;
> - smp_wmb();
> -
> - vdso_data->use_syscall = use_syscall;
> - vdso_data->xtime_coarse_sec = tk->xtime_sec;
> - vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >>
> - tk->tkr_mono.shift;
> - vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
> - vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
> -
> - /* Read without the seqlock held by clock_getres() */
> - WRITE_ONCE(vdso_data->hrtimer_res, hrtimer_resolution);
> -
> - if (!use_syscall) {
> - /* tkr_mono.cycle_last == tkr_raw.cycle_last */
> - vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
> - vdso_data->raw_time_sec = tk->raw_sec;
> - vdso_data->raw_time_nsec = tk->tkr_raw.xtime_nsec;
> - vdso_data->xtime_clock_sec = tk->xtime_sec;
> - vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec;
> - vdso_data->cs_mono_mult = tk->tkr_mono.mult;
> - vdso_data->cs_raw_mult = tk->tkr_raw.mult;
> - /* tkr_mono.shift == tkr_raw.shift */
> - vdso_data->cs_shift = tk->tkr_mono.shift;
> - }
> -
> - smp_wmb();
> - ++vdso_data->tb_seq_count;
> -}
> -
> -void update_vsyscall_tz(void)
> -{
> - vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
> - vdso_data->tz_dsttime = sys_tz.tz_dsttime;
> -}
> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
> index fa230ff09aa1..3acfc813e966 100644
> --- a/arch/arm64/kernel/vdso/Makefile
> +++ b/arch/arm64/kernel/vdso/Makefile
> @@ -6,7 +6,12 @@
> # Heavily based on the vDSO Makefiles for other archs.
> #
>
> -obj-vdso := gettimeofday.o note.o sigreturn.o
> +# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
> +# the inclusion of generic Makefile.
> +ARCH_REL_TYPE_ABS := R_AARCH64_JUMP_SLOT|R_AARCH64_GLOB_DAT|R_AARCH64_ABS64
> +include $(srctree)/lib/vdso/Makefile
> +
> +obj-vdso := vgettimeofday.o note.o sigreturn.o
>
> # Build rules
> targets := $(obj-vdso) vdso.so vdso.so.dbg
> @@ -15,6 +20,24 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
> ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \
> --build-id -n -T
>
> +ccflags-y := -fno-common -fno-builtin -fno-stack-protector
> +ccflags-y += -DDISABLE_BRANCH_PROFILING
> +
> +VDSO_LDFLAGS := -Bsymbolic
> +
> +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
> +KBUILD_CFLAGS += $(DISABLE_LTO)
> +KASAN_SANITIZE := n
> +UBSAN_SANITIZE := n
> +OBJECT_FILES_NON_STANDARD := y
> +KCOV_INSTRUMENT := n
> +
> +ifeq ($(c-gettimeofday-y),)
> +CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny
> +else
> +CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -include $(c-gettimeofday-y)
> +endif
> +
> # Disable gcov profiling for VDSO code
> GCOV_PROFILE := n
>
> @@ -28,6 +51,7 @@ $(obj)/vdso.o : $(obj)/vdso.so
> # Link rule for the .so file, .lds has to be first
> $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
> $(call if_changed,ld)
> + $(call if_changed,vdso_check)
>
> # Strip rule for the .so file
> $(obj)/%.so: OBJCOPYFLAGS := -S
> @@ -42,13 +66,9 @@ quiet_cmd_vdsosym = VDSOSYM $@
> include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
> $(call if_changed,vdsosym)
>
> -# Assembly rules for the .S files
> -$(obj-vdso): %.o: %.S FORCE
> - $(call if_changed_dep,vdsoas)
> -
> # Actual build commands
> -quiet_cmd_vdsoas = VDSOA $@
> - cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
> +quiet_cmd_vdsocc = VDSOCC $@
> + cmd_vdsocc = $(CC) $(a_flags) $(c_flags) -c -o $@ $<
>
> # Install commands for the unstripped file
> quiet_cmd_vdso_install = INSTALL $@
> diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
> deleted file mode 100644
> index 856fee6d3512..000000000000
> --- a/arch/arm64/kernel/vdso/gettimeofday.S
> +++ /dev/null
> @@ -1,334 +0,0 @@
> -/*
> - * Userspace implementations of gettimeofday() and friends.
> - *
> - * Copyright (C) 2012 ARM Limited
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - *
> - * 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, see <http://www.gnu.org/licenses/>.
> - *
> - * Author: Will Deacon <will.deacon@arm.com>
> - */
> -
> -#include <linux/linkage.h>
> -#include <asm/asm-offsets.h>
> -#include <asm/unistd.h>
> -
> -#define NSEC_PER_SEC_LO16 0xca00
> -#define NSEC_PER_SEC_HI16 0x3b9a
> -
> -vdso_data .req x6
> -seqcnt .req w7
> -w_tmp .req w8
> -x_tmp .req x8
> -
> -/*
> - * Conventions for macro arguments:
> - * - An argument is write-only if its name starts with "res".
> - * - All other arguments are read-only, unless otherwise specified.
> - */
> -
> - .macro seqcnt_acquire
> -9999: ldr seqcnt, [vdso_data, #VDSO_TB_SEQ_COUNT]
> - tbnz seqcnt, #0, 9999b
> - dmb ishld
> - .endm
> -
> - .macro seqcnt_check fail
> - dmb ishld
> - ldr w_tmp, [vdso_data, #VDSO_TB_SEQ_COUNT]
> - cmp w_tmp, seqcnt
> - b.ne \fail
> - .endm
> -
> - .macro syscall_check fail
> - ldr w_tmp, [vdso_data, #VDSO_USE_SYSCALL]
> - cbnz w_tmp, \fail
> - .endm
> -
> - .macro get_nsec_per_sec res
> - mov \res, #NSEC_PER_SEC_LO16
> - movk \res, #NSEC_PER_SEC_HI16, lsl #16
> - .endm
> -
> - /*
> - * Returns the clock delta, in nanoseconds left-shifted by the clock
> - * shift.
> - */
> - .macro get_clock_shifted_nsec res, cycle_last, mult
> - /* Read the virtual counter. */
> - isb
> - mrs x_tmp, cntvct_el0
> - /* Calculate cycle delta and convert to ns. */
> - sub \res, x_tmp, \cycle_last
> - /* We can only guarantee 56 bits of precision. */
> - movn x_tmp, #0xff00, lsl #48
> - and \res, x_tmp, \res
> - mul \res, \res, \mult
> - /*
> - * Fake address dependency from the value computed from the counter
> - * register to subsequent data page accesses so that the sequence
> - * locking also orders the read of the counter.
> - */
> - and x_tmp, \res, xzr
> - add vdso_data, vdso_data, x_tmp
> - .endm
> -
> - /*
> - * Returns in res_{sec,nsec} the REALTIME timespec, based on the
> - * "wall time" (xtime) and the clock_mono delta.
> - */
> - .macro get_ts_realtime res_sec, res_nsec, \
> - clock_nsec, xtime_sec, xtime_nsec, nsec_to_sec
> - add \res_nsec, \clock_nsec, \xtime_nsec
> - udiv x_tmp, \res_nsec, \nsec_to_sec
> - add \res_sec, \xtime_sec, x_tmp
> - msub \res_nsec, x_tmp, \nsec_to_sec, \res_nsec
> - .endm
> -
> - /*
> - * Returns in res_{sec,nsec} the timespec based on the clock_raw delta,
> - * used for CLOCK_MONOTONIC_RAW.
> - */
> - .macro get_ts_clock_raw res_sec, res_nsec, clock_nsec, nsec_to_sec
> - udiv \res_sec, \clock_nsec, \nsec_to_sec
> - msub \res_nsec, \res_sec, \nsec_to_sec, \clock_nsec
> - .endm
> -
> - /* sec and nsec are modified in place. */
> - .macro add_ts sec, nsec, ts_sec, ts_nsec, nsec_to_sec
> - /* Add timespec. */
> - add \sec, \sec, \ts_sec
> - add \nsec, \nsec, \ts_nsec
> -
> - /* Normalise the new timespec. */
> - cmp \nsec, \nsec_to_sec
> - b.lt 9999f
> - sub \nsec, \nsec, \nsec_to_sec
> - add \sec, \sec, #1
> -9999:
> - cmp \nsec, #0
> - b.ge 9998f
> - add \nsec, \nsec, \nsec_to_sec
> - sub \sec, \sec, #1
> -9998:
> - .endm
> -
> - .macro clock_gettime_return, shift=0
> - .if \shift == 1
> - lsr x11, x11, x12
> - .endif
> - stp x10, x11, [x1, #TSPEC_TV_SEC]
> - mov x0, xzr
> - ret
> - .endm
> -
> - .macro jump_slot jumptable, index, label
> - .if (. - \jumptable) != 4 * (\index)
> - .error "Jump slot index mismatch"
> - .endif
> - b \label
> - .endm
> -
> - .text
> -
> -/* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */
> -ENTRY(__kernel_gettimeofday)
> - .cfi_startproc
> - adr vdso_data, _vdso_data
> - /* If tv is NULL, skip to the timezone code. */
> - cbz x0, 2f
> -
> - /* Compute the time of day. */
> -1: seqcnt_acquire
> - syscall_check fail=4f
> - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
> - /* w11 = cs_mono_mult, w12 = cs_shift */
> - ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
> - ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
> -
> - get_nsec_per_sec res=x9
> - lsl x9, x9, x12
> -
> - get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
> - seqcnt_check fail=1b
> - get_ts_realtime res_sec=x10, res_nsec=x11, \
> - clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
> -
> - /* Convert ns to us. */
> - mov x13, #1000
> - lsl x13, x13, x12
> - udiv x11, x11, x13
> - stp x10, x11, [x0, #TVAL_TV_SEC]
> -2:
> - /* If tz is NULL, return 0. */
> - cbz x1, 3f
> - ldp w4, w5, [vdso_data, #VDSO_TZ_MINWEST]
> - stp w4, w5, [x1, #TZ_MINWEST]
> -3:
> - mov x0, xzr
> - ret
> -4:
> - /* Syscall fallback. */
> - mov x8, #__NR_gettimeofday
> - svc #0
> - ret
> - .cfi_endproc
> -ENDPROC(__kernel_gettimeofday)
> -
> -#define JUMPSLOT_MAX CLOCK_MONOTONIC_COARSE
> -
> -/* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
> -ENTRY(__kernel_clock_gettime)
> - .cfi_startproc
> - cmp w0, #JUMPSLOT_MAX
> - b.hi syscall
> - adr vdso_data, _vdso_data
> - adr x_tmp, jumptable
> - add x_tmp, x_tmp, w0, uxtw #2
> - br x_tmp
> -
> - ALIGN
> -jumptable:
> - jump_slot jumptable, CLOCK_REALTIME, realtime
> - jump_slot jumptable, CLOCK_MONOTONIC, monotonic
> - b syscall
> - b syscall
> - jump_slot jumptable, CLOCK_MONOTONIC_RAW, monotonic_raw
> - jump_slot jumptable, CLOCK_REALTIME_COARSE, realtime_coarse
> - jump_slot jumptable, CLOCK_MONOTONIC_COARSE, monotonic_coarse
> -
> - .if (. - jumptable) != 4 * (JUMPSLOT_MAX + 1)
> - .error "Wrong jumptable size"
> - .endif
> -
> - ALIGN
> -realtime:
> - seqcnt_acquire
> - syscall_check fail=syscall
> - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
> - /* w11 = cs_mono_mult, w12 = cs_shift */
> - ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
> - ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
> -
> - /* All computations are done with left-shifted nsecs. */
> - get_nsec_per_sec res=x9
> - lsl x9, x9, x12
> -
> - get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
> - seqcnt_check fail=realtime
> - get_ts_realtime res_sec=x10, res_nsec=x11, \
> - clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
> - clock_gettime_return, shift=1
> -
> - ALIGN
> -monotonic:
> - seqcnt_acquire
> - syscall_check fail=syscall
> - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
> - /* w11 = cs_mono_mult, w12 = cs_shift */
> - ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
> - ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
> - ldp x3, x4, [vdso_data, #VDSO_WTM_CLK_SEC]
> -
> - /* All computations are done with left-shifted nsecs. */
> - lsl x4, x4, x12
> - get_nsec_per_sec res=x9
> - lsl x9, x9, x12
> -
> - get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
> - seqcnt_check fail=monotonic
> - get_ts_realtime res_sec=x10, res_nsec=x11, \
> - clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
> -
> - add_ts sec=x10, nsec=x11, ts_sec=x3, ts_nsec=x4, nsec_to_sec=x9
> - clock_gettime_return, shift=1
> -
> - ALIGN
> -monotonic_raw:
> - seqcnt_acquire
> - syscall_check fail=syscall
> - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
> - /* w11 = cs_raw_mult, w12 = cs_shift */
> - ldp w12, w11, [vdso_data, #VDSO_CS_SHIFT]
> - ldp x13, x14, [vdso_data, #VDSO_RAW_TIME_SEC]
> -
> - /* All computations are done with left-shifted nsecs. */
> - get_nsec_per_sec res=x9
> - lsl x9, x9, x12
> -
> - get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
> - seqcnt_check fail=monotonic_raw
> - get_ts_clock_raw res_sec=x10, res_nsec=x11, \
> - clock_nsec=x15, nsec_to_sec=x9
> -
> - add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9
> - clock_gettime_return, shift=1
> -
> - ALIGN
> -realtime_coarse:
> - seqcnt_acquire
> - ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC]
> - seqcnt_check fail=realtime_coarse
> - clock_gettime_return
> -
> - ALIGN
> -monotonic_coarse:
> - seqcnt_acquire
> - ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC]
> - ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC]
> - seqcnt_check fail=monotonic_coarse
> -
> - /* Computations are done in (non-shifted) nsecs. */
> - get_nsec_per_sec res=x9
> - add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9
> - clock_gettime_return
> -
> - ALIGN
> -syscall: /* Syscall fallback. */
> - mov x8, #__NR_clock_gettime
> - svc #0
> - ret
> - .cfi_endproc
> -ENDPROC(__kernel_clock_gettime)
> -
> -/* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
> -ENTRY(__kernel_clock_getres)
> - .cfi_startproc
> - cmp w0, #CLOCK_REALTIME
> - ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
> - ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne
> - b.ne 1f
> -
> - adr vdso_data, _vdso_data
> - ldr w2, [vdso_data, #CLOCK_REALTIME_RES]
> - b 2f
> -1:
> - cmp w0, #CLOCK_REALTIME_COARSE
> - ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
> - b.ne 4f
> - ldr x2, 5f
> -2:
> - cbz x1, 3f
> - stp xzr, x2, [x1]
> -
> -3: /* res == NULL. */
> - mov w0, wzr
> - ret
> -
> -4: /* Syscall fallback. */
> - mov x8, #__NR_clock_getres
> - svc #0
> - ret
> -5:
> - .quad CLOCK_COARSE_RES
> - .cfi_endproc
> -ENDPROC(__kernel_clock_getres)
> diff --git a/arch/arm64/kernel/vdso/vgettimeofday.c b/arch/arm64/kernel/vdso/vgettimeofday.c
> new file mode 100644
> index 000000000000..3c58f19dbdf4
> --- /dev/null
> +++ b/arch/arm64/kernel/vdso/vgettimeofday.c
> @@ -0,0 +1,28 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * ARM64 userspace implementations of gettimeofday() and similar.
> + *
> + * Copyright (C) 2018 ARM Limited
> + *
> + */
> +#include <linux/time.h>
> +#include <linux/types.h>
> +
> +int __kernel_clock_gettime(clockid_t clock,
> + struct __kernel_timespec *ts)
> +{
> + return __cvdso_clock_gettime(clock, ts);
> +}
> +
> +int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
> + struct timezone *tz)
> +{
> + return __cvdso_gettimeofday(tv, tz);
> +}
> +
> +int __kernel_clock_getres(clockid_t clock_id,
> + struct __kernel_timespec *res)
> +{
> + return __cvdso_clock_getres(clock_id, res);
> +}
> +
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-28 13:09 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Marek Szyprowski
@ 2019-06-28 14:32 ` Vincenzo Frascino
2019-06-28 16:50 ` Sylwester Nawrocki
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-28 14:32 UTC (permalink / raw)
To: Marek Szyprowski, linux-arch, linux-arm-kernel, linux-kernel,
linux-mips, linux-kselftest
Cc: Shuah Khan, Andre Przywara, Arnd Bergmann, Huw Davies,
Catalin Marinas, Daniel Lezcano, Will Deacon, Russell King,
Ralf Baechle, Mark Salyzyn, Paul Burton, Dmitry Safonov,
Rasmus Villemoes, Thomas Gleixner, Shijith Thotton,
Peter Collingbourne, Sylwester Nawrocki
Hi Marek,
On 6/28/19 2:09 PM, Marek Szyprowski wrote:
> Dear All,
>
> On 2019-06-21 11:52, Vincenzo Frascino wrote:
>> To take advantage of the commonly defined vdso interface for
>> gettimeofday the architectural code requires an adaptation.
>>
>> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>>
>> With the new implementation arm64 gains support for CLOCK_BOOTTIME
>> and CLOCK_TAI.
>>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>> Tested-by: Shijith Thotton <sthotton@marvell.com>
>> Tested-by: Andre Przywara <andre.przywara@arm.com>
>> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
>
> This patch causes serious regression on Samsung Exynos5433 SoC based
> TM2(e) boards. The time in userspace is always set to begin of the epoch:
>
> # date 062813152019
> Fri Jun 28 13:15:00 UTC 2019
> # date
> Thu Jan 1 00:00:00 UTC 1970
> # date
> Thu Jan 1 00:00:00 UTC 1970
>
> I've noticed that since the patch landed in Linux next-20190625 and
> bisect indeed pointed to this patch.
>
Thank you for reporting this, seems that the next that you posted is missing
some fixes for arm64.
Could you please try the tree below?
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/vdso
Let us know if the functionality is restored. Otherwise the issue will require
further investigation.
>> ---
>> arch/arm64/Kconfig | 2 +
>> arch/arm64/include/asm/vdso/gettimeofday.h | 86 ++++++
>> arch/arm64/include/asm/vdso/vsyscall.h | 53 ++++
>> arch/arm64/include/asm/vdso_datapage.h | 48 ---
>> arch/arm64/kernel/asm-offsets.c | 33 +-
>> arch/arm64/kernel/vdso.c | 51 +---
>> arch/arm64/kernel/vdso/Makefile | 34 ++-
>> arch/arm64/kernel/vdso/gettimeofday.S | 334 ---------------------
>> arch/arm64/kernel/vdso/vgettimeofday.c | 28 ++
>> 9 files changed, 223 insertions(+), 446 deletions(-)
>> create mode 100644 arch/arm64/include/asm/vdso/gettimeofday.h
>> create mode 100644 arch/arm64/include/asm/vdso/vsyscall.h
>> delete mode 100644 arch/arm64/include/asm/vdso_datapage.h
>> delete mode 100644 arch/arm64/kernel/vdso/gettimeofday.S
>> create mode 100644 arch/arm64/kernel/vdso/vgettimeofday.c
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 697ea0510729..952c9f8cf3b8 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -107,6 +107,7 @@ config ARM64
>> select GENERIC_STRNCPY_FROM_USER
>> select GENERIC_STRNLEN_USER
>> select GENERIC_TIME_VSYSCALL
>> + select GENERIC_GETTIMEOFDAY
>> select HANDLE_DOMAIN_IRQ
>> select HARDIRQS_SW_RESEND
>> select HAVE_PCI
>> @@ -160,6 +161,7 @@ config ARM64
>> select HAVE_SYSCALL_TRACEPOINTS
>> select HAVE_KPROBES
>> select HAVE_KRETPROBES
>> + select HAVE_GENERIC_VDSO
>> select IOMMU_DMA if IOMMU_SUPPORT
>> select IRQ_DOMAIN
>> select IRQ_FORCED_THREADING
>> diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
>> new file mode 100644
>> index 000000000000..bc3cb6738051
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
>> @@ -0,0 +1,86 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Copyright (C) 2018 ARM Limited
>> + */
>> +#ifndef __ASM_VDSO_GETTIMEOFDAY_H
>> +#define __ASM_VDSO_GETTIMEOFDAY_H
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +#include <asm/unistd.h>
>> +#include <uapi/linux/time.h>
>> +
>> +#define VDSO_HAS_CLOCK_GETRES 1
>> +
>> +static __always_inline int gettimeofday_fallback(
>> + struct __kernel_old_timeval *_tv,
>> + struct timezone *_tz)
>> +{
>> + register struct timezone *tz asm("x1") = _tz;
>> + register struct __kernel_old_timeval *tv asm("x0") = _tv;
>> + register long ret asm ("x0");
>> + register long nr asm("x8") = __NR_gettimeofday;
>> +
>> + asm volatile(
>> + " svc #0\n"
>> + : "=r" (ret)
>> + : "r" (tv), "r" (tz), "r" (nr)
>> + : "memory");
>> +
>> + return ret;
>> +}
>> +
>> +static __always_inline long clock_gettime_fallback(
>> + clockid_t _clkid,
>> + struct __kernel_timespec *_ts)
>> +{
>> + register struct __kernel_timespec *ts asm("x1") = _ts;
>> + register clockid_t clkid asm("x0") = _clkid;
>> + register long ret asm ("x0");
>> + register long nr asm("x8") = __NR_clock_gettime;
>> +
>> + asm volatile(
>> + " svc #0\n"
>> + : "=r" (ret)
>> + : "r" (clkid), "r" (ts), "r" (nr)
>> + : "memory");
>> +
>> + return ret;
>> +}
>> +
>> +static __always_inline int clock_getres_fallback(
>> + clockid_t _clkid,
>> + struct __kernel_timespec *_ts)
>> +{
>> + register struct __kernel_timespec *ts asm("x1") = _ts;
>> + register clockid_t clkid asm("x0") = _clkid;
>> + register long ret asm ("x0");
>> + register long nr asm("x8") = __NR_clock_getres;
>> +
>> + asm volatile(
>> + " svc #0\n"
>> + : "=r" (ret)
>> + : "r" (clkid), "r" (ts), "r" (nr)
>> + : "memory");
>> +
>> + return ret;
>> +}
>> +
>> +static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
>> +{
>> + u64 res;
>> +
>> + asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
>> +
>> + return res;
>> +}
>> +
>> +static __always_inline
>> +const struct vdso_data *__arch_get_vdso_data(void)
>> +{
>> + return _vdso_data;
>> +}
>> +
>> +#endif /* !__ASSEMBLY__ */
>> +
>> +#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
>> diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
>> new file mode 100644
>> index 000000000000..0c731bfc7c8c
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/vdso/vsyscall.h
>> @@ -0,0 +1,53 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +#ifndef __ASM_VDSO_VSYSCALL_H
>> +#define __ASM_VDSO_VSYSCALL_H
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +#include <linux/timekeeper_internal.h>
>> +#include <vdso/datapage.h>
>> +
>> +#define VDSO_PRECISION_MASK ~(0xFF00ULL<<48)
>> +
>> +extern struct vdso_data *vdso_data;
>> +
>> +/*
>> + * Update the vDSO data page to keep in sync with kernel timekeeping.
>> + */
>> +static __always_inline
>> +struct vdso_data *__arm64_get_k_vdso_data(void)
>> +{
>> + return vdso_data;
>> +}
>> +#define __arch_get_k_vdso_data __arm64_get_k_vdso_data
>> +
>> +static __always_inline
>> +int __arm64_get_clock_mode(struct timekeeper *tk)
>> +{
>> + u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
>> +
>> + return use_syscall;
>> +}
>> +#define __arch_get_clock_mode __arm64_get_clock_mode
>> +
>> +static __always_inline
>> +int __arm64_use_vsyscall(struct vdso_data *vdata)
>> +{
>> + return !vdata[CS_HRES_COARSE].clock_mode;
>> +}
>> +#define __arch_use_vsyscall __arm64_use_vsyscall
>> +
>> +static __always_inline
>> +void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
>> +{
>> + vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
>> + vdata[CS_RAW].mask = VDSO_PRECISION_MASK;
>> +}
>> +#define __arch_update_vsyscall __arm64_update_vsyscall
>> +
>> +/* The asm-generic header needs to be included after the definitions above */
>> +#include <asm-generic/vdso/vsyscall.h>
>> +
>> +#endif /* !__ASSEMBLY__ */
>> +
>> +#endif /* __ASM_VDSO_VSYSCALL_H */
>> diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h
>> deleted file mode 100644
>> index f89263c8e11a..000000000000
>> --- a/arch/arm64/include/asm/vdso_datapage.h
>> +++ /dev/null
>> @@ -1,48 +0,0 @@
>> -/*
>> - * Copyright (C) 2012 ARM Limited
>> - *
>> - * This program is free software; you can redistribute it and/or modify
>> - * it under the terms of the GNU General Public License version 2 as
>> - * published by the Free Software Foundation.
>> - *
>> - * 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, see <http://www.gnu.org/licenses/>.
>> - */
>> -#ifndef __ASM_VDSO_DATAPAGE_H
>> -#define __ASM_VDSO_DATAPAGE_H
>> -
>> -#ifdef __KERNEL__
>> -
>> -#ifndef __ASSEMBLY__
>> -
>> -struct vdso_data {
>> - __u64 cs_cycle_last; /* Timebase at clocksource init */
>> - __u64 raw_time_sec; /* Raw time */
>> - __u64 raw_time_nsec;
>> - __u64 xtime_clock_sec; /* Kernel time */
>> - __u64 xtime_clock_nsec;
>> - __u64 xtime_coarse_sec; /* Coarse time */
>> - __u64 xtime_coarse_nsec;
>> - __u64 wtm_clock_sec; /* Wall to monotonic time */
>> - __u64 wtm_clock_nsec;
>> - __u32 tb_seq_count; /* Timebase sequence counter */
>> - /* cs_* members must be adjacent and in this order (ldp accesses) */
>> - __u32 cs_mono_mult; /* NTP-adjusted clocksource multiplier */
>> - __u32 cs_shift; /* Clocksource shift (mono = raw) */
>> - __u32 cs_raw_mult; /* Raw clocksource multiplier */
>> - __u32 tz_minuteswest; /* Whacky timezone stuff */
>> - __u32 tz_dsttime;
>> - __u32 use_syscall;
>> - __u32 hrtimer_res;
>> -};
>> -
>> -#endif /* !__ASSEMBLY__ */
>> -
>> -#endif /* __KERNEL__ */
>> -
>> -#endif /* __ASM_VDSO_DATAPAGE_H */
>> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
>> index 947e39896e28..9e4b7ccbab2f 100644
>> --- a/arch/arm64/kernel/asm-offsets.c
>> +++ b/arch/arm64/kernel/asm-offsets.c
>> @@ -25,13 +25,13 @@
>> #include <linux/kvm_host.h>
>> #include <linux/preempt.h>
>> #include <linux/suspend.h>
>> +#include <vdso/datapage.h>
>> #include <asm/cpufeature.h>
>> #include <asm/fixmap.h>
>> #include <asm/thread_info.h>
>> #include <asm/memory.h>
>> #include <asm/smp_plat.h>
>> #include <asm/suspend.h>
>> -#include <asm/vdso_datapage.h>
>> #include <linux/kbuild.h>
>> #include <linux/arm-smccc.h>
>>
>> @@ -100,17 +100,28 @@ int main(void)
>> DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
>> DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
>> BLANK();
>> - DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last));
>> - DEFINE(VDSO_RAW_TIME_SEC, offsetof(struct vdso_data, raw_time_sec));
>> - DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec));
>> - DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec));
>> - DEFINE(VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec));
>> - DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec));
>> - DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count));
>> - DEFINE(VDSO_CS_MONO_MULT, offsetof(struct vdso_data, cs_mono_mult));
>> - DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift));
>> + DEFINE(VDSO_SEQ, offsetof(struct vdso_data, seq));
>> + DEFINE(VDSO_CLK_MODE, offsetof(struct vdso_data, clock_mode));
>> + DEFINE(VDSO_CYCLE_LAST, offsetof(struct vdso_data, cycle_last));
>> + DEFINE(VDSO_MASK, offsetof(struct vdso_data, mask));
>> + DEFINE(VDSO_MULT, offsetof(struct vdso_data, mult));
>> + DEFINE(VDSO_SHIFT, offsetof(struct vdso_data, shift));
>> + DEFINE(VDSO_REALTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].sec));
>> + DEFINE(VDSO_REALTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME].nsec));
>> + DEFINE(VDSO_MONO_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].sec));
>> + DEFINE(VDSO_MONO_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC].nsec));
>> + DEFINE(VDSO_MONO_RAW_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].sec));
>> + DEFINE(VDSO_MONO_RAW_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_RAW].nsec));
>> + DEFINE(VDSO_BOOTTIME_SEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].sec));
>> + DEFINE(VDSO_BOOTTIME_NSEC, offsetof(struct vdso_data, basetime[CLOCK_BOOTTIME].nsec));
>> + DEFINE(VDSO_TAI_SEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].sec));
>> + DEFINE(VDSO_TAI_NSEC, offsetof(struct vdso_data, basetime[CLOCK_TAI].nsec));
>> + DEFINE(VDSO_RT_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].sec));
>> + DEFINE(VDSO_RT_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_REALTIME_COARSE].nsec));
>> + DEFINE(VDSO_MONO_COARSE_SEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].sec));
>> + DEFINE(VDSO_MONO_COARSE_NSEC, offsetof(struct vdso_data, basetime[CLOCK_MONOTONIC_COARSE].nsec));
>> DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest));
>> - DEFINE(VDSO_USE_SYSCALL, offsetof(struct vdso_data, use_syscall));
>> + DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
>> BLANK();
>> DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec));
>> DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
>> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
>> index 8074cbd3a3a8..23c38303a52a 100644
>> --- a/arch/arm64/kernel/vdso.c
>> +++ b/arch/arm64/kernel/vdso.c
>> @@ -31,11 +31,13 @@
>> #include <linux/slab.h>
>> #include <linux/timekeeper_internal.h>
>> #include <linux/vmalloc.h>
>> +#include <vdso/datapage.h>
>> +#include <vdso/helpers.h>
>> +#include <vdso/vsyscall.h>
>>
>> #include <asm/cacheflush.h>
>> #include <asm/signal32.h>
>> #include <asm/vdso.h>
>> -#include <asm/vdso_datapage.h>
>>
>> extern char vdso_start[], vdso_end[];
>> static unsigned long vdso_pages __ro_after_init;
>> @@ -44,10 +46,10 @@ static unsigned long vdso_pages __ro_after_init;
>> * The vDSO data page.
>> */
>> static union {
>> - struct vdso_data data;
>> + struct vdso_data data[CS_BASES];
>> u8 page[PAGE_SIZE];
>> } vdso_data_store __page_aligned_data;
>> -struct vdso_data *vdso_data = &vdso_data_store.data;
>> +struct vdso_data *vdso_data = vdso_data_store.data;
>>
>> #ifdef CONFIG_COMPAT
>> /*
>> @@ -280,46 +282,3 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>> up_write(&mm->mmap_sem);
>> return PTR_ERR(ret);
>> }
>> -
>> -/*
>> - * Update the vDSO data page to keep in sync with kernel timekeeping.
>> - */
>> -void update_vsyscall(struct timekeeper *tk)
>> -{
>> - u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
>> -
>> - ++vdso_data->tb_seq_count;
>> - smp_wmb();
>> -
>> - vdso_data->use_syscall = use_syscall;
>> - vdso_data->xtime_coarse_sec = tk->xtime_sec;
>> - vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >>
>> - tk->tkr_mono.shift;
>> - vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
>> - vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
>> -
>> - /* Read without the seqlock held by clock_getres() */
>> - WRITE_ONCE(vdso_data->hrtimer_res, hrtimer_resolution);
>> -
>> - if (!use_syscall) {
>> - /* tkr_mono.cycle_last == tkr_raw.cycle_last */
>> - vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
>> - vdso_data->raw_time_sec = tk->raw_sec;
>> - vdso_data->raw_time_nsec = tk->tkr_raw.xtime_nsec;
>> - vdso_data->xtime_clock_sec = tk->xtime_sec;
>> - vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec;
>> - vdso_data->cs_mono_mult = tk->tkr_mono.mult;
>> - vdso_data->cs_raw_mult = tk->tkr_raw.mult;
>> - /* tkr_mono.shift == tkr_raw.shift */
>> - vdso_data->cs_shift = tk->tkr_mono.shift;
>> - }
>> -
>> - smp_wmb();
>> - ++vdso_data->tb_seq_count;
>> -}
>> -
>> -void update_vsyscall_tz(void)
>> -{
>> - vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
>> - vdso_data->tz_dsttime = sys_tz.tz_dsttime;
>> -}
>> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
>> index fa230ff09aa1..3acfc813e966 100644
>> --- a/arch/arm64/kernel/vdso/Makefile
>> +++ b/arch/arm64/kernel/vdso/Makefile
>> @@ -6,7 +6,12 @@
>> # Heavily based on the vDSO Makefiles for other archs.
>> #
>>
>> -obj-vdso := gettimeofday.o note.o sigreturn.o
>> +# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
>> +# the inclusion of generic Makefile.
>> +ARCH_REL_TYPE_ABS := R_AARCH64_JUMP_SLOT|R_AARCH64_GLOB_DAT|R_AARCH64_ABS64
>> +include $(srctree)/lib/vdso/Makefile
>> +
>> +obj-vdso := vgettimeofday.o note.o sigreturn.o
>>
>> # Build rules
>> targets := $(obj-vdso) vdso.so vdso.so.dbg
>> @@ -15,6 +20,24 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
>> ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \
>> --build-id -n -T
>>
>> +ccflags-y := -fno-common -fno-builtin -fno-stack-protector
>> +ccflags-y += -DDISABLE_BRANCH_PROFILING
>> +
>> +VDSO_LDFLAGS := -Bsymbolic
>> +
>> +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
>> +KBUILD_CFLAGS += $(DISABLE_LTO)
>> +KASAN_SANITIZE := n
>> +UBSAN_SANITIZE := n
>> +OBJECT_FILES_NON_STANDARD := y
>> +KCOV_INSTRUMENT := n
>> +
>> +ifeq ($(c-gettimeofday-y),)
>> +CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny
>> +else
>> +CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -include $(c-gettimeofday-y)
>> +endif
>> +
>> # Disable gcov profiling for VDSO code
>> GCOV_PROFILE := n
>>
>> @@ -28,6 +51,7 @@ $(obj)/vdso.o : $(obj)/vdso.so
>> # Link rule for the .so file, .lds has to be first
>> $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
>> $(call if_changed,ld)
>> + $(call if_changed,vdso_check)
>>
>> # Strip rule for the .so file
>> $(obj)/%.so: OBJCOPYFLAGS := -S
>> @@ -42,13 +66,9 @@ quiet_cmd_vdsosym = VDSOSYM $@
>> include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
>> $(call if_changed,vdsosym)
>>
>> -# Assembly rules for the .S files
>> -$(obj-vdso): %.o: %.S FORCE
>> - $(call if_changed_dep,vdsoas)
>> -
>> # Actual build commands
>> -quiet_cmd_vdsoas = VDSOA $@
>> - cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
>> +quiet_cmd_vdsocc = VDSOCC $@
>> + cmd_vdsocc = $(CC) $(a_flags) $(c_flags) -c -o $@ $<
>>
>> # Install commands for the unstripped file
>> quiet_cmd_vdso_install = INSTALL $@
>> diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
>> deleted file mode 100644
>> index 856fee6d3512..000000000000
>> --- a/arch/arm64/kernel/vdso/gettimeofday.S
>> +++ /dev/null
>> @@ -1,334 +0,0 @@
>> -/*
>> - * Userspace implementations of gettimeofday() and friends.
>> - *
>> - * Copyright (C) 2012 ARM Limited
>> - *
>> - * This program is free software; you can redistribute it and/or modify
>> - * it under the terms of the GNU General Public License version 2 as
>> - * published by the Free Software Foundation.
>> - *
>> - * 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, see <http://www.gnu.org/licenses/>.
>> - *
>> - * Author: Will Deacon <will.deacon@arm.com>
>> - */
>> -
>> -#include <linux/linkage.h>
>> -#include <asm/asm-offsets.h>
>> -#include <asm/unistd.h>
>> -
>> -#define NSEC_PER_SEC_LO16 0xca00
>> -#define NSEC_PER_SEC_HI16 0x3b9a
>> -
>> -vdso_data .req x6
>> -seqcnt .req w7
>> -w_tmp .req w8
>> -x_tmp .req x8
>> -
>> -/*
>> - * Conventions for macro arguments:
>> - * - An argument is write-only if its name starts with "res".
>> - * - All other arguments are read-only, unless otherwise specified.
>> - */
>> -
>> - .macro seqcnt_acquire
>> -9999: ldr seqcnt, [vdso_data, #VDSO_TB_SEQ_COUNT]
>> - tbnz seqcnt, #0, 9999b
>> - dmb ishld
>> - .endm
>> -
>> - .macro seqcnt_check fail
>> - dmb ishld
>> - ldr w_tmp, [vdso_data, #VDSO_TB_SEQ_COUNT]
>> - cmp w_tmp, seqcnt
>> - b.ne \fail
>> - .endm
>> -
>> - .macro syscall_check fail
>> - ldr w_tmp, [vdso_data, #VDSO_USE_SYSCALL]
>> - cbnz w_tmp, \fail
>> - .endm
>> -
>> - .macro get_nsec_per_sec res
>> - mov \res, #NSEC_PER_SEC_LO16
>> - movk \res, #NSEC_PER_SEC_HI16, lsl #16
>> - .endm
>> -
>> - /*
>> - * Returns the clock delta, in nanoseconds left-shifted by the clock
>> - * shift.
>> - */
>> - .macro get_clock_shifted_nsec res, cycle_last, mult
>> - /* Read the virtual counter. */
>> - isb
>> - mrs x_tmp, cntvct_el0
>> - /* Calculate cycle delta and convert to ns. */
>> - sub \res, x_tmp, \cycle_last
>> - /* We can only guarantee 56 bits of precision. */
>> - movn x_tmp, #0xff00, lsl #48
>> - and \res, x_tmp, \res
>> - mul \res, \res, \mult
>> - /*
>> - * Fake address dependency from the value computed from the counter
>> - * register to subsequent data page accesses so that the sequence
>> - * locking also orders the read of the counter.
>> - */
>> - and x_tmp, \res, xzr
>> - add vdso_data, vdso_data, x_tmp
>> - .endm
>> -
>> - /*
>> - * Returns in res_{sec,nsec} the REALTIME timespec, based on the
>> - * "wall time" (xtime) and the clock_mono delta.
>> - */
>> - .macro get_ts_realtime res_sec, res_nsec, \
>> - clock_nsec, xtime_sec, xtime_nsec, nsec_to_sec
>> - add \res_nsec, \clock_nsec, \xtime_nsec
>> - udiv x_tmp, \res_nsec, \nsec_to_sec
>> - add \res_sec, \xtime_sec, x_tmp
>> - msub \res_nsec, x_tmp, \nsec_to_sec, \res_nsec
>> - .endm
>> -
>> - /*
>> - * Returns in res_{sec,nsec} the timespec based on the clock_raw delta,
>> - * used for CLOCK_MONOTONIC_RAW.
>> - */
>> - .macro get_ts_clock_raw res_sec, res_nsec, clock_nsec, nsec_to_sec
>> - udiv \res_sec, \clock_nsec, \nsec_to_sec
>> - msub \res_nsec, \res_sec, \nsec_to_sec, \clock_nsec
>> - .endm
>> -
>> - /* sec and nsec are modified in place. */
>> - .macro add_ts sec, nsec, ts_sec, ts_nsec, nsec_to_sec
>> - /* Add timespec. */
>> - add \sec, \sec, \ts_sec
>> - add \nsec, \nsec, \ts_nsec
>> -
>> - /* Normalise the new timespec. */
>> - cmp \nsec, \nsec_to_sec
>> - b.lt 9999f
>> - sub \nsec, \nsec, \nsec_to_sec
>> - add \sec, \sec, #1
>> -9999:
>> - cmp \nsec, #0
>> - b.ge 9998f
>> - add \nsec, \nsec, \nsec_to_sec
>> - sub \sec, \sec, #1
>> -9998:
>> - .endm
>> -
>> - .macro clock_gettime_return, shift=0
>> - .if \shift == 1
>> - lsr x11, x11, x12
>> - .endif
>> - stp x10, x11, [x1, #TSPEC_TV_SEC]
>> - mov x0, xzr
>> - ret
>> - .endm
>> -
>> - .macro jump_slot jumptable, index, label
>> - .if (. - \jumptable) != 4 * (\index)
>> - .error "Jump slot index mismatch"
>> - .endif
>> - b \label
>> - .endm
>> -
>> - .text
>> -
>> -/* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */
>> -ENTRY(__kernel_gettimeofday)
>> - .cfi_startproc
>> - adr vdso_data, _vdso_data
>> - /* If tv is NULL, skip to the timezone code. */
>> - cbz x0, 2f
>> -
>> - /* Compute the time of day. */
>> -1: seqcnt_acquire
>> - syscall_check fail=4f
>> - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
>> - /* w11 = cs_mono_mult, w12 = cs_shift */
>> - ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
>> - ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
>> -
>> - get_nsec_per_sec res=x9
>> - lsl x9, x9, x12
>> -
>> - get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
>> - seqcnt_check fail=1b
>> - get_ts_realtime res_sec=x10, res_nsec=x11, \
>> - clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
>> -
>> - /* Convert ns to us. */
>> - mov x13, #1000
>> - lsl x13, x13, x12
>> - udiv x11, x11, x13
>> - stp x10, x11, [x0, #TVAL_TV_SEC]
>> -2:
>> - /* If tz is NULL, return 0. */
>> - cbz x1, 3f
>> - ldp w4, w5, [vdso_data, #VDSO_TZ_MINWEST]
>> - stp w4, w5, [x1, #TZ_MINWEST]
>> -3:
>> - mov x0, xzr
>> - ret
>> -4:
>> - /* Syscall fallback. */
>> - mov x8, #__NR_gettimeofday
>> - svc #0
>> - ret
>> - .cfi_endproc
>> -ENDPROC(__kernel_gettimeofday)
>> -
>> -#define JUMPSLOT_MAX CLOCK_MONOTONIC_COARSE
>> -
>> -/* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
>> -ENTRY(__kernel_clock_gettime)
>> - .cfi_startproc
>> - cmp w0, #JUMPSLOT_MAX
>> - b.hi syscall
>> - adr vdso_data, _vdso_data
>> - adr x_tmp, jumptable
>> - add x_tmp, x_tmp, w0, uxtw #2
>> - br x_tmp
>> -
>> - ALIGN
>> -jumptable:
>> - jump_slot jumptable, CLOCK_REALTIME, realtime
>> - jump_slot jumptable, CLOCK_MONOTONIC, monotonic
>> - b syscall
>> - b syscall
>> - jump_slot jumptable, CLOCK_MONOTONIC_RAW, monotonic_raw
>> - jump_slot jumptable, CLOCK_REALTIME_COARSE, realtime_coarse
>> - jump_slot jumptable, CLOCK_MONOTONIC_COARSE, monotonic_coarse
>> -
>> - .if (. - jumptable) != 4 * (JUMPSLOT_MAX + 1)
>> - .error "Wrong jumptable size"
>> - .endif
>> -
>> - ALIGN
>> -realtime:
>> - seqcnt_acquire
>> - syscall_check fail=syscall
>> - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
>> - /* w11 = cs_mono_mult, w12 = cs_shift */
>> - ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
>> - ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
>> -
>> - /* All computations are done with left-shifted nsecs. */
>> - get_nsec_per_sec res=x9
>> - lsl x9, x9, x12
>> -
>> - get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
>> - seqcnt_check fail=realtime
>> - get_ts_realtime res_sec=x10, res_nsec=x11, \
>> - clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
>> - clock_gettime_return, shift=1
>> -
>> - ALIGN
>> -monotonic:
>> - seqcnt_acquire
>> - syscall_check fail=syscall
>> - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
>> - /* w11 = cs_mono_mult, w12 = cs_shift */
>> - ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT]
>> - ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC]
>> - ldp x3, x4, [vdso_data, #VDSO_WTM_CLK_SEC]
>> -
>> - /* All computations are done with left-shifted nsecs. */
>> - lsl x4, x4, x12
>> - get_nsec_per_sec res=x9
>> - lsl x9, x9, x12
>> -
>> - get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
>> - seqcnt_check fail=monotonic
>> - get_ts_realtime res_sec=x10, res_nsec=x11, \
>> - clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9
>> -
>> - add_ts sec=x10, nsec=x11, ts_sec=x3, ts_nsec=x4, nsec_to_sec=x9
>> - clock_gettime_return, shift=1
>> -
>> - ALIGN
>> -monotonic_raw:
>> - seqcnt_acquire
>> - syscall_check fail=syscall
>> - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST]
>> - /* w11 = cs_raw_mult, w12 = cs_shift */
>> - ldp w12, w11, [vdso_data, #VDSO_CS_SHIFT]
>> - ldp x13, x14, [vdso_data, #VDSO_RAW_TIME_SEC]
>> -
>> - /* All computations are done with left-shifted nsecs. */
>> - get_nsec_per_sec res=x9
>> - lsl x9, x9, x12
>> -
>> - get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11
>> - seqcnt_check fail=monotonic_raw
>> - get_ts_clock_raw res_sec=x10, res_nsec=x11, \
>> - clock_nsec=x15, nsec_to_sec=x9
>> -
>> - add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9
>> - clock_gettime_return, shift=1
>> -
>> - ALIGN
>> -realtime_coarse:
>> - seqcnt_acquire
>> - ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC]
>> - seqcnt_check fail=realtime_coarse
>> - clock_gettime_return
>> -
>> - ALIGN
>> -monotonic_coarse:
>> - seqcnt_acquire
>> - ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC]
>> - ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC]
>> - seqcnt_check fail=monotonic_coarse
>> -
>> - /* Computations are done in (non-shifted) nsecs. */
>> - get_nsec_per_sec res=x9
>> - add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9
>> - clock_gettime_return
>> -
>> - ALIGN
>> -syscall: /* Syscall fallback. */
>> - mov x8, #__NR_clock_gettime
>> - svc #0
>> - ret
>> - .cfi_endproc
>> -ENDPROC(__kernel_clock_gettime)
>> -
>> -/* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
>> -ENTRY(__kernel_clock_getres)
>> - .cfi_startproc
>> - cmp w0, #CLOCK_REALTIME
>> - ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
>> - ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne
>> - b.ne 1f
>> -
>> - adr vdso_data, _vdso_data
>> - ldr w2, [vdso_data, #CLOCK_REALTIME_RES]
>> - b 2f
>> -1:
>> - cmp w0, #CLOCK_REALTIME_COARSE
>> - ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
>> - b.ne 4f
>> - ldr x2, 5f
>> -2:
>> - cbz x1, 3f
>> - stp xzr, x2, [x1]
>> -
>> -3: /* res == NULL. */
>> - mov w0, wzr
>> - ret
>> -
>> -4: /* Syscall fallback. */
>> - mov x8, #__NR_clock_getres
>> - svc #0
>> - ret
>> -5:
>> - .quad CLOCK_COARSE_RES
>> - .cfi_endproc
>> -ENDPROC(__kernel_clock_getres)
>> diff --git a/arch/arm64/kernel/vdso/vgettimeofday.c b/arch/arm64/kernel/vdso/vgettimeofday.c
>> new file mode 100644
>> index 000000000000..3c58f19dbdf4
>> --- /dev/null
>> +++ b/arch/arm64/kernel/vdso/vgettimeofday.c
>> @@ -0,0 +1,28 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * ARM64 userspace implementations of gettimeofday() and similar.
>> + *
>> + * Copyright (C) 2018 ARM Limited
>> + *
>> + */
>> +#include <linux/time.h>
>> +#include <linux/types.h>
>> +
>> +int __kernel_clock_gettime(clockid_t clock,
>> + struct __kernel_timespec *ts)
>> +{
>> + return __cvdso_clock_gettime(clock, ts);
>> +}
>> +
>> +int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
>> + struct timezone *tz)
>> +{
>> + return __cvdso_gettimeofday(tv, tz);
>> +}
>> +
>> +int __kernel_clock_getres(clockid_t clock_id,
>> + struct __kernel_timespec *res)
>> +{
>> + return __cvdso_clock_getres(clock_id, res);
>> +}
>> +
>
> Best regards
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-28 14:32 ` Vincenzo Frascino
@ 2019-06-28 16:50 ` Sylwester Nawrocki
2019-06-29 6:58 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Sylwester Nawrocki @ 2019-06-28 16:50 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: Marek Szyprowski, linux-arch, linux-arm-kernel, linux-kernel,
linux-mips, linux-kselftest, Shuah Khan, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, Russell King, Ralf Baechle, Mark Salyzyn,
Paul Burton, Dmitry Safonov, Rasmus Villemoes, Thomas Gleixner,
Shijith Thotton, Peter Collingbourne
Hi Vincenzo,
On 6/28/19 16:32, Vincenzo Frascino wrote:
> On 6/28/19 2:09 PM, Marek Szyprowski wrote:
>> On 2019-06-21 11:52, Vincenzo Frascino wrote:
>>> To take advantage of the commonly defined vdso interface for
>>> gettimeofday the architectural code requires an adaptation.
>>>
>>> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>>>
>>> With the new implementation arm64 gains support for CLOCK_BOOTTIME
>>> and CLOCK_TAI.
>>>
>>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>>> Cc: Will Deacon <will.deacon@arm.com>
>>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>>> Tested-by: Shijith Thotton <sthotton@marvell.com>
>>> Tested-by: Andre Przywara <andre.przywara@arm.com>
>>> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
>>
>> This patch causes serious regression on Samsung Exynos5433 SoC based
>> TM2(e) boards. The time in userspace is always set to begin of the epoch:
>>
>> # date 062813152019
>> Fri Jun 28 13:15:00 UTC 2019
>> # date
>> Thu Jan 1 00:00:00 UTC 1970
>> # date
>> Thu Jan 1 00:00:00 UTC 1970
>>
>> I've noticed that since the patch landed in Linux next-20190625 and
>> bisect indeed pointed to this patch.
>>
> Thank you for reporting this, seems that the next that you posted is missing
> some fixes for arm64.
>
> Could you please try the tree below?
>
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/vdso
>
> Let us know if the functionality is restored. Otherwise the issue will require
> further investigation.
Marek is already out for holidays, I gave your tree a try but kernel from
that branch was failing to boot on TM2(e).
Then I have cherry-picked 5 patches from the branch that seemed to
be missing in next-20190628:
28028f3174cf1 (HEAD) MAINTAINERS: Fix Andy's surname and the directory entries of VDSO
ec8f8e4bf2206 arm64: vdso: Fix compilation with clang older than 8
721882ebb5729 arm64: compat: Fix __arch_get_hw_counter() implementation
7027fea977a3d arm64: Fix __arch_get_hw_counter() implementation
10b305853fe22 lib/vdso: Make delta calculation work correctly
48568d8c7f479 (tag: next-20190628, linux-next/master) Add linux-next specific files for 20190628
With those 5 additional patches on top of next-20190628 the problem
is not observed any more. date, ping, etc. seems to be working well.
# date
Fri Jun 28 16:39:22 UTC 2019
#
# systemctl stop systemd-timesyncd
#
# date 062818392019
Fri Jun 28 18:39:00 UTC 2019
# date
Fri Jun 28 18:39:01 UTC 2019
#
# date 062818432019; date
Fri Jun 28 18:43:00 UTC 2019
Fri Jun 28 18:43:00 UTC 2019
# date
Fri Jun 28 18:43:04 UTC 2019
--
Regards,
Sylwester
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-28 16:50 ` Sylwester Nawrocki
@ 2019-06-29 6:58 ` Vincenzo Frascino
2019-07-08 12:57 ` Sylwester Nawrocki
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-29 6:58 UTC (permalink / raw)
To: Sylwester Nawrocki
Cc: Marek Szyprowski, linux-arch, linux-arm-kernel, linux-kernel,
linux-mips, linux-kselftest, Shuah Khan, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, Russell King, Ralf Baechle, Mark Salyzyn,
Paul Burton, Dmitry Safonov, Rasmus Villemoes, Thomas Gleixner,
Shijith Thotton, Peter Collingbourne
Hi Sylwester,
thank you for the quick turn around to my email.
On 6/28/19 5:50 PM, Sylwester Nawrocki wrote:
> Hi Vincenzo,
>
> On 6/28/19 16:32, Vincenzo Frascino wrote:
>> On 6/28/19 2:09 PM, Marek Szyprowski wrote:
>>> On 2019-06-21 11:52, Vincenzo Frascino wrote:
>>>> To take advantage of the commonly defined vdso interface for
>>>> gettimeofday the architectural code requires an adaptation.
>>>>
>>>> Re-implement the gettimeofday vdso in C in order to use lib/vdso.
>>>>
>>>> With the new implementation arm64 gains support for CLOCK_BOOTTIME
>>>> and CLOCK_TAI.
>>>>
>>>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>>>> Cc: Will Deacon <will.deacon@arm.com>
>>>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>>>> Tested-by: Shijith Thotton <sthotton@marvell.com>
>>>> Tested-by: Andre Przywara <andre.przywara@arm.com>
>>>> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
>>>
>>> This patch causes serious regression on Samsung Exynos5433 SoC based
>>> TM2(e) boards. The time in userspace is always set to begin of the epoch:
>>>
>>> # date 062813152019
>>> Fri Jun 28 13:15:00 UTC 2019
>>> # date
>>> Thu Jan 1 00:00:00 UTC 1970
>>> # date
>>> Thu Jan 1 00:00:00 UTC 1970
>>>
>>> I've noticed that since the patch landed in Linux next-20190625 and
>>> bisect indeed pointed to this patch.
>>>
>> Thank you for reporting this, seems that the next that you posted is missing
>> some fixes for arm64.
>>
>> Could you please try the tree below?
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/vdso
>>
>> Let us know if the functionality is restored. Otherwise the issue will require
>> further investigation.
>
> Marek is already out for holidays, I gave your tree a try but kernel from
> that branch was failing to boot on TM2(e).
>
> Then I have cherry-picked 5 patches from the branch that seemed to
> be missing in next-20190628:
>
> 28028f3174cf1 (HEAD) MAINTAINERS: Fix Andy's surname and the directory entries of VDSO
> ec8f8e4bf2206 arm64: vdso: Fix compilation with clang older than 8
> 721882ebb5729 arm64: compat: Fix __arch_get_hw_counter() implementation
> 7027fea977a3d arm64: Fix __arch_get_hw_counter() implementation
> 10b305853fe22 lib/vdso: Make delta calculation work correctly
> 48568d8c7f479 (tag: next-20190628, linux-next/master) Add linux-next specific files for 20190628
>
> With those 5 additional patches on top of next-20190628 the problem
> is not observed any more. date, ping, etc. seems to be working well.
>
> # date
> Fri Jun 28 16:39:22 UTC 2019
> #
> # systemctl stop systemd-timesyncd
> #
> # date 062818392019
> Fri Jun 28 18:39:00 UTC 2019
> # date
> Fri Jun 28 18:39:01 UTC 2019
> #
> # date 062818432019; date
> Fri Jun 28 18:43:00 UTC 2019
> Fri Jun 28 18:43:00 UTC 2019
> # date
> Fri Jun 28 18:43:04 UTC 2019
>
This seems ok, thanks for spending some time to test our patches against your board.
If I may, I would like to ask to you one favor, could you please keep an eye on
next and once those patches are merged repeat the test?
I want just to make sure that the regression does not reappear.
Have a nice weekend.
> --
> Regards,
> Sylwester
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-06-29 6:58 ` Vincenzo Frascino
@ 2019-07-08 12:57 ` Sylwester Nawrocki
2019-07-08 13:09 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Sylwester Nawrocki @ 2019-07-08 12:57 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: Marek Szyprowski, linux-arch, linux-arm-kernel, linux-kernel,
linux-mips, linux-kselftest, Shuah Khan, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, Russell King, Ralf Baechle, Mark Salyzyn,
Paul Burton, Dmitry Safonov, Rasmus Villemoes, Thomas Gleixner,
Shijith Thotton, Peter Collingbourne
Hi Vincenzo,
On 6/29/19 08:58, Vincenzo Frascino wrote:
> If I may, I would like to ask to you one favor, could you please keep an eye on
> next and once those patches are merged repeat the test?
>
> I want just to make sure that the regression does not reappear.
My apologies, I forgot about this for a moment. I repeated the test with
next-20190705 tag and couldn't see any regressions.
--
Regards,
Sylwester
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation
2019-07-08 12:57 ` Sylwester Nawrocki
@ 2019-07-08 13:09 ` Vincenzo Frascino
0 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-08 13:09 UTC (permalink / raw)
To: Sylwester Nawrocki
Cc: Marek Szyprowski, linux-arch, linux-arm-kernel, linux-kernel,
linux-mips, linux-kselftest, Shuah Khan, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, Russell King, Ralf Baechle, Mark Salyzyn,
Paul Burton, Dmitry Safonov, Rasmus Villemoes, Thomas Gleixner,
Shijith Thotton, Peter Collingbourne
Hi Sylwester,
On 08/07/2019 13:57, Sylwester Nawrocki wrote:
> Hi Vincenzo,
>
> On 6/29/19 08:58, Vincenzo Frascino wrote:
>> If I may, I would like to ask to you one favor, could you please keep an eye on
>> next and once those patches are merged repeat the test?
>>
>> I want just to make sure that the regression does not reappear.
>
> My apologies, I forgot about this for a moment. I repeated the test with
> next-20190705 tag and couldn't see any regressions.
>
No problem and thank you for the confirmation.
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH v7 05/25] arm64: Build vDSO with -ffixed-x18
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (3 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 04/25] arm64: Substitute gettimeofday with C implementation Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 06/25] arm64: compat: Add missing syscall numbers Vincenzo Frascino
` (21 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara,
Mark Salyzyn
From: Peter Collingbourne <pcc@google.com>
The vDSO needs to be build with x18 reserved in order to accommodate
userspace platform ABIs built on top of Linux that use the register
to carry inter-procedural state, as provided for by the AAPCS.
An example of such a platform ABI is the one that will be used by an
upcoming version of Android.
Although this change is currently a no-op due to the fact that the vDSO
is currently implemented in pure assembly on arm64, it is necessary
in order to prepare for another change [1] that will add C code to
the vDSO.
[1] https://patchwork.kernel.org/patch/10044501/
Signed-off-by: Peter Collingbourne <pcc@google.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
Cc: Mark Salyzyn <salyzyn@google.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
---
arch/arm64/kernel/vdso/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index 3acfc813e966..ec81d28aeb5d 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -20,7 +20,7 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \
--build-id -n -T
-ccflags-y := -fno-common -fno-builtin -fno-stack-protector
+ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18
ccflags-y += -DDISABLE_BRANCH_PROFILING
VDSO_LDFLAGS := -Bsymbolic
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 06/25] arm64: compat: Add missing syscall numbers
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (4 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 05/25] arm64: Build vDSO with -ffixed-x18 Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 07/25] arm64: compat: Expose signal related structures Vincenzo Frascino
` (20 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
vDSO requires gettimeofday and clock_gettime syscalls to implement the
fallback mechanism.
Add the missing syscall numbers to unistd.h for arm64.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/include/asm/unistd.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 70e6882853c0..81cc05acccc9 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -33,8 +33,13 @@
#define __NR_compat_exit 1
#define __NR_compat_read 3
#define __NR_compat_write 4
+#define __NR_compat_gettimeofday 78
#define __NR_compat_sigreturn 119
#define __NR_compat_rt_sigreturn 173
+#define __NR_compat_clock_getres 247
+#define __NR_compat_clock_gettime 263
+#define __NR_compat_clock_gettime64 403
+#define __NR_compat_clock_getres_time64 406
/*
* The following SVCs are ARM private.
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 07/25] arm64: compat: Expose signal related structures
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (5 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 06/25] arm64: compat: Add missing syscall numbers Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 08/25] arm64: compat: Generate asm offsets for signals Vincenzo Frascino
` (19 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
The compat signal data structures are required as part of the compat
vDSO implementation in order to provide the unwinding information for
the sigreturn trampolines.
Expose the mentioned data structures as part of signal32.h.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/include/asm/signal32.h | 46 +++++++++++++++++++++++++++++++
arch/arm64/kernel/signal32.c | 46 -------------------------------
2 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h
index 58e288aaf0ba..1f05268f4c6d 100644
--- a/arch/arm64/include/asm/signal32.h
+++ b/arch/arm64/include/asm/signal32.h
@@ -20,6 +20,52 @@
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
+struct compat_sigcontext {
+ /* We always set these two fields to 0 */
+ compat_ulong_t trap_no;
+ compat_ulong_t error_code;
+
+ compat_ulong_t oldmask;
+ compat_ulong_t arm_r0;
+ compat_ulong_t arm_r1;
+ compat_ulong_t arm_r2;
+ compat_ulong_t arm_r3;
+ compat_ulong_t arm_r4;
+ compat_ulong_t arm_r5;
+ compat_ulong_t arm_r6;
+ compat_ulong_t arm_r7;
+ compat_ulong_t arm_r8;
+ compat_ulong_t arm_r9;
+ compat_ulong_t arm_r10;
+ compat_ulong_t arm_fp;
+ compat_ulong_t arm_ip;
+ compat_ulong_t arm_sp;
+ compat_ulong_t arm_lr;
+ compat_ulong_t arm_pc;
+ compat_ulong_t arm_cpsr;
+ compat_ulong_t fault_address;
+};
+
+struct compat_ucontext {
+ compat_ulong_t uc_flags;
+ compat_uptr_t uc_link;
+ compat_stack_t uc_stack;
+ struct compat_sigcontext uc_mcontext;
+ compat_sigset_t uc_sigmask;
+ int __unused[32 - (sizeof(compat_sigset_t) / sizeof(int))];
+ compat_ulong_t uc_regspace[128] __attribute__((__aligned__(8)));
+};
+
+struct compat_sigframe {
+ struct compat_ucontext uc;
+ compat_ulong_t retcode[2];
+};
+
+struct compat_rt_sigframe {
+ struct compat_siginfo info;
+ struct compat_sigframe sig;
+};
+
int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index caea6e25db2a..74e06d8c7c2b 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -30,42 +30,6 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
-struct compat_sigcontext {
- /* We always set these two fields to 0 */
- compat_ulong_t trap_no;
- compat_ulong_t error_code;
-
- compat_ulong_t oldmask;
- compat_ulong_t arm_r0;
- compat_ulong_t arm_r1;
- compat_ulong_t arm_r2;
- compat_ulong_t arm_r3;
- compat_ulong_t arm_r4;
- compat_ulong_t arm_r5;
- compat_ulong_t arm_r6;
- compat_ulong_t arm_r7;
- compat_ulong_t arm_r8;
- compat_ulong_t arm_r9;
- compat_ulong_t arm_r10;
- compat_ulong_t arm_fp;
- compat_ulong_t arm_ip;
- compat_ulong_t arm_sp;
- compat_ulong_t arm_lr;
- compat_ulong_t arm_pc;
- compat_ulong_t arm_cpsr;
- compat_ulong_t fault_address;
-};
-
-struct compat_ucontext {
- compat_ulong_t uc_flags;
- compat_uptr_t uc_link;
- compat_stack_t uc_stack;
- struct compat_sigcontext uc_mcontext;
- compat_sigset_t uc_sigmask;
- int __unused[32 - (sizeof (compat_sigset_t) / sizeof (int))];
- compat_ulong_t uc_regspace[128] __attribute__((__aligned__(8)));
-};
-
struct compat_vfp_sigframe {
compat_ulong_t magic;
compat_ulong_t size;
@@ -92,16 +56,6 @@ struct compat_aux_sigframe {
unsigned long end_magic;
} __attribute__((__aligned__(8)));
-struct compat_sigframe {
- struct compat_ucontext uc;
- compat_ulong_t retcode[2];
-};
-
-struct compat_rt_sigframe {
- struct compat_siginfo info;
- struct compat_sigframe sig;
-};
-
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 08/25] arm64: compat: Generate asm offsets for signals
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (6 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 07/25] arm64: compat: Expose signal related structures Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 09/25] lib: vdso: Add compat support Vincenzo Frascino
` (18 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
Update asm-offsets for arm64 to generate the correct offsets for
compat signals.
They will be useful for the implementation of the compat sigreturn
trampolines in vDSO context.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/kernel/asm-offsets.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 9e4b7ccbab2f..c0d8b9f40022 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -30,6 +30,7 @@
#include <asm/fixmap.h>
#include <asm/thread_info.h>
#include <asm/memory.h>
+#include <asm/signal32.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include <linux/kbuild.h>
@@ -77,6 +78,11 @@ int main(void)
DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe));
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
BLANK();
+#ifdef CONFIG_COMPAT
+ DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_sigframe, uc.uc_mcontext.arm_r0));
+ DEFINE(COMPAT_RT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_rt_sigframe, sig.uc.uc_mcontext.arm_r0));
+ BLANK();
+#endif
DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter));
BLANK();
DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 09/25] lib: vdso: Add compat support
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (7 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 08/25] arm64: compat: Generate asm offsets for signals Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 10/25] arm64: compat: Add vDSO Vincenzo Frascino
` (17 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
Some 64 bit architectures have support for 32 bit applications that
require a separate version of the vDSOs.
Add support to the generic code for compat fallback functions.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
lib/vdso/gettimeofday.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 473e2dda0220..fc43f457ed2c 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -21,7 +21,11 @@
* - clock_gettime_fallback(): fallback for clock_gettime.
* - clock_getres_fallback(): fallback for clock_getres.
*/
+#ifdef ENABLE_COMPAT_VDSO
+#include <asm/vdso/compat_gettimeofday.h>
+#else
#include <asm/vdso/gettimeofday.h>
+#endif /* ENABLE_COMPAT_VDSO */
static int do_hres(const struct vdso_data *vd,
clockid_t clk,
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 10/25] arm64: compat: Add vDSO
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (8 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 09/25] lib: vdso: Add compat support Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-24 14:00 ` Catalin Marinas
` (3 more replies)
2019-06-21 9:52 ` [PATCH v7 11/25] arm64: Refactor vDSO code Vincenzo Frascino
` (16 subsequent siblings)
26 siblings, 4 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
Provide the arm64 compat (AArch32) vDSO in kernel/vdso32 in a similar
way to what happens in kernel/vdso.
The compat vDSO leverages on an adaptation of the arm architecture code
with few changes:
- Use of lib/vdso for gettimeofday
- Implementation of syscall based fallback
- Introduction of clock_getres for the compat library
- Implementation of trampolines
- Implementation of elf note
To build the compat vDSO a 32 bit compiler is required and needs to be
specified via CONFIG_CROSS_COMPILE_COMPAT_VDSO.
The implementation of the configuration option will be contained in a
future patch.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/include/asm/vdso/compat_barrier.h | 51 +++++
.../include/asm/vdso/compat_gettimeofday.h | 110 +++++++++++
arch/arm64/kernel/vdso32/.gitignore | 2 +
arch/arm64/kernel/vdso32/Makefile | 186 ++++++++++++++++++
arch/arm64/kernel/vdso32/note.c | 15 ++
arch/arm64/kernel/vdso32/sigreturn.S | 62 ++++++
arch/arm64/kernel/vdso32/vdso.S | 19 ++
arch/arm64/kernel/vdso32/vdso.lds.S | 82 ++++++++
arch/arm64/kernel/vdso32/vgettimeofday.c | 59 ++++++
9 files changed, 586 insertions(+)
create mode 100644 arch/arm64/include/asm/vdso/compat_barrier.h
create mode 100644 arch/arm64/include/asm/vdso/compat_gettimeofday.h
create mode 100644 arch/arm64/kernel/vdso32/.gitignore
create mode 100644 arch/arm64/kernel/vdso32/Makefile
create mode 100644 arch/arm64/kernel/vdso32/note.c
create mode 100644 arch/arm64/kernel/vdso32/sigreturn.S
create mode 100644 arch/arm64/kernel/vdso32/vdso.S
create mode 100644 arch/arm64/kernel/vdso32/vdso.lds.S
create mode 100644 arch/arm64/kernel/vdso32/vgettimeofday.c
diff --git a/arch/arm64/include/asm/vdso/compat_barrier.h b/arch/arm64/include/asm/vdso/compat_barrier.h
new file mode 100644
index 000000000000..ea24ea856b07
--- /dev/null
+++ b/arch/arm64/include/asm/vdso/compat_barrier.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 ARM Limited
+ */
+#ifndef __COMPAT_BARRIER_H
+#define __COMPAT_BARRIER_H
+
+#ifndef __ASSEMBLY__
+/*
+ * Warning: This code is meant to be used with
+ * ENABLE_COMPAT_VDSO only.
+ */
+#ifndef ENABLE_COMPAT_VDSO
+#error This header is meant to be used with ENABLE_COMPAT_VDSO only
+#endif
+
+#ifdef dmb
+#undef dmb
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
+#elif __LINUX_ARM_ARCH__ == 6
+#define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
+ : : "r" (0) : "memory")
+#else
+#define dmb(x) __asm__ __volatile__ ("" : : : "memory")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 8
+#define aarch32_smp_mb() dmb(ish)
+#define aarch32_smp_rmb() dmb(ishld)
+#define aarch32_smp_wmb() dmb(ishst)
+#else
+#define aarch32_smp_mb() dmb(ish)
+#define aarch32_smp_rmb() aarch32_smp_mb()
+#define aarch32_smp_wmb() dmb(ishst)
+#endif
+
+
+#undef smp_mb
+#undef smp_rmb
+#undef smp_wmb
+
+#define smp_mb() aarch32_smp_mb()
+#define smp_rmb() aarch32_smp_rmb()
+#define smp_wmb() aarch32_smp_wmb()
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __COMPAT_BARRIER_H */
diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
new file mode 100644
index 000000000000..7a39c8340936
--- /dev/null
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 ARM Limited
+ */
+#ifndef __ASM_VDSO_GETTIMEOFDAY_H
+#define __ASM_VDSO_GETTIMEOFDAY_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/unistd.h>
+#include <uapi/linux/time.h>
+
+#include <asm/vdso/compat_barrier.h>
+
+#define VDSO_HAS_CLOCK_GETRES 1
+
+static __always_inline int gettimeofday_fallback(
+ struct __kernel_old_timeval *_tv,
+ struct timezone *_tz)
+{
+ register struct timezone *tz asm("r1") = _tz;
+ register struct __kernel_old_timeval *tv asm("r0") = _tv;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_compat_gettimeofday;
+
+ asm volatile(
+ " swi #0\n"
+ : "=r" (ret)
+ : "r" (tv), "r" (tz), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static __always_inline long clock_gettime_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ register struct __kernel_timespec *ts asm("r1") = _ts;
+ register clockid_t clkid asm("r0") = _clkid;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_compat_clock_gettime64;
+
+ asm volatile(
+ " swi #0\n"
+ : "=r" (ret)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static __always_inline int clock_getres_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ register struct __kernel_timespec *ts asm("r1") = _ts;
+ register clockid_t clkid asm("r0") = _clkid;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_compat_clock_getres_time64;
+
+ /* The checks below are required for ABI consistency with arm */
+ if ((_clkid >= MAX_CLOCKS) && (_ts == NULL))
+ return -EINVAL;
+
+ asm volatile(
+ " swi #0\n"
+ : "=r" (ret)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
+{
+ u64 res;
+
+ isb();
+ asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (res));
+
+ return res;
+}
+
+static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
+{
+ const struct vdso_data *ret;
+
+ /*
+ * This simply puts &_vdso_data into ret. The reason why we don't use
+ * `ret = _vdso_data` is that the compiler tends to optimise this in a
+ * very suboptimal way: instead of keeping &_vdso_data in a register,
+ * it goes through a relocation almost every time _vdso_data must be
+ * accessed (even in subfunctions). This is both time and space
+ * consuming: each relocation uses a word in the code section, and it
+ * has to be loaded at runtime.
+ *
+ * This trick hides the assignment from the compiler. Since it cannot
+ * track where the pointer comes from, it will only use one relocation
+ * where __arch_get_vdso_data() is called, and then keep the result in
+ * a register.
+ */
+ asm volatile("mov %0, %1" : "=r"(ret) : "r"(_vdso_data));
+
+ return ret;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/arm64/kernel/vdso32/.gitignore b/arch/arm64/kernel/vdso32/.gitignore
new file mode 100644
index 000000000000..4fea950fa5ed
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/.gitignore
@@ -0,0 +1,2 @@
+vdso.lds
+vdso.so.raw
diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
new file mode 100644
index 000000000000..288c14d30b45
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/Makefile
@@ -0,0 +1,186 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for vdso32
+#
+
+# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+# the inclusion of generic Makefile.
+ARCH_REL_TYPE_ABS := R_ARM_JUMP_SLOT|R_ARM_GLOB_DAT|R_ARM_ABS32
+include $(srctree)/lib/vdso/Makefile
+
+COMPATCC := $(CROSS_COMPILE_COMPAT)gcc
+
+# Same as cc-*option, but using COMPATCC instead of CC
+cc32-option = $(call try-run,\
+ $(COMPATCC) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
+cc32-disable-warning = $(call try-run,\
+ $(COMPATCC) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+cc32-ldoption = $(call try-run,\
+ $(COMPATCC) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
+
+# We cannot use the global flags to compile the vDSO files, the main reason
+# being that the 32-bit compiler may be older than the main (64-bit) compiler
+# and therefore may not understand flags set using $(cc-option ...). Besides,
+# arch-specific options should be taken from the arm Makefile instead of the
+# arm64 one.
+# As a result we set our own flags here.
+
+# From top-level Makefile
+# NOSTDINC_FLAGS
+VDSO_CPPFLAGS := -nostdinc -isystem $(shell $(COMPATCC) -print-file-name=include)
+VDSO_CPPFLAGS += $(LINUXINCLUDE)
+VDSO_CPPFLAGS += $(KBUILD_CPPFLAGS)
+
+# Common C and assembly flags
+# From top-level Makefile
+VDSO_CAFLAGS := $(VDSO_CPPFLAGS)
+VDSO_CAFLAGS += $(call cc32-option,-fno-PIE)
+ifdef CONFIG_DEBUG_INFO
+VDSO_CAFLAGS += -g
+endif
+ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(COMPATCC)), y)
+VDSO_CAFLAGS += -DCC_HAVE_ASM_GOTO
+endif
+
+# From arm Makefile
+VDSO_CAFLAGS += $(call cc32-option,-fno-dwarf2-cfi-asm)
+VDSO_CAFLAGS += -mabi=aapcs-linux -mfloat-abi=soft
+ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
+VDSO_CAFLAGS += -mbig-endian
+else
+VDSO_CAFLAGS += -mlittle-endian
+endif
+
+# From arm vDSO Makefile
+VDSO_CAFLAGS += -fPIC -fno-builtin -fno-stack-protector
+VDSO_CAFLAGS += -DDISABLE_BRANCH_PROFILING
+
+# Try to compile for ARMv8. If the compiler is too old and doesn't support it,
+# fall back to v7. There is no easy way to check for what architecture the code
+# is being compiled, so define a macro specifying that (see arch/arm/Makefile).
+VDSO_CAFLAGS += $(call cc32-option,-march=armv8-a -D__LINUX_ARM_ARCH__=8,\
+ -march=armv7-a -D__LINUX_ARM_ARCH__=7)
+
+VDSO_CFLAGS := $(VDSO_CAFLAGS)
+VDSO_CFLAGS += -DENABLE_COMPAT_VDSO=1
+# KBUILD_CFLAGS from top-level Makefile
+VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+ -fno-strict-aliasing -fno-common \
+ -Werror-implicit-function-declaration \
+ -Wno-format-security \
+ -std=gnu89
+VDSO_CFLAGS += -O2
+# Some useful compiler-dependent flags from top-level Makefile
+VDSO_CFLAGS += $(call cc32-option,-Wdeclaration-after-statement,)
+VDSO_CFLAGS += $(call cc32-option,-Wno-pointer-sign)
+VDSO_CFLAGS += $(call cc32-option,-fno-strict-overflow)
+VDSO_CFLAGS += $(call cc32-option,-Werror=strict-prototypes)
+VDSO_CFLAGS += $(call cc32-option,-Werror=date-time)
+VDSO_CFLAGS += $(call cc32-option,-Werror=incompatible-pointer-types)
+
+# The 32-bit compiler does not provide 128-bit integers, which are used in
+# some headers that are indirectly included from the vDSO code.
+# This hack makes the compiler happy and should trigger a warning/error if
+# variables of such type are referenced.
+VDSO_CFLAGS += -D__uint128_t='void*'
+# Silence some warnings coming from headers that operate on long's
+# (on GCC 4.8 or older, there is unfortunately no way to silence this warning)
+VDSO_CFLAGS += $(call cc32-disable-warning,shift-count-overflow)
+VDSO_CFLAGS += -Wno-int-to-pointer-cast
+
+VDSO_AFLAGS := $(VDSO_CAFLAGS)
+VDSO_AFLAGS += -D__ASSEMBLY__
+
+VDSO_LDFLAGS := $(VDSO_CPPFLAGS)
+# From arm vDSO Makefile
+VDSO_LDFLAGS += -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1
+VDSO_LDFLAGS += -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
+VDSO_LDFLAGS += -nostdlib -shared -mfloat-abi=soft
+VDSO_LDFLAGS += $(call cc32-ldoption,-Wl$(comma)--hash-style=sysv)
+VDSO_LDFLAGS += $(call cc32-ldoption,-Wl$(comma)--build-id)
+VDSO_LDFLAGS += $(call cc32-ldoption,-fuse-ld=bfd)
+
+
+# Borrow vdsomunge.c from the arm vDSO
+# We have to use a relative path because scripts/Makefile.host prefixes
+# $(hostprogs-y) with $(obj)
+munge := ../../../arm/vdso/vdsomunge
+hostprogs-y := $(munge)
+
+c-obj-vdso := note.o
+c-obj-vdso-gettimeofday := vgettimeofday.o
+asm-obj-vdso := sigreturn.o
+
+ifneq ($(c-gettimeofday-y),)
+VDSO_CFLAGS_gettimeofday_o += -include $(c-gettimeofday-y)
+endif
+
+VDSO_CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
+
+# Build rules
+targets := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso) vdso.so vdso.so.dbg vdso.so.raw
+c-obj-vdso := $(addprefix $(obj)/, $(c-obj-vdso))
+c-obj-vdso-gettimeofday := $(addprefix $(obj)/, $(c-obj-vdso-gettimeofday))
+asm-obj-vdso := $(addprefix $(obj)/, $(asm-obj-vdso))
+obj-vdso := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso)
+
+obj-y += vdso.o
+extra-y += vdso.lds
+CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+
+# Force dependency (vdso.s includes vdso.so through incbin)
+$(obj)/vdso.o: $(obj)/vdso.so
+
+include/generated/vdso32-offsets.h: $(obj)/vdso.so.dbg FORCE
+ $(call if_changed,vdsosym)
+
+# Strip rule for vdso.so
+$(obj)/vdso.so: OBJCOPYFLAGS := -S
+$(obj)/vdso.so: $(obj)/vdso.so.dbg FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vdso.so.dbg: $(obj)/vdso.so.raw $(obj)/$(munge) FORCE
+ $(call if_changed,vdsomunge)
+
+# Link rule for the .so file, .lds has to be first
+$(obj)/vdso.so.raw: $(src)/vdso.lds $(obj-vdso) FORCE
+ $(call if_changed,vdsold)
+ $(call if_changed,vdso_check)
+
+# Compilation rules for the vDSO sources
+$(c-obj-vdso): %.o: %.c FORCE
+ $(call if_changed_dep,vdsocc)
+$(c-obj-vdso-gettimeofday): %.o: %.c FORCE
+ $(call if_changed_dep,vdsocc_gettimeofday)
+$(asm-obj-vdso): %.o: %.S FORCE
+ $(call if_changed_dep,vdsoas)
+
+# Actual build commands
+quiet_cmd_vdsold = VDSOL $@
+ cmd_vdsold = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_LDFLAGS) \
+ -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@
+quiet_cmd_vdsocc = VDSOC $@
+ cmd_vdsocc = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) -c -o $@ $<
+quiet_cmd_vdsocc_gettimeofday = VDSOC_GTD $@
+ cmd_vdsocc_gettimeofday = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) $(VDSO_CFLAGS_gettimeofday_o) -c -o $@ $<
+quiet_cmd_vdsoas = VDSOA $@
+ cmd_vdsoas = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_AFLAGS) -c -o $@ $<
+
+quiet_cmd_vdsomunge = MUNGE $@
+ cmd_vdsomunge = $(obj)/$(munge) $< $@
+
+# Generate vDSO offsets using helper script (borrowed from the 64-bit vDSO)
+gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
+quiet_cmd_vdsosym = VDSOSYM $@
+# The AArch64 nm should be able to read an AArch32 binary
+ cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
+
+# Install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/vdso32.so
+
+vdso.so: $(obj)/vdso.so.dbg
+ @mkdir -p $(MODLIB)/vdso
+ $(call cmd,vdso_install)
+
+vdso_install: vdso.so
diff --git a/arch/arm64/kernel/vdso32/note.c b/arch/arm64/kernel/vdso32/note.c
new file mode 100644
index 000000000000..eff5bf9efb8b
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/note.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2012-2018 ARM Limited
+ *
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ */
+
+#include <linux/uts.h>
+#include <linux/version.h>
+#include <linux/elfnote.h>
+#include <linux/build-salt.h>
+
+ELFNOTE32("Linux", 0, LINUX_VERSION_CODE);
+BUILD_SALT;
diff --git a/arch/arm64/kernel/vdso32/sigreturn.S b/arch/arm64/kernel/vdso32/sigreturn.S
new file mode 100644
index 000000000000..1a81277c2d09
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/sigreturn.S
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This file provides both A32 and T32 versions, in accordance with the
+ * arm sigreturn code.
+ *
+ * Copyright (C) 2018 ARM Limited
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/unistd.h>
+
+#define ARM_ENTRY(name) \
+ ENTRY(name)
+
+#define ARM_ENDPROC(name) \
+ .type name, %function; \
+ END(name)
+
+ .text
+
+ .arm
+ .fnstart
+ .save {r0-r15}
+ .pad #COMPAT_SIGFRAME_REGS_OFFSET
+ nop
+ARM_ENTRY(__kernel_sigreturn_arm)
+ mov r7, #__NR_compat_sigreturn
+ svc #0
+ .fnend
+ARM_ENDPROC(__kernel_sigreturn_arm)
+
+ .fnstart
+ .save {r0-r15}
+ .pad #COMPAT_RT_SIGFRAME_REGS_OFFSET
+ nop
+ARM_ENTRY(__kernel_rt_sigreturn_arm)
+ mov r7, #__NR_compat_rt_sigreturn
+ svc #0
+ .fnend
+ARM_ENDPROC(__kernel_rt_sigreturn_arm)
+
+ .thumb
+ .fnstart
+ .save {r0-r15}
+ .pad #COMPAT_SIGFRAME_REGS_OFFSET
+ nop
+ARM_ENTRY(__kernel_sigreturn_thumb)
+ mov r7, #__NR_compat_sigreturn
+ svc #0
+ .fnend
+ARM_ENDPROC(__kernel_sigreturn_thumb)
+
+ .fnstart
+ .save {r0-r15}
+ .pad #COMPAT_RT_SIGFRAME_REGS_OFFSET
+ nop
+ARM_ENTRY(__kernel_rt_sigreturn_thumb)
+ mov r7, #__NR_compat_rt_sigreturn
+ svc #0
+ .fnend
+ARM_ENDPROC(__kernel_rt_sigreturn_thumb)
diff --git a/arch/arm64/kernel/vdso32/vdso.S b/arch/arm64/kernel/vdso32/vdso.S
new file mode 100644
index 000000000000..e72ac7bc4c04
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/vdso.S
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/page.h>
+
+ .globl vdso32_start, vdso32_end
+ .section .rodata
+ .balign PAGE_SIZE
+vdso32_start:
+ .incbin "arch/arm64/kernel/vdso32/vdso.so"
+ .balign PAGE_SIZE
+vdso32_end:
+
+ .previous
diff --git a/arch/arm64/kernel/vdso32/vdso.lds.S b/arch/arm64/kernel/vdso32/vdso.lds.S
new file mode 100644
index 000000000000..a3944927eaeb
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/vdso.lds.S
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Adapted from arm64 version.
+ *
+ * GNU linker script for the VDSO library.
+ * Heavily based on the vDSO linker scripts for other archs.
+ *
+ * Copyright (C) 2012-2018 ARM Limited
+ */
+
+#include <linux/const.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+ PROVIDE_HIDDEN(_vdso_data = . - PAGE_SIZE);
+ . = VDSO_LBASE + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+
+ .text : { *(.text*) } :text =0xe7f001f2
+
+ .got : { *(.got) }
+ .rel.plt : { *(.rel.plt) }
+
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.data .data.* .gnu.linkonce.d.* .sdata*)
+ *(.bss .sbss .dynbss .dynsbss)
+ }
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+}
+
+VERSION
+{
+ LINUX_2.6 {
+ global:
+ __vdso_clock_gettime;
+ __vdso_gettimeofday;
+ __vdso_clock_getres;
+ __kernel_sigreturn_arm;
+ __kernel_sigreturn_thumb;
+ __kernel_rt_sigreturn_arm;
+ __kernel_rt_sigreturn_thumb;
+ __vdso_clock_gettime64;
+ local: *;
+ };
+}
+
+/*
+ * Make the sigreturn code visible to the kernel.
+ */
+VDSO_compat_sigreturn_arm = __kernel_sigreturn_arm;
+VDSO_compat_sigreturn_thumb = __kernel_sigreturn_thumb;
+VDSO_compat_rt_sigreturn_arm = __kernel_rt_sigreturn_arm;
+VDSO_compat_rt_sigreturn_thumb = __kernel_rt_sigreturn_thumb;
diff --git a/arch/arm64/kernel/vdso32/vgettimeofday.c b/arch/arm64/kernel/vdso32/vgettimeofday.c
new file mode 100644
index 000000000000..54fc1c2ce93f
--- /dev/null
+++ b/arch/arm64/kernel/vdso32/vgettimeofday.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM64 compat userspace implementations of gettimeofday() and similar.
+ *
+ * Copyright (C) 2018 ARM Limited
+ *
+ */
+#include <linux/time.h>
+#include <linux/types.h>
+
+int __vdso_clock_gettime(clockid_t clock,
+ struct old_timespec32 *ts)
+{
+ /* The checks below are required for ABI consistency with arm */
+ if ((u32)ts >= TASK_SIZE_32)
+ return -EFAULT;
+
+ return __cvdso_clock_gettime32(clock, ts);
+}
+
+int __vdso_clock_gettime64(clockid_t clock,
+ struct __kernel_timespec *ts)
+{
+ /* The checks below are required for ABI consistency with arm */
+ if ((u32)ts >= TASK_SIZE_32)
+ return -EFAULT;
+
+ return __cvdso_clock_gettime(clock, ts);
+}
+
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
+ struct timezone *tz)
+{
+ return __cvdso_gettimeofday(tv, tz);
+}
+
+int __vdso_clock_getres(clockid_t clock_id,
+ struct old_timespec32 *res)
+{
+ /* The checks below are required for ABI consistency with arm */
+ if ((u32)res >= TASK_SIZE_32)
+ return -EFAULT;
+
+ return __cvdso_clock_getres_time32(clock_id, res);
+}
+
+/* Avoid unresolved references emitted by GCC */
+
+void __aeabi_unwind_cpp_pr0(void)
+{
+}
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+}
+
+void __aeabi_unwind_cpp_pr2(void)
+{
+}
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-06-21 9:52 ` [PATCH v7 10/25] arm64: compat: Add vDSO Vincenzo Frascino
@ 2019-06-24 14:00 ` Catalin Marinas
2019-07-10 4:02 ` John Stultz
` (2 subsequent siblings)
3 siblings, 0 replies; 108+ messages in thread
From: Catalin Marinas @ 2019-06-24 14:00 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
On Fri, Jun 21, 2019 at 10:52:37AM +0100, Vincenzo Frascino wrote:
> --- /dev/null
> +++ b/arch/arm64/include/asm/vdso/compat_barrier.h
> @@ -0,0 +1,51 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2018 ARM Limited
> + */
> +#ifndef __COMPAT_BARRIER_H
> +#define __COMPAT_BARRIER_H
> +
> +#ifndef __ASSEMBLY__
> +/*
> + * Warning: This code is meant to be used with
> + * ENABLE_COMPAT_VDSO only.
> + */
> +#ifndef ENABLE_COMPAT_VDSO
> +#error This header is meant to be used with ENABLE_COMPAT_VDSO only
> +#endif
> +
> +#ifdef dmb
> +#undef dmb
> +#endif
> +
> +#if __LINUX_ARM_ARCH__ >= 7
> +#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
> +#elif __LINUX_ARM_ARCH__ == 6
> +#define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
> + : : "r" (0) : "memory")
> +#else
> +#define dmb(x) __asm__ __volatile__ ("" : : : "memory")
> +#endif
We don't need pre-ARMv7 barriers (they've been deprecated and the arm64
kernel actually traps and emulates them by default). Also your Makefile
changes never define a __LINUX_ARM_ARCH__ lower than 7. Fix-up below:
------8<-----------------------
From 5655a0313ce7bb731bfed6a19bcfe6b1100b542a Mon Sep 17 00:00:00 2001
From: Catalin Marinas <catalin.marinas@arm.com>
Date: Mon, 24 Jun 2019 12:16:06 +0100
Subject: [PATCH] arm64: compat: No need for pre-ARMv7 barriers on an ARMv8
system
This patch removes the deprecated (pre-ARMv7) compat barriers as they
would not be used on an ARMv8 system.
Fixes: a7f71a2c8903 ("arm64: compat: Add vDSO")
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/include/asm/vdso/compat_barrier.h | 7 -------
1 file changed, 7 deletions(-)
diff --git a/arch/arm64/include/asm/vdso/compat_barrier.h b/arch/arm64/include/asm/vdso/compat_barrier.h
index ea24ea856b07..fb60a88b5ed4 100644
--- a/arch/arm64/include/asm/vdso/compat_barrier.h
+++ b/arch/arm64/include/asm/vdso/compat_barrier.h
@@ -18,14 +18,7 @@
#undef dmb
#endif
-#if __LINUX_ARM_ARCH__ >= 7
#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
-#elif __LINUX_ARM_ARCH__ == 6
-#define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
- : : "r" (0) : "memory")
-#else
-#define dmb(x) __asm__ __volatile__ ("" : : : "memory")
-#endif
#if __LINUX_ARM_ARCH__ >= 8
#define aarch32_smp_mb() dmb(ish)
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-06-21 9:52 ` [PATCH v7 10/25] arm64: compat: Add vDSO Vincenzo Frascino
2019-06-24 14:00 ` Catalin Marinas
@ 2019-07-10 4:02 ` John Stultz
2019-07-10 6:12 ` Thomas Gleixner
` (2 more replies)
2019-07-10 13:04 ` [PATCH] arm64: vdso: Fix ABI regression in compat vdso Vincenzo Frascino
2019-07-10 14:01 ` [PATCH v2] " Vincenzo Frascino
3 siblings, 3 replies; 108+ messages in thread
From: John Stultz @ 2019-07-10 4:02 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, lkml, linux-mips, linux-kselftest,
Shuah Khan, Andre Przywara, Arnd Bergmann, Huw Davies,
Catalin Marinas, Daniel Lezcano, Will Deacon, Russell King,
Ralf Baechle, Mark Salyzyn, Paul Burton, Dmitry Safonov,
Rasmus Villemoes, Thomas Gleixner, Shijith Thotton,
Peter Collingbourne
On Fri, Jun 21, 2019 at 3:18 AM Vincenzo Frascino
<vincenzo.frascino@arm.com> wrote:
>
> Provide the arm64 compat (AArch32) vDSO in kernel/vdso32 in a similar
> way to what happens in kernel/vdso.
>
> The compat vDSO leverages on an adaptation of the arm architecture code
> with few changes:
> - Use of lib/vdso for gettimeofday
> - Implementation of syscall based fallback
> - Introduction of clock_getres for the compat library
> - Implementation of trampolines
> - Implementation of elf note
>
> To build the compat vDSO a 32 bit compiler is required and needs to be
> specified via CONFIG_CROSS_COMPILE_COMPAT_VDSO.
>
Hey Vincenzo!
Congrats on getting this work merged, I know its been a long effort
over a number of years!
Though unfortunately, it seems the arm64 vdso code that just landed is
breaking AOSP for me.
I see a lot of the following errors:
01-01 01:22:14.097 755 755 F libc : Fatal signal 11 (SIGSEGV),
code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 755 (cameraserver),
pid 755 (cameraserver)
01-01 01:22:14.112 759 759 F libc : Fatal signal 11 (SIGSEGV),
code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 759
(android.hardwar), pid 759 (android.hardwar)
01-01 01:22:14.120 756 756 F libc : Fatal signal 11 (SIGSEGV),
code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 756 (drmserver),
pid 756 (drmserver)
Which go away if I revert the vdso merge that went in via tip/timers.
I tried to bisect things down a bit, but as some later fixes are
required (at one point, date was returning the start epoch and never
increasing), this hasn't worked too well. But I'm guessing since I
see: "CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will
not be built", and the system is half working, I'm guessing this is an
issue with just the 32bit code failing. While I can try to sort out
the proper CROSS_COMPILE_COMPAT in my build environment, I assume
userland shouldn't be crashing if that value isn't set.
Any chance this issue has already been raised?
thanks
-john
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-07-10 4:02 ` John Stultz
@ 2019-07-10 6:12 ` Thomas Gleixner
2019-07-10 9:48 ` Vincenzo Frascino
2019-07-10 8:27 ` Will Deacon
2019-07-10 9:47 ` Vincenzo Frascino
2 siblings, 1 reply; 108+ messages in thread
From: Thomas Gleixner @ 2019-07-10 6:12 UTC (permalink / raw)
To: John Stultz
Cc: Vincenzo Frascino, linux-arch, linux-arm-kernel, lkml,
linux-mips, linux-kselftest, Shuah Khan, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, Russell King, Ralf Baechle, Mark Salyzyn,
Paul Burton, Dmitry Safonov, Rasmus Villemoes, Shijith Thotton,
Peter Collingbourne
On Tue, 9 Jul 2019, John Stultz wrote:
> Though unfortunately, it seems the arm64 vdso code that just landed is
> breaking AOSP for me.
>
> I see a lot of the following errors:
> 01-01 01:22:14.097 755 755 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 755 (cameraserver),
> pid 755 (cameraserver)
> 01-01 01:22:14.112 759 759 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 759
> (android.hardwar), pid 759 (android.hardwar)
> 01-01 01:22:14.120 756 756 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 756 (drmserver),
> pid 756 (drmserver)
>
> Which go away if I revert the vdso merge that went in via tip/timers.
>
> I tried to bisect things down a bit, but as some later fixes are
> required (at one point, date was returning the start epoch and never
> increasing), this hasn't worked too well. But I'm guessing since I
> see: "CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will
> not be built", and the system is half working, I'm guessing this is an
> issue with just the 32bit code failing. While I can try to sort out
> the proper CROSS_COMPILE_COMPAT in my build environment, I assume
> userland shouldn't be crashing if that value isn't set.
The obvious question is whether the VDSO is mapped to the 32bit process in
that case. It shouldn't...
Thanks,
tglx
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-07-10 6:12 ` Thomas Gleixner
@ 2019-07-10 9:48 ` Vincenzo Frascino
0 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-10 9:48 UTC (permalink / raw)
To: Thomas Gleixner, John Stultz
Cc: linux-arch, linux-arm-kernel, lkml, linux-mips, linux-kselftest,
Shuah Khan, Andre Przywara, Arnd Bergmann, Huw Davies,
Catalin Marinas, Daniel Lezcano, Will Deacon, Russell King,
Ralf Baechle, Mark Salyzyn, Paul Burton, Dmitry Safonov,
Rasmus Villemoes, Shijith Thotton, Peter Collingbourne
On 10/07/2019 07:12, Thomas Gleixner wrote:
> On Tue, 9 Jul 2019, John Stultz wrote:
>> Though unfortunately, it seems the arm64 vdso code that just landed is
>> breaking AOSP for me.
>>
>> I see a lot of the following errors:
>> 01-01 01:22:14.097 755 755 F libc : Fatal signal 11 (SIGSEGV),
>> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 755 (cameraserver),
>> pid 755 (cameraserver)
>> 01-01 01:22:14.112 759 759 F libc : Fatal signal 11 (SIGSEGV),
>> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 759
>> (android.hardwar), pid 759 (android.hardwar)
>> 01-01 01:22:14.120 756 756 F libc : Fatal signal 11 (SIGSEGV),
>> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 756 (drmserver),
>> pid 756 (drmserver)
>>
>> Which go away if I revert the vdso merge that went in via tip/timers.
>>
>> I tried to bisect things down a bit, but as some later fixes are
>> required (at one point, date was returning the start epoch and never
>> increasing), this hasn't worked too well. But I'm guessing since I
>> see: "CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will
>> not be built", and the system is half working, I'm guessing this is an
>> issue with just the 32bit code failing. While I can try to sort out
>> the proper CROSS_COMPILE_COMPAT in my build environment, I assume
>> userland shouldn't be crashing if that value isn't set.
>
> The obvious question is whether the VDSO is mapped to the 32bit process in
> that case. It shouldn't...
>
Agreed. I am investing if/why this is happening and will post a fix accordingly.
> Thanks,
>
> tglx
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-07-10 4:02 ` John Stultz
2019-07-10 6:12 ` Thomas Gleixner
@ 2019-07-10 8:27 ` Will Deacon
2019-07-10 8:58 ` Thomas Gleixner
2019-07-10 9:47 ` Vincenzo Frascino
2 siblings, 1 reply; 108+ messages in thread
From: Will Deacon @ 2019-07-10 8:27 UTC (permalink / raw)
To: John Stultz
Cc: Vincenzo Frascino, linux-arch, linux-arm-kernel, lkml,
linux-mips, linux-kselftest, Shuah Khan, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, Russell King, Ralf Baechle, Mark Salyzyn,
Paul Burton, Dmitry Safonov, Rasmus Villemoes, Thomas Gleixner,
Shijith Thotton, Peter Collingbourne
Hi John,
On Tue, Jul 09, 2019 at 09:02:54PM -0700, John Stultz wrote:
> On Fri, Jun 21, 2019 at 3:18 AM Vincenzo Frascino
> <vincenzo.frascino@arm.com> wrote:
> >
> > Provide the arm64 compat (AArch32) vDSO in kernel/vdso32 in a similar
> > way to what happens in kernel/vdso.
> >
> > The compat vDSO leverages on an adaptation of the arm architecture code
> > with few changes:
> > - Use of lib/vdso for gettimeofday
> > - Implementation of syscall based fallback
> > - Introduction of clock_getres for the compat library
> > - Implementation of trampolines
> > - Implementation of elf note
> >
> > To build the compat vDSO a 32 bit compiler is required and needs to be
> > specified via CONFIG_CROSS_COMPILE_COMPAT_VDSO.
> >
>
> Hey Vincenzo!
> Congrats on getting this work merged, I know its been a long effort
> over a number of years!
>
> Though unfortunately, it seems the arm64 vdso code that just landed is
> breaking AOSP for me.
>
> I see a lot of the following errors:
> 01-01 01:22:14.097 755 755 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 755 (cameraserver),
> pid 755 (cameraserver)
> 01-01 01:22:14.112 759 759 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 759
> (android.hardwar), pid 759 (android.hardwar)
> 01-01 01:22:14.120 756 756 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 756 (drmserver),
> pid 756 (drmserver)
>
> Which go away if I revert the vdso merge that went in via tip/timers.
>
> I tried to bisect things down a bit, but as some later fixes are
> required (at one point, date was returning the start epoch and never
> increasing), this hasn't worked too well. But I'm guessing since I
> see: "CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will
> not be built", and the system is half working, I'm guessing this is an
> issue with just the 32bit code failing. While I can try to sort out
> the proper CROSS_COMPILE_COMPAT in my build environment, I assume
> userland shouldn't be crashing if that value isn't set.
>
> Any chance this issue has already been raised?
First I've seen of it, although Vincenzo is likely to know better than me.
In the meantime, please can you share your .config?
Thanks,
Will
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-07-10 8:27 ` Will Deacon
@ 2019-07-10 8:58 ` Thomas Gleixner
2019-07-10 9:12 ` Will Deacon
0 siblings, 1 reply; 108+ messages in thread
From: Thomas Gleixner @ 2019-07-10 8:58 UTC (permalink / raw)
To: Will Deacon
Cc: John Stultz, Vincenzo Frascino, linux-arch, linux-arm-kernel,
lkml, linux-mips, linux-kselftest, Shuah Khan, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, Russell King, Ralf Baechle, Mark Salyzyn,
Paul Burton, Dmitry Safonov, Rasmus Villemoes, Shijith Thotton,
Peter Collingbourne
On Wed, 10 Jul 2019, Will Deacon wrote:
> On Tue, Jul 09, 2019 at 09:02:54PM -0700, John Stultz wrote:
> > I tried to bisect things down a bit, but as some later fixes are
> > required (at one point, date was returning the start epoch and never
> > increasing), this hasn't worked too well. But I'm guessing since I
> > see: "CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will
> > not be built", and the system is half working, I'm guessing this is an
> > issue with just the 32bit code failing. While I can try to sort out
> > the proper CROSS_COMPILE_COMPAT in my build environment, I assume
> > userland shouldn't be crashing if that value isn't set.
> >
> > Any chance this issue has already been raised?
>
> First I've seen of it, although Vincenzo is likely to know better than me.
> In the meantime, please can you share your .config?
I think the key is: CROSS_COMPILE_COMPAT not defined or empty. And then run
32bit userspace.
Thanks,
tglx
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-07-10 8:58 ` Thomas Gleixner
@ 2019-07-10 9:12 ` Will Deacon
0 siblings, 0 replies; 108+ messages in thread
From: Will Deacon @ 2019-07-10 9:12 UTC (permalink / raw)
To: Thomas Gleixner
Cc: John Stultz, Vincenzo Frascino, linux-arch, linux-arm-kernel,
lkml, linux-mips, linux-kselftest, Shuah Khan, Andre Przywara,
Arnd Bergmann, Huw Davies, Catalin Marinas, Daniel Lezcano,
Will Deacon, Russell King, Ralf Baechle, Mark Salyzyn,
Paul Burton, Dmitry Safonov, Rasmus Villemoes, Shijith Thotton,
Peter Collingbourne
On Wed, Jul 10, 2019 at 10:58:25AM +0200, Thomas Gleixner wrote:
> On Wed, 10 Jul 2019, Will Deacon wrote:
> > On Tue, Jul 09, 2019 at 09:02:54PM -0700, John Stultz wrote:
> > > I tried to bisect things down a bit, but as some later fixes are
> > > required (at one point, date was returning the start epoch and never
> > > increasing), this hasn't worked too well. But I'm guessing since I
> > > see: "CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will
> > > not be built", and the system is half working, I'm guessing this is an
> > > issue with just the 32bit code failing. While I can try to sort out
> > > the proper CROSS_COMPILE_COMPAT in my build environment, I assume
> > > userland shouldn't be crashing if that value isn't set.
> > >
> > > Any chance this issue has already been raised?
> >
> > First I've seen of it, although Vincenzo is likely to know better than me.
> > In the meantime, please can you share your .config?
>
> I think the key is: CROSS_COMPILE_COMPAT not defined or empty. And then run
> 32bit userspace.
The part I was wondering about is whether the vectors page has been disabled
at the same time, since I'm fairly sure I've already been running with the
above (but I can easily double-check).
Will
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-07-10 4:02 ` John Stultz
2019-07-10 6:12 ` Thomas Gleixner
2019-07-10 8:27 ` Will Deacon
@ 2019-07-10 9:47 ` Vincenzo Frascino
2019-07-10 13:41 ` Vincenzo Frascino
2 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-10 9:47 UTC (permalink / raw)
To: John Stultz
Cc: linux-arch, linux-arm-kernel, lkml, linux-mips, linux-kselftest,
Shuah Khan, Andre Przywara, Arnd Bergmann, Huw Davies,
Catalin Marinas, Daniel Lezcano, Will Deacon, Russell King,
Ralf Baechle, Mark Salyzyn, Paul Burton, Dmitry Safonov,
Rasmus Villemoes, Thomas Gleixner, Shijith Thotton,
Peter Collingbourne
Hi John,
On 10/07/2019 05:02, John Stultz wrote:
> On Fri, Jun 21, 2019 at 3:18 AM Vincenzo Frascino
> <vincenzo.frascino@arm.com> wrote:
>>
>> Provide the arm64 compat (AArch32) vDSO in kernel/vdso32 in a similar
>> way to what happens in kernel/vdso.
>>
>> The compat vDSO leverages on an adaptation of the arm architecture code
>> with few changes:
>> - Use of lib/vdso for gettimeofday
>> - Implementation of syscall based fallback
>> - Introduction of clock_getres for the compat library
>> - Implementation of trampolines
>> - Implementation of elf note
>>
>> To build the compat vDSO a 32 bit compiler is required and needs to be
>> specified via CONFIG_CROSS_COMPILE_COMPAT_VDSO.
>>
>
> Hey Vincenzo!
> Congrats on getting this work merged, I know its been a long effort
> over a number of years!
>
> Though unfortunately, it seems the arm64 vdso code that just landed is
> breaking AOSP for me.
>
> I see a lot of the following errors:
> 01-01 01:22:14.097 755 755 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 755 (cameraserver),
> pid 755 (cameraserver)
> 01-01 01:22:14.112 759 759 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 759
> (android.hardwar), pid 759 (android.hardwar)
> 01-01 01:22:14.120 756 756 F libc : Fatal signal 11 (SIGSEGV),
> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 756 (drmserver),
> pid 756 (drmserver)
>
> Which go away if I revert the vdso merge that went in via tip/timers.
>
> I tried to bisect things down a bit, but as some later fixes are
> required (at one point, date was returning the start epoch and never
> increasing), this hasn't worked too well. But I'm guessing since I
> see: "CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will
> not be built", and the system is half working, I'm guessing this is an
> issue with just the 32bit code failing. While I can try to sort out
> the proper CROSS_COMPILE_COMPAT in my build environment, I assume
> userland shouldn't be crashing if that value isn't set.
>
> Any chance this issue has already been raised?
>
I do not have Android (bionic/libc) as part of my testing environment hence I
never saw this issue. Thanks for reporting it.
I am investigating the problem and will post a fix as soon as it is ready.
As Will suggested, .config would help the debugging and I would like to ask to
you to test my fix once it is ready. Is that OK for you?
> thanks
> -john
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 10/25] arm64: compat: Add vDSO
2019-07-10 9:47 ` Vincenzo Frascino
@ 2019-07-10 13:41 ` Vincenzo Frascino
0 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-10 13:41 UTC (permalink / raw)
To: John Stultz
Cc: linux-arch, Shijith Thotton, Peter Collingbourne, Arnd Bergmann,
Huw Davies, Andre Przywara, Daniel Lezcano, Will Deacon, lkml,
Ralf Baechle, linux-mips, Paul Burton, Rasmus Villemoes,
linux-kselftest, Catalin Marinas, Russell King, Dmitry Safonov,
Mark Salyzyn, Shuah Khan, Thomas Gleixner, linux-arm-kernel
Hi John,
On 10/07/2019 10:47, Vincenzo Frascino wrote:
> Hi John,
>
> On 10/07/2019 05:02, John Stultz wrote:
>> On Fri, Jun 21, 2019 at 3:18 AM Vincenzo Frascino
>> <vincenzo.frascino@arm.com> wrote:
>>>
>>> Provide the arm64 compat (AArch32) vDSO in kernel/vdso32 in a similar
>>> way to what happens in kernel/vdso.
>>>
>>> The compat vDSO leverages on an adaptation of the arm architecture code
>>> with few changes:
>>> - Use of lib/vdso for gettimeofday
>>> - Implementation of syscall based fallback
>>> - Introduction of clock_getres for the compat library
>>> - Implementation of trampolines
>>> - Implementation of elf note
>>>
>>> To build the compat vDSO a 32 bit compiler is required and needs to be
>>> specified via CONFIG_CROSS_COMPILE_COMPAT_VDSO.
>>>
>>
>> Hey Vincenzo!
>> Congrats on getting this work merged, I know its been a long effort
>> over a number of years!
>>
>> Though unfortunately, it seems the arm64 vdso code that just landed is
>> breaking AOSP for me.
>>
>> I see a lot of the following errors:
>> 01-01 01:22:14.097 755 755 F libc : Fatal signal 11 (SIGSEGV),
>> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 755 (cameraserver),
>> pid 755 (cameraserver)
>> 01-01 01:22:14.112 759 759 F libc : Fatal signal 11 (SIGSEGV),
>> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 759
>> (android.hardwar), pid 759 (android.hardwar)
>> 01-01 01:22:14.120 756 756 F libc : Fatal signal 11 (SIGSEGV),
>> code 1 (SEGV_MAPERR), fault addr 0x3cf2c96c in tid 756 (drmserver),
>> pid 756 (drmserver)
>>
>> Which go away if I revert the vdso merge that went in via tip/timers.
>>
>> I tried to bisect things down a bit, but as some later fixes are
>> required (at one point, date was returning the start epoch and never
>> increasing), this hasn't worked too well. But I'm guessing since I
>> see: "CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will
>> not be built", and the system is half working, I'm guessing this is an
>> issue with just the 32bit code failing. While I can try to sort out
>> the proper CROSS_COMPILE_COMPAT in my build environment, I assume
>> userland shouldn't be crashing if that value isn't set.
>>
>> Any chance this issue has already been raised?
>>
>
> I do not have Android (bionic/libc) as part of my testing environment hence I
> never saw this issue. Thanks for reporting it.
>
> I am investigating the problem and will post a fix as soon as it is ready.
>
> As Will suggested, .config would help the debugging and I would like to ask to
> you to test my fix once it is ready. Is that OK for you?
>
>> thanks
>> -john
>>
>
Seems that the problem you are experiencing is caused by an ABI regression for
which I provided a fix in [1]. Could you please verify that works for you as well?
[1] https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2046889.html
Please find below the tests that I conducted to verify that when
CROSS_COMPILE_COMPAT is not defined or empty the compat vdso library is not exposed.
# cat main-arm32.c
#include <stdio.h>
#include <sys/auxv.h>
int main()
{
uintptr_t vdso = (uintptr_t) getauxval(AT_SYSINFO_EHDR);
printf("AT_SYSINFO_EHDR: %p\n", vdso);
[...]
return 0;
}
# file main-arm32
main-arm32: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically
linked, interpreter /lib/ld-, for GNU/Linux 3.2.0, with d
When CROSS_COMPILE_COMPAT is _not_ defined:
===========================================
# ./main-arm32
AT_SYSINFO_EHDR: (nil)
Memory Map:
-----------
00008000-00010000 rw-p 00000000 00:00 0
00010000-00011000 r-xp 00000000 00:13 24905929 /home/vinfra01/bin/main-arm32
00011000-00020000 rw-p 00000000 00:00 0
00020000-00021000 r--p 00000000 00:13 24905929 /home/vinfra01/bin/main-arm32
00021000-00022000 rw-p 00001000 00:13 24905929 /home/vinfra01/bin/main-arm32
00022000-f773d000 rw-p 00000000 00:00 0 [heap]
f773d000-f781f000 r-xp 00000000 00:13 24906912 /lib/arm-linux-gnueabihf/libc-2.27.so
f781f000-f782f000 ---p 000e2000 00:13 24906912 /lib/arm-linux-gnueabihf/libc-2.27.so
f782f000-f7831000 r--p 000e2000 00:13 24906912 /lib/arm-linux-gnueabihf/libc-2.27.so
f7831000-f7832000 rw-p 000e4000 00:13 24906912 /lib/arm-linux-gnueabihf/libc-2.27.so
f7832000-f7835000 rw-p 00000000 00:00 0
f7835000-f784b000 rw-p 00000000 00:00 0
f784b000-f7863000 r-xp 00000000 00:13 24906908 /lib/arm-linux-gnueabihf/ld-2.27.so
f7863000-f7870000 rw-p 00000000 00:00 0
f7870000-f7872000 rw-p 00000000 00:00 0
f7872000-f7873000 r-xp 00000000 00:00 0 [sigpage]
f7873000-f7874000 r--p 00018000 00:13 24906908 /lib/arm-linux-gnueabihf/ld-2.27.so
f7874000-f7875000 rw-p 00019000 00:13 24906908 /lib/arm-linux-gnueabihf/ld-2.27.so
f7875000-ff77a000 rw-p 00000000 00:00 0
ff87a000-ff89b000 rw-p 00000000 00:00 0 [stack]
ff89b000-ffff0000 rw-p 00000000 00:00 0
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
ffff1000-fffff000 rw-p 00000000 00:00 0
vdsotest for compat [2]:
------------------------
Note: vDSO version of clock_gettime not found
clock-gettime-monotonic: syscall: 796 nsec/call
clock-gettime-monotonic: libc: 816 nsec/call
clock-gettime-monotonic: vdso: not tested
Note: vDSO version of clock_gettime not found
Note: vDSO version of clock_gettime not found
Note: vDSO version of clock_getres not found
clock-getres-monotonic: syscall: 567 nsec/call
clock-getres-monotonic: libc: 581 nsec/call
clock-getres-monotonic: vdso: not tested
Note: vDSO version of clock_getres not found
Note: vDSO version of clock_getres not found
Note: vDSO version of clock_gettime not found
clock-gettime-monotonic-coarse: syscall: 617 nsec/call
clock-gettime-monotonic-coarse: libc: 656 nsec/call
clock-gettime-monotonic-coarse: vdso: not tested
Note: vDSO version of clock_gettime not found
Note: vDSO version of clock_gettime not found
Note: vDSO version of clock_getres not found
clock-getres-monotonic-coarse: syscall: 591 nsec/call
clock-getres-monotonic-coarse: libc: 614 nsec/call
clock-getres-monotonic-coarse: vdso: not tested
Note: vDSO version of clock_getres not found
Note: vDSO version of clock_getres not found
Note: vDSO version of clock_gettime not found
clock-gettime-realtime: syscall: 819 nsec/call
clock-gettime-realtime: libc: 858 nsec/call
clock-gettime-realtime: vdso: not tested
Note: vDSO version of clock_gettime not found
Note: vDSO version of clock_gettime not found
Note: vDSO version of clock_getres not found
clock-getres-realtime: syscall: 567 nsec/call
clock-getres-realtime: libc: 583 nsec/call
clock-getres-realtime: vdso: not tested
Note: vDSO version of clock_getres not found
Note: vDSO version of clock_getres not found
Note: vDSO version of clock_gettime not found
clock-gettime-realtime-coarse: syscall: 599 nsec/call
clock-gettime-realtime-coarse: libc: 638 nsec/call
clock-gettime-realtime-coarse: vdso: not tested
Note: vDSO version of clock_gettime not found
Note: vDSO version of clock_gettime not found
Note: vDSO version of clock_getres not found
clock-getres-realtime-coarse: syscall: 591 nsec/call
clock-getres-realtime-coarse: libc: 610 nsec/call
clock-getres-realtime-coarse: vdso: not tested
Note: vDSO version of clock_getres not found
Note: vDSO version of clock_getres not found
Note: vDSO version of getcpu not found
getcpu: syscall: 431 nsec/call
getcpu: libc: 451 nsec/call
getcpu: vdso: not tested
Note: vDSO version of getcpu not found
Note: vDSO version of getcpu not found
Note: vDSO version of gettimeofday not found
gettimeofday: syscall: 765 nsec/call
gettimeofday: libc: 808 nsec/call
gettimeofday: vdso: not tested
Note: vDSO version of gettimeofday not found
Note: vDSO version of gettimeofday not found
When CROSS_COMPILE_COMPAT is defined:
=====================================
# ./main-arm32
AT_SYSINFO_EHDR: 0xf7a67000
Memory map:
-----------
00008000-00010000 rw-p 00000000 00:00 0
00010000-00011000 r-xp 00000000 00:13 24905929 /home/vinfra01/bin/main-arm32
00011000-00020000 rw-p 00000000 00:00 0
00020000-00021000 r--p 00000000 00:13 24905929 /home/vinfra01/bin/main-arm32
00021000-00022000 rw-p 00001000 00:13 24905929 /home/vinfra01/bin/main-arm32
00022000-f7932000 rw-p 00000000 00:00 0 [heap]
f7932000-f7a14000 r-xp 00000000 00:13 24906912 /lib/arm-linux-gnueabihf/libc-2.27.so
f7a14000-f7a24000 ---p 000e2000 00:13 24906912 /lib/arm-linux-gnueabihf/libc-2.27.so
f7a24000-f7a26000 r--p 000e2000 00:13 24906912 /lib/arm-linux-gnueabihf/libc-2.27.so
f7a26000-f7a27000 rw-p 000e4000 00:13 24906912 /lib/arm-linux-gnueabihf/libc-2.27.so
f7a27000-f7a2a000 rw-p 00000000 00:00 0
f7a2a000-f7a40000 rw-p 00000000 00:00 0
f7a40000-f7a58000 r-xp 00000000 00:13 24906908 /lib/arm-linux-gnueabihf/ld-2.27.so
f7a58000-f7a64000 rw-p 00000000 00:00 0
f7a64000-f7a66000 rw-p 00000000 00:00 0
f7a66000-f7a67000 r--p 00000000 00:00 0 [vvar]
f7a67000-f7a68000 r-xp 00000000 00:00 0 [vdso]
f7a68000-f7a69000 r--p 00018000 00:13 24906908 /lib/arm-linux-gnueabihf/ld-2.27.so
f7a69000-f7a6a000 rw-p 00019000 00:13 24906908 /lib/arm-linux-gnueabihf/ld-2.27.so
f7a6a000-ff6d8000 rw-p 00000000 00:00 0
ff7d8000-ff7f9000 rw-p 00000000 00:00 0 [stack]
ff7f9000-ffff0000 rw-p 00000000 00:00 0
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
ffff1000-fffff000 rw-p 00000000 00:00 0
vdsotest for compat [2]:
------------------------
clock-gettime-monotonic: syscall: 700 nsec/call
clock-gettime-monotonic: libc: 226 nsec/call
clock-gettime-monotonic: vdso: 189 nsec/call
clock-getres-monotonic: syscall: 582 nsec/call
clock-getres-monotonic: libc: 581 nsec/call
clock-getres-monotonic: vdso: 40 nsec/call
clock-gettime-monotonic-coarse: syscall: 618 nsec/call
clock-gettime-monotonic-coarse: libc: 103 nsec/call
clock-gettime-monotonic-coarse: vdso: 85 nsec/call
clock-getres-monotonic-coarse: syscall: 602 nsec/call
clock-getres-monotonic-coarse: libc: 610 nsec/call
clock-getres-monotonic-coarse: vdso: 64 nsec/call
clock-gettime-realtime: syscall: 741 nsec/call
clock-gettime-realtime: libc: 209 nsec/call
clock-gettime-realtime: vdso: 189 nsec/call
clock-getres-realtime: syscall: 627 nsec/call
clock-getres-realtime: libc: 604 nsec/call
clock-getres-realtime: vdso: 41 nsec/call
clock-gettime-realtime-coarse: syscall: 640 nsec/call
clock-gettime-realtime-coarse: libc: 105 nsec/call
clock-gettime-realtime-coarse: vdso: 84 nsec/call
clock-getres-realtime-coarse: syscall: 597 nsec/call
clock-getres-realtime-coarse: libc: 608 nsec/call
clock-getres-realtime-coarse: vdso: 46 nsec/call
Note: vDSO version of getcpu not found
getcpu: syscall: 492 nsec/call
getcpu: libc: 492 nsec/call
getcpu: vdso: not tested
Note: vDSO version of getcpu not found
Note: vDSO version of getcpu not found
gettimeofday: syscall: 664 nsec/call
gettimeofday: libc: 224 nsec/call
gettimeofday: vdso: 185 nsec/call
[2] https://github.com/nathanlynch/vdsotest
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH] arm64: vdso: Fix ABI regression in compat vdso
2019-06-21 9:52 ` [PATCH v7 10/25] arm64: compat: Add vDSO Vincenzo Frascino
2019-06-24 14:00 ` Catalin Marinas
2019-07-10 4:02 ` John Stultz
@ 2019-07-10 13:04 ` Vincenzo Frascino
2019-07-10 13:25 ` Will Deacon
2019-07-10 14:01 ` [PATCH v2] " Vincenzo Frascino
3 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-10 13:04 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara, luto, john.stultz
Prior to the introduction of Unified vDSO support and compat layer for
vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
In the current implementation, AT_SYSINFO_EHDR is defined even if the
compat vdso layer is not built and this causes a regression in the
expected behavior of the ABI.
Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
tasks is defined only when CONFIG_GENERIC_COMPAT_VDSO and
CONFIG_COMPAT_VDSO are enabled.
Reported-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/arm64/include/asm/elf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 3c7037c6ba9b..b7992bb9d414 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -202,7 +202,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
({ \
set_thread_flag(TIF_32BIT); \
})
-#ifdef CONFIG_GENERIC_COMPAT_VDSO
+#if defined(CONFIG_COMPAT_VDSO) && defined(CONFIG_GENERIC_COMPAT_VDSO)
#define COMPAT_ARCH_DLINFO \
do { \
/* \
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH] arm64: vdso: Fix ABI regression in compat vdso
2019-07-10 13:04 ` [PATCH] arm64: vdso: Fix ABI regression in compat vdso Vincenzo Frascino
@ 2019-07-10 13:25 ` Will Deacon
2019-07-10 13:42 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Will Deacon @ 2019-07-10 13:25 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, catalin.marinas, will.deacon, arnd, linux, ralf,
paul.burton, daniel.lezcano, tglx, salyzyn, pcc, shuah,
0x7f454c46, linux, huw, sthotton, andre.przywara, luto,
john.stultz
On Wed, Jul 10, 2019 at 02:04:52PM +0100, Vincenzo Frascino wrote:
> Prior to the introduction of Unified vDSO support and compat layer for
> vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
> In the current implementation, AT_SYSINFO_EHDR is defined even if the
> compat vdso layer is not built and this causes a regression in the
> expected behavior of the ABI.
>
> Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
> tasks is defined only when CONFIG_GENERIC_COMPAT_VDSO and
> CONFIG_COMPAT_VDSO are enabled.
I think you could do a better job in the changelog of explaining what's
actually going on here. The problem seems to be that you're advertising
the presence of a non-existent vDSO to userspace.
> Reported-by: John Stultz <john.stultz@linaro.org>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> ---
> arch/arm64/include/asm/elf.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 3c7037c6ba9b..b7992bb9d414 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -202,7 +202,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
> ({ \
> set_thread_flag(TIF_32BIT); \
> })
> -#ifdef CONFIG_GENERIC_COMPAT_VDSO
> +#if defined(CONFIG_COMPAT_VDSO) && defined(CONFIG_GENERIC_COMPAT_VDSO)
Can't this just be #ifdef CONFIG_COMPAT_VDSO ?
John -- can you give this a whirl, please?
Cheers,
Will
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH] arm64: vdso: Fix ABI regression in compat vdso
2019-07-10 13:25 ` Will Deacon
@ 2019-07-10 13:42 ` Vincenzo Frascino
0 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-10 13:42 UTC (permalink / raw)
To: Will Deacon
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, catalin.marinas, will.deacon, arnd, linux, ralf,
paul.burton, daniel.lezcano, tglx, salyzyn, pcc, shuah,
0x7f454c46, linux, huw, sthotton, andre.przywara, luto,
john.stultz
On 10/07/2019 14:25, Will Deacon wrote:
> On Wed, Jul 10, 2019 at 02:04:52PM +0100, Vincenzo Frascino wrote:
>> Prior to the introduction of Unified vDSO support and compat layer for
>> vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
>> In the current implementation, AT_SYSINFO_EHDR is defined even if the
>> compat vdso layer is not built and this causes a regression in the
>> expected behavior of the ABI.
>>
>> Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
>> tasks is defined only when CONFIG_GENERIC_COMPAT_VDSO and
>> CONFIG_COMPAT_VDSO are enabled.
>
> I think you could do a better job in the changelog of explaining what's
> actually going on here. The problem seems to be that you're advertising
> the presence of a non-existent vDSO to userspace.
>
>> Reported-by: John Stultz <john.stultz@linaro.org>
>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>> ---
>> arch/arm64/include/asm/elf.h | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
>> index 3c7037c6ba9b..b7992bb9d414 100644
>> --- a/arch/arm64/include/asm/elf.h
>> +++ b/arch/arm64/include/asm/elf.h
>> @@ -202,7 +202,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
>> ({ \
>> set_thread_flag(TIF_32BIT); \
>> })
>> -#ifdef CONFIG_GENERIC_COMPAT_VDSO
>> +#if defined(CONFIG_COMPAT_VDSO) && defined(CONFIG_GENERIC_COMPAT_VDSO)
>
> Can't this just be #ifdef CONFIG_COMPAT_VDSO ?
>
Yes, I realized it after I pushed the patch that CONFIG_GENERIC_COMPAT_VDSO can
be removed. Posting v2 shortly.
> John -- can you give this a whirl, please?
>
> Cheers,
>
> Will
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH v2] arm64: vdso: Fix ABI regression in compat vdso
2019-06-21 9:52 ` [PATCH v7 10/25] arm64: compat: Add vDSO Vincenzo Frascino
` (2 preceding siblings ...)
2019-07-10 13:04 ` [PATCH] arm64: vdso: Fix ABI regression in compat vdso Vincenzo Frascino
@ 2019-07-10 14:01 ` Vincenzo Frascino
2019-07-10 15:44 ` John Stultz
2019-07-11 9:45 ` Will Deacon
3 siblings, 2 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-10 14:01 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara, luto, john.stultz
Prior to the introduction of Unified vDSO support and compat layer for
vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
In the current implementation, AT_SYSINFO_EHDR is defined even if the
compat vdso layer is not built and this causes a regression in the
expected behavior of the ABI.
Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
tasks is defined only when CONFIG_COMPAT_VDSO is enabled.
Reported-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/arm64/include/asm/elf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 3c7037c6ba9b..b618017205a3 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -202,7 +202,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
({ \
set_thread_flag(TIF_32BIT); \
})
-#ifdef CONFIG_GENERIC_COMPAT_VDSO
+#ifdef CONFIG_COMPAT_VDSO
#define COMPAT_ARCH_DLINFO \
do { \
/* \
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v2] arm64: vdso: Fix ABI regression in compat vdso
2019-07-10 14:01 ` [PATCH v2] " Vincenzo Frascino
@ 2019-07-10 15:44 ` John Stultz
2019-07-10 15:53 ` Vincenzo Frascino
2019-07-11 9:45 ` Will Deacon
1 sibling, 1 reply; 108+ messages in thread
From: John Stultz @ 2019-07-10 15:44 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, lkml, linux-mips, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King - ARM Linux, Ralf Baechle, Paul Burton,
Daniel Lezcano, Thomas Gleixner, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara,
Andy Lutomirski
On Wed, Jul 10, 2019 at 7:01 AM Vincenzo Frascino
<vincenzo.frascino@arm.com> wrote:
>
> Prior to the introduction of Unified vDSO support and compat layer for
> vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
> In the current implementation, AT_SYSINFO_EHDR is defined even if the
> compat vdso layer is not built and this causes a regression in the
> expected behavior of the ABI.
>
> Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
> tasks is defined only when CONFIG_COMPAT_VDSO is enabled.
>
> Reported-by: John Stultz <john.stultz@linaro.org>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
This seems to solve it for me!
Thanks so much for the quick turnaround on a fix. I really appreciate it!
Tested-by: John Stultz <john.stultz@linaro.org>
thanks
-john
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v2] arm64: vdso: Fix ABI regression in compat vdso
2019-07-10 15:44 ` John Stultz
@ 2019-07-10 15:53 ` Vincenzo Frascino
0 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-10 15:53 UTC (permalink / raw)
To: John Stultz
Cc: linux-arch, linux-arm-kernel, lkml, linux-mips, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King - ARM Linux, Ralf Baechle, Paul Burton,
Daniel Lezcano, Thomas Gleixner, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara,
Andy Lutomirski
Hi John,
On 10/07/2019 16:44, John Stultz wrote:
> On Wed, Jul 10, 2019 at 7:01 AM Vincenzo Frascino
> <vincenzo.frascino@arm.com> wrote:
>>
>> Prior to the introduction of Unified vDSO support and compat layer for
>> vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
>> In the current implementation, AT_SYSINFO_EHDR is defined even if the
>> compat vdso layer is not built and this causes a regression in the
>> expected behavior of the ABI.
>>
>> Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
>> tasks is defined only when CONFIG_COMPAT_VDSO is enabled.
>>
>> Reported-by: John Stultz <john.stultz@linaro.org>
>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>
> This seems to solve it for me!
> Thanks so much for the quick turnaround on a fix. I really appreciate it!
>
> Tested-by: John Stultz <john.stultz@linaro.org>
>
Thank you for the quick reply, it means I can go home early today ;-)
> thanks
> -john
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v2] arm64: vdso: Fix ABI regression in compat vdso
2019-07-10 14:01 ` [PATCH v2] " Vincenzo Frascino
2019-07-10 15:44 ` John Stultz
@ 2019-07-11 9:45 ` Will Deacon
2019-07-11 10:34 ` Thomas Gleixner
1 sibling, 1 reply; 108+ messages in thread
From: Will Deacon @ 2019-07-11 9:45 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, shuah, andre.przywara, arnd, huw,
catalin.marinas, daniel.lezcano, will.deacon, linux, ralf,
salyzyn, luto, paul.burton, john.stultz, 0x7f454c46, linux, tglx,
sthotton, pcc
On Wed, Jul 10, 2019 at 03:01:19PM +0100, Vincenzo Frascino wrote:
> Prior to the introduction of Unified vDSO support and compat layer for
> vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
> In the current implementation, AT_SYSINFO_EHDR is defined even if the
> compat vdso layer is not built and this causes a regression in the
> expected behavior of the ABI.
>
> Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
> tasks is defined only when CONFIG_COMPAT_VDSO is enabled.
>
> Reported-by: John Stultz <john.stultz@linaro.org>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> ---
> arch/arm64/include/asm/elf.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 3c7037c6ba9b..b618017205a3 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -202,7 +202,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
> ({ \
> set_thread_flag(TIF_32BIT); \
> })
> -#ifdef CONFIG_GENERIC_COMPAT_VDSO
> +#ifdef CONFIG_COMPAT_VDSO
> #define COMPAT_ARCH_DLINFO \
> do { \
> /* \
Acked-by: Will Deacon <will@kernel.org>
I can take this at -rc1 via arm64 unless tglx plans to send it during the
rest of the merge window. Please let me know.
Will
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v2] arm64: vdso: Fix ABI regression in compat vdso
2019-07-11 9:45 ` Will Deacon
@ 2019-07-11 10:34 ` Thomas Gleixner
2019-07-11 11:32 ` Will Deacon
0 siblings, 1 reply; 108+ messages in thread
From: Thomas Gleixner @ 2019-07-11 10:34 UTC (permalink / raw)
To: Will Deacon
Cc: Vincenzo Frascino, linux-arch, linux-arm-kernel, linux-kernel,
linux-mips, linux-kselftest, shuah, andre.przywara, arnd, huw,
catalin.marinas, daniel.lezcano, will.deacon, linux, ralf,
salyzyn, luto, paul.burton, john.stultz, 0x7f454c46, linux,
sthotton, pcc
On Thu, 11 Jul 2019, Will Deacon wrote:
> On Wed, Jul 10, 2019 at 03:01:19PM +0100, Vincenzo Frascino wrote:
> > Prior to the introduction of Unified vDSO support and compat layer for
> > vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
> > In the current implementation, AT_SYSINFO_EHDR is defined even if the
> > compat vdso layer is not built and this causes a regression in the
> > expected behavior of the ABI.
> >
> > Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
> > tasks is defined only when CONFIG_COMPAT_VDSO is enabled.
> >
> > Reported-by: John Stultz <john.stultz@linaro.org>
> > Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> > ---
> > arch/arm64/include/asm/elf.h | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> > index 3c7037c6ba9b..b618017205a3 100644
> > --- a/arch/arm64/include/asm/elf.h
> > +++ b/arch/arm64/include/asm/elf.h
> > @@ -202,7 +202,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
> > ({ \
> > set_thread_flag(TIF_32BIT); \
> > })
> > -#ifdef CONFIG_GENERIC_COMPAT_VDSO
> > +#ifdef CONFIG_COMPAT_VDSO
> > #define COMPAT_ARCH_DLINFO \
> > do { \
> > /* \
>
> Acked-by: Will Deacon <will@kernel.org>
>
> I can take this at -rc1 via arm64 unless tglx plans to send it during the
> rest of the merge window. Please let me know.
I had no plan to pick it up, but if you want I can route it through timer
urgents so it hits Linus tree before rc1.
Thanks,
tglx
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v2] arm64: vdso: Fix ABI regression in compat vdso
2019-07-11 10:34 ` Thomas Gleixner
@ 2019-07-11 11:32 ` Will Deacon
0 siblings, 0 replies; 108+ messages in thread
From: Will Deacon @ 2019-07-11 11:32 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Vincenzo Frascino, linux-arch, linux-arm-kernel, linux-kernel,
linux-mips, linux-kselftest, shuah, andre.przywara, arnd, huw,
catalin.marinas, daniel.lezcano, will.deacon, linux, ralf,
salyzyn, luto, paul.burton, john.stultz, 0x7f454c46, linux,
sthotton, pcc
On Thu, Jul 11, 2019 at 12:34:27PM +0200, Thomas Gleixner wrote:
> On Thu, 11 Jul 2019, Will Deacon wrote:
> > On Wed, Jul 10, 2019 at 03:01:19PM +0100, Vincenzo Frascino wrote:
> > > Prior to the introduction of Unified vDSO support and compat layer for
> > > vDSO on arm64, AT_SYSINFO_EHDR was not defined for compat tasks.
> > > In the current implementation, AT_SYSINFO_EHDR is defined even if the
> > > compat vdso layer is not built and this causes a regression in the
> > > expected behavior of the ABI.
> > >
> > > Restore the ABI behavior making sure that AT_SYSINFO_EHDR for compat
> > > tasks is defined only when CONFIG_COMPAT_VDSO is enabled.
> > >
> > > Reported-by: John Stultz <john.stultz@linaro.org>
> > > Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> > > ---
> > > arch/arm64/include/asm/elf.h | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> > > index 3c7037c6ba9b..b618017205a3 100644
> > > --- a/arch/arm64/include/asm/elf.h
> > > +++ b/arch/arm64/include/asm/elf.h
> > > @@ -202,7 +202,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
> > > ({ \
> > > set_thread_flag(TIF_32BIT); \
> > > })
> > > -#ifdef CONFIG_GENERIC_COMPAT_VDSO
> > > +#ifdef CONFIG_COMPAT_VDSO
> > > #define COMPAT_ARCH_DLINFO \
> > > do { \
> > > /* \
> >
> > Acked-by: Will Deacon <will@kernel.org>
> >
> > I can take this at -rc1 via arm64 unless tglx plans to send it during the
> > rest of the merge window. Please let me know.
>
> I had no plan to pick it up, but if you want I can route it through timer
> urgents so it hits Linus tree before rc1.
I don't think it's urgent, so I'll just queue it along with any other fixes
that show up at -rc1.
Cheers,
Will
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH v7 11/25] arm64: Refactor vDSO code
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (9 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 10/25] arm64: compat: Add vDSO Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 12/25] arm64: compat: vDSO setup for compat layer Vincenzo Frascino
` (15 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
Most of the code for initializing the vDSOs in arm64 and compat will
be in common, hence a refactor of the current code is required to avoid
duplication and simplify maintainability.
Refactor vdso.c to simplify the implementation of arm64 vDSO compat
(which will be pushed with a future patch).
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/kernel/vdso.c | 215 ++++++++++++++++++++++++++-------------
1 file changed, 144 insertions(+), 71 deletions(-)
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 23c38303a52a..aa1fb25a9fe4 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -40,7 +40,31 @@
#include <asm/vdso.h>
extern char vdso_start[], vdso_end[];
-static unsigned long vdso_pages __ro_after_init;
+
+/* vdso_lookup arch_index */
+enum arch_vdso_type {
+ ARM64_VDSO = 0,
+};
+#define VDSO_TYPES (ARM64_VDSO + 1)
+
+struct __vdso_abi {
+ const char *name;
+ const char *vdso_code_start;
+ const char *vdso_code_end;
+ unsigned long vdso_pages;
+ /* Data Mapping */
+ struct vm_special_mapping *dm;
+ /* Code Mapping */
+ struct vm_special_mapping *cm;
+};
+
+static struct __vdso_abi vdso_lookup[VDSO_TYPES] __ro_after_init = {
+ {
+ .name = "vdso",
+ .vdso_code_start = vdso_start,
+ .vdso_code_end = vdso_end,
+ },
+};
/*
* The vDSO data page.
@@ -51,10 +75,110 @@ static union {
} vdso_data_store __page_aligned_data;
struct vdso_data *vdso_data = vdso_data_store.data;
+static int __vdso_remap(enum arch_vdso_type arch_index,
+ const struct vm_special_mapping *sm,
+ struct vm_area_struct *new_vma)
+{
+ unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
+ unsigned long vdso_size = vdso_lookup[arch_index].vdso_code_end -
+ vdso_lookup[arch_index].vdso_code_start;
+
+ if (vdso_size != new_size)
+ return -EINVAL;
+
+ current->mm->context.vdso = (void *)new_vma->vm_start;
+
+ return 0;
+}
+
+static int __vdso_init(enum arch_vdso_type arch_index)
+{
+ int i;
+ struct page **vdso_pagelist;
+ unsigned long pfn;
+
+ if (memcmp(vdso_lookup[arch_index].vdso_code_start, "\177ELF", 4)) {
+ pr_err("vDSO is not a valid ELF object!\n");
+ return -EINVAL;
+ }
+
+ vdso_lookup[arch_index].vdso_pages = (
+ vdso_lookup[arch_index].vdso_code_end -
+ vdso_lookup[arch_index].vdso_code_start) >>
+ PAGE_SHIFT;
+
+ /* Allocate the vDSO pagelist, plus a page for the data. */
+ vdso_pagelist = kcalloc(vdso_lookup[arch_index].vdso_pages + 1,
+ sizeof(struct page *),
+ GFP_KERNEL);
+ if (vdso_pagelist == NULL)
+ return -ENOMEM;
+
+ /* Grab the vDSO data page. */
+ vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data));
+
+
+ /* Grab the vDSO code pages. */
+ pfn = sym_to_pfn(vdso_lookup[arch_index].vdso_code_start);
+
+ for (i = 0; i < vdso_lookup[arch_index].vdso_pages; i++)
+ vdso_pagelist[i + 1] = pfn_to_page(pfn + i);
+
+ vdso_lookup[arch_index].dm->pages = &vdso_pagelist[0];
+ vdso_lookup[arch_index].cm->pages = &vdso_pagelist[1];
+
+ return 0;
+}
+
+static int __setup_additional_pages(enum arch_vdso_type arch_index,
+ struct mm_struct *mm,
+ struct linux_binprm *bprm,
+ int uses_interp)
+{
+ unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
+ void *ret;
+
+ vdso_text_len = vdso_lookup[arch_index].vdso_pages << PAGE_SHIFT;
+ /* Be sure to map the data page */
+ vdso_mapping_len = vdso_text_len + PAGE_SIZE;
+
+ vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
+ if (IS_ERR_VALUE(vdso_base)) {
+ ret = ERR_PTR(vdso_base);
+ goto up_fail;
+ }
+
+ ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
+ VM_READ|VM_MAYREAD,
+ vdso_lookup[arch_index].dm);
+ if (IS_ERR(ret))
+ goto up_fail;
+
+ vdso_base += PAGE_SIZE;
+ mm->context.vdso = (void *)vdso_base;
+ ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
+ VM_READ|VM_EXEC|
+ VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+ vdso_lookup[arch_index].cm);
+ if (IS_ERR(ret))
+ goto up_fail;
+
+ return 0;
+
+up_fail:
+ mm->context.vdso = NULL;
+ return PTR_ERR(ret);
+}
+
#ifdef CONFIG_COMPAT
/*
* Create and map the vectors page for AArch32 tasks.
*/
+/*
+ * aarch32_vdso_pages:
+ * 0 - kuser helpers
+ * 1 - sigreturn code
+ */
#define C_VECTORS 0
#define C_SIGPAGE 1
#define C_PAGES (C_SIGPAGE + 1)
@@ -183,18 +307,18 @@ int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
static int vdso_mremap(const struct vm_special_mapping *sm,
struct vm_area_struct *new_vma)
{
- unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
- unsigned long vdso_size = vdso_end - vdso_start;
-
- if (vdso_size != new_size)
- return -EINVAL;
-
- current->mm->context.vdso = (void *)new_vma->vm_start;
-
- return 0;
+ return __vdso_remap(ARM64_VDSO, sm, new_vma);
}
-static struct vm_special_mapping vdso_spec[2] __ro_after_init = {
+/*
+ * aarch64_vdso_pages:
+ * 0 - vvar
+ * 1 - vdso
+ */
+#define A_VVAR 0
+#define A_VDSO 1
+#define A_PAGES (A_VDSO + 1)
+static struct vm_special_mapping vdso_spec[A_PAGES] __ro_after_init = {
{
.name = "[vvar]",
},
@@ -206,37 +330,10 @@ static struct vm_special_mapping vdso_spec[2] __ro_after_init = {
static int __init vdso_init(void)
{
- int i;
- struct page **vdso_pagelist;
- unsigned long pfn;
-
- if (memcmp(vdso_start, "\177ELF", 4)) {
- pr_err("vDSO is not a valid ELF object!\n");
- return -EINVAL;
- }
-
- vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
-
- /* Allocate the vDSO pagelist, plus a page for the data. */
- vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
- GFP_KERNEL);
- if (vdso_pagelist == NULL)
- return -ENOMEM;
-
- /* Grab the vDSO data page. */
- vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data));
-
+ vdso_lookup[ARM64_VDSO].dm = &vdso_spec[A_VVAR];
+ vdso_lookup[ARM64_VDSO].cm = &vdso_spec[A_VDSO];
- /* Grab the vDSO code pages. */
- pfn = sym_to_pfn(vdso_start);
-
- for (i = 0; i < vdso_pages; i++)
- vdso_pagelist[i + 1] = pfn_to_page(pfn + i);
-
- vdso_spec[0].pages = &vdso_pagelist[0];
- vdso_spec[1].pages = &vdso_pagelist[1];
-
- return 0;
+ return __vdso_init(ARM64_VDSO);
}
arch_initcall(vdso_init);
@@ -244,41 +341,17 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp)
{
struct mm_struct *mm = current->mm;
- unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
- void *ret;
-
- vdso_text_len = vdso_pages << PAGE_SHIFT;
- /* Be sure to map the data page */
- vdso_mapping_len = vdso_text_len + PAGE_SIZE;
+ int ret;
if (down_write_killable(&mm->mmap_sem))
return -EINTR;
- vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
- if (IS_ERR_VALUE(vdso_base)) {
- ret = ERR_PTR(vdso_base);
- goto up_fail;
- }
- ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
- VM_READ|VM_MAYREAD,
- &vdso_spec[0]);
- if (IS_ERR(ret))
- goto up_fail;
-
- vdso_base += PAGE_SIZE;
- mm->context.vdso = (void *)vdso_base;
- ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
- VM_READ|VM_EXEC|
- VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
- &vdso_spec[1]);
- if (IS_ERR(ret))
- goto up_fail;
+ ret = __setup_additional_pages(ARM64_VDSO,
+ mm,
+ bprm,
+ uses_interp);
up_write(&mm->mmap_sem);
- return 0;
-up_fail:
- mm->context.vdso = NULL;
- up_write(&mm->mmap_sem);
- return PTR_ERR(ret);
+ return ret;
}
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 12/25] arm64: compat: vDSO setup for compat layer
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (10 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 11/25] arm64: Refactor vDSO code Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 13/25] arm64: elf: vDSO code page discovery Vincenzo Frascino
` (14 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
If CONFIG_GENERIC_COMPAT_VDSO is enabled, compat vDSO are installed in a
compat (32 bit) process instead of sigpage.
Add the necessary code to setup the vDSO required pages.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/kernel/vdso.c | 90 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 88 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index aa1fb25a9fe4..ad3a81b2c7ce 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -40,12 +40,22 @@
#include <asm/vdso.h>
extern char vdso_start[], vdso_end[];
+#ifdef CONFIG_COMPAT_VDSO
+extern char vdso32_start[], vdso32_end[];
+#endif /* CONFIG_COMPAT_VDSO */
/* vdso_lookup arch_index */
enum arch_vdso_type {
ARM64_VDSO = 0,
+#ifdef CONFIG_COMPAT_VDSO
+ ARM64_VDSO32 = 1,
+#endif /* CONFIG_COMPAT_VDSO */
};
+#ifdef CONFIG_COMPAT_VDSO
+#define VDSO_TYPES (ARM64_VDSO32 + 1)
+#else
#define VDSO_TYPES (ARM64_VDSO + 1)
+#endif /* CONFIG_COMPAT_VDSO */
struct __vdso_abi {
const char *name;
@@ -64,6 +74,13 @@ static struct __vdso_abi vdso_lookup[VDSO_TYPES] __ro_after_init = {
.vdso_code_start = vdso_start,
.vdso_code_end = vdso_end,
},
+#ifdef CONFIG_COMPAT_VDSO
+ {
+ .name = "vdso32",
+ .vdso_code_start = vdso32_start,
+ .vdso_code_end = vdso32_end,
+ },
+#endif /* CONFIG_COMPAT_VDSO */
};
/*
@@ -174,24 +191,52 @@ static int __setup_additional_pages(enum arch_vdso_type arch_index,
/*
* Create and map the vectors page for AArch32 tasks.
*/
+#ifdef CONFIG_COMPAT_VDSO
+static int aarch32_vdso_mremap(const struct vm_special_mapping *sm,
+ struct vm_area_struct *new_vma)
+{
+ return __vdso_remap(ARM64_VDSO32, sm, new_vma);
+}
+#endif /* CONFIG_COMPAT_VDSO */
+
/*
* aarch32_vdso_pages:
* 0 - kuser helpers
* 1 - sigreturn code
+ * or (CONFIG_COMPAT_VDSO):
+ * 0 - kuser helpers
+ * 1 - vdso data
+ * 2 - vdso code
*/
#define C_VECTORS 0
+#ifdef CONFIG_COMPAT_VDSO
+#define C_VVAR 1
+#define C_VDSO 2
+#define C_PAGES (C_VDSO + 1)
+#else
#define C_SIGPAGE 1
#define C_PAGES (C_SIGPAGE + 1)
+#endif /* CONFIG_COMPAT_VDSO */
static struct page *aarch32_vdso_pages[C_PAGES] __ro_after_init;
-static const struct vm_special_mapping aarch32_vdso_spec[C_PAGES] = {
+static struct vm_special_mapping aarch32_vdso_spec[C_PAGES] = {
{
.name = "[vectors]", /* ABI */
.pages = &aarch32_vdso_pages[C_VECTORS],
},
+#ifdef CONFIG_COMPAT_VDSO
+ {
+ .name = "[vvar]",
+ },
+ {
+ .name = "[vdso]",
+ .mremap = aarch32_vdso_mremap,
+ },
+#else
{
.name = "[sigpage]", /* ABI */
.pages = &aarch32_vdso_pages[C_SIGPAGE],
},
+#endif /* CONFIG_COMPAT_VDSO */
};
static int aarch32_alloc_kuser_vdso_page(void)
@@ -214,7 +259,33 @@ static int aarch32_alloc_kuser_vdso_page(void)
return 0;
}
-static int __init aarch32_alloc_vdso_pages(void)
+#ifdef CONFIG_COMPAT_VDSO
+static int __aarch32_alloc_vdso_pages(void)
+{
+ int ret;
+
+ vdso_lookup[ARM64_VDSO32].dm = &aarch32_vdso_spec[C_VVAR];
+ vdso_lookup[ARM64_VDSO32].cm = &aarch32_vdso_spec[C_VDSO];
+
+ ret = __vdso_init(ARM64_VDSO32);
+ if (ret)
+ return ret;
+
+ ret = aarch32_alloc_kuser_vdso_page();
+ if (ret) {
+ unsigned long c_vvar =
+ (unsigned long)page_to_virt(aarch32_vdso_pages[C_VVAR]);
+ unsigned long c_vdso =
+ (unsigned long)page_to_virt(aarch32_vdso_pages[C_VDSO]);
+
+ free_page(c_vvar);
+ free_page(c_vdso);
+ }
+
+ return ret;
+}
+#else
+static int __aarch32_alloc_vdso_pages(void)
{
extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];
int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start;
@@ -235,6 +306,12 @@ static int __init aarch32_alloc_vdso_pages(void)
return ret;
}
+#endif /* CONFIG_COMPAT_VDSO */
+
+static int __init aarch32_alloc_vdso_pages(void)
+{
+ return __aarch32_alloc_vdso_pages();
+}
arch_initcall(aarch32_alloc_vdso_pages);
static int aarch32_kuser_helpers_setup(struct mm_struct *mm)
@@ -256,6 +333,7 @@ static int aarch32_kuser_helpers_setup(struct mm_struct *mm)
return PTR_ERR_OR_ZERO(ret);
}
+#ifndef CONFIG_COMPAT_VDSO
static int aarch32_sigreturn_setup(struct mm_struct *mm)
{
unsigned long addr;
@@ -283,6 +361,7 @@ static int aarch32_sigreturn_setup(struct mm_struct *mm)
out:
return PTR_ERR_OR_ZERO(ret);
}
+#endif /* !CONFIG_COMPAT_VDSO */
int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
@@ -296,7 +375,14 @@ int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (ret)
goto out;
+#ifdef CONFIG_COMPAT_VDSO
+ ret = __setup_additional_pages(ARM64_VDSO32,
+ mm,
+ bprm,
+ uses_interp);
+#else
ret = aarch32_sigreturn_setup(mm);
+#endif /* CONFIG_COMPAT_VDSO */
out:
up_write(&mm->mmap_sem);
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 13/25] arm64: elf: vDSO code page discovery
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (11 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 12/25] arm64: compat: vDSO setup for compat layer Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 14/25] arm64: compat: Get sigreturn trampolines from vDSO Vincenzo Frascino
` (13 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
Like in normal vDSOs, when compat vDSOs are enabled the auxiliary
vector symbol AT_SYSINFO_EHDR needs to point at the address of the
vDSO code, to allow the dynamic linker to find it.
Add the necessary code to the elf arm64 module to make this possible.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/include/asm/elf.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 355d120b78cb..34cabaf78011 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -213,7 +213,21 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
({ \
set_thread_flag(TIF_32BIT); \
})
+#ifdef CONFIG_GENERIC_COMPAT_VDSO
+#define COMPAT_ARCH_DLINFO \
+do { \
+ /* \
+ * Note that we use Elf64_Off instead of elf_addr_t because \
+ * elf_addr_t in compat is defined as Elf32_Addr and casting \
+ * current->mm->context.vdso to it triggers a cast warning of \
+ * cast from pointer to integer of different size. \
+ */ \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, \
+ (Elf64_Off)current->mm->context.vdso); \
+} while (0)
+#else
#define COMPAT_ARCH_DLINFO
+#endif
extern int aarch32_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);
#define compat_arch_setup_additional_pages \
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 14/25] arm64: compat: Get sigreturn trampolines from vDSO
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (12 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 13/25] arm64: elf: vDSO code page discovery Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 15/25] arm64: Add vDSO compat support Vincenzo Frascino
` (12 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
When the compat vDSO is enabled, the sigreturn trampolines are not
anymore available through [sigpage] but through [vdso].
Add the relevant code the enable the feature.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/include/asm/vdso.h | 3 +++
arch/arm64/kernel/signal32.c | 26 ++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
index 839ce0031bd5..9b197e5ea759 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -28,6 +28,9 @@
#ifndef __ASSEMBLY__
#include <generated/vdso-offsets.h>
+#ifdef CONFIG_COMPAT_VDSO
+#include <generated/vdso32-offsets.h>
+#endif
#define VDSO_SYMBOL(base, name) \
({ \
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 74e06d8c7c2b..4fca2e1937b2 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -29,6 +29,7 @@
#include <asm/traps.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#include <asm/vdso.h>
struct compat_vfp_sigframe {
compat_ulong_t magic;
@@ -352,6 +353,30 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
retcode = ptr_to_compat(ka->sa.sa_restorer);
} else {
/* Set up sigreturn pointer */
+#ifdef CONFIG_COMPAT_VDSO
+ void *vdso_base = current->mm->context.vdso;
+ void *vdso_trampoline;
+
+ if (ka->sa.sa_flags & SA_SIGINFO) {
+ if (thumb) {
+ vdso_trampoline = VDSO_SYMBOL(vdso_base,
+ compat_rt_sigreturn_thumb);
+ } else {
+ vdso_trampoline = VDSO_SYMBOL(vdso_base,
+ compat_rt_sigreturn_arm);
+ }
+ } else {
+ if (thumb) {
+ vdso_trampoline = VDSO_SYMBOL(vdso_base,
+ compat_sigreturn_thumb);
+ } else {
+ vdso_trampoline = VDSO_SYMBOL(vdso_base,
+ compat_sigreturn_arm);
+ }
+ }
+
+ retcode = ptr_to_compat(vdso_trampoline) + thumb;
+#else
unsigned int idx = thumb << 1;
if (ka->sa.sa_flags & SA_SIGINFO)
@@ -359,6 +384,7 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
retcode = (unsigned long)current->mm->context.vdso +
(idx << 2) + thumb;
+#endif
}
regs->regs[0] = usig;
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 15/25] arm64: Add vDSO compat support
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (13 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 14/25] arm64: compat: Get sigreturn trampolines from vDSO Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 16/25] arm: Add support for generic vDSO Vincenzo Frascino
` (11 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
Add vDSO compat support to the arm64 building system.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Tested-by: Shijith Thotton <sthotton@marvell.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/Makefile | 23 +++++++++++++++++++++--
arch/arm64/kernel/Makefile | 6 +++++-
3 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 952c9f8cf3b8..f5eb592b8579 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -108,6 +108,7 @@ config ARM64
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
+ select GENERIC_COMPAT_VDSO if (!CPU_BIG_ENDIAN && COMPAT)
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_PCI
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index b025304bde46..4db50d4b2476 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -49,9 +49,25 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable)
endif
endif
-KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst)
+ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
+ CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%)
+
+ ifeq ($(CONFIG_CC_IS_CLANG), y)
+ $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built)
+ else ifeq ($(CROSS_COMPILE_COMPAT),)
+ $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built)
+ else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),)
+ $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT)
+ else
+ export CROSS_COMPILE_COMPAT
+ export CONFIG_COMPAT_VDSO := y
+ compat_vdso := -DCONFIG_COMPAT_VDSO=1
+ endif
+endif
+
+KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst) $(compat_vdso)
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
-KBUILD_AFLAGS += $(lseinstr) $(brokengasinst)
+KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) $(compat_vdso)
KBUILD_CFLAGS += $(call cc-option,-mabi=lp64)
KBUILD_AFLAGS += $(call cc-option,-mabi=lp64)
@@ -163,6 +179,9 @@ ifeq ($(KBUILD_EXTMOD),)
prepare: vdso_prepare
vdso_prepare: prepare0
$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h
+ $(if $(CONFIG_COMPAT_VDSO),$(Q)$(MAKE) \
+ $(build)=arch/arm64/kernel/vdso32 \
+ include/generated/vdso32-offsets.h)
endif
define archhelp
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 9e7dcb2c31c7..478491f07b4f 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -28,7 +28,10 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
$(call if_changed,objcopy)
obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
- sigreturn32.o sys_compat.o
+ sys_compat.o
+ifneq ($(CONFIG_COMPAT_VDSO), y)
+obj-$(CONFIG_COMPAT) += sigreturn32.o
+endif
obj-$(CONFIG_KUSER_HELPERS) += kuser32.o
obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
obj-$(CONFIG_MODULES) += module.o
@@ -62,6 +65,7 @@ obj-$(CONFIG_ARM64_SSBD) += ssbd.o
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
obj-y += vdso/ probes/
+obj-$(CONFIG_COMPAT_VDSO) += vdso32/
head-y := head.o
extra-y += $(head-y) vmlinux.lds
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 16/25] arm: Add support for generic vDSO
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (14 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 15/25] arm64: Add vDSO compat support Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-12-04 13:51 ` [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash) Guenter Roeck
2019-06-21 9:52 ` [PATCH v7 17/25] arm: Add clock_getres entry point Vincenzo Frascino
` (10 subsequent siblings)
26 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
The arm vDSO library requires some adaptations to use to take advantage
of the newly introduced generic vDSO library.
Introduce the following changes:
- Modification vdso.c to be compliant with the common vdso datapage
- Use of lib/vdso for gettimeofday
- Implementation of elf note
Cc: Russell King <linux@armlinux.org.uk>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/arm/Kconfig | 3 +
arch/arm/include/asm/vdso/gettimeofday.h | 74 +++++++
arch/arm/include/asm/vdso/vsyscall.h | 71 +++++++
arch/arm/include/asm/vdso_datapage.h | 29 +--
arch/arm/kernel/vdso.c | 87 +-------
arch/arm/vdso/Makefile | 13 +-
arch/arm/vdso/note.c | 15 ++
arch/arm/vdso/vgettimeofday.c | 256 +----------------------
8 files changed, 192 insertions(+), 356 deletions(-)
create mode 100644 arch/arm/include/asm/vdso/gettimeofday.h
create mode 100644 arch/arm/include/asm/vdso/vsyscall.h
create mode 100644 arch/arm/vdso/note.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8869742a85df..a238fc34e478 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -53,6 +53,8 @@ config ARM
select GENERIC_SMP_IDLE_THREAD
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
+ select GENERIC_GETTIMEOFDAY
+ select GENERIC_VDSO_32
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
@@ -101,6 +103,7 @@ config ARM
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UID16
select HAVE_VIRT_CPU_ACCOUNTING_GEN
+ select HAVE_GENERIC_VDSO if AEABI
select IRQ_FORCED_THREADING
select MODULES_USE_ELF_REL
select NEED_DMA_MAP_STATE
diff --git a/arch/arm/include/asm/vdso/gettimeofday.h b/arch/arm/include/asm/vdso/gettimeofday.h
new file mode 100644
index 000000000000..30ce4e87dffc
--- /dev/null
+++ b/arch/arm/include/asm/vdso/gettimeofday.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 ARM Limited
+ */
+#ifndef __ASM_VDSO_GETTIMEOFDAY_H
+#define __ASM_VDSO_GETTIMEOFDAY_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/barrier.h>
+#include <asm/cp15.h>
+#include <asm/unistd.h>
+#include <uapi/linux/time.h>
+
+extern struct vdso_data *__get_datapage(void);
+
+static __always_inline int gettimeofday_fallback(
+ struct __kernel_old_timeval *_tv,
+ struct timezone *_tz)
+{
+ register struct timezone *tz asm("r1") = _tz;
+ register struct __kernel_old_timeval *tv asm("r0") = _tv;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_gettimeofday;
+
+ asm volatile(
+ " swi #0\n"
+ : "=r" (ret)
+ : "r" (tv), "r" (tz), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static __always_inline long clock_gettime_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ register struct __kernel_timespec *ts asm("r1") = _ts;
+ register clockid_t clkid asm("r0") = _clkid;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_clock_gettime64;
+
+ asm volatile(
+ " swi #0\n"
+ : "=r" (ret)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
+static __always_inline u64 __arch_get_hw_counter(int clock_mode)
+{
+#ifdef CONFIG_ARM_ARCH_TIMER
+ u64 cycle_now;
+
+ isb();
+ cycle_now = read_sysreg(CNTVCT);
+
+ return cycle_now;
+#else
+ return -EINVAL; /* use fallback */
+#endif
+}
+
+static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
+{
+ return __get_datapage();
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/arm/include/asm/vdso/vsyscall.h b/arch/arm/include/asm/vdso/vsyscall.h
new file mode 100644
index 000000000000..c4166f317071
--- /dev/null
+++ b/arch/arm/include/asm/vdso/vsyscall.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_VDSO_VSYSCALL_H
+#define __ASM_VDSO_VSYSCALL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/timekeeper_internal.h>
+#include <vdso/datapage.h>
+#include <asm/cacheflush.h>
+
+extern struct vdso_data *vdso_data;
+extern bool cntvct_ok;
+
+static __always_inline
+bool tk_is_cntvct(const struct timekeeper *tk)
+{
+ if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
+ return false;
+
+ if (!tk->tkr_mono.clock->archdata.vdso_direct)
+ return false;
+
+ return true;
+}
+
+/*
+ * Update the vDSO data page to keep in sync with kernel timekeeping.
+ */
+static __always_inline
+struct vdso_data *__arm_get_k_vdso_data(void)
+{
+ return vdso_data;
+}
+#define __arch_get_k_vdso_data __arm_get_k_vdso_data
+
+static __always_inline
+int __arm_update_vdso_data(void)
+{
+ return !cntvct_ok;
+}
+#define __arch_update_vdso_data __arm_update_vdso_data
+
+static __always_inline
+int __arm_get_clock_mode(struct timekeeper *tk)
+{
+ u32 __tk_is_cntvct = tk_is_cntvct(tk);
+
+ return __tk_is_cntvct;
+}
+#define __arch_get_clock_mode __arm_get_clock_mode
+
+static __always_inline
+int __arm_use_vsyscall(struct vdso_data *vdata)
+{
+ return vdata[CS_HRES_COARSE].clock_mode;
+}
+#define __arch_use_vsyscall __arm_use_vsyscall
+
+static __always_inline
+void __arm_sync_vdso_data(struct vdso_data *vdata)
+{
+ flush_dcache_page(virt_to_page(vdata));
+}
+#define __arch_sync_vdso_data __arm_sync_vdso_data
+
+/* The asm-generic header needs to be included after the definitions above */
+#include <asm-generic/vdso/vsyscall.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_VSYSCALL_H */
diff --git a/arch/arm/include/asm/vdso_datapage.h b/arch/arm/include/asm/vdso_datapage.h
index 9be259442fca..bfdbbd2b5fe7 100644
--- a/arch/arm/include/asm/vdso_datapage.h
+++ b/arch/arm/include/asm/vdso_datapage.h
@@ -22,35 +22,12 @@
#ifndef __ASSEMBLY__
+#include <vdso/datapage.h>
#include <asm/page.h>
-/* Try to be cache-friendly on systems that don't implement the
- * generic timer: fit the unconditionally updated fields in the first
- * 32 bytes.
- */
-struct vdso_data {
- u32 seq_count; /* sequence count - odd during updates */
- u16 tk_is_cntvct; /* fall back to syscall if false */
- u16 cs_shift; /* clocksource shift */
- u32 xtime_coarse_sec; /* coarse time */
- u32 xtime_coarse_nsec;
-
- u32 wtm_clock_sec; /* wall to monotonic offset */
- u32 wtm_clock_nsec;
- u32 xtime_clock_sec; /* CLOCK_REALTIME - seconds */
- u32 cs_mult; /* clocksource multiplier */
-
- u64 cs_cycle_last; /* last cycle value */
- u64 cs_mask; /* clocksource mask */
-
- u64 xtime_clock_snsec; /* CLOCK_REALTIME sub-ns base */
- u32 tz_minuteswest; /* timezone info for gettimeofday(2) */
- u32 tz_dsttime;
-};
-
union vdso_data_store {
- struct vdso_data data;
- u8 page[PAGE_SIZE];
+ struct vdso_data data[CS_BASES];
+ u8 page[PAGE_SIZE];
};
#endif /* !__ASSEMBLY__ */
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index f4dd7f9663c1..9a9cea8b333d 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -34,6 +34,8 @@
#include <asm/vdso.h>
#include <asm/vdso_datapage.h>
#include <clocksource/arm_arch_timer.h>
+#include <vdso/helpers.h>
+#include <vdso/vsyscall.h>
#define MAX_SYMNAME 64
@@ -48,7 +50,7 @@ unsigned int vdso_total_pages __ro_after_init;
* The VDSO data page.
*/
static union vdso_data_store vdso_data_store __page_aligned_data;
-static struct vdso_data *vdso_data = &vdso_data_store.data;
+struct vdso_data *vdso_data = vdso_data_store.data;
static struct page *vdso_data_page __ro_after_init;
static const struct vm_special_mapping vdso_data_mapping = {
@@ -88,7 +90,7 @@ struct elfinfo {
/* Cached result of boot-time check for whether the arch timer exists,
* and if so, whether the virtual counter is useable.
*/
-static bool cntvct_ok __ro_after_init;
+bool cntvct_ok __ro_after_init;
static bool __init cntvct_functional(void)
{
@@ -274,84 +276,3 @@ void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
mm->context.vdso = addr;
}
-static void vdso_write_begin(struct vdso_data *vdata)
-{
- ++vdso_data->seq_count;
- smp_wmb(); /* Pairs with smp_rmb in vdso_read_retry */
-}
-
-static void vdso_write_end(struct vdso_data *vdata)
-{
- smp_wmb(); /* Pairs with smp_rmb in vdso_read_begin */
- ++vdso_data->seq_count;
-}
-
-static bool tk_is_cntvct(const struct timekeeper *tk)
-{
- if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
- return false;
-
- if (!tk->tkr_mono.clock->archdata.vdso_direct)
- return false;
-
- return true;
-}
-
-/**
- * update_vsyscall - update the vdso data page
- *
- * Increment the sequence counter, making it odd, indicating to
- * userspace that an update is in progress. Update the fields used
- * for coarse clocks and, if the architected system timer is in use,
- * the fields used for high precision clocks. Increment the sequence
- * counter again, making it even, indicating to userspace that the
- * update is finished.
- *
- * Userspace is expected to sample seq_count before reading any other
- * fields from the data page. If seq_count is odd, userspace is
- * expected to wait until it becomes even. After copying data from
- * the page, userspace must sample seq_count again; if it has changed
- * from its previous value, userspace must retry the whole sequence.
- *
- * Calls to update_vsyscall are serialized by the timekeeping core.
- */
-void update_vsyscall(struct timekeeper *tk)
-{
- struct timespec64 *wtm = &tk->wall_to_monotonic;
-
- if (!cntvct_ok) {
- /* The entry points have been zeroed, so there is no
- * point in updating the data page.
- */
- return;
- }
-
- vdso_write_begin(vdso_data);
-
- vdso_data->tk_is_cntvct = tk_is_cntvct(tk);
- vdso_data->xtime_coarse_sec = tk->xtime_sec;
- vdso_data->xtime_coarse_nsec = (u32)(tk->tkr_mono.xtime_nsec >>
- tk->tkr_mono.shift);
- vdso_data->wtm_clock_sec = wtm->tv_sec;
- vdso_data->wtm_clock_nsec = wtm->tv_nsec;
-
- if (vdso_data->tk_is_cntvct) {
- vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
- vdso_data->xtime_clock_sec = tk->xtime_sec;
- vdso_data->xtime_clock_snsec = tk->tkr_mono.xtime_nsec;
- vdso_data->cs_mult = tk->tkr_mono.mult;
- vdso_data->cs_shift = tk->tkr_mono.shift;
- vdso_data->cs_mask = tk->tkr_mono.mask;
- }
-
- vdso_write_end(vdso_data);
-
- flush_dcache_page(virt_to_page(vdso_data));
-}
-
-void update_vsyscall_tz(void)
-{
- vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
- vdso_data->tz_dsttime = sys_tz.tz_dsttime;
- flush_dcache_page(virt_to_page(vdso_data));
-}
diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
index fadf554d9391..0c8a819ef4f1 100644
--- a/arch/arm/vdso/Makefile
+++ b/arch/arm/vdso/Makefile
@@ -1,7 +1,13 @@
# SPDX-License-Identifier: GPL-2.0
+
+# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+# the inclusion of generic Makefile.
+ARCH_REL_TYPE_ABS := R_ARM_JUMP_SLOT|R_ARM_GLOB_DAT|R_ARM_ABS32
+include $(srctree)/lib/vdso/Makefile
+
hostprogs-y := vdsomunge
-obj-vdso := vgettimeofday.o datapage.o
+obj-vdso := vgettimeofday.o datapage.o note.o
# Build rules
targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.so.raw vdso.lds
@@ -25,7 +31,11 @@ CFLAGS_REMOVE_vdso.o = -pg
# Force -O2 to avoid libgcc dependencies
CFLAGS_REMOVE_vgettimeofday.o = -pg -Os
+ifeq ($(c-gettimeofday-y),)
CFLAGS_vgettimeofday.o = -O2
+else
+CFLAGS_vgettimeofday.o = -O2 -include $(c-gettimeofday-y)
+endif
# Disable gcov profiling for VDSO code
GCOV_PROFILE := n
@@ -39,6 +49,7 @@ $(obj)/vdso.o : $(obj)/vdso.so
# Link rule for the .so file
$(obj)/vdso.so.raw: $(obj)/vdso.lds $(obj-vdso) FORCE
$(call if_changed,ld)
+ $(call if_changed,vdso_check)
$(obj)/vdso.so.dbg: $(obj)/vdso.so.raw $(obj)/vdsomunge FORCE
$(call if_changed,vdsomunge)
diff --git a/arch/arm/vdso/note.c b/arch/arm/vdso/note.c
new file mode 100644
index 000000000000..eff5bf9efb8b
--- /dev/null
+++ b/arch/arm/vdso/note.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2012-2018 ARM Limited
+ *
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ */
+
+#include <linux/uts.h>
+#include <linux/version.h>
+#include <linux/elfnote.h>
+#include <linux/build-salt.h>
+
+ELFNOTE32("Linux", 0, LINUX_VERSION_CODE);
+BUILD_SALT;
diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c
index 7bdbf5d5c47d..fea6b3c89f43 100644
--- a/arch/arm/vdso/vgettimeofday.c
+++ b/arch/arm/vdso/vgettimeofday.c
@@ -1,5 +1,8 @@
/*
+ * ARM userspace implementations of gettimeofday() and similar.
+ *
* Copyright 2015 Mentor Graphics Corporation.
+ * Copyright (C) 2018 ARM Limited
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -14,258 +17,19 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-#include <linux/compiler.h>
-#include <linux/hrtimer.h>
#include <linux/time.h>
-#include <asm/barrier.h>
-#include <asm/bug.h>
-#include <asm/cp15.h>
-#include <asm/page.h>
-#include <asm/unistd.h>
-#include <asm/vdso_datapage.h>
-
-#ifndef CONFIG_AEABI
-#error This code depends on AEABI system call conventions
-#endif
-
-extern struct vdso_data *__get_datapage(void);
-
-static notrace u32 __vdso_read_begin(const struct vdso_data *vdata)
-{
- u32 seq;
-repeat:
- seq = READ_ONCE(vdata->seq_count);
- if (seq & 1) {
- cpu_relax();
- goto repeat;
- }
- return seq;
-}
-
-static notrace u32 vdso_read_begin(const struct vdso_data *vdata)
-{
- u32 seq;
-
- seq = __vdso_read_begin(vdata);
-
- smp_rmb(); /* Pairs with smp_wmb in vdso_write_end */
- return seq;
-}
-
-static notrace int vdso_read_retry(const struct vdso_data *vdata, u32 start)
-{
- smp_rmb(); /* Pairs with smp_wmb in vdso_write_begin */
- return vdata->seq_count != start;
-}
-
-static notrace long clock_gettime_fallback(clockid_t _clkid,
- struct timespec *_ts)
-{
- register struct timespec *ts asm("r1") = _ts;
- register clockid_t clkid asm("r0") = _clkid;
- register long ret asm ("r0");
- register long nr asm("r7") = __NR_clock_gettime;
-
- asm volatile(
- " swi #0\n"
- : "=r" (ret)
- : "r" (clkid), "r" (ts), "r" (nr)
- : "memory");
-
- return ret;
-}
-
-static notrace int do_realtime_coarse(struct timespec *ts,
- struct vdso_data *vdata)
-{
- u32 seq;
-
- do {
- seq = vdso_read_begin(vdata);
-
- ts->tv_sec = vdata->xtime_coarse_sec;
- ts->tv_nsec = vdata->xtime_coarse_nsec;
-
- } while (vdso_read_retry(vdata, seq));
-
- return 0;
-}
-
-static notrace int do_monotonic_coarse(struct timespec *ts,
- struct vdso_data *vdata)
-{
- struct timespec tomono;
- u32 seq;
-
- do {
- seq = vdso_read_begin(vdata);
-
- ts->tv_sec = vdata->xtime_coarse_sec;
- ts->tv_nsec = vdata->xtime_coarse_nsec;
-
- tomono.tv_sec = vdata->wtm_clock_sec;
- tomono.tv_nsec = vdata->wtm_clock_nsec;
-
- } while (vdso_read_retry(vdata, seq));
-
- ts->tv_sec += tomono.tv_sec;
- timespec_add_ns(ts, tomono.tv_nsec);
-
- return 0;
-}
-
-#ifdef CONFIG_ARM_ARCH_TIMER
-
-static notrace u64 get_ns(struct vdso_data *vdata)
-{
- u64 cycle_delta;
- u64 cycle_now;
- u64 nsec;
-
- isb();
- cycle_now = read_sysreg(CNTVCT);
-
- cycle_delta = (cycle_now - vdata->cs_cycle_last) & vdata->cs_mask;
-
- nsec = (cycle_delta * vdata->cs_mult) + vdata->xtime_clock_snsec;
- nsec >>= vdata->cs_shift;
+#include <linux/types.h>
- return nsec;
-}
-
-static notrace int do_realtime(struct timespec *ts, struct vdso_data *vdata)
-{
- u64 nsecs;
- u32 seq;
-
- do {
- seq = vdso_read_begin(vdata);
-
- if (!vdata->tk_is_cntvct)
- return -1;
-
- ts->tv_sec = vdata->xtime_clock_sec;
- nsecs = get_ns(vdata);
-
- } while (vdso_read_retry(vdata, seq));
-
- ts->tv_nsec = 0;
- timespec_add_ns(ts, nsecs);
-
- return 0;
-}
-
-static notrace int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
-{
- struct timespec tomono;
- u64 nsecs;
- u32 seq;
-
- do {
- seq = vdso_read_begin(vdata);
-
- if (!vdata->tk_is_cntvct)
- return -1;
-
- ts->tv_sec = vdata->xtime_clock_sec;
- nsecs = get_ns(vdata);
-
- tomono.tv_sec = vdata->wtm_clock_sec;
- tomono.tv_nsec = vdata->wtm_clock_nsec;
-
- } while (vdso_read_retry(vdata, seq));
-
- ts->tv_sec += tomono.tv_sec;
- ts->tv_nsec = 0;
- timespec_add_ns(ts, nsecs + tomono.tv_nsec);
-
- return 0;
-}
-
-#else /* CONFIG_ARM_ARCH_TIMER */
-
-static notrace int do_realtime(struct timespec *ts, struct vdso_data *vdata)
-{
- return -1;
-}
-
-static notrace int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
+int __vdso_clock_gettime(clockid_t clock,
+ struct old_timespec32 *ts)
{
- return -1;
+ return __cvdso_clock_gettime32(clock, ts);
}
-#endif /* CONFIG_ARM_ARCH_TIMER */
-
-notrace int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
+ struct timezone *tz)
{
- struct vdso_data *vdata;
- int ret = -1;
-
- vdata = __get_datapage();
-
- switch (clkid) {
- case CLOCK_REALTIME_COARSE:
- ret = do_realtime_coarse(ts, vdata);
- break;
- case CLOCK_MONOTONIC_COARSE:
- ret = do_monotonic_coarse(ts, vdata);
- break;
- case CLOCK_REALTIME:
- ret = do_realtime(ts, vdata);
- break;
- case CLOCK_MONOTONIC:
- ret = do_monotonic(ts, vdata);
- break;
- default:
- break;
- }
-
- if (ret)
- ret = clock_gettime_fallback(clkid, ts);
-
- return ret;
-}
-
-static notrace long gettimeofday_fallback(struct timeval *_tv,
- struct timezone *_tz)
-{
- register struct timezone *tz asm("r1") = _tz;
- register struct timeval *tv asm("r0") = _tv;
- register long ret asm ("r0");
- register long nr asm("r7") = __NR_gettimeofday;
-
- asm volatile(
- " swi #0\n"
- : "=r" (ret)
- : "r" (tv), "r" (tz), "r" (nr)
- : "memory");
-
- return ret;
-}
-
-notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
-{
- struct timespec ts;
- struct vdso_data *vdata;
- int ret;
-
- vdata = __get_datapage();
-
- ret = do_realtime(&ts, vdata);
- if (ret)
- return gettimeofday_fallback(tv, tz);
-
- if (tv) {
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / 1000;
- }
- if (tz) {
- tz->tz_minuteswest = vdata->tz_minuteswest;
- tz->tz_dsttime = vdata->tz_dsttime;
- }
-
- return ret;
+ return __cvdso_gettimeofday(tv, tz);
}
/* Avoid unresolved references emitted by GCC */
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-06-21 9:52 ` [PATCH v7 16/25] arm: Add support for generic vDSO Vincenzo Frascino
@ 2019-12-04 13:51 ` Guenter Roeck
2019-12-04 13:58 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Guenter Roeck @ 2019-12-04 13:51 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton,
Andre Przywara
On Fri, Jun 21, 2019 at 10:52:43AM +0100, Vincenzo Frascino wrote:
> The arm vDSO library requires some adaptations to use to take advantage
> of the newly introduced generic vDSO library.
>
> Introduce the following changes:
> - Modification vdso.c to be compliant with the common vdso datapage
> - Use of lib/vdso for gettimeofday
> - Implementation of elf note
>
> Cc: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
This patch causes a crash with qemu's mcimx6ul-evk emulation while running
imx_v6_v7_defconfig.
[ 19.976852] Run /sbin/init as init process
[ 20.044931] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
There is nothing else useful in the log, unfortunately.
Reverting the following three patches fixes the problem.
74d06efb9c2f ARM: 8932/1: Add clock_gettime64 entry point
052e76a31b4a ARM: 8931/1: Add clock_getres entry point
20e2fc42312f ARM: 8930/1: Add support for generic vDSO
Guenter
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-12-04 13:51 ` [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash) Guenter Roeck
@ 2019-12-04 13:58 ` Vincenzo Frascino
2019-12-04 16:16 ` Guenter Roeck
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-12-04 13:58 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton,
Andre Przywara
Hi Guenter,
On 12/4/19 1:51 PM, Guenter Roeck wrote:
> On Fri, Jun 21, 2019 at 10:52:43AM +0100, Vincenzo Frascino wrote:
>> The arm vDSO library requires some adaptations to use to take advantage
>> of the newly introduced generic vDSO library.
>>
>> Introduce the following changes:
>> - Modification vdso.c to be compliant with the common vdso datapage
>> - Use of lib/vdso for gettimeofday
>> - Implementation of elf note
>>
>> Cc: Russell King <linux@armlinux.org.uk>
>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>
> This patch causes a crash with qemu's mcimx6ul-evk emulation while running
> imx_v6_v7_defconfig.
>
Thank you for reporting this. Could you please provide some details on how I can
reproduce the scenario you are describing?
> [ 19.976852] Run /sbin/init as init process
> [ 20.044931] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
>
> There is nothing else useful in the log, unfortunately.
>
> Reverting the following three patches fixes the problem.
>
> 74d06efb9c2f ARM: 8932/1: Add clock_gettime64 entry point
> 052e76a31b4a ARM: 8931/1: Add clock_getres entry point
> 20e2fc42312f ARM: 8930/1: Add support for generic vDSO
>
> Guenter
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-12-04 13:58 ` Vincenzo Frascino
@ 2019-12-04 16:16 ` Guenter Roeck
2019-12-04 17:15 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Guenter Roeck @ 2019-12-04 16:16 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton,
Andre Przywara
On Wed, Dec 04, 2019 at 01:58:25PM +0000, Vincenzo Frascino wrote:
> Hi Guenter,
>
> On 12/4/19 1:51 PM, Guenter Roeck wrote:
> > On Fri, Jun 21, 2019 at 10:52:43AM +0100, Vincenzo Frascino wrote:
> >> The arm vDSO library requires some adaptations to use to take advantage
> >> of the newly introduced generic vDSO library.
> >>
> >> Introduce the following changes:
> >> - Modification vdso.c to be compliant with the common vdso datapage
> >> - Use of lib/vdso for gettimeofday
> >> - Implementation of elf note
> >>
> >> Cc: Russell King <linux@armlinux.org.uk>
> >> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> >
> > This patch causes a crash with qemu's mcimx6ul-evk emulation while running
> > imx_v6_v7_defconfig.
> >
>
> Thank you for reporting this. Could you please provide some details on how I can
> reproduce the scenario you are describing?
>
- Build imx_v6_v7_defconfig
- Get root file system or initrd, for example from
https://github.com/groeck/linux-build-test/tree/master/rootfs/arm
- Run image. Example, with initrd:
qemu-system-arm -M mcimx6ul-evk -kernel arch/arm/boot/zImage \
-no-reboot -initrd rootfs-armv7a.cpio \
-m 256 -display none -serial null \
--append 'rdinit=/sbin/init earlycon=ec_imx6q,mmio,0x21e8000,115200n8 console=ttymxc1,115200'
-dtb arch/arm/boot/dts/imx6ul-14x14-evk.dtb \
-nographic -monitor null -serial stdio
qemu has to be v3.1 or later to support the machine.
Hope this helps,
Guenter
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-12-04 16:16 ` Guenter Roeck
@ 2019-12-04 17:15 ` Vincenzo Frascino
2019-12-04 19:39 ` Guenter Roeck
2019-12-05 9:42 ` Philippe Mathieu-Daudé
0 siblings, 2 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-12-04 17:15 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton,
Andre Przywara
Hi Guenter,
On 12/4/19 4:16 PM, Guenter Roeck wrote:
> On Wed, Dec 04, 2019 at 01:58:25PM +0000, Vincenzo Frascino wrote:
>> Hi Guenter,
>>
>> On 12/4/19 1:51 PM, Guenter Roeck wrote:
>>> On Fri, Jun 21, 2019 at 10:52:43AM +0100, Vincenzo Frascino wrote:
>>>> The arm vDSO library requires some adaptations to use to take advantage
>>>> of the newly introduced generic vDSO library.
>>>>
>>>> Introduce the following changes:
>>>> - Modification vdso.c to be compliant with the common vdso datapage
>>>> - Use of lib/vdso for gettimeofday
>>>> - Implementation of elf note
>>>>
>>>> Cc: Russell King <linux@armlinux.org.uk>
>>>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>>>
>>> This patch causes a crash with qemu's mcimx6ul-evk emulation while running
>>> imx_v6_v7_defconfig.
>>>
>>
>> Thank you for reporting this. Could you please provide some details on how I can
>> reproduce the scenario you are describing?
>>
> - Build imx_v6_v7_defconfig
> - Get root file system or initrd, for example from
> https://github.com/groeck/linux-build-test/tree/master/rootfs/arm
> - Run image. Example, with initrd:
> qemu-system-arm -M mcimx6ul-evk -kernel arch/arm/boot/zImage \
> -no-reboot -initrd rootfs-armv7a.cpio \
> -m 256 -display none -serial null \
> --append 'rdinit=/sbin/init earlycon=ec_imx6q,mmio,0x21e8000,115200n8 console=ttymxc1,115200'
> -dtb arch/arm/boot/dts/imx6ul-14x14-evk.dtb \
> -nographic -monitor null -serial stdio
>
> qemu has to be v3.1 or later to support the machine.
>
Thanks for this. Could you please try the patch below the scissors? Seems fixing
the issue for me.
> Hope this helps,
> Guenter
>
--
Regards,
Vincenzo
--->8---
Author: Vincenzo Frascino <vincenzo.frascino@arm.com>
Date: Wed Dec 4 16:58:55 2019 +0000
arm: Fix __arch_get_hw_counter() access to CNTVCT
__arch_get_hw_counter() should check clock_mode to see if it can access
CNTVCT. With the conversion to unified vDSO this check has been left out.
This causes on imx v6 and v7 (imx_v6_v7_defconfig) and other platforms to
hang at boot during the execution of the init process as per below:
[ 19.976852] Run /sbin/init as init process
[ 20.044931] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x00000004
Fix the problem verifying that clock_mode is set coherently before
accessing CNTVCT.
Cc: Russell King <linux@armlinux.org.uk>
Reported-by: Guenter Roeck <linux@roeck-us.net>
Investigated-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
diff --git a/arch/arm/include/asm/vdso/gettimeofday.h
b/arch/arm/include/asm/vdso/gettimeofday.h
index 5b879ae7afc1..0ad2429c324f 100644
--- a/arch/arm/include/asm/vdso/gettimeofday.h
+++ b/arch/arm/include/asm/vdso/gettimeofday.h
@@ -75,6 +75,9 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode)
#ifdef CONFIG_ARM_ARCH_TIMER
u64 cycle_now;
+ if (!clock_mode)
+ return -EINVAL;
+
isb();
cycle_now = read_sysreg(CNTVCT);
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-12-04 17:15 ` Vincenzo Frascino
@ 2019-12-04 19:39 ` Guenter Roeck
2019-12-05 9:42 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 108+ messages in thread
From: Guenter Roeck @ 2019-12-04 19:39 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton,
Andre Przywara
On Wed, Dec 04, 2019 at 05:15:26PM +0000, Vincenzo Frascino wrote:
> Hi Guenter,
>
> On 12/4/19 4:16 PM, Guenter Roeck wrote:
> > On Wed, Dec 04, 2019 at 01:58:25PM +0000, Vincenzo Frascino wrote:
> >> Hi Guenter,
> >>
> >> On 12/4/19 1:51 PM, Guenter Roeck wrote:
> >>> On Fri, Jun 21, 2019 at 10:52:43AM +0100, Vincenzo Frascino wrote:
> >>>> The arm vDSO library requires some adaptations to use to take advantage
> >>>> of the newly introduced generic vDSO library.
> >>>>
> >>>> Introduce the following changes:
> >>>> - Modification vdso.c to be compliant with the common vdso datapage
> >>>> - Use of lib/vdso for gettimeofday
> >>>> - Implementation of elf note
> >>>>
> >>>> Cc: Russell King <linux@armlinux.org.uk>
> >>>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> >>>
> >>> This patch causes a crash with qemu's mcimx6ul-evk emulation while running
> >>> imx_v6_v7_defconfig.
> >>>
> >>
> >> Thank you for reporting this. Could you please provide some details on how I can
> >> reproduce the scenario you are describing?
> >>
> > - Build imx_v6_v7_defconfig
> > - Get root file system or initrd, for example from
> > https://github.com/groeck/linux-build-test/tree/master/rootfs/arm
> > - Run image. Example, with initrd:
> > qemu-system-arm -M mcimx6ul-evk -kernel arch/arm/boot/zImage \
> > -no-reboot -initrd rootfs-armv7a.cpio \
> > -m 256 -display none -serial null \
> > --append 'rdinit=/sbin/init earlycon=ec_imx6q,mmio,0x21e8000,115200n8 console=ttymxc1,115200'
> > -dtb arch/arm/boot/dts/imx6ul-14x14-evk.dtb \
> > -nographic -monitor null -serial stdio
> >
> > qemu has to be v3.1 or later to support the machine.
> >
>
> Thanks for this. Could you please try the patch below the scissors? Seems fixing
> the issue for me.
>
> > Hope this helps,
> > Guenter
> >
>
> --
> Regards,
> Vincenzo
>
> --->8---
>
> Author: Vincenzo Frascino <vincenzo.frascino@arm.com>
> Date: Wed Dec 4 16:58:55 2019 +0000
>
> arm: Fix __arch_get_hw_counter() access to CNTVCT
>
> __arch_get_hw_counter() should check clock_mode to see if it can access
> CNTVCT. With the conversion to unified vDSO this check has been left out.
>
> This causes on imx v6 and v7 (imx_v6_v7_defconfig) and other platforms to
> hang at boot during the execution of the init process as per below:
>
> [ 19.976852] Run /sbin/init as init process
> [ 20.044931] Kernel panic - not syncing: Attempted to kill init!
> exitcode=0x00000004
>
> Fix the problem verifying that clock_mode is set coherently before
> accessing CNTVCT.
>
> Cc: Russell King <linux@armlinux.org.uk>
> Reported-by: Guenter Roeck <linux@roeck-us.net>
> Investigated-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>
WFM.
Tested-by: Guenter Roeck <linux@roeck-us.net>
Guenter
> diff --git a/arch/arm/include/asm/vdso/gettimeofday.h
> b/arch/arm/include/asm/vdso/gettimeofday.h
> index 5b879ae7afc1..0ad2429c324f 100644
> --- a/arch/arm/include/asm/vdso/gettimeofday.h
> +++ b/arch/arm/include/asm/vdso/gettimeofday.h
> @@ -75,6 +75,9 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode)
> #ifdef CONFIG_ARM_ARCH_TIMER
> u64 cycle_now;
>
> + if (!clock_mode)
> + return -EINVAL;
> +
> isb();
> cycle_now = read_sysreg(CNTVCT);
>
>
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-12-04 17:15 ` Vincenzo Frascino
2019-12-04 19:39 ` Guenter Roeck
@ 2019-12-05 9:42 ` Philippe Mathieu-Daudé
2019-12-05 10:00 ` Vincenzo Frascino
1 sibling, 1 reply; 108+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-12-05 9:42 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: Guenter Roeck, linux-arch, linux-arm-kernel, open list,
open list:BROADCOM NVRAM DRIVER, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
On Wed, Dec 4, 2019 at 6:23 PM Vincenzo Frascino
<vincenzo.frascino@arm.com> wrote:
> On 12/4/19 4:16 PM, Guenter Roeck wrote:
[...]
> --->8---
>
> Author: Vincenzo Frascino <vincenzo.frascino@arm.com>
> Date: Wed Dec 4 16:58:55 2019 +0000
>
> arm: Fix __arch_get_hw_counter() access to CNTVCT
>
> __arch_get_hw_counter() should check clock_mode to see if it can access
> CNTVCT. With the conversion to unified vDSO this check has been left out.
>
> This causes on imx v6 and v7 (imx_v6_v7_defconfig) and other platforms to
> hang at boot during the execution of the init process as per below:
>
> [ 19.976852] Run /sbin/init as init process
> [ 20.044931] Kernel panic - not syncing: Attempted to kill init!
> exitcode=0x00000004
>
> Fix the problem verifying that clock_mode is set coherently before
> accessing CNTVCT.
>
> Cc: Russell King <linux@armlinux.org.uk>
> Reported-by: Guenter Roeck <linux@roeck-us.net>
> Investigated-by: Arnd Bergmann <arnd@arndb.de>
There are only 2 "Investigated-by" vs 7k+ "Suggested-by"... Is there a
real difference?
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>
> diff --git a/arch/arm/include/asm/vdso/gettimeofday.h
> b/arch/arm/include/asm/vdso/gettimeofday.h
> index 5b879ae7afc1..0ad2429c324f 100644
> --- a/arch/arm/include/asm/vdso/gettimeofday.h
> +++ b/arch/arm/include/asm/vdso/gettimeofday.h
> @@ -75,6 +75,9 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode)
> #ifdef CONFIG_ARM_ARCH_TIMER
> u64 cycle_now;
>
> + if (!clock_mode)
> + return -EINVAL;
> +
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> isb();
> cycle_now = read_sysreg(CNTVCT);
>
>
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-12-05 9:42 ` Philippe Mathieu-Daudé
@ 2019-12-05 10:00 ` Vincenzo Frascino
2019-12-05 11:02 ` Arnd Bergmann
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-12-05 10:00 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: Guenter Roeck, linux-arch, linux-arm-kernel, open list,
open list:BROADCOM NVRAM DRIVER, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
[-- Attachment #1: Type: text/plain, Size: 464 bytes --]
Hi Philippe,
On 05/12/2019 09:42, Philippe Mathieu-Daudé wrote:
> There are only 2 "Investigated-by" vs 7k+ "Suggested-by"... Is there a
> real difference?
Not sure about that. My take is that Suggested-by is used when someone suggests
you how to possibly implement a feature and you go and do that. Investigated-by
is when there is a fix to make and someone comes to you with the exact solution
like in this case Arnd did.
--
Regards,
Vincenzo
[-- Attachment #2: pEpkey.asc --]
[-- Type: application/pgp-keys, Size: 14291 bytes --]
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-12-05 10:00 ` Vincenzo Frascino
@ 2019-12-05 11:02 ` Arnd Bergmann
2019-12-05 14:56 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 108+ messages in thread
From: Arnd Bergmann @ 2019-12-05 11:02 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: Philippe Mathieu-Daudé,
Guenter Roeck, linux-arch, Linux ARM, open list,
open list:BROADCOM NVRAM DRIVER,
open list:KERNEL SELFTEST FRAMEWORK, Catalin Marinas,
Will Deacon, Russell King, Ralf Baechle, Paul Burton,
Daniel Lezcano, Thomas Gleixner, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
On Thu, Dec 5, 2019 at 11:00 AM Vincenzo Frascino
<vincenzo.frascino@arm.com> wrote:
>
> Hi Philippe,
>
> On 05/12/2019 09:42, Philippe Mathieu-Daudé wrote:
> > There are only 2 "Investigated-by" vs 7k+ "Suggested-by"... Is there a
> > real difference?
>
> Not sure about that. My take is that Suggested-by is used when someone suggests
> you how to possibly implement a feature and you go and do that. Investigated-by
> is when there is a fix to make and someone comes to you with the exact solution
> like in this case Arnd did.
It's not a standard tag, but I suggested it because it does explain
better what I did.
You could also just explain in clear text that I did the analysis and then add
the more normal Suggested-by tag, I don't care either way.
Arnd
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 16/25] arm: Add support for generic vDSO (causing crash)
2019-12-05 11:02 ` Arnd Bergmann
@ 2019-12-05 14:56 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 108+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-12-05 14:56 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Vincenzo Frascino, Guenter Roeck, linux-arch, Linux ARM,
open list, open list:BROADCOM NVRAM DRIVER,
open list:KERNEL SELFTEST FRAMEWORK, Catalin Marinas,
Will Deacon, Russell King, Ralf Baechle, Paul Burton,
Daniel Lezcano, Thomas Gleixner, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
On Thu, Dec 5, 2019 at 12:02 PM Arnd Bergmann <arnd@arndb.de> wrote:
> On Thu, Dec 5, 2019 at 11:00 AM Vincenzo Frascino
> <vincenzo.frascino@arm.com> wrote:
> >
> > Hi Philippe,
> >
> > On 05/12/2019 09:42, Philippe Mathieu-Daudé wrote:
> > > There are only 2 "Investigated-by" vs 7k+ "Suggested-by"... Is there a
> > > real difference?
> >
> > Not sure about that. My take is that Suggested-by is used when someone suggests
> > you how to possibly implement a feature and you go and do that. Investigated-by
> > is when there is a fix to make and someone comes to you with the exact solution
> > like in this case Arnd did.
>
> It's not a standard tag, but I suggested it because it does explain
> better what I did.
>
> You could also just explain in clear text that I did the analysis and then add
> the more normal Suggested-by tag, I don't care either way.
No problem, I was just wondering the subtle difference between both tags.
I don't mind which one you use, as long as this issue get fixed :)
Thanks for the patch BTW!
Regards,
Phil.
> Arnd
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH v7 17/25] arm: Add clock_getres entry point
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (15 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 16/25] arm: Add support for generic vDSO Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 18/25] arm: Add clock_gettime64 " Vincenzo Frascino
` (9 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
The generic vDSO library provides an implementation of clock_getres() that
can be leveraged by each architecture.
Add clock_getres() entry point on arm to be on pair with arm64.
Cc: Russell King <linux@armlinux.org.uk>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/arm/include/asm/vdso/gettimeofday.h | 20 ++++++++++++++++++++
arch/arm/vdso/vdso.lds.S | 1 +
arch/arm/vdso/vgettimeofday.c | 6 ++++++
3 files changed, 27 insertions(+)
diff --git a/arch/arm/include/asm/vdso/gettimeofday.h b/arch/arm/include/asm/vdso/gettimeofday.h
index 30ce4e87dffc..5b879ae7afc1 100644
--- a/arch/arm/include/asm/vdso/gettimeofday.h
+++ b/arch/arm/include/asm/vdso/gettimeofday.h
@@ -12,6 +12,8 @@
#include <asm/unistd.h>
#include <uapi/linux/time.h>
+#define VDSO_HAS_CLOCK_GETRES 1
+
extern struct vdso_data *__get_datapage(void);
static __always_inline int gettimeofday_fallback(
@@ -50,6 +52,24 @@ static __always_inline long clock_gettime_fallback(
return ret;
}
+static __always_inline int clock_getres_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ register struct __kernel_timespec *ts asm("r1") = _ts;
+ register clockid_t clkid asm("r0") = _clkid;
+ register long ret asm ("r0");
+ register long nr asm("r7") = __NR_clock_getres_time64;
+
+ asm volatile(
+ " swi #0\n"
+ : "=r" (ret)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "memory");
+
+ return ret;
+}
+
static __always_inline u64 __arch_get_hw_counter(int clock_mode)
{
#ifdef CONFIG_ARM_ARCH_TIMER
diff --git a/arch/arm/vdso/vdso.lds.S b/arch/arm/vdso/vdso.lds.S
index 89ca89f12d23..1d81e8c3acf6 100644
--- a/arch/arm/vdso/vdso.lds.S
+++ b/arch/arm/vdso/vdso.lds.S
@@ -82,6 +82,7 @@ VERSION
global:
__vdso_clock_gettime;
__vdso_gettimeofday;
+ __vdso_clock_getres;
local: *;
};
}
diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c
index fea6b3c89f43..d3330c0c1147 100644
--- a/arch/arm/vdso/vgettimeofday.c
+++ b/arch/arm/vdso/vgettimeofday.c
@@ -32,6 +32,12 @@ int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
return __cvdso_gettimeofday(tv, tz);
}
+int __vdso_clock_getres(clockid_t clock_id,
+ struct old_timespec32 *res)
+{
+ return __cvdso_clock_getres_time32(clock_id, res);
+}
+
/* Avoid unresolved references emitted by GCC */
void __aeabi_unwind_cpp_pr0(void)
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 18/25] arm: Add clock_gettime64 entry point
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (16 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 17/25] arm: Add clock_getres entry point Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 19/25] mips: Add support for generic vDSO Vincenzo Frascino
` (8 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
With the release of Linux 5.1 has been added a new syscall,
clock_gettime64, that provided a 64 bit time value for a specified
clock_ID to make the kernel Y2038 safe on 32 bit architectures.
Update the arm specific vDSO library accordingly with what it has
been done for the kernel syscall exposing the clock_gettime64 entry
point.
Cc: Russell King <linux@armlinux.org.uk>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/arm/vdso/vdso.lds.S | 1 +
arch/arm/vdso/vgettimeofday.c | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/arch/arm/vdso/vdso.lds.S b/arch/arm/vdso/vdso.lds.S
index 1d81e8c3acf6..05581140fd12 100644
--- a/arch/arm/vdso/vdso.lds.S
+++ b/arch/arm/vdso/vdso.lds.S
@@ -83,6 +83,7 @@ VERSION
__vdso_clock_gettime;
__vdso_gettimeofday;
__vdso_clock_getres;
+ __vdso_clock_gettime64;
local: *;
};
}
diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c
index d3330c0c1147..0742a0bb4763 100644
--- a/arch/arm/vdso/vgettimeofday.c
+++ b/arch/arm/vdso/vgettimeofday.c
@@ -26,6 +26,12 @@ int __vdso_clock_gettime(clockid_t clock,
return __cvdso_clock_gettime32(clock, ts);
}
+int __vdso_clock_gettime64(clockid_t clock,
+ struct __kernel_timespec *ts)
+{
+ return __cvdso_clock_gettime(clock, ts);
+}
+
int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
struct timezone *tz)
{
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 19/25] mips: Add support for generic vDSO
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (17 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 18/25] arm: Add clock_gettime64 " Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-07-26 5:15 ` Paul Burton
2019-06-21 9:52 ` [PATCH v7 20/25] mips: Add clock_getres entry point Vincenzo Frascino
` (7 subsequent siblings)
26 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
The mips vDSO library requires some adaptations to take advantage of the
newly introduced generic vDSO library.
Introduce the following changes:
- Modification of vdso.c to be compliant with the common vdso datapage
- Use of lib/vdso for gettimeofday
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/mips/Kconfig | 2 +
arch/mips/include/asm/vdso.h | 78 +----------
arch/mips/include/asm/vdso/gettimeofday.h | 151 ++++++++++++++++++++++
arch/mips/{ => include/asm}/vdso/vdso.h | 6 +-
arch/mips/include/asm/vdso/vsyscall.h | 43 ++++++
arch/mips/kernel/vdso.c | 37 +-----
arch/mips/vdso/Makefile | 27 +++-
arch/mips/vdso/elf.S | 2 +-
arch/mips/vdso/sigreturn.S | 2 +-
arch/mips/vdso/vgettimeofday.c | 40 ++++++
10 files changed, 273 insertions(+), 115 deletions(-)
create mode 100644 arch/mips/include/asm/vdso/gettimeofday.h
rename arch/mips/{ => include/asm}/vdso/vdso.h (89%)
create mode 100644 arch/mips/include/asm/vdso/vsyscall.h
create mode 100644 arch/mips/vdso/vgettimeofday.c
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 70d3200476bf..390c052cac9a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -34,6 +34,7 @@ config MIPS
select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
+ select GENERIC_GETTIMEOFDAY
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_COMPILER_H
select HAVE_ARCH_JUMP_LABEL
@@ -72,6 +73,7 @@ config MIPS
select HAVE_STACKPROTECTOR
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP
+ select HAVE_GENERIC_VDSO
select IRQ_FORCED_THREADING
select ISA if EISA
select MODULES_USE_ELF_RELA if MODULES && 64BIT
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
index a013fa4a3682..cc7b516129a8 100644
--- a/arch/mips/include/asm/vdso.h
+++ b/arch/mips/include/asm/vdso.h
@@ -8,6 +8,7 @@
#define __ASM_VDSO_H
#include <linux/mm_types.h>
+#include <vdso/datapage.h>
#include <asm/barrier.h>
@@ -49,84 +50,9 @@ extern struct mips_vdso_image vdso_image_o32;
extern struct mips_vdso_image vdso_image_n32;
#endif
-/**
- * union mips_vdso_data - Data provided by the kernel for the VDSO.
- * @xtime_sec: Current real time (seconds part).
- * @xtime_nsec: Current real time (nanoseconds part, shifted).
- * @wall_to_mono_sec: Wall-to-monotonic offset (seconds part).
- * @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part).
- * @seq_count: Counter to synchronise updates (odd = updating).
- * @cs_shift: Clocksource shift value.
- * @clock_mode: Clocksource to use for time functions.
- * @cs_mult: Clocksource multiplier value.
- * @cs_cycle_last: Clock cycle value at last update.
- * @cs_mask: Clocksource mask value.
- * @tz_minuteswest: Minutes west of Greenwich (from timezone).
- * @tz_dsttime: Type of DST correction (from timezone).
- *
- * This structure contains data needed by functions within the VDSO. It is
- * populated by the kernel and mapped read-only into user memory. The time
- * fields are mirrors of internal data from the timekeeping infrastructure.
- *
- * Note: Care should be taken when modifying as the layout must remain the same
- * for both 64- and 32-bit (for 32-bit userland on 64-bit kernel).
- */
union mips_vdso_data {
- struct {
- u64 xtime_sec;
- u64 xtime_nsec;
- u64 wall_to_mono_sec;
- u64 wall_to_mono_nsec;
- u32 seq_count;
- u32 cs_shift;
- u8 clock_mode;
- u32 cs_mult;
- u64 cs_cycle_last;
- u64 cs_mask;
- s32 tz_minuteswest;
- s32 tz_dsttime;
- };
-
+ struct vdso_data data[CS_BASES];
u8 page[PAGE_SIZE];
};
-static inline u32 vdso_data_read_begin(const union mips_vdso_data *data)
-{
- u32 seq;
-
- while (true) {
- seq = READ_ONCE(data->seq_count);
- if (likely(!(seq & 1))) {
- /* Paired with smp_wmb() in vdso_data_write_*(). */
- smp_rmb();
- return seq;
- }
-
- cpu_relax();
- }
-}
-
-static inline bool vdso_data_read_retry(const union mips_vdso_data *data,
- u32 start_seq)
-{
- /* Paired with smp_wmb() in vdso_data_write_*(). */
- smp_rmb();
- return unlikely(data->seq_count != start_seq);
-}
-
-static inline void vdso_data_write_begin(union mips_vdso_data *data)
-{
- ++data->seq_count;
-
- /* Ensure sequence update is written before other data page values. */
- smp_wmb();
-}
-
-static inline void vdso_data_write_end(union mips_vdso_data *data)
-{
- /* Ensure data values are written before updating sequence again. */
- smp_wmb();
- ++data->seq_count;
-}
-
#endif /* __ASM_VDSO_H */
diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h
new file mode 100644
index 000000000000..aa20865b288b
--- /dev/null
+++ b/arch/mips/include/asm/vdso/gettimeofday.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2018 ARM Limited
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * 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.
+ */
+#ifndef __ASM_VDSO_GETTIMEOFDAY_H
+#define __ASM_VDSO_GETTIMEOFDAY_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/compiler.h>
+#include <linux/time.h>
+
+#include <asm/vdso/vdso.h>
+#include <asm/clocksource.h>
+#include <asm/io.h>
+#include <asm/unistd.h>
+#include <asm/vdso.h>
+
+#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
+
+static __always_inline long gettimeofday_fallback(
+ struct __kernel_old_timeval *_tv,
+ struct timezone *_tz)
+{
+ register struct timezone *tz asm("a1") = _tz;
+ register struct __kernel_old_timeval *tv asm("a0") = _tv;
+ register long ret asm("v0");
+ register long nr asm("v0") = __NR_gettimeofday;
+ register long error asm("a3");
+
+ asm volatile(
+ " syscall\n"
+ : "=r" (ret), "=r" (error)
+ : "r" (tv), "r" (tz), "r" (nr)
+ : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
+ "$14", "$15", "$24", "$25", "hi", "lo", "memory");
+
+ return error ? -ret : ret;
+}
+
+#else
+
+static __always_inline long gettimeofday_fallback(
+ struct __kernel_old_timeval *_tv,
+ struct timezone *_tz)
+{
+ return -1;
+}
+
+#endif
+
+static __always_inline long clock_gettime_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ register struct __kernel_timespec *ts asm("a1") = _ts;
+ register clockid_t clkid asm("a0") = _clkid;
+ register long ret asm("v0");
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ register long nr asm("v0") = __NR_clock_gettime;
+#else
+ register long nr asm("v0") = __NR_clock_gettime64;
+#endif
+ register long error asm("a3");
+
+ asm volatile(
+ " syscall\n"
+ : "=r" (ret), "=r" (error)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
+ "$14", "$15", "$24", "$25", "hi", "lo", "memory");
+
+ return error ? -ret : ret;
+}
+
+#ifdef CONFIG_CSRC_R4K
+
+static __always_inline u64 read_r4k_count(void)
+{
+ unsigned int count;
+
+ __asm__ __volatile__(
+ " .set push\n"
+ " .set mips32r2\n"
+ " rdhwr %0, $2\n"
+ " .set pop\n"
+ : "=r" (count));
+
+ return count;
+}
+
+#endif
+
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+
+static __always_inline u64 read_gic_count(const struct vdso_data *data)
+{
+ void __iomem *gic = get_gic(data);
+ u32 hi, hi2, lo;
+
+ do {
+ hi = __raw_readl(gic + sizeof(lo));
+ lo = __raw_readl(gic);
+ hi2 = __raw_readl(gic + sizeof(lo));
+ } while (hi2 != hi);
+
+ return (((u64)hi) << 32) + lo;
+}
+
+#endif
+
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
+{
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+ const struct vdso_data *data = get_vdso_data();
+#endif
+ u64 cycle_now;
+
+ switch (clock_mode) {
+#ifdef CONFIG_CSRC_R4K
+ case VDSO_CLOCK_R4K:
+ cycle_now = read_r4k_count();
+ break;
+#endif
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+ case VDSO_CLOCK_GIC:
+ cycle_now = read_gic_count(data);
+ break;
+#endif
+ default:
+ cycle_now = 0;
+ break;
+ }
+
+ return cycle_now;
+}
+
+static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
+{
+ return get_vdso_data();
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/mips/vdso/vdso.h b/arch/mips/include/asm/vdso/vdso.h
similarity index 89%
rename from arch/mips/vdso/vdso.h
rename to arch/mips/include/asm/vdso/vdso.h
index 14b1931be69c..526695bc65ee 100644
--- a/arch/mips/vdso/vdso.h
+++ b/arch/mips/include/asm/vdso/vdso.h
@@ -68,14 +68,14 @@ static inline unsigned long get_vdso_base(void)
return addr;
}
-static inline const union mips_vdso_data *get_vdso_data(void)
+static inline const struct vdso_data *get_vdso_data(void)
{
- return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
+ return (const struct vdso_data *)(get_vdso_base() - PAGE_SIZE);
}
#ifdef CONFIG_CLKSRC_MIPS_GIC
-static inline void __iomem *get_gic(const union mips_vdso_data *data)
+static inline void __iomem *get_gic(const struct vdso_data *data)
{
return (void __iomem *)data - PAGE_SIZE;
}
diff --git a/arch/mips/include/asm/vdso/vsyscall.h b/arch/mips/include/asm/vdso/vsyscall.h
new file mode 100644
index 000000000000..195314732233
--- /dev/null
+++ b/arch/mips/include/asm/vdso/vsyscall.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_VDSO_VSYSCALL_H
+#define __ASM_VDSO_VSYSCALL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/timekeeper_internal.h>
+#include <vdso/datapage.h>
+
+extern struct vdso_data *vdso_data;
+
+/*
+ * Update the vDSO data page to keep in sync with kernel timekeeping.
+ */
+static __always_inline
+struct vdso_data *__mips_get_k_vdso_data(void)
+{
+ return vdso_data;
+}
+#define __arch_get_k_vdso_data __mips_get_k_vdso_data
+
+static __always_inline
+int __mips_get_clock_mode(struct timekeeper *tk)
+{
+ u32 clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
+
+ return clock_mode;
+}
+#define __arch_get_clock_mode __mips_get_clock_mode
+
+static __always_inline
+int __mips_use_vsyscall(struct vdso_data *vdata)
+{
+ return (vdata[CS_HRES_COARSE].clock_mode != VDSO_CLOCK_NONE);
+}
+#define __arch_use_vsyscall __mips_use_vsyscall
+
+/* The asm-generic header needs to be included after the definitions above */
+#include <asm-generic/vdso/vsyscall.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_VSYSCALL_H */
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 3a372686ffca..bc35f8499111 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -20,9 +20,12 @@
#include <asm/mips-cps.h>
#include <asm/page.h>
#include <asm/vdso.h>
+#include <vdso/helpers.h>
+#include <vdso/vsyscall.h>
/* Kernel-provided data used by the VDSO. */
-static union mips_vdso_data vdso_data __page_aligned_data;
+static union mips_vdso_data mips_vdso_data __page_aligned_data;
+struct vdso_data *vdso_data = mips_vdso_data.data;
/*
* Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as
@@ -66,34 +69,6 @@ static int __init init_vdso(void)
}
subsys_initcall(init_vdso);
-void update_vsyscall(struct timekeeper *tk)
-{
- vdso_data_write_begin(&vdso_data);
-
- vdso_data.xtime_sec = tk->xtime_sec;
- vdso_data.xtime_nsec = tk->tkr_mono.xtime_nsec;
- vdso_data.wall_to_mono_sec = tk->wall_to_monotonic.tv_sec;
- vdso_data.wall_to_mono_nsec = tk->wall_to_monotonic.tv_nsec;
- vdso_data.cs_shift = tk->tkr_mono.shift;
-
- vdso_data.clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
- if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
- vdso_data.cs_mult = tk->tkr_mono.mult;
- vdso_data.cs_cycle_last = tk->tkr_mono.cycle_last;
- vdso_data.cs_mask = tk->tkr_mono.mask;
- }
-
- vdso_data_write_end(&vdso_data);
-}
-
-void update_vsyscall_tz(void)
-{
- if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
- vdso_data.tz_minuteswest = sys_tz.tz_minuteswest;
- vdso_data.tz_dsttime = sys_tz.tz_dsttime;
- }
-}
-
static unsigned long vdso_base(void)
{
unsigned long base;
@@ -163,7 +138,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
*/
if (cpu_has_dc_aliases) {
base = __ALIGN_MASK(base, shm_align_mask);
- base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask;
+ base += ((unsigned long)vdso_data - gic_size) & shm_align_mask;
}
data_addr = base + gic_size;
@@ -189,7 +164,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
/* Map data page. */
ret = remap_pfn_range(vma, data_addr,
- virt_to_phys(&vdso_data) >> PAGE_SHIFT,
+ virt_to_phys(vdso_data) >> PAGE_SHIFT,
PAGE_SIZE, PAGE_READONLY);
if (ret)
goto out;
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index 7221df24cb23..95df49402a53 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -1,6 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
# Objects to go into the VDSO.
-obj-vdso-y := elf.o gettimeofday.o sigreturn.o
+
+# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+# the inclusion of generic Makefile.
+ARCH_REL_TYPE_ABS := R_MIPS_JUMP_SLOT|R_MIPS_GLOB_DAT
+include $(srctree)/lib/vdso/Makefile
+
+obj-vdso-y := elf.o vgettimeofday.o sigreturn.o
# Common compiler flags between ABIs.
ccflags-vdso := \
@@ -15,15 +21,25 @@ ifdef CONFIG_CC_IS_CLANG
ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS))
endif
+#
+# The -fno-jump-tables flag only prevents the compiler from generating
+# jump tables but does not prevent the compiler from emitting absolute
+# offsets.
cflags-vdso := $(ccflags-vdso) \
$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
- -O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
- -DDISABLE_BRANCH_PROFILING \
+ -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
+ -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
$(call cc-option, -fno-asynchronous-unwind-tables) \
$(call cc-option, -fno-stack-protector)
aflags-vdso := $(ccflags-vdso) \
-D__ASSEMBLY__ -Wa,-gdwarf-2
+ifneq ($(c-gettimeofday-y),)
+CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
+endif
+
+CFLAGS_REMOVE_vgettimeofday.o = -pg
+
#
# For the pre-R6 code in arch/mips/vdso/vdso.h for locating
# the base address of VDSO, the linker will emit a R_MIPS_PC32
@@ -48,6 +64,8 @@ VDSO_LDFLAGS := \
$(addprefix -Wl$(comma),$(filter -E%,$(KBUILD_CFLAGS))) \
-nostdlib -shared -Wl,--hash-style=sysv -Wl,--build-id
+CFLAGS_REMOVE_vdso.o = -pg
+
GCOV_PROFILE := n
UBSAN_SANITIZE := n
@@ -96,6 +114,7 @@ $(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi)
$(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE
$(call if_changed,vdsold)
+ $(call if_changed,vdso_check)
$(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \
$(obj)/genvdso FORCE
@@ -134,6 +153,7 @@ $(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE
$(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE
$(call if_changed,vdsold)
+ $(call if_changed,vdso_check)
$(obj)/vdso-o32-image.c: VDSO_NAME := o32
$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \
@@ -174,6 +194,7 @@ $(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE
$(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE
$(call if_changed,vdsold)
+ $(call if_changed,vdso_check)
$(obj)/vdso-n32-image.c: VDSO_NAME := n32
$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \
diff --git a/arch/mips/vdso/elf.S b/arch/mips/vdso/elf.S
index e7543e8f426c..a25cb147f1ca 100644
--- a/arch/mips/vdso/elf.S
+++ b/arch/mips/vdso/elf.S
@@ -4,7 +4,7 @@
* Author: Alex Smith <alex.smith@imgtec.com>
*/
-#include "vdso.h"
+#include <asm/vdso/vdso.h>
#include <asm/isa-rev.h>
diff --git a/arch/mips/vdso/sigreturn.S b/arch/mips/vdso/sigreturn.S
index c3597632874b..e5c0ab98ab46 100644
--- a/arch/mips/vdso/sigreturn.S
+++ b/arch/mips/vdso/sigreturn.S
@@ -4,7 +4,7 @@
* Author: Alex Smith <alex.smith@imgtec.com>
*/
-#include "vdso.h"
+#include <asm/vdso/vdso.h>
#include <uapi/asm/unistd.h>
diff --git a/arch/mips/vdso/vgettimeofday.c b/arch/mips/vdso/vgettimeofday.c
new file mode 100644
index 000000000000..1c46dace041e
--- /dev/null
+++ b/arch/mips/vdso/vgettimeofday.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * MIPS64 and compat userspace implementations of gettimeofday()
+ * and similar.
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ * Copyright (C) 2018 ARM Limited
+ *
+ */
+#include <linux/time.h>
+#include <linux/types.h>
+
+#if _MIPS_SIM != _MIPS_SIM_ABI64
+int __vdso_clock_gettime(clockid_t clock,
+ struct old_timespec32 *ts)
+{
+ return __cvdso_clock_gettime32(clock, ts);
+}
+
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
+ struct timezone *tz)
+{
+ return __cvdso_gettimeofday(tv, tz);
+}
+
+#else
+
+int __vdso_clock_gettime(clockid_t clock,
+ struct __kernel_timespec *ts)
+{
+ return __cvdso_clock_gettime(clock, ts);
+}
+
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
+ struct timezone *tz)
+{
+ return __cvdso_gettimeofday(tv, tz);
+}
+
+#endif
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 19/25] mips: Add support for generic vDSO
2019-06-21 9:52 ` [PATCH v7 19/25] mips: Add support for generic vDSO Vincenzo Frascino
@ 2019-07-26 5:15 ` Paul Burton
2019-07-26 16:29 ` [PATCH 0/2] mips: vdso: Fix Makefile Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Paul Burton @ 2019-07-26 5:15 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton,
Andre Przywara, linux-mips
Hello,
Vincenzo Frascino wrote:
> The mips vDSO library requires some adaptations to take advantage of the
> newly introduced generic vDSO library.
>
> Introduce the following changes:
> - Modification of vdso.c to be compliant with the common vdso datapage
> - Use of lib/vdso for gettimeofday
>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Paul Burton <paul.burton@mips.com>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Applied to mips-next.
Thanks,
Paul
[ This message was auto-generated; if you believe anything is incorrect
then please email paul.burton@mips.com to report it. ]
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH 0/2] mips: vdso: Fix Makefile
2019-07-26 5:15 ` Paul Burton
@ 2019-07-26 16:29 ` Vincenzo Frascino
2019-07-26 16:29 ` [PATCH 1/2] mips: vdso: Fix source path Vincenzo Frascino
` (2 more replies)
0 siblings, 3 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-26 16:29 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara, luto
Consequently to the unified vDSO transition of the MIPS architecture few
compilation issues appeared due to:
- A wrong source path for the configuration environment settings for
the O32 and N32 vDSO library generation.
- A flip/flop vDSO building bug that would cause to rebuild the vDSO
library every second time.
This patch series addresses both the issues providing the respective
fixes.
This patchset is rebased on top of mips-next.
Cc: Paul Burton <paul.burton@mips.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Vincenzo Frascino (2):
mips: vdso: Fix source path
mips: vdso: Fix flip/flop vdso building bug
arch/mips/vdso/Makefile | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
--
2.22.0
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH 1/2] mips: vdso: Fix source path
2019-07-26 16:29 ` [PATCH 0/2] mips: vdso: Fix Makefile Vincenzo Frascino
@ 2019-07-26 16:29 ` Vincenzo Frascino
2019-07-26 16:29 ` [PATCH 2/2] mips: vdso: Fix flip/flop vdso building bug Vincenzo Frascino
2019-07-28 22:20 ` [PATCH 0/2] mips: vdso: Fix Makefile Paul Burton
2 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-26 16:29 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara, luto
The vdso library for o32 and n32 does not compile compile correctly
due to a wrong inclusion path for config-n32-o32-env.c resulting in
the error below:
cc1: fatal error: arch/mips/vdso/config-n32-o32-env.c:
No such file or dnirectory
compilation terminated.
arch/mips/vdso/Makefile:153: recipe for target
'arch/mips/vdso/vgettimeofday-o32.o' failed
make[3]: *** [arch/mips/vdso/vgettimeofday-o32.o] Error 1
scripts/Makefile.build:490: recipe for target 'arch/mips/vdso' failed
Fix the config-n32-o32-env.c inclusion path prepending the $(srctree)
variable.
Cc: Paul Burton <paul.burton@mips.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/mips/vdso/Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index de853c6aab28..6b482ac52e61 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -40,8 +40,8 @@ CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
# config-n32-o32-env.c prepares the environment to build a 32bit vDSO
# library on a 64bit kernel.
# Note: Needs to be included before than the generic library.
-CFLAGS_vgettimeofday-o32.o = -include $(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
-CFLAGS_vgettimeofday-n32.o = -include $(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
+CFLAGS_vgettimeofday-o32.o = -include $(srctree)/$(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
+CFLAGS_vgettimeofday-n32.o = -include $(srctree)/$(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
endif
CFLAGS_REMOVE_vgettimeofday.o = -pg
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH 2/2] mips: vdso: Fix flip/flop vdso building bug
2019-07-26 16:29 ` [PATCH 0/2] mips: vdso: Fix Makefile Vincenzo Frascino
2019-07-26 16:29 ` [PATCH 1/2] mips: vdso: Fix source path Vincenzo Frascino
@ 2019-07-26 16:29 ` Vincenzo Frascino
2019-07-28 22:20 ` [PATCH 0/2] mips: vdso: Fix Makefile Paul Burton
2 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-07-26 16:29 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: catalin.marinas, will.deacon, arnd, linux, ralf, paul.burton,
daniel.lezcano, tglx, salyzyn, pcc, shuah, 0x7f454c46, linux,
huw, sthotton, andre.przywara, luto
Running "make" on an already compiled kernel tree will rebuild the
vdso library even if this has not been modified.
$ make
GEN Makefile
Using linux as source for kernel
CALL linux/scripts/atomic/check-atomics.sh
CALL linux/scripts/checksyscalls.sh
<stdin>:1511:2: warning: #warning syscall clone3 not implemented [-Wcpp]
CHK include/generated/compile.h
VDSO arch/mips/vdso/vdso.so.dbg.raw
OBJCOPY arch/mips/vdso/vdso.so.raw
GENVDSO arch/mips/vdso/vdso-image.c
CC arch/mips/vdso/vdso-image.o
AR arch/mips/vdso/built-in.a
AR arch/mips/built-in.a
CHK include/generated/autoksyms.h
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
AR init/built-in.a
LD vmlinux.o
MODPOST vmlinux.o
MODINFO modules.builtin.modinfo
KSYM .tmp_kallsyms1.o
KSYM .tmp_kallsyms2.o
LD vmlinux
SORTEX vmlinux
SYSMAP System.map
Building modules, stage 2.
ITS arch/mips/boot/vmlinux.gz.its
OBJCOPY arch/mips/boot/vmlinux.bin
MODPOST 7 modules
GZIP arch/mips/boot/vmlinux.bin.gz
ITB arch/mips/boot/vmlinux.gz.itb
The issue is generated by the fact that "if_changed" is called twice
in a single target.
Fix the build bug merging the two commands into a single function.
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/mips/vdso/Makefile | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index 6b482ac52e61..69cfa0a5339e 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -79,11 +79,14 @@ UBSAN_SANITIZE := n
# Shared build commands.
#
+quiet_cmd_vdsold_and_vdso_check = LD $@
+ cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check)
+
quiet_cmd_vdsold = VDSO $@
cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \
-Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@
-quiet_cmd_vdsoas_o_S = AS $@
+quiet_cmd_vdsoas_o_S = AS $@
cmd_vdsoas_o_S = $(CC) $(a_flags) -c -o $@ $<
# Strip rule for the raw .so files
@@ -119,8 +122,7 @@ $(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi)
$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi)
$(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE
- $(call if_changed,vdsold)
- $(call if_changed,vdso_check)
+ $(call if_changed,vdsold_and_vdso_check)
$(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \
$(obj)/genvdso FORCE
@@ -158,8 +160,7 @@ $(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE
$(call if_changed_dep,cpp_lds_S)
$(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE
- $(call if_changed,vdsold)
- $(call if_changed,vdso_check)
+ $(call if_changed,vdsold_and_vdso_check)
$(obj)/vdso-o32-image.c: VDSO_NAME := o32
$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \
@@ -199,8 +200,7 @@ $(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE
$(call if_changed_dep,cpp_lds_S)
$(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE
- $(call if_changed,vdsold)
- $(call if_changed,vdso_check)
+ $(call if_changed,vdsold_and_vdso_check)
$(obj)/vdso-n32-image.c: VDSO_NAME := n32
$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH 0/2] mips: vdso: Fix Makefile
2019-07-26 16:29 ` [PATCH 0/2] mips: vdso: Fix Makefile Vincenzo Frascino
2019-07-26 16:29 ` [PATCH 1/2] mips: vdso: Fix source path Vincenzo Frascino
2019-07-26 16:29 ` [PATCH 2/2] mips: vdso: Fix flip/flop vdso building bug Vincenzo Frascino
@ 2019-07-28 22:20 ` Paul Burton
2 siblings, 0 replies; 108+ messages in thread
From: Paul Burton @ 2019-07-28 22:20 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, catalin.marinas, will.deacon, arnd, linux, ralf,
Paul Burton, daniel.lezcano, tglx, salyzyn, pcc, shuah,
0x7f454c46, linux, huw, sthotton, andre.przywara, luto,
linux-mips
Hello,
Vincenzo Frascino wrote:
> Consequently to the unified vDSO transition of the MIPS architecture few
> compilation issues appeared due to:
> - A wrong source path for the configuration environment settings for
> the O32 and N32 vDSO library generation.
> - A flip/flop vDSO building bug that would cause to rebuild the vDSO
> library every second time.
>
> This patch series addresses both the issues providing the respective
> fixes.
>
> This patchset is rebased on top of mips-next.
>
> Cc: Paul Burton <paul.burton@mips.com>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>
> Vincenzo Frascino (2):
> mips: vdso: Fix source path
> mips: vdso: Fix flip/flop vdso building bug
>
> arch/mips/vdso/Makefile | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
Series applied to mips-next.
Thanks,
Paul
[ This message was auto-generated; if you believe anything is incorrect
then please email paul.burton@mips.com to report it. ]
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH v7 20/25] mips: Add clock_getres entry point
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (18 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 19/25] mips: Add support for generic vDSO Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-07-26 5:15 ` Paul Burton
2019-06-21 9:52 ` [PATCH v7 21/25] mips: Add clock_gettime64 " Vincenzo Frascino
` (6 subsequent siblings)
26 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
The generic vDSO library provides an implementation of clock_getres()
that can be leveraged by each architecture.
Add clock_getres() entry point on mips.
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/mips/include/asm/vdso/gettimeofday.h | 26 +++++++++++++++++++++++
arch/mips/vdso/vdso.lds.S | 1 +
arch/mips/vdso/vgettimeofday.c | 12 +++++++++++
3 files changed, 39 insertions(+)
diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h
index aa20865b288b..c59fe08b0347 100644
--- a/arch/mips/include/asm/vdso/gettimeofday.h
+++ b/arch/mips/include/asm/vdso/gettimeofday.h
@@ -22,6 +22,8 @@
#include <asm/unistd.h>
#include <asm/vdso.h>
+#define VDSO_HAS_CLOCK_GETRES 1
+
#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
static __always_inline long gettimeofday_fallback(
@@ -79,6 +81,30 @@ static __always_inline long clock_gettime_fallback(
return error ? -ret : ret;
}
+static __always_inline int clock_getres_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ register struct __kernel_timespec *ts asm("a1") = _ts;
+ register clockid_t clkid asm("a0") = _clkid;
+ register long ret asm("v0");
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ register long nr asm("v0") = __NR_clock_getres;
+#else
+ register long nr asm("v0") = __NR_clock_getres_time64;
+#endif
+ register long error asm("a3");
+
+ asm volatile(
+ " syscall\n"
+ : "=r" (ret), "=r" (error)
+ : "r" (clkid), "r" (ts), "r" (nr)
+ : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
+ "$14", "$15", "$24", "$25", "hi", "lo", "memory");
+
+ return error ? -ret : ret;
+}
+
#ifdef CONFIG_CSRC_R4K
static __always_inline u64 read_r4k_count(void)
diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S
index 94d90c440590..ad9f2f2c0c97 100644
--- a/arch/mips/vdso/vdso.lds.S
+++ b/arch/mips/vdso/vdso.lds.S
@@ -95,6 +95,7 @@ VERSION
global:
__vdso_clock_gettime;
__vdso_gettimeofday;
+ __vdso_clock_getres;
#endif
local: *;
};
diff --git a/arch/mips/vdso/vgettimeofday.c b/arch/mips/vdso/vgettimeofday.c
index 1c46dace041e..48e1ab32204b 100644
--- a/arch/mips/vdso/vgettimeofday.c
+++ b/arch/mips/vdso/vgettimeofday.c
@@ -23,6 +23,12 @@ int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
return __cvdso_gettimeofday(tv, tz);
}
+int __vdso_clock_getres(clockid_t clock_id,
+ struct old_timespec32 *res)
+{
+ return __cvdso_clock_getres_time32(clock_id, res);
+}
+
#else
int __vdso_clock_gettime(clockid_t clock,
@@ -37,4 +43,10 @@ int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
return __cvdso_gettimeofday(tv, tz);
}
+int __vdso_clock_getres(clockid_t clock_id,
+ struct __kernel_timespec *res)
+{
+ return __cvdso_clock_getres(clock_id, res);
+}
+
#endif
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 20/25] mips: Add clock_getres entry point
2019-06-21 9:52 ` [PATCH v7 20/25] mips: Add clock_getres entry point Vincenzo Frascino
@ 2019-07-26 5:15 ` Paul Burton
0 siblings, 0 replies; 108+ messages in thread
From: Paul Burton @ 2019-07-26 5:15 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton,
Andre Przywara, linux-mips
Hello,
Vincenzo Frascino wrote:
> The generic vDSO library provides an implementation of clock_getres()
> that can be leveraged by each architecture.
>
> Add clock_getres() entry point on mips.
>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Paul Burton <paul.burton@mips.com>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Applied to mips-next.
Thanks,
Paul
[ This message was auto-generated; if you believe anything is incorrect
then please email paul.burton@mips.com to report it. ]
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH v7 21/25] mips: Add clock_gettime64 entry point
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (19 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 20/25] mips: Add clock_getres entry point Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-07-26 5:15 ` Paul Burton
2019-06-21 9:52 ` [PATCH v7 22/25] x86: Add support for generic vDSO Vincenzo Frascino
` (5 subsequent siblings)
26 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
With the release of Linux 5.1 has been added a new syscall,
clock_gettime64, that provided a 64 bit time value for a specified
clock_ID to make the kernel Y2038 safe on 32 bit architectures.
Update the mips32 specific vDSO library accordingly with what it has
been done for the kernel syscall exposing the clock_gettime64 entry
point.
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/mips/vdso/vdso.lds.S | 3 +++
arch/mips/vdso/vgettimeofday.c | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S
index ad9f2f2c0c97..da4627430aba 100644
--- a/arch/mips/vdso/vdso.lds.S
+++ b/arch/mips/vdso/vdso.lds.S
@@ -96,6 +96,9 @@ VERSION
__vdso_clock_gettime;
__vdso_gettimeofday;
__vdso_clock_getres;
+#if _MIPS_SIM != _MIPS_SIM_ABI64
+ __vdso_clock_gettime64;
+#endif
#endif
local: *;
};
diff --git a/arch/mips/vdso/vgettimeofday.c b/arch/mips/vdso/vgettimeofday.c
index 48e1ab32204b..6ebdc37c89fc 100644
--- a/arch/mips/vdso/vgettimeofday.c
+++ b/arch/mips/vdso/vgettimeofday.c
@@ -29,6 +29,12 @@ int __vdso_clock_getres(clockid_t clock_id,
return __cvdso_clock_getres_time32(clock_id, res);
}
+int __vdso_clock_gettime64(clockid_t clock,
+ struct __kernel_timespec *ts)
+{
+ return __cvdso_clock_gettime(clock, ts);
+}
+
#else
int __vdso_clock_gettime(clockid_t clock,
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 21/25] mips: Add clock_gettime64 entry point
2019-06-21 9:52 ` [PATCH v7 21/25] mips: Add clock_gettime64 " Vincenzo Frascino
@ 2019-07-26 5:15 ` Paul Burton
0 siblings, 0 replies; 108+ messages in thread
From: Paul Burton @ 2019-07-26 5:15 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton,
Andre Przywara, linux-mips
Hello,
Vincenzo Frascino wrote:
> With the release of Linux 5.1 has been added a new syscall,
> clock_gettime64, that provided a 64 bit time value for a specified
> clock_ID to make the kernel Y2038 safe on 32 bit architectures.
>
> Update the mips32 specific vDSO library accordingly with what it has
> been done for the kernel syscall exposing the clock_gettime64 entry
> point.
>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Paul Burton <paul.burton@mips.com>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Applied to mips-next.
Thanks,
Paul
[ This message was auto-generated; if you believe anything is incorrect
then please email paul.burton@mips.com to report it. ]
^ permalink raw reply [flat|nested] 108+ messages in thread
* [PATCH v7 22/25] x86: Add support for generic vDSO
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (20 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 21/25] mips: Add clock_gettime64 " Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 23/25] x86: Add clock_getres entry point Vincenzo Frascino
` (4 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
The x86 vDSO library requires some adaptations to take advantage of the
newly introduced generic vDSO library.
Introduce the following changes:
- Modification of vdso.c to be compliant with the common vdso datapage
- Use of lib/vdso for gettimeofday
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/x86/Kconfig | 3 +
arch/x86/entry/vdso/Makefile | 9 +
arch/x86/entry/vdso/vclock_gettime.c | 241 +++--------------------
arch/x86/entry/vdso/vdsox32.lds.S | 1 +
arch/x86/entry/vsyscall/Makefile | 2 -
arch/x86/entry/vsyscall/vsyscall_gtod.c | 83 --------
arch/x86/include/asm/pvclock.h | 2 +-
arch/x86/include/asm/vdso/gettimeofday.h | 175 ++++++++++++++++
arch/x86/include/asm/vdso/vsyscall.h | 44 +++++
arch/x86/include/asm/vgtod.h | 75 +------
arch/x86/include/asm/vvar.h | 7 +-
arch/x86/kernel/pvclock.c | 1 +
12 files changed, 270 insertions(+), 373 deletions(-)
delete mode 100644 arch/x86/entry/vsyscall/vsyscall_gtod.c
create mode 100644 arch/x86/include/asm/vdso/gettimeofday.h
create mode 100644 arch/x86/include/asm/vdso/vsyscall.h
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2bbbd4d1ba31..51a98d6eae8e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -17,6 +17,7 @@ config X86_32
select HAVE_DEBUG_STACKOVERFLOW
select MODULES_USE_ELF_REL
select OLD_SIGACTION
+ select GENERIC_VDSO_32
config X86_64
def_bool y
@@ -121,6 +122,7 @@ config X86
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
+ select GENERIC_GETTIMEOFDAY
select HARDLOCKUP_CHECK_TIMESTAMP if X86_64
select HAVE_ACPI_APEI if ACPI
select HAVE_ACPI_APEI_NMI if ACPI
@@ -202,6 +204,7 @@ config X86
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UNSTABLE_SCHED_CLOCK
select HAVE_USER_RETURN_NOTIFIER
+ select HAVE_GENERIC_VDSO
select HOTPLUG_SMT if SMP
select IRQ_FORCED_THREADING
select NEED_SG_DMA_LENGTH
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index 42fe42e82baf..39106111be86 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -3,6 +3,12 @@
# Building vDSO images for x86.
#
+# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+# the inclusion of generic Makefile.
+ARCH_REL_TYPE_ABS := R_X86_64_JUMP_SLOT|R_X86_64_GLOB_DAT|R_X86_64_RELATIVE|
+ARCH_REL_TYPE_ABS += R_386_GLOB_DAT|R_386_JMP_SLOT|R_386_RELATIVE
+include $(srctree)/lib/vdso/Makefile
+
KBUILD_CFLAGS += $(DISABLE_LTO)
KASAN_SANITIZE := n
UBSAN_SANITIZE := n
@@ -51,6 +57,7 @@ VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -soname linux-vdso.so.1 --no-undefined \
$(obj)/vdso64.so.dbg: $(obj)/vdso.lds $(vobjs) FORCE
$(call if_changed,vdso)
+ $(call if_changed,vdso_check)
HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/$(SUBARCH)/include/uapi
hostprogs-y += vdso2c
@@ -121,6 +128,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
$(obj)/vdsox32.so.dbg: $(obj)/vdsox32.lds $(vobjx32s) FORCE
$(call if_changed,vdso)
+ $(call if_changed,vdso_check)
CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -soname linux-gate.so.1
@@ -160,6 +168,7 @@ $(obj)/vdso32.so.dbg: FORCE \
$(obj)/vdso32/system_call.o \
$(obj)/vdso32/sigreturn.o
$(call if_changed,vdso)
+ $(call if_changed,vdso_check)
#
# The DSO images are built using a special linker script.
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
index 310e7bf59ad2..4a7ef4ca4f52 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -1,241 +1,58 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright 2006 Andi Kleen, SUSE Labs.
- *
* Fast user context implementation of clock_gettime, gettimeofday, and time.
*
+ * Copyright 2006 Andi Kleen, SUSE Labs.
+ * Copyright 2019 ARM Limited
+ *
* 32 Bit compat layer by Stefani Seibold <stefani@seibold.net>
* sponsored by Rohde & Schwarz GmbH & Co. KG Munich/Germany
- *
- * The code should have no internal unresolved relocations.
- * Check with readelf after changing.
*/
-
-#include <uapi/linux/time.h>
-#include <asm/vgtod.h>
-#include <asm/vvar.h>
-#include <asm/unistd.h>
-#include <asm/msr.h>
-#include <asm/pvclock.h>
-#include <asm/mshyperv.h>
-#include <linux/math64.h>
#include <linux/time.h>
#include <linux/kernel.h>
-#include <clocksource/hyperv_timer.h>
+#include <linux/types.h>
-#define gtod (&VVAR(vsyscall_gtod_data))
+#include "../../../../lib/vdso/gettimeofday.c"
-extern int __vdso_clock_gettime(clockid_t clock, struct timespec *ts);
-extern int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz);
+extern int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
extern time_t __vdso_time(time_t *t);
-#ifdef CONFIG_PARAVIRT_CLOCK
-extern u8 pvclock_page[PAGE_SIZE]
- __attribute__((visibility("hidden")));
-#endif
-
-#ifdef CONFIG_HYPERV_TSCPAGE
-extern u8 hvclock_page[PAGE_SIZE]
- __attribute__((visibility("hidden")));
-#endif
-
-#ifndef BUILD_VDSO32
-
-notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
-{
- long ret;
- asm ("syscall" : "=a" (ret), "=m" (*ts) :
- "0" (__NR_clock_gettime), "D" (clock), "S" (ts) :
- "rcx", "r11");
- return ret;
-}
-
-#else
-
-notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
+ struct timezone *tz)
{
- long ret;
-
- asm (
- "mov %%ebx, %%edx \n"
- "mov %[clock], %%ebx \n"
- "call __kernel_vsyscall \n"
- "mov %%edx, %%ebx \n"
- : "=a" (ret), "=m" (*ts)
- : "0" (__NR_clock_gettime), [clock] "g" (clock), "c" (ts)
- : "edx");
- return ret;
+ return __cvdso_gettimeofday(tv, tz);
}
+int gettimeofday(struct __kernel_old_timeval *, struct timezone *)
+ __attribute__((weak, alias("__vdso_gettimeofday")));
-#endif
-
-#ifdef CONFIG_PARAVIRT_CLOCK
-static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void)
+time_t __vdso_time(time_t *t)
{
- return (const struct pvclock_vsyscall_time_info *)&pvclock_page;
+ return __cvdso_time(t);
}
+time_t time(time_t *t)
+ __attribute__((weak, alias("__vdso_time")));
-static notrace u64 vread_pvclock(void)
-{
- const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti;
- u32 version;
- u64 ret;
-
- /*
- * Note: The kernel and hypervisor must guarantee that cpu ID
- * number maps 1:1 to per-CPU pvclock time info.
- *
- * Because the hypervisor is entirely unaware of guest userspace
- * preemption, it cannot guarantee that per-CPU pvclock time
- * info is updated if the underlying CPU changes or that that
- * version is increased whenever underlying CPU changes.
- *
- * On KVM, we are guaranteed that pvti updates for any vCPU are
- * atomic as seen by *all* vCPUs. This is an even stronger
- * guarantee than we get with a normal seqlock.
- *
- * On Xen, we don't appear to have that guarantee, but Xen still
- * supplies a valid seqlock using the version field.
- *
- * We only do pvclock vdso timing at all if
- * PVCLOCK_TSC_STABLE_BIT is set, and we interpret that bit to
- * mean that all vCPUs have matching pvti and that the TSC is
- * synced, so we can just look at vCPU 0's pvti.
- */
-
- do {
- version = pvclock_read_begin(pvti);
-
- if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT)))
- return U64_MAX;
- ret = __pvclock_read_cycles(pvti, rdtsc_ordered());
- } while (pvclock_read_retry(pvti, version));
+#if defined(CONFIG_X86_64) && !defined(BUILD_VDSO32_64)
+/* both 64-bit and x32 use these */
+extern int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts);
- return ret;
-}
-#endif
-#ifdef CONFIG_HYPERV_TSCPAGE
-static notrace u64 vread_hvclock(void)
+int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
{
- const struct ms_hyperv_tsc_page *tsc_pg =
- (const struct ms_hyperv_tsc_page *)&hvclock_page;
-
- return hv_read_tsc_page(tsc_pg);
+ return __cvdso_clock_gettime(clock, ts);
}
-#endif
-
-notrace static inline u64 vgetcyc(int mode)
-{
- if (mode == VCLOCK_TSC)
- return (u64)rdtsc_ordered();
-#ifdef CONFIG_PARAVIRT_CLOCK
- else if (mode == VCLOCK_PVCLOCK)
- return vread_pvclock();
-#endif
-#ifdef CONFIG_HYPERV_TSCPAGE
- else if (mode == VCLOCK_HVCLOCK)
- return vread_hvclock();
-#endif
- return U64_MAX;
-}
-
-notrace static int do_hres(clockid_t clk, struct timespec *ts)
-{
- struct vgtod_ts *base = >od->basetime[clk];
- u64 cycles, last, sec, ns;
- unsigned int seq;
-
- do {
- seq = gtod_read_begin(gtod);
- cycles = vgetcyc(gtod->vclock_mode);
- ns = base->nsec;
- last = gtod->cycle_last;
- if (unlikely((s64)cycles < 0))
- return vdso_fallback_gettime(clk, ts);
- if (cycles > last)
- ns += (cycles - last) * gtod->mult;
- ns >>= gtod->shift;
- sec = base->sec;
- } while (unlikely(gtod_read_retry(gtod, seq)));
-
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
-notrace static void do_coarse(clockid_t clk, struct timespec *ts)
-{
- struct vgtod_ts *base = >od->basetime[clk];
- unsigned int seq;
+int clock_gettime(clockid_t, struct __kernel_timespec *)
+ __attribute__((weak, alias("__vdso_clock_gettime")));
- do {
- seq = gtod_read_begin(gtod);
- ts->tv_sec = base->sec;
- ts->tv_nsec = base->nsec;
- } while (unlikely(gtod_read_retry(gtod, seq)));
-}
+#else
+/* i386 only */
+extern int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts);
-notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
+int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
{
- unsigned int msk;
-
- /* Sort out negative (CPU/FD) and invalid clocks */
- if (unlikely((unsigned int) clock >= MAX_CLOCKS))
- return vdso_fallback_gettime(clock, ts);
-
- /*
- * Convert the clockid to a bitmask and use it to check which
- * clocks are handled in the VDSO directly.
- */
- msk = 1U << clock;
- if (likely(msk & VGTOD_HRES)) {
- return do_hres(clock, ts);
- } else if (msk & VGTOD_COARSE) {
- do_coarse(clock, ts);
- return 0;
- }
- return vdso_fallback_gettime(clock, ts);
+ return __cvdso_clock_gettime32(clock, ts);
}
-
-int clock_gettime(clockid_t, struct timespec *)
+int clock_gettime(clockid_t, struct old_timespec32 *)
__attribute__((weak, alias("__vdso_clock_gettime")));
-notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
-{
- if (likely(tv != NULL)) {
- struct timespec *ts = (struct timespec *) tv;
-
- do_hres(CLOCK_REALTIME, ts);
- tv->tv_usec /= 1000;
- }
- if (unlikely(tz != NULL)) {
- tz->tz_minuteswest = gtod->tz_minuteswest;
- tz->tz_dsttime = gtod->tz_dsttime;
- }
-
- return 0;
-}
-int gettimeofday(struct timeval *, struct timezone *)
- __attribute__((weak, alias("__vdso_gettimeofday")));
-
-/*
- * This will break when the xtime seconds get inaccurate, but that is
- * unlikely
- */
-notrace time_t __vdso_time(time_t *t)
-{
- /* This is atomic on x86 so we don't need any locks. */
- time_t result = READ_ONCE(gtod->basetime[CLOCK_REALTIME].sec);
-
- if (t)
- *t = result;
- return result;
-}
-time_t time(time_t *t)
- __attribute__((weak, alias("__vdso_time")));
+#endif
diff --git a/arch/x86/entry/vdso/vdsox32.lds.S b/arch/x86/entry/vdso/vdsox32.lds.S
index 05cd1c5c4a15..16a8050a4fb6 100644
--- a/arch/x86/entry/vdso/vdsox32.lds.S
+++ b/arch/x86/entry/vdso/vdsox32.lds.S
@@ -21,6 +21,7 @@ VERSION {
__vdso_gettimeofday;
__vdso_getcpu;
__vdso_time;
+ __vdso_clock_getres;
local: *;
};
}
diff --git a/arch/x86/entry/vsyscall/Makefile b/arch/x86/entry/vsyscall/Makefile
index 1ac4dd116c26..93c1b3e949a7 100644
--- a/arch/x86/entry/vsyscall/Makefile
+++ b/arch/x86/entry/vsyscall/Makefile
@@ -2,7 +2,5 @@
#
# Makefile for the x86 low level vsyscall code
#
-obj-y := vsyscall_gtod.o
-
obj-$(CONFIG_X86_VSYSCALL_EMULATION) += vsyscall_64.o vsyscall_emu_64.o
diff --git a/arch/x86/entry/vsyscall/vsyscall_gtod.c b/arch/x86/entry/vsyscall/vsyscall_gtod.c
deleted file mode 100644
index cfcdba082feb..000000000000
--- a/arch/x86/entry/vsyscall/vsyscall_gtod.c
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
- * Copyright 2003 Andi Kleen, SuSE Labs.
- *
- * Modified for x86 32 bit architecture by
- * Stefani Seibold <stefani@seibold.net>
- * sponsored by Rohde & Schwarz GmbH & Co. KG Munich/Germany
- *
- * Thanks to hpa@transmeta.com for some useful hint.
- * Special thanks to Ingo Molnar for his early experience with
- * a different vsyscall implementation for Linux/IA32 and for the name.
- *
- */
-
-#include <linux/timekeeper_internal.h>
-#include <asm/vgtod.h>
-#include <asm/vvar.h>
-
-int vclocks_used __read_mostly;
-
-DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data);
-
-void update_vsyscall_tz(void)
-{
- vsyscall_gtod_data.tz_minuteswest = sys_tz.tz_minuteswest;
- vsyscall_gtod_data.tz_dsttime = sys_tz.tz_dsttime;
-}
-
-void update_vsyscall(struct timekeeper *tk)
-{
- int vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
- struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data;
- struct vgtod_ts *base;
- u64 nsec;
-
- /* Mark the new vclock used. */
- BUILD_BUG_ON(VCLOCK_MAX >= 32);
- WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << vclock_mode));
-
- gtod_write_begin(vdata);
-
- /* copy vsyscall data */
- vdata->vclock_mode = vclock_mode;
- vdata->cycle_last = tk->tkr_mono.cycle_last;
- vdata->mask = tk->tkr_mono.mask;
- vdata->mult = tk->tkr_mono.mult;
- vdata->shift = tk->tkr_mono.shift;
-
- base = &vdata->basetime[CLOCK_REALTIME];
- base->sec = tk->xtime_sec;
- base->nsec = tk->tkr_mono.xtime_nsec;
-
- base = &vdata->basetime[CLOCK_TAI];
- base->sec = tk->xtime_sec + (s64)tk->tai_offset;
- base->nsec = tk->tkr_mono.xtime_nsec;
-
- base = &vdata->basetime[CLOCK_MONOTONIC];
- base->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
- nsec = tk->tkr_mono.xtime_nsec;
- nsec += ((u64)tk->wall_to_monotonic.tv_nsec << tk->tkr_mono.shift);
- while (nsec >= (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
- nsec -= ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift;
- base->sec++;
- }
- base->nsec = nsec;
-
- base = &vdata->basetime[CLOCK_REALTIME_COARSE];
- base->sec = tk->xtime_sec;
- base->nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
-
- base = &vdata->basetime[CLOCK_MONOTONIC_COARSE];
- base->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
- nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
- nsec += tk->wall_to_monotonic.tv_nsec;
- while (nsec >= NSEC_PER_SEC) {
- nsec -= NSEC_PER_SEC;
- base->sec++;
- }
- base->nsec = nsec;
-
- gtod_write_end(vdata);
-}
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
index b6033680d458..19b695ff2c68 100644
--- a/arch/x86/include/asm/pvclock.h
+++ b/arch/x86/include/asm/pvclock.h
@@ -2,7 +2,7 @@
#ifndef _ASM_X86_PVCLOCK_H
#define _ASM_X86_PVCLOCK_H
-#include <linux/clocksource.h>
+#include <asm/clocksource.h>
#include <asm/pvclock-abi.h>
/* some helper functions for xen and kvm pv clock sources */
diff --git a/arch/x86/include/asm/vdso/gettimeofday.h b/arch/x86/include/asm/vdso/gettimeofday.h
new file mode 100644
index 000000000000..a274d4fea7a5
--- /dev/null
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Fast user context implementation of clock_gettime, gettimeofday, and time.
+ *
+ * Copyright (C) 2019 ARM Limited.
+ * Copyright 2006 Andi Kleen, SUSE Labs.
+ * 32 Bit compat layer by Stefani Seibold <stefani@seibold.net>
+ * sponsored by Rohde & Schwarz GmbH & Co. KG Munich/Germany
+ */
+#ifndef __ASM_VDSO_GETTIMEOFDAY_H
+#define __ASM_VDSO_GETTIMEOFDAY_H
+
+#ifndef __ASSEMBLY__
+
+#include <clocksource/hyperv_timer.h>
+#include <uapi/linux/time.h>
+#include <asm/vgtod.h>
+#include <asm/vvar.h>
+#include <asm/unistd.h>
+#include <asm/msr.h>
+#include <asm/pvclock.h>
+
+#define __vdso_data (VVAR(_vdso_data))
+
+#define VDSO_HAS_TIME 1
+
+#ifdef CONFIG_PARAVIRT_CLOCK
+extern u8 pvclock_page[PAGE_SIZE]
+ __attribute__((visibility("hidden")));
+#endif
+
+#ifdef CONFIG_HYPERV_TSCPAGE
+extern u8 hvclock_page[PAGE_SIZE]
+ __attribute__((visibility("hidden")));
+#endif
+
+#ifndef BUILD_VDSO32
+
+static __always_inline long clock_gettime_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ long ret;
+ asm ("syscall" : "=a" (ret), "=m" (*_ts) :
+ "0" (__NR_clock_gettime), "D" (_clkid), "S" (_ts) :
+ "rcx", "r11");
+ return ret;
+}
+
+static __always_inline long gettimeofday_fallback(
+ struct __kernel_old_timeval *_tv,
+ struct timezone *_tz)
+{
+ long ret;
+ asm("syscall" : "=a" (ret) :
+ "0" (__NR_gettimeofday), "D" (_tv), "S" (_tz) : "memory");
+ return ret;
+}
+
+#else
+
+static __always_inline long clock_gettime_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ long ret;
+
+ asm (
+ "mov %%ebx, %%edx \n"
+ "mov %[clock], %%ebx \n"
+ "call __kernel_vsyscall \n"
+ "mov %%edx, %%ebx \n"
+ : "=a" (ret), "=m" (*_ts)
+ : "0" (__NR_clock_gettime64), [clock] "g" (_clkid), "c" (_ts)
+ : "edx");
+ return ret;
+}
+
+static __always_inline long gettimeofday_fallback(
+ struct __kernel_old_timeval *_tv,
+ struct timezone *_tz)
+{
+ long ret;
+ asm(
+ "mov %%ebx, %%edx \n"
+ "mov %2, %%ebx \n"
+ "call __kernel_vsyscall \n"
+ "mov %%edx, %%ebx \n"
+ : "=a" (ret)
+ : "0" (__NR_gettimeofday), "g" (_tv), "c" (_tz)
+ : "memory", "edx");
+ return ret;
+}
+
+#endif
+
+#ifdef CONFIG_PARAVIRT_CLOCK
+static const struct pvclock_vsyscall_time_info *get_pvti0(void)
+{
+ return (const struct pvclock_vsyscall_time_info *)&pvclock_page;
+}
+
+static u64 vread_pvclock(void)
+{
+ const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti;
+ u32 version;
+ u64 ret;
+
+ /*
+ * Note: The kernel and hypervisor must guarantee that cpu ID
+ * number maps 1:1 to per-CPU pvclock time info.
+ *
+ * Because the hypervisor is entirely unaware of guest userspace
+ * preemption, it cannot guarantee that per-CPU pvclock time
+ * info is updated if the underlying CPU changes or that that
+ * version is increased whenever underlying CPU changes.
+ *
+ * On KVM, we are guaranteed that pvti updates for any vCPU are
+ * atomic as seen by *all* vCPUs. This is an even stronger
+ * guarantee than we get with a normal seqlock.
+ *
+ * On Xen, we don't appear to have that guarantee, but Xen still
+ * supplies a valid seqlock using the version field.
+ *
+ * We only do pvclock vdso timing at all if
+ * PVCLOCK_TSC_STABLE_BIT is set, and we interpret that bit to
+ * mean that all vCPUs have matching pvti and that the TSC is
+ * synced, so we can just look at vCPU 0's pvti.
+ */
+
+ do {
+ version = pvclock_read_begin(pvti);
+
+ if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT)))
+ return U64_MAX;
+
+ ret = __pvclock_read_cycles(pvti, rdtsc_ordered());
+ } while (pvclock_read_retry(pvti, version));
+
+ return ret;
+}
+#endif
+#ifdef CONFIG_HYPERV_TSCPAGE
+static u64 vread_hvclock(void)
+{
+ const struct ms_hyperv_tsc_page *tsc_pg =
+ (const struct ms_hyperv_tsc_page *)&hvclock_page;
+
+ return hv_read_tsc_page(tsc_pg);
+}
+#endif
+
+static inline u64 __arch_get_hw_counter(s32 clock_mode)
+{
+ if (clock_mode == VCLOCK_TSC)
+ return (u64)rdtsc_ordered();
+#ifdef CONFIG_PARAVIRT_CLOCK
+ else if (clock_mode == VCLOCK_PVCLOCK)
+ return vread_pvclock();
+#endif
+#ifdef CONFIG_HYPERV_TSCPAGE
+ else if (clock_mode == VCLOCK_HVCLOCK)
+ return vread_hvclock();
+#endif
+ return U64_MAX;
+}
+
+static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
+{
+ return __vdso_data;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h
new file mode 100644
index 000000000000..0026ab2123ce
--- /dev/null
+++ b/arch/x86/include/asm/vdso/vsyscall.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_VDSO_VSYSCALL_H
+#define __ASM_VDSO_VSYSCALL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/hrtimer.h>
+#include <linux/timekeeper_internal.h>
+#include <vdso/datapage.h>
+#include <asm/vgtod.h>
+#include <asm/vvar.h>
+
+int vclocks_used __read_mostly;
+
+DEFINE_VVAR(struct vdso_data, _vdso_data);
+/*
+ * Update the vDSO data page to keep in sync with kernel timekeeping.
+ */
+static __always_inline
+struct vdso_data *__x86_get_k_vdso_data(void)
+{
+ return _vdso_data;
+}
+#define __arch_get_k_vdso_data __x86_get_k_vdso_data
+
+static __always_inline
+int __x86_get_clock_mode(struct timekeeper *tk)
+{
+ int vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
+
+ /* Mark the new vclock used. */
+ BUILD_BUG_ON(VCLOCK_MAX >= 32);
+ WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << vclock_mode));
+
+ return vclock_mode;
+}
+#define __arch_get_clock_mode __x86_get_clock_mode
+
+/* The asm-generic header needs to be included after the definitions above */
+#include <asm-generic/vdso/vsyscall.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_VSYSCALL_H */
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h
index 913a133f8e6f..a2638c6124ed 100644
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -3,7 +3,9 @@
#define _ASM_X86_VGTOD_H
#include <linux/compiler.h>
-#include <linux/clocksource.h>
+#include <asm/clocksource.h>
+#include <vdso/datapage.h>
+#include <vdso/helpers.h>
#include <uapi/linux/time.h>
@@ -13,81 +15,10 @@ typedef u64 gtod_long_t;
typedef unsigned long gtod_long_t;
#endif
-/*
- * There is one of these objects in the vvar page for each
- * vDSO-accelerated clockid. For high-resolution clocks, this encodes
- * the time corresponding to vsyscall_gtod_data.cycle_last. For coarse
- * clocks, this encodes the actual time.
- *
- * To confuse the reader, for high-resolution clocks, nsec is left-shifted
- * by vsyscall_gtod_data.shift.
- */
-struct vgtod_ts {
- u64 sec;
- u64 nsec;
-};
-
-#define VGTOD_BASES (CLOCK_TAI + 1)
-#define VGTOD_HRES (BIT(CLOCK_REALTIME) | BIT(CLOCK_MONOTONIC) | BIT(CLOCK_TAI))
-#define VGTOD_COARSE (BIT(CLOCK_REALTIME_COARSE) | BIT(CLOCK_MONOTONIC_COARSE))
-
-/*
- * vsyscall_gtod_data will be accessed by 32 and 64 bit code at the same time
- * so be carefull by modifying this structure.
- */
-struct vsyscall_gtod_data {
- unsigned int seq;
-
- int vclock_mode;
- u64 cycle_last;
- u64 mask;
- u32 mult;
- u32 shift;
-
- struct vgtod_ts basetime[VGTOD_BASES];
-
- int tz_minuteswest;
- int tz_dsttime;
-};
-extern struct vsyscall_gtod_data vsyscall_gtod_data;
-
extern int vclocks_used;
static inline bool vclock_was_used(int vclock)
{
return READ_ONCE(vclocks_used) & (1 << vclock);
}
-static inline unsigned int gtod_read_begin(const struct vsyscall_gtod_data *s)
-{
- unsigned int ret;
-
-repeat:
- ret = READ_ONCE(s->seq);
- if (unlikely(ret & 1)) {
- cpu_relax();
- goto repeat;
- }
- smp_rmb();
- return ret;
-}
-
-static inline int gtod_read_retry(const struct vsyscall_gtod_data *s,
- unsigned int start)
-{
- smp_rmb();
- return unlikely(s->seq != start);
-}
-
-static inline void gtod_write_begin(struct vsyscall_gtod_data *s)
-{
- ++s->seq;
- smp_wmb();
-}
-
-static inline void gtod_write_end(struct vsyscall_gtod_data *s)
-{
- smp_wmb();
- ++s->seq;
-}
-
#endif /* _ASM_X86_VGTOD_H */
diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h
index e474f5c6e387..32f5d9a0b90e 100644
--- a/arch/x86/include/asm/vvar.h
+++ b/arch/x86/include/asm/vvar.h
@@ -32,19 +32,20 @@
extern char __vvar_page;
#define DECLARE_VVAR(offset, type, name) \
- extern type vvar_ ## name __attribute__((visibility("hidden")));
+ extern type vvar_ ## name[CS_BASES] \
+ __attribute__((visibility("hidden")));
#define VVAR(name) (vvar_ ## name)
#define DEFINE_VVAR(type, name) \
- type name \
+ type name[CS_BASES] \
__attribute__((section(".vvar_" #name), aligned(16))) __visible
#endif
/* DECLARE_VVAR(offset, type, name) */
-DECLARE_VVAR(128, struct vsyscall_gtod_data, vsyscall_gtod_data)
+DECLARE_VVAR(128, struct vdso_data, _vdso_data)
#undef DECLARE_VVAR
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 0ff3e294d0e5..10125358b9c4 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -3,6 +3,7 @@
*/
+#include <linux/clocksource.h>
#include <linux/kernel.h>
#include <linux/percpu.h>
#include <linux/notifier.h>
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 23/25] x86: Add clock_getres entry point
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (21 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 22/25] x86: Add support for generic vDSO Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 24/25] x86: Add clock_gettime64 " Vincenzo Frascino
` (3 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
The generic vDSO library provides an implementation of clock_getres()
that can be leveraged by each architecture.
Add clock_getres() entry point on x86.
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/x86/entry/vdso/vclock_gettime.c | 17 ++++++++++++++
arch/x86/entry/vdso/vdso.lds.S | 2 ++
arch/x86/entry/vdso/vdso32/vdso32.lds.S | 1 +
arch/x86/include/asm/vdso/gettimeofday.h | 30 ++++++++++++++++++++++++
4 files changed, 50 insertions(+)
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
index 4a7ef4ca4f52..de9212a4833e 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -36,6 +36,7 @@ time_t time(time_t *t)
#if defined(CONFIG_X86_64) && !defined(BUILD_VDSO32_64)
/* both 64-bit and x32 use these */
extern int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts);
+extern int __vdso_clock_getres(clockid_t clock, struct __kernel_timespec *res);
int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
{
@@ -44,9 +45,18 @@ int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
int clock_gettime(clockid_t, struct __kernel_timespec *)
__attribute__((weak, alias("__vdso_clock_gettime")));
+int __vdso_clock_getres(clockid_t clock,
+ struct __kernel_timespec *res)
+{
+ return __cvdso_clock_getres(clock, res);
+}
+int clock_getres(clockid_t, struct __kernel_timespec *)
+ __attribute__((weak, alias("__vdso_clock_getres")));
+
#else
/* i386 only */
extern int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts);
+extern int __vdso_clock_getres(clockid_t clock, struct old_timespec32 *res);
int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
{
@@ -55,4 +65,11 @@ int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
int clock_gettime(clockid_t, struct old_timespec32 *)
__attribute__((weak, alias("__vdso_clock_gettime")));
+int __vdso_clock_getres(clockid_t clock,
+ struct old_timespec32 *res)
+{
+ return __cvdso_clock_getres_time32(clock, res);
+}
+int clock_getres(clockid_t, struct old_timespec32 *)
+ __attribute__((weak, alias("__vdso_clock_getres")));
#endif
diff --git a/arch/x86/entry/vdso/vdso.lds.S b/arch/x86/entry/vdso/vdso.lds.S
index d3a2dce4cfa9..36b644e16272 100644
--- a/arch/x86/entry/vdso/vdso.lds.S
+++ b/arch/x86/entry/vdso/vdso.lds.S
@@ -25,6 +25,8 @@ VERSION {
__vdso_getcpu;
time;
__vdso_time;
+ clock_getres;
+ __vdso_clock_getres;
local: *;
};
}
diff --git a/arch/x86/entry/vdso/vdso32/vdso32.lds.S b/arch/x86/entry/vdso/vdso32/vdso32.lds.S
index 422764a81d32..991b26cc855b 100644
--- a/arch/x86/entry/vdso/vdso32/vdso32.lds.S
+++ b/arch/x86/entry/vdso/vdso32/vdso32.lds.S
@@ -26,6 +26,7 @@ VERSION
__vdso_clock_gettime;
__vdso_gettimeofday;
__vdso_time;
+ __vdso_clock_getres;
};
LINUX_2.5 {
diff --git a/arch/x86/include/asm/vdso/gettimeofday.h b/arch/x86/include/asm/vdso/gettimeofday.h
index a274d4fea7a5..df8c8dfadfa7 100644
--- a/arch/x86/include/asm/vdso/gettimeofday.h
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -24,6 +24,8 @@
#define VDSO_HAS_TIME 1
+#define VDSO_HAS_CLOCK_GETRES 1
+
#ifdef CONFIG_PARAVIRT_CLOCK
extern u8 pvclock_page[PAGE_SIZE]
__attribute__((visibility("hidden")));
@@ -57,6 +59,17 @@ static __always_inline long gettimeofday_fallback(
return ret;
}
+static __always_inline long clock_getres_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ long ret;
+ asm ("syscall" : "=a" (ret), "=m" (*_ts) :
+ "0" (__NR_clock_getres), "D" (_clkid), "S" (_ts) :
+ "rcx", "r11");
+ return ret;
+}
+
#else
static __always_inline long clock_gettime_fallback(
@@ -92,6 +105,23 @@ static __always_inline long gettimeofday_fallback(
return ret;
}
+static __always_inline long clock_getres_fallback(
+ clockid_t _clkid,
+ struct __kernel_timespec *_ts)
+{
+ long ret;
+
+ asm (
+ "mov %%ebx, %%edx \n"
+ "mov %[clock], %%ebx \n"
+ "call __kernel_vsyscall \n"
+ "mov %%edx, %%ebx \n"
+ : "=a" (ret), "=m" (*_ts)
+ : "0" (__NR_clock_getres_time64), [clock] "g" (_clkid), "c" (_ts)
+ : "edx");
+ return ret;
+}
+
#endif
#ifdef CONFIG_PARAVIRT_CLOCK
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 24/25] x86: Add clock_gettime64 entry point
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (22 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 23/25] x86: Add clock_getres entry point Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-21 9:52 ` [PATCH v7 25/25] kselftest: Extend vDSO selftest Vincenzo Frascino
` (2 subsequent siblings)
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
With the release of Linux 5.1 has been added a new syscall,
clock_gettime64, that provided a 64 bit time value for a specified
clock_ID to make the kernel Y2038 safe on 32 bit architectures.
Update the x86 specific vDSO library accordingly with what it has
been done for the kernel syscall exposing the clock_gettime64 entry
point.
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/x86/entry/vdso/vclock_gettime.c | 7 +++++++
arch/x86/entry/vdso/vdso32/vdso32.lds.S | 1 +
2 files changed, 8 insertions(+)
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
index de9212a4833e..d6d03e933191 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -65,6 +65,13 @@ int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
int clock_gettime(clockid_t, struct old_timespec32 *)
__attribute__((weak, alias("__vdso_clock_gettime")));
+int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts)
+{
+ return __cvdso_clock_gettime(clock, ts);
+}
+int clock_gettime64(clockid_t, struct __kernel_timespec *)
+ __attribute__((weak, alias("__vdso_clock_gettime64")));
+
int __vdso_clock_getres(clockid_t clock,
struct old_timespec32 *res)
{
diff --git a/arch/x86/entry/vdso/vdso32/vdso32.lds.S b/arch/x86/entry/vdso/vdso32/vdso32.lds.S
index 991b26cc855b..c7720995ab1a 100644
--- a/arch/x86/entry/vdso/vdso32/vdso32.lds.S
+++ b/arch/x86/entry/vdso/vdso32/vdso32.lds.S
@@ -27,6 +27,7 @@ VERSION
__vdso_gettimeofday;
__vdso_time;
__vdso_clock_getres;
+ __vdso_clock_gettime64;
};
LINUX_2.5 {
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* [PATCH v7 25/25] kselftest: Extend vDSO selftest
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (23 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 24/25] x86: Add clock_gettime64 " Vincenzo Frascino
@ 2019-06-21 9:52 ` Vincenzo Frascino
2019-06-24 0:34 ` [PATCH v7 00/25] Unify vDSOs across more architectures Thomas Gleixner
2019-06-24 12:50 ` Andre Przywara
26 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-21 9:52 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linux-kernel, linux-mips, linux-kselftest
Cc: Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Thomas Gleixner,
Mark Salyzyn, Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara
The current version of the multiarch vDSO selftest verifies only
gettimeofday.
Extend the vDSO selftest to the other library functions:
- time
- clock_getres
- clock_gettime
The extension has been used to verify the unified vdso library on the
supported architectures.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
tools/testing/selftests/vDSO/Makefile | 2 +
tools/testing/selftests/vDSO/vdso_config.h | 90 +++++++
tools/testing/selftests/vDSO/vdso_full_test.c | 244 ++++++++++++++++++
3 files changed, 336 insertions(+)
create mode 100644 tools/testing/selftests/vDSO/vdso_config.h
create mode 100644 tools/testing/selftests/vDSO/vdso_full_test.c
diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile
index 9e03d61f52fd..68e9b4a1cdcf 100644
--- a/tools/testing/selftests/vDSO/Makefile
+++ b/tools/testing/selftests/vDSO/Makefile
@@ -5,6 +5,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not)
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
TEST_GEN_PROGS := $(OUTPUT)/vdso_test
+TEST_GEN_PROGS += $(OUTPUT)/vdso_full_test
ifeq ($(ARCH),x86)
TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86
endif
@@ -18,6 +19,7 @@ endif
all: $(TEST_GEN_PROGS)
$(OUTPUT)/vdso_test: parse_vdso.c vdso_test.c
+$(OUTPUT)/vdso_full_test: parse_vdso.c vdso_full_test.c
$(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
$(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \
vdso_standalone_test_x86.c parse_vdso.c \
diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h
new file mode 100644
index 000000000000..eeb725df6045
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_config.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * vdso_config.h: Configuration options for vDSO tests.
+ * Copyright (c) 2019 Arm Ltd.
+ */
+#ifndef __VDSO_CONFIG_H__
+#define __VDSO_CONFIG_H__
+
+/*
+ * Each architecture exports its vDSO implementation with different names
+ * and a different version from the others, so we need to handle it as a
+ * special case.
+ */
+#if defined(__arm__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#elif defined(__aarch64__)
+#define VDSO_VERSION 3
+#define VDSO_NAMES 0
+#elif defined(__powerpc__)
+#define VDSO_VERSION 1
+#define VDSO_NAMES 0
+#define VDSO_32BIT 1
+#elif defined(__powerpc64__)
+#define VDSO_VERSION 1
+#define VDSO_NAMES 0
+#elif defined (__s390__)
+#define VDSO_VERSION 2
+#define VDSO_NAMES 0
+#define VDSO_32BIT 1
+#elif defined (__s390X__)
+#define VDSO_VERSION 2
+#define VDSO_NAMES 0
+#elif defined(__mips__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#elif defined(__sparc__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#elif defined(__i386__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#elif defined(__x86_64__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#elif defined(__riscv__)
+#define VDSO_VERSION 5
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#else /* nds32 */
+#define VDSO_VERSION 4
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#endif
+
+static const char *versions[6] = {
+ "LINUX_2.6",
+ "LINUX_2.6.15",
+ "LINUX_2.6.29",
+ "LINUX_2.6.39",
+ "LINUX_4",
+ "LINUX_4.15",
+};
+
+static const char *names[2][5] = {
+ {
+ "__kernel_gettimeofday",
+ "__kernel_clock_gettime",
+ "__kernel_time",
+ "__kernel_clock_getres",
+#if defined(VDSO_32BIT)
+ "__kernel_clock_gettime64",
+#endif
+ },
+ {
+ "__vdso_gettimeofday",
+ "__vdso_clock_gettime",
+ "__vdso_time",
+ "__vdso_clock_getres",
+#if defined(VDSO_32BIT)
+ "__vdso_clock_gettime64",
+#endif
+ },
+};
+
+#endif /* __VDSO_CONFIG_H__ */
diff --git a/tools/testing/selftests/vDSO/vdso_full_test.c b/tools/testing/selftests/vDSO/vdso_full_test.c
new file mode 100644
index 000000000000..3d603f1394af
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_full_test.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * vdso_full_test.c: Sample code to test all the timers.
+ * Copyright (c) 2019 Arm Ltd.
+ *
+ * Compile with:
+ * gcc -std=gnu99 vdso_full_test.c parse_vdso.c
+ *
+ */
+
+#include <stdint.h>
+#include <elf.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/auxv.h>
+#include <sys/time.h>
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "../kselftest.h"
+#include "vdso_config.h"
+
+extern void *vdso_sym(const char *version, const char *name);
+extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
+extern void vdso_init_from_auxv(void *auxv);
+
+static const char *version;
+static const char **name;
+
+typedef long (*vdso_gettimeofday_t)(struct timeval *tv, struct timezone *tz);
+typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts);
+typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts);
+typedef time_t (*vdso_time_t)(time_t *t);
+
+static int vdso_test_gettimeofday(void)
+{
+ /* Find gettimeofday. */
+ vdso_gettimeofday_t vdso_gettimeofday =
+ (vdso_gettimeofday_t)vdso_sym(version, name[0]);
+
+ if (!vdso_gettimeofday) {
+ printf("Could not find %s\n", name[0]);
+ return KSFT_SKIP;
+ }
+
+ struct timeval tv;
+ long ret = vdso_gettimeofday(&tv, 0);
+
+ if (ret == 0) {
+ printf("The time is %lld.%06lld\n",
+ (long long)tv.tv_sec, (long long)tv.tv_usec);
+ } else {
+ printf("%s failed\n", name[0]);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
+}
+
+static int vdso_test_clock_gettime(clockid_t clk_id)
+{
+ /* Find clock_gettime. */
+ vdso_clock_gettime_t vdso_clock_gettime =
+ (vdso_clock_gettime_t)vdso_sym(version, name[1]);
+
+ if (!vdso_clock_gettime) {
+ printf("Could not find %s\n", name[1]);
+ return KSFT_SKIP;
+ }
+
+ struct timespec ts;
+ long ret = vdso_clock_gettime(clk_id, &ts);
+
+ if (ret == 0) {
+ printf("The time is %lld.%06lld\n",
+ (long long)ts.tv_sec, (long long)ts.tv_nsec);
+ } else {
+ printf("%s failed\n", name[1]);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
+}
+
+static int vdso_test_time(void)
+{
+ /* Find time. */
+ vdso_time_t vdso_time =
+ (vdso_time_t)vdso_sym(version, name[2]);
+
+ if (!vdso_time) {
+ printf("Could not find %s\n", name[2]);
+ return KSFT_SKIP;
+ }
+
+ long ret = vdso_time(NULL);
+
+ if (ret > 0) {
+ printf("The time in hours since January 1, 1970 is %lld\n",
+ (long long)(ret / 3600));
+ } else {
+ printf("%s failed\n", name[2]);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
+}
+
+static int vdso_test_clock_getres(clockid_t clk_id)
+{
+ /* Find clock_getres. */
+ vdso_clock_getres_t vdso_clock_getres =
+ (vdso_clock_getres_t)vdso_sym(version, name[3]);
+
+ if (!vdso_clock_getres) {
+ printf("Could not find %s\n", name[3]);
+ return KSFT_SKIP;
+ }
+
+ struct timespec ts, sys_ts;
+ long ret = vdso_clock_getres(clk_id, &ts);
+
+ if (ret == 0) {
+ printf("The resolution is %lld %lld\n",
+ (long long)ts.tv_sec, (long long)ts.tv_nsec);
+ } else {
+ printf("%s failed\n", name[3]);
+ return KSFT_FAIL;
+ }
+
+ ret = syscall(SYS_clock_getres, clk_id, &sys_ts);
+
+ if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec)) {
+ printf("%s failed\n", name[3]);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
+}
+
+const char *vdso_clock_name[12] = {
+ "CLOCK_REALTIME",
+ "CLOCK_MONOTONIC",
+ "CLOCK_PROCESS_CPUTIME_ID",
+ "CLOCK_THREAD_CPUTIME_ID",
+ "CLOCK_MONOTONIC_RAW",
+ "CLOCK_REALTIME_COARSE",
+ "CLOCK_MONOTONIC_COARSE",
+ "CLOCK_BOOTTIME",
+ "CLOCK_REALTIME_ALARM",
+ "CLOCK_BOOTTIME_ALARM",
+ "CLOCK_SGI_CYCLE",
+ "CLOCK_TAI",
+};
+
+/*
+ * This function calls vdso_test_clock_gettime and vdso_test_clock_getres
+ * with different values for clock_id.
+ */
+static inline int vdso_test_clock(clockid_t clock_id)
+{
+ int ret0, ret1;
+
+ ret0 = vdso_test_clock_gettime(clock_id);
+ /* A skipped test is considered passed */
+ if (ret0 == KSFT_SKIP)
+ ret0 = KSFT_PASS;
+
+ ret1 = vdso_test_clock_getres(clock_id);
+ /* A skipped test is considered passed */
+ if (ret1 == KSFT_SKIP)
+ ret1 = KSFT_PASS;
+
+ ret0 += ret1;
+
+ printf("clock_id: %s", vdso_clock_name[clock_id]);
+
+ if (ret0 > 0)
+ printf(" [FAIL]\n");
+ else
+ printf(" [PASS]\n");
+
+ return ret0;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
+ int ret;
+
+ if (!sysinfo_ehdr) {
+ printf("AT_SYSINFO_EHDR is not present!\n");
+ return KSFT_SKIP;
+ }
+
+ version = versions[VDSO_VERSION];
+ name = (const char **)&names[VDSO_NAMES];
+
+ printf("[vDSO kselftest] VDSO_VERSION: %s\n", version);
+
+ vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
+
+ ret = vdso_test_gettimeofday();
+
+#if _POSIX_TIMERS > 0
+
+#ifdef CLOCK_REALTIME
+ ret += vdso_test_clock(CLOCK_REALTIME);
+#endif
+
+#ifdef CLOCK_BOOTTIME
+ ret += vdso_test_clock(CLOCK_BOOTTIME);
+#endif
+
+#ifdef CLOCK_TAI
+ ret += vdso_test_clock(CLOCK_TAI);
+#endif
+
+#ifdef CLOCK_REALTIME_COARSE
+ ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
+#endif
+
+#ifdef CLOCK_MONOTONIC
+ ret += vdso_test_clock(CLOCK_MONOTONIC);
+#endif
+
+#ifdef CLOCK_MONOTONIC_RAW
+ ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
+#endif
+
+#ifdef CLOCK_MONOTONIC_COARSE
+ ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
+#endif
+
+#endif
+
+ ret += vdso_test_time();
+
+ if (ret > 0)
+ return KSFT_FAIL;
+
+ return KSFT_PASS;
+}
--
2.21.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (24 preceding siblings ...)
2019-06-21 9:52 ` [PATCH v7 25/25] kselftest: Extend vDSO selftest Vincenzo Frascino
@ 2019-06-24 0:34 ` Thomas Gleixner
2019-06-24 1:15 ` Andy Lutomirski
` (3 more replies)
2019-06-24 12:50 ` Andre Przywara
26 siblings, 4 replies; 108+ messages in thread
From: Thomas Gleixner @ 2019-06-24 0:34 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara,
Dmitry Safonov, Andrei Vagin, Linus Torvalds, Andy Lutomirski,
Michael Kelley, Sasha Levin
Vincenzo,
On Fri, 21 Jun 2019, Vincenzo Frascino wrote:
> vDSO (virtual dynamic shared object) is a mechanism that the Linux
> kernel provides as an alternative to system calls to reduce where
> possible the costs in terms of cycles.
> This is possible because certain syscalls like gettimeofday() do
> not write any data and return one or more values that are stored
> in the kernel, which makes relatively safe calling them directly
> as a library function.
>
> Even if the mechanism is pretty much standard, every architecture
> in the last few years ended up implementing their own vDSO library
> in the architectural code.
....
> This implementation contains the portings to the common library for: arm64,
> compat mode for arm64, arm, mips, x86_64, x32, compat mode for x86_64 and
> i386.
I picked up the core implementation and the ARM64 and x86 conversion. I did
some refinements in several places, coding style, naming conventions,
comments and changelogs including subject prefixes. Please double check!
I did not merge the ARM and MIPS parts as they lack any form of
acknowlegment from their maintainers. Please talk to those folks. If they
ack/review the changes then I can pick them up and they go into 5.3 or they
have to go in a later cycle. Nevertheless it was well worth the trouble to
have those conversions done to confirm that the new common library fits a
bunch of different architectures.
As you can see from the commit dates, this has soaked for some time in a
WIP branch and I did extensive regression testing. So far so good.
Thanks a lot for going through several iterations. It's a very much
appreciated effort!
Especially with the upcoming time namespaces this will avoid a lot of
duplicated and pointlessly different horrors all over the architecture
space. Any architecture which wants to gain that support needs to convert
to the generic VDSO first.
As you have become the dude who knows almost everything about VDSO
including all the nasty pitfalls, I propose the patch below.
Thanks,
tglx
8<------------
Subject: MAINTAINERS: Add entry for the generic VDSO library
From: Thomas Gleixner <tglx@linutronix.de>
Date: Mon, 24 Jun 2019 02:03:50 +0200
Asign the following folks in alphabetic order:
- Andy for being the VDSO wizard of x86 and in general. He's also the
performance monitor of choice and the code in the generic library is
heavily influenced by his previous x86 VDSO work.
- Thomas for being the dude who has to deal with any form of time(r)
nonsense anyway
- Vincenzo for being the poor sod who went through all the different
architecture implementations in order to unify them. A lot of knowledge
gained from VDSO implementation details to the intricacies of taming the
build system.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
MAINTAINERS | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6665,6 +6665,18 @@ L: kvm@vger.kernel.org
S: Supported
F: drivers/uio/uio_pci_generic.c
+GENERIC VDSO LIBRARY:
+M: Andy Lutomirksy <luto@kernel.org>
+M: Thomas Gleixner <tglx@linutronix.de>
+M: Vincenzo Frascino <vincenzo.frascino@arm.com>
+L: linux-kernel@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/vdso
+S: Maintained
+F: lib/vdso
+F: kernel/time/vsyscall.c
+F: include/vdso
+F: include/asm-generic/vdso/vsyscall.h
+
GENWQE (IBM Generic Workqueue Card)
M: Frank Haverkamp <haver@linux.ibm.com>
S: Supported
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 0:34 ` [PATCH v7 00/25] Unify vDSOs across more architectures Thomas Gleixner
@ 2019-06-24 1:15 ` Andy Lutomirski
2019-06-24 7:42 ` Thomas Gleixner
2019-06-24 13:21 ` Vincenzo Frascino
` (2 subsequent siblings)
3 siblings, 1 reply; 108+ messages in thread
From: Andy Lutomirski @ 2019-06-24 1:15 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Vincenzo Frascino, linux-arch, LAK, LKML, linux-mips,
open list:KERNEL SELFTEST FRAMEWORK, Catalin Marinas,
Will Deacon, Arnd Bergmann, Russell King, Ralf Baechle,
Paul Burton, Daniel Lezcano, Mark Salyzyn, Peter Collingbourne,
Shuah Khan, Dmitry Safonov, Rasmus Villemoes, Huw Davies,
Shijith Thotton, Andre Przywara, Dmitry Safonov, Andrei Vagin,
Linus Torvalds, Andy Lutomirski, Michael Kelley, Sasha Levin
On Sun, Jun 23, 2019 at 5:34 PM Thomas Gleixner <tglx@linutronix.de> wrote:
> +GENERIC VDSO LIBRARY:
> +M: Andy Lutomirksy <luto@kernel.org>
Lutomirski, perhaps? Although I do appreciate the opportunity to say
"not me!" :)
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 1:15 ` Andy Lutomirski
@ 2019-06-24 7:42 ` Thomas Gleixner
0 siblings, 0 replies; 108+ messages in thread
From: Thomas Gleixner @ 2019-06-24 7:42 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Vincenzo Frascino, linux-arch, LAK, LKML, linux-mips,
open list:KERNEL SELFTEST FRAMEWORK, Catalin Marinas,
Will Deacon, Arnd Bergmann, Russell King, Ralf Baechle,
Paul Burton, Daniel Lezcano, Mark Salyzyn, Peter Collingbourne,
Shuah Khan, Dmitry Safonov, Rasmus Villemoes, Huw Davies,
Shijith Thotton, Andre Przywara, Dmitry Safonov, Andrei Vagin,
Linus Torvalds, Michael Kelley, Sasha Levin
On Sun, 23 Jun 2019, Andy Lutomirski wrote:
> On Sun, Jun 23, 2019 at 5:34 PM Thomas Gleixner <tglx@linutronix.de> wrote:
> > +GENERIC VDSO LIBRARY:
> > +M: Andy Lutomirksy <luto@kernel.org>
>
> Lutomirski, perhaps?
Ooops. Where did I copy that from?
> Although I do appreciate the opportunity to say "not me!" :)
You just gave me the perfect exit plan. I'll change my surname to Gleyxner
and head off to the goat farm :)
Thanks,
tglx
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 0:34 ` [PATCH v7 00/25] Unify vDSOs across more architectures Thomas Gleixner
2019-06-24 1:15 ` Andy Lutomirski
@ 2019-06-24 13:21 ` Vincenzo Frascino
2019-06-24 14:18 ` Thomas Gleixner
2019-06-24 18:41 ` Paul Burton
3 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-24 13:21 UTC (permalink / raw)
To: Thomas Gleixner
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara,
Dmitry Safonov, Andrei Vagin, Linus Torvalds, Andy Lutomirski,
Michael Kelley, Sasha Levin
Hi Thomas,
On 24/06/2019 01:34, Thomas Gleixner wrote:
> Vincenzo,
>
> On Fri, 21 Jun 2019, Vincenzo Frascino wrote:
>> vDSO (virtual dynamic shared object) is a mechanism that the Linux
>> kernel provides as an alternative to system calls to reduce where
>> possible the costs in terms of cycles.
>> This is possible because certain syscalls like gettimeofday() do
>> not write any data and return one or more values that are stored
>> in the kernel, which makes relatively safe calling them directly
>> as a library function.
>>
>> Even if the mechanism is pretty much standard, every architecture
>> in the last few years ended up implementing their own vDSO library
>> in the architectural code.
>
> ....
>
>> This implementation contains the portings to the common library for: arm64,
>> compat mode for arm64, arm, mips, x86_64, x32, compat mode for x86_64 and
>> i386.
>
> I picked up the core implementation and the ARM64 and x86 conversion. I did
> some refinements in several places, coding style, naming conventions,
> comments and changelogs including subject prefixes. Please double check!
>
I tested your changes and they seem OK
(git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/vdso).
...
> As you can see from the commit dates, this has soaked for some time in a
> WIP branch and I did extensive regression testing. So far so good.
>
> Thanks a lot for going through several iterations. It's a very much
> appreciated effort!
>
It has been a lot of fun and I learned many many things about the vDSOs and the
kernel that I did not know before. Thanks to you for your patience and guidance.
> Especially with the upcoming time namespaces this will avoid a lot of
> duplicated and pointlessly different horrors all over the architecture
> space. Any architecture which wants to gain that support needs to convert
> to the generic VDSO first.
>
> As you have become the dude who knows almost everything about VDSO
> including all the nasty pitfalls, I propose the patch below.
>
Thanks for this, it means a lot to me.
> Thanks,
>
> tglx
>
> 8<------------
> Subject: MAINTAINERS: Add entry for the generic VDSO library
> From: Thomas Gleixner <tglx@linutronix.de>
> Date: Mon, 24 Jun 2019 02:03:50 +0200
>
> Asign the following folks in alphabetic order:
>
> - Andy for being the VDSO wizard of x86 and in general. He's also the
> performance monitor of choice and the code in the generic library is
> heavily influenced by his previous x86 VDSO work.
>
> - Thomas for being the dude who has to deal with any form of time(r)
> nonsense anyway
>
> - Vincenzo for being the poor sod who went through all the different
> architecture implementations in order to unify them. A lot of knowledge
> gained from VDSO implementation details to the intricacies of taming the
> build system.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> MAINTAINERS | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6665,6 +6665,18 @@ L: kvm@vger.kernel.org
> S: Supported
> F: drivers/uio/uio_pci_generic.c
>
> +GENERIC VDSO LIBRARY:
> +M: Andy Lutomirksy <luto@kernel.org>
> +M: Thomas Gleixner <tglx@linutronix.de>
> +M: Vincenzo Frascino <vincenzo.frascino@arm.com>
> +L: linux-kernel@vger.kernel.org
> +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/vdso
> +S: Maintained
> +F: lib/vdso
> +F: kernel/time/vsyscall.c
> +F: include/vdso
> +F: include/asm-generic/vdso/vsyscall.h
> +
> GENWQE (IBM Generic Workqueue Card)
> M: Frank Haverkamp <haver@linux.ibm.com>
> S: Supported
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 0:34 ` [PATCH v7 00/25] Unify vDSOs across more architectures Thomas Gleixner
2019-06-24 1:15 ` Andy Lutomirski
2019-06-24 13:21 ` Vincenzo Frascino
@ 2019-06-24 14:18 ` Thomas Gleixner
2019-06-24 14:23 ` Russell King - ARM Linux admin
2019-06-24 18:41 ` Paul Burton
3 siblings, 1 reply; 108+ messages in thread
From: Thomas Gleixner @ 2019-06-24 14:18 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Paul Burton, Daniel Lezcano, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara,
Dmitry Safonov, Andrei Vagin, Linus Torvalds, Andy Lutomirski,
Michael Kelley, Sasha Levin
Vincenzo,
On Mon, 24 Jun 2019, Thomas Gleixner wrote:
> I did not merge the ARM and MIPS parts as they lack any form of
> acknowlegment from their maintainers. Please talk to those folks. If they
> ack/review the changes then I can pick them up and they go into 5.3 or they
> have to go in a later cycle. Nevertheless it was well worth the trouble to
> have those conversions done to confirm that the new common library fits a
> bunch of different architectures.
I talked to Russell King and he suggested to file the ARM parts into his
patch system and he'll pick them up after 5.3-rc1.
https://www.arm.linux.org.uk/developer/patches/
I paged out how to deal with it, but you'll surely manage :)
Thanks,
tglx
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 14:18 ` Thomas Gleixner
@ 2019-06-24 14:23 ` Russell King - ARM Linux admin
2019-06-24 14:49 ` Catalin Marinas
0 siblings, 1 reply; 108+ messages in thread
From: Russell King - ARM Linux admin @ 2019-06-24 14:23 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Vincenzo Frascino, Andy Lutomirski, Rasmus Villemoes,
Catalin Marinas, Will Deacon, linux-mips, linux-kselftest,
Shuah Khan, linux-arch, Dmitry Safonov, Daniel Lezcano,
Sasha Levin, Arnd Bergmann, Andre Przywara, Dmitry Safonov,
Michael Kelley, Peter Collingbourne, LAK, Andrei Vagin,
Huw Davies, LKML, Ralf Baechle, Mark Salyzyn, Paul Burton,
Shijith Thotton, Linus Torvalds
On Mon, Jun 24, 2019 at 04:18:28PM +0200, Thomas Gleixner wrote:
> Vincenzo,
>
> On Mon, 24 Jun 2019, Thomas Gleixner wrote:
>
> > I did not merge the ARM and MIPS parts as they lack any form of
> > acknowlegment from their maintainers. Please talk to those folks. If they
> > ack/review the changes then I can pick them up and they go into 5.3 or they
> > have to go in a later cycle. Nevertheless it was well worth the trouble to
> > have those conversions done to confirm that the new common library fits a
> > bunch of different architectures.
>
> I talked to Russell King and he suggested to file the ARM parts into his
> patch system and he'll pick them up after 5.3-rc1.
>
> https://www.arm.linux.org.uk/developer/patches/
>
> I paged out how to deal with it, but you'll surely manage :)
Easy way: ask git to add the "KernelVersion" tag as a header to the
email using --add-header to e.g. git format-patch, and just mail them
to patches@armlinux.org.uk
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 14:23 ` Russell King - ARM Linux admin
@ 2019-06-24 14:49 ` Catalin Marinas
2019-06-24 16:20 ` Vincenzo Frascino
2019-10-25 11:42 ` Geert Uytterhoeven
0 siblings, 2 replies; 108+ messages in thread
From: Catalin Marinas @ 2019-06-24 14:49 UTC (permalink / raw)
To: Russell King - ARM Linux admin
Cc: Thomas Gleixner, Vincenzo Frascino, Andy Lutomirski,
Rasmus Villemoes, Will Deacon, linux-mips, linux-kselftest,
Shuah Khan, linux-arch, Dmitry Safonov, Daniel Lezcano,
Sasha Levin, Arnd Bergmann, Andre Przywara, Dmitry Safonov,
Michael Kelley, Peter Collingbourne, LAK, Andrei Vagin,
Huw Davies, LKML, Ralf Baechle, Mark Salyzyn, Paul Burton,
Shijith Thotton, Linus Torvalds
On Mon, Jun 24, 2019 at 03:23:46PM +0100, Russell King wrote:
> On Mon, Jun 24, 2019 at 04:18:28PM +0200, Thomas Gleixner wrote:
> > Vincenzo,
> >
> > On Mon, 24 Jun 2019, Thomas Gleixner wrote:
> >
> > > I did not merge the ARM and MIPS parts as they lack any form of
> > > acknowlegment from their maintainers. Please talk to those folks. If they
> > > ack/review the changes then I can pick them up and they go into 5.3 or they
> > > have to go in a later cycle. Nevertheless it was well worth the trouble to
> > > have those conversions done to confirm that the new common library fits a
> > > bunch of different architectures.
> >
> > I talked to Russell King and he suggested to file the ARM parts into his
> > patch system and he'll pick them up after 5.3-rc1.
> >
> > https://www.arm.linux.org.uk/developer/patches/
> >
> > I paged out how to deal with it, but you'll surely manage :)
>
> Easy way: ask git to add the "KernelVersion" tag as a header to the
> email using --add-header to e.g. git format-patch, and just mail them
> to patches@armlinux.org.uk
Although I haven't send patches to Russell in a while, I still have a
git alias in my .gitconfig (only works with one patch at a time IIRC,
sending multiple patches may arrive in a different order):
[alias]
send-rmk-email = !git send-email --add-header=\"KernelVersion: $(git describe --abbrev=0)\" --no-thread --suppress-cc=all --to="patches@arm.linux.org.uk"
--
Catalin
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 14:49 ` Catalin Marinas
@ 2019-06-24 16:20 ` Vincenzo Frascino
2019-10-25 11:42 ` Geert Uytterhoeven
1 sibling, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-24 16:20 UTC (permalink / raw)
To: Catalin Marinas, Russell King - ARM Linux admin
Cc: Thomas Gleixner, Andy Lutomirski, Rasmus Villemoes, Will Deacon,
linux-mips, linux-kselftest, Shuah Khan, linux-arch,
Dmitry Safonov, Daniel Lezcano, Sasha Levin, Arnd Bergmann,
Andre Przywara, Dmitry Safonov, Michael Kelley,
Peter Collingbourne, LAK, Andrei Vagin, Huw Davies, LKML,
Ralf Baechle, Mark Salyzyn, Paul Burton, Shijith Thotton,
Linus Torvalds
On 24/06/2019 15:49, Catalin Marinas wrote:
> On Mon, Jun 24, 2019 at 03:23:46PM +0100, Russell King wrote:
>> On Mon, Jun 24, 2019 at 04:18:28PM +0200, Thomas Gleixner wrote:
>>> Vincenzo,
>>>
>>> On Mon, 24 Jun 2019, Thomas Gleixner wrote:
>>>
>>>> I did not merge the ARM and MIPS parts as they lack any form of
>>>> acknowlegment from their maintainers. Please talk to those folks. If they
>>>> ack/review the changes then I can pick them up and they go into 5.3 or they
>>>> have to go in a later cycle. Nevertheless it was well worth the trouble to
>>>> have those conversions done to confirm that the new common library fits a
>>>> bunch of different architectures.
>>>
>>> I talked to Russell King and he suggested to file the ARM parts into his
>>> patch system and he'll pick them up after 5.3-rc1.
>>>
>>> https://www.arm.linux.org.uk/developer/patches/
>>>
>>> I paged out how to deal with it, but you'll surely manage :)
>>
>> Easy way: ask git to add the "KernelVersion" tag as a header to the
>> email using --add-header to e.g. git format-patch, and just mail them
>> to patches@armlinux.org.uk
>
> Although I haven't send patches to Russell in a while, I still have a
> git alias in my .gitconfig (only works with one patch at a time IIRC,
> sending multiple patches may arrive in a different order):
>
> [alias]
> send-rmk-email = !git send-email --add-header=\"KernelVersion: $(git describe --abbrev=0)\" --no-thread --suppress-cc=all --to="patches@arm.linux.org.uk"
>
Thanks to all for the hints and the support. I will send the patches to Russel
as agreed.
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 14:49 ` Catalin Marinas
2019-06-24 16:20 ` Vincenzo Frascino
@ 2019-10-25 11:42 ` Geert Uytterhoeven
1 sibling, 0 replies; 108+ messages in thread
From: Geert Uytterhoeven @ 2019-10-25 11:42 UTC (permalink / raw)
To: Catalin Marinas
Cc: Russell King - ARM Linux admin, Thomas Gleixner,
Vincenzo Frascino, Andy Lutomirski, Rasmus Villemoes,
Will Deacon, linux-mips, open list:KERNEL SELFTEST FRAMEWORK,
Shuah Khan, Linux-Arch, Dmitry Safonov, Daniel Lezcano,
Sasha Levin, Arnd Bergmann, Andre Przywara, Dmitry Safonov,
Michael Kelley, Peter Collingbourne, LAK, Andrei Vagin,
Huw Davies, LKML, Ralf Baechle, Mark Salyzyn, Paul Burton,
Shijith Thotton, Linus Torvalds
Hi Catalin,
On Mon, Jun 24, 2019 at 4:51 PM Catalin Marinas <catalin.marinas@arm.com> wrote:
> On Mon, Jun 24, 2019 at 03:23:46PM +0100, Russell King wrote:
> > On Mon, Jun 24, 2019 at 04:18:28PM +0200, Thomas Gleixner wrote:
> > > I talked to Russell King and he suggested to file the ARM parts into his
> > > patch system and he'll pick them up after 5.3-rc1.
> > >
> > > https://www.arm.linux.org.uk/developer/patches/
> > >
> > > I paged out how to deal with it, but you'll surely manage :)
> >
> > Easy way: ask git to add the "KernelVersion" tag as a header to the
> > email using --add-header to e.g. git format-patch, and just mail them
> > to patches@armlinux.org.uk
>
> Although I haven't send patches to Russell in a while, I still have a
> git alias in my .gitconfig (only works with one patch at a time IIRC,
> sending multiple patches may arrive in a different order):
>
> [alias]
> send-rmk-email = !git send-email --add-header=\"KernelVersion: $(git describe --abbrev=0)\" --no-thread --suppress-cc=all --to="patches@arm.linux.org.uk"
Doesn't seem to work: no header was added, and my patch was rejected.
There does seem to be a "--add-header" option for git-format-patch, but
it adds the header at the top, just below the "Subject:"-header, instead
of below the "---", so that needs manual editing, too.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 0:34 ` [PATCH v7 00/25] Unify vDSOs across more architectures Thomas Gleixner
` (2 preceding siblings ...)
2019-06-24 14:18 ` Thomas Gleixner
@ 2019-06-24 18:41 ` Paul Burton
2019-06-24 23:16 ` Vincenzo Frascino
3 siblings, 1 reply; 108+ messages in thread
From: Paul Burton @ 2019-06-24 18:41 UTC (permalink / raw)
To: Thomas Gleixner, Vincenzo Frascino
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Daniel Lezcano, Mark Salyzyn, Peter Collingbourne,
Shuah Khan, Dmitry Safonov, Rasmus Villemoes, Huw Davies,
Shijith Thotton, Andre Przywara, Dmitry Safonov, Andrei Vagin,
Linus Torvalds, Andy Lutomirski, Michael Kelley, Sasha Levin
Hello,
On Mon, Jun 24, 2019 at 02:34:24AM +0200, Thomas Gleixner wrote:
> I did not merge the ARM and MIPS parts as they lack any form of
> acknowlegment from their maintainers. Please talk to those folks. If they
> ack/review the changes then I can pick them up and they go into 5.3 or they
> have to go in a later cycle. Nevertheless it was well worth the trouble to
> have those conversions done to confirm that the new common library fits a
> bunch of different architectures.
Apologies for not being more proactive on the MIPS front here; life &
work are extra busy at the moment... But thanks Vincenzo for including
MIPS in the work here.
Unfortunately after applying the 3 MIPS patches (19-21) atop the current
tip.git timers/vdso branch at ecf9db3d1f1a ("x86/vdso: Give the
[ph]vclock_page declarations real types") I see build failures for the
o32 compat VDSO, shown below. This is using the gcc 8.1.0 mips-linux
toolchain from here:
https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/x86_64-gcc-8.1.0-nolibc-mips-linux.tar.xz
Configuration is 64r6el_defconfig. The following helps remove the
implicit declaration warnings (and eww to including C files via CFLAGS),
but it still doesn't build:
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index 95df49402a53..aa38049bdb24 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -36,6 +36,8 @@ aflags-vdso := $(ccflags-vdso) \
ifneq ($(c-gettimeofday-y),)
CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
+CFLAGS_vgettimeofday-o32.o = -include $(c-gettimeofday-y)
+CFLAGS_vgettimeofday-n32.o = -include $(c-gettimeofday-y)
endif
CFLAGS_REMOVE_vgettimeofday.o = -pg
So the MIPS bits here need more work.
Thanks,
Paul
CC arch/mips/vdso/vgettimeofday-o32.o
In file included from ./include/linux/bitops.h:19,
from ./include/linux/kernel.h:12,
from ./include/linux/list.h:9,
from ./include/linux/preempt.h:11,
from ./include/linux/spinlock.h:51,
from ./include/linux/seqlock.h:36,
from ./include/linux/time.h:6,
from arch/mips/vdso/vgettimeofday.c:10:
./arch/mips/include/asm/bitops.h: In function '__fls':
./arch/mips/include/asm/bitops.h:518:21: warning: left shift count >= width of type [-Wshift-count-overflow]
if (!(word & (~0ul << 32))) {
^~
./arch/mips/include/asm/bitops.h:520:8: warning: left shift count >= width of type [-Wshift-count-overflow]
word <<= 32;
^~~
./arch/mips/include/asm/bitops.h:523:21: warning: left shift count >= width of type [-Wshift-count-overflow]
if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
^~
./arch/mips/include/asm/bitops.h:527:21: warning: left shift count >= width of type [-Wshift-count-overflow]
if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
^~
./arch/mips/include/asm/bitops.h:531:21: warning: left shift count >= width of type [-Wshift-count-overflow]
if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
^~
./arch/mips/include/asm/bitops.h:535:21: warning: left shift count >= width of type [-Wshift-count-overflow]
if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
^~
./arch/mips/include/asm/bitops.h:539:21: warning: left shift count >= width of type [-Wshift-count-overflow]
if (!(word & (~0ul << (BITS_PER_LONG-1))))
^~
In file included from ./arch/mips/include/asm/mmiowb.h:5,
from ./include/linux/spinlock.h:60,
from ./include/linux/seqlock.h:36,
from ./include/linux/time.h:6,
from arch/mips/vdso/vgettimeofday.c:10:
./arch/mips/include/asm/io.h: In function 'phys_to_virt':
./arch/mips/include/asm/io.h:136:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
return (void *)(address + PAGE_OFFSET - PHYS_OFFSET);
^
In file included from ./include/linux/bitops.h:5,
from ./include/linux/kernel.h:12,
from ./include/linux/list.h:9,
from ./include/linux/preempt.h:11,
from ./include/linux/spinlock.h:51,
from ./include/linux/seqlock.h:36,
from ./include/linux/time.h:6,
from arch/mips/vdso/vgettimeofday.c:10:
./arch/mips/include/asm/mips-cm.h: In function 'mips_cm_max_vp_width':
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:152:28: note: in expansion of macro 'GENMASK'
#define CM_GCR_REV_MAJOR GENMASK(15, 8)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:156:22: note: in expansion of macro 'CM_GCR_REV_MAJOR'
(((major) << __ffs(CM_GCR_REV_MAJOR)) | \
^~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:161:23: note: in expansion of macro 'CM_ENCODE_REV'
#define CM_REV_CM3 CM_ENCODE_REV(8, 0)
^~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:367:28: note: in expansion of macro 'CM_REV_CM3'
if (mips_cm_revision() >= CM_REV_CM3)
^~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:153:28: note: in expansion of macro 'GENMASK'
#define CM_GCR_REV_MINOR GENMASK(7, 0)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:157:22: note: in expansion of macro 'CM_GCR_REV_MINOR'
((minor) << __ffs(CM_GCR_REV_MINOR)))
^~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:161:23: note: in expansion of macro 'CM_ENCODE_REV'
#define CM_REV_CM3 CM_ENCODE_REV(8, 0)
^~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:367:28: note: in expansion of macro 'CM_REV_CM3'
if (mips_cm_revision() >= CM_REV_CM3)
^~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:239:36: note: in expansion of macro 'GENMASK'
#define CM_GCR_SYS_CONFIG2_MAXVPW GENMASK(3, 0)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:368:35: note: in expansion of macro 'CM_GCR_SYS_CONFIG2_MAXVPW'
return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW;
^~~~~~~~~~~~~~~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:293:33: note: in expansion of macro 'GENMASK'
#define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:376:32: note: in expansion of macro 'CM_GCR_Cx_CONFIG_PVPE'
cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE;
^~~~~~~~~~~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:293:33: note: in expansion of macro 'GENMASK'
#define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:377:24: note: in expansion of macro 'CM_GCR_Cx_CONFIG_PVPE'
return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1;
^~~~~~~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_numclusters':
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:152:28: note: in expansion of macro 'GENMASK'
#define CM_GCR_REV_MAJOR GENMASK(15, 8)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:156:22: note: in expansion of macro 'CM_GCR_REV_MAJOR'
(((major) << __ffs(CM_GCR_REV_MAJOR)) | \
^~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
^~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h:117:27: note: in expansion of macro 'CM_REV_CM3_5'
if (mips_cm_revision() < CM_REV_CM3_5)
^~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:153:28: note: in expansion of macro 'GENMASK'
#define CM_GCR_REV_MINOR GENMASK(7, 0)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:157:22: note: in expansion of macro 'CM_GCR_REV_MINOR'
((minor) << __ffs(CM_GCR_REV_MINOR)))
^~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
^~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h:117:27: note: in expansion of macro 'CM_REV_CM3_5'
if (mips_cm_revision() < CM_REV_CM3_5)
^~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:133:37: note: in expansion of macro 'GENMASK'
#define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23)
^~~~~~~
./arch/mips/include/asm/mips-cps.h:120:37: note: in expansion of macro 'CM_GCR_CONFIG_NUM_CLUSTERS'
num_clusters = read_gcr_config() & CM_GCR_CONFIG_NUM_CLUSTERS;
^~~~~~~~~~~~~~~~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:133:37: note: in expansion of macro 'GENMASK'
#define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23)
^~~~~~~
./arch/mips/include/asm/mips-cps.h:121:25: note: in expansion of macro 'CM_GCR_CONFIG_NUM_CLUSTERS'
num_clusters >>= __ffs(CM_GCR_CONFIG_NUM_CLUSTERS);
^~~~~~~~~~~~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_cluster_config':
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:152:28: note: in expansion of macro 'GENMASK'
#define CM_GCR_REV_MAJOR GENMASK(15, 8)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:156:22: note: in expansion of macro 'CM_GCR_REV_MAJOR'
(((major) << __ffs(CM_GCR_REV_MAJOR)) | \
^~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
^~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h:137:27: note: in expansion of macro 'CM_REV_CM3_5'
if (mips_cm_revision() < CM_REV_CM3_5) {
^~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:153:28: note: in expansion of macro 'GENMASK'
#define CM_GCR_REV_MINOR GENMASK(7, 0)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:157:22: note: in expansion of macro 'CM_GCR_REV_MINOR'
((minor) << __ffs(CM_GCR_REV_MINOR)))
^~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
^~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h:137:27: note: in expansion of macro 'CM_REV_CM3_5'
if (mips_cm_revision() < CM_REV_CM3_5) {
^~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_numcores':
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:135:32: note: in expansion of macro 'GENMASK'
#define CM_GCR_CONFIG_PCORES GENMASK(7, 0)
^~~~~~~
./arch/mips/include/asm/mips-cps.h:172:50: note: in expansion of macro 'CM_GCR_CONFIG_PCORES'
return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
^~~~~~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_numiocu':
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:134:33: note: in expansion of macro 'GENMASK'
#define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8)
^~~~~~~
./arch/mips/include/asm/mips-cps.h:189:48: note: in expansion of macro 'CM_GCR_CONFIG_NUMIOCU'
num_iocu = mips_cps_cluster_config(cluster) & CM_GCR_CONFIG_NUMIOCU;
^~~~~~~~~~~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:134:33: note: in expansion of macro 'GENMASK'
#define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8)
^~~~~~~
./arch/mips/include/asm/mips-cps.h:190:21: note: in expansion of macro 'CM_GCR_CONFIG_NUMIOCU'
num_iocu >>= __ffs(CM_GCR_CONFIG_NUMIOCU);
^~~~~~~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_numvps':
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:152:28: note: in expansion of macro 'GENMASK'
#define CM_GCR_REV_MAJOR GENMASK(15, 8)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:156:22: note: in expansion of macro 'CM_GCR_REV_MAJOR'
(((major) << __ffs(CM_GCR_REV_MAJOR)) | \
^~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
^~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h:216:27: note: in expansion of macro 'CM_REV_CM3_5'
if (mips_cm_revision() < CM_REV_CM3_5) {
^~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:153:28: note: in expansion of macro 'GENMASK'
#define CM_GCR_REV_MINOR GENMASK(7, 0)
^~~~~~~
./arch/mips/include/asm/mips-cm.h:157:22: note: in expansion of macro 'CM_GCR_REV_MINOR'
((minor) << __ffs(CM_GCR_REV_MINOR)))
^~~~~~~~~~~~~~~~
./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
^~~~~~~~~~~~~
./arch/mips/include/asm/mips-cps.h:216:27: note: in expansion of macro 'CM_REV_CM3_5'
if (mips_cm_revision() < CM_REV_CM3_5) {
^~~~~~~~~~~~
./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
^~
./arch/mips/include/asm/mips-cm.h:293:33: note: in expansion of macro 'GENMASK'
#define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0)
^~~~~~~
./arch/mips/include/asm/mips-cps.h:233:21: note: in expansion of macro 'CM_GCR_Cx_CONFIG_PVPE'
return (cfg + 1) & CM_GCR_Cx_CONFIG_PVPE;
^~~~~~~~~~~~~~~~~~~~~
arch/mips/vdso/vgettimeofday.c: In function '__vdso_clock_gettime':
arch/mips/vdso/vgettimeofday.c:17:9: error: implicit declaration of function '__cvdso_clock_gettime32'; did you mean '__vdso_clock_gettime'? [-Werror=implicit-function-declaration]
return __cvdso_clock_gettime32(clock, ts);
^~~~~~~~~~~~~~~~~~~~~~~
__vdso_clock_gettime
arch/mips/vdso/vgettimeofday.c: In function '__vdso_gettimeofday':
arch/mips/vdso/vgettimeofday.c:23:9: error: implicit declaration of function '__cvdso_gettimeofday'; did you mean '__vdso_gettimeofday'? [-Werror=implicit-function-declaration]
return __cvdso_gettimeofday(tv, tz);
^~~~~~~~~~~~~~~~~~~~
__vdso_gettimeofday
arch/mips/vdso/vgettimeofday.c: In function '__vdso_clock_getres':
arch/mips/vdso/vgettimeofday.c:29:9: error: implicit declaration of function '__cvdso_clock_getres_time32'; did you mean '__vdso_clock_gettime'? [-Werror=implicit-function-declaration]
return __cvdso_clock_getres_time32(clock_id, res);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
__vdso_clock_gettime
arch/mips/vdso/vgettimeofday.c: In function '__vdso_clock_gettime64':
arch/mips/vdso/vgettimeofday.c:35:9: error: implicit declaration of function '__cvdso_clock_gettime'; did you mean '__vdso_clock_gettime'? [-Werror=implicit-function-declaration]
return __cvdso_clock_gettime(clock, ts);
^~~~~~~~~~~~~~~~~~~~~
__vdso_clock_gettime
cc1: some warnings being treated as errors
make[1]: *** [arch/mips/vdso/Makefile:148: arch/mips/vdso/vgettimeofday-o32.o] Error 1
make: *** [Makefile:1746: arch/mips/vdso/vgettimeofday-o32.o] Error 2
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 18:41 ` Paul Burton
@ 2019-06-24 23:16 ` Vincenzo Frascino
2019-06-25 17:11 ` Paul Burton
0 siblings, 1 reply; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-24 23:16 UTC (permalink / raw)
To: Paul Burton, Thomas Gleixner
Cc: linux-arch, LAK, LKML, linux-mips, linux-kselftest,
Catalin Marinas, Will Deacon, Arnd Bergmann, Russell King,
Ralf Baechle, Daniel Lezcano, Mark Salyzyn, Peter Collingbourne,
Shuah Khan, Dmitry Safonov, Rasmus Villemoes, Huw Davies,
Shijith Thotton, Andre Przywara, Dmitry Safonov, Andrei Vagin,
Linus Torvalds, Andy Lutomirski, Michael Kelley, Sasha Levin
[-- Attachment #1: Type: text/plain, Size: 20347 bytes --]
Hi Paul,
thank you for your review.
On 6/24/19 7:41 PM, Paul Burton wrote:
> Hello,
>
> On Mon, Jun 24, 2019 at 02:34:24AM +0200, Thomas Gleixner wrote:
>> I did not merge the ARM and MIPS parts as they lack any form of
>> acknowlegment from their maintainers. Please talk to those folks. If they
>> ack/review the changes then I can pick them up and they go into 5.3 or they
>> have to go in a later cycle. Nevertheless it was well worth the trouble to
>> have those conversions done to confirm that the new common library fits a
>> bunch of different architectures.
>
> Apologies for not being more proactive on the MIPS front here; life &
> work are extra busy at the moment... But thanks Vincenzo for including
> MIPS in the work here.
>
No problem.
> Unfortunately after applying the 3 MIPS patches (19-21) atop the current
> tip.git timers/vdso branch at ecf9db3d1f1a ("x86/vdso: Give the
> [ph]vclock_page declarations real types") I see build failures for the
> o32 compat VDSO, shown below. This is using the gcc 8.1.0 mips-linux
> toolchain from here:
>
> https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/x86_64-gcc-8.1.0-nolibc-mips-linux.tar.xz
>
> Configuration is 64r6el_defconfig. The following helps remove the
> implicit declaration warnings (and eww to including C files via CFLAGS),
> but it still doesn't build:
>
> diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
> index 95df49402a53..aa38049bdb24 100644
> --- a/arch/mips/vdso/Makefile
> +++ b/arch/mips/vdso/Makefile
> @@ -36,6 +36,8 @@ aflags-vdso := $(ccflags-vdso) \
>
> ifneq ($(c-gettimeofday-y),)
> CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
> +CFLAGS_vgettimeofday-o32.o = -include $(c-gettimeofday-y)
> +CFLAGS_vgettimeofday-n32.o = -include $(c-gettimeofday-y)
> endif
>
> CFLAGS_REMOVE_vgettimeofday.o = -pg
>
> So the MIPS bits here need more work.
>
I admit, the one proposed was a nice challenge and it took me a while to
understand the differences in between the O32, N32 and N64 binaries and what was
causing the reported issue.
In the end I concluded that all the errors seen here depend on the fact that I
tested my vdso implementation on MIPS32el only (as stated in the cover letter)
and that when I tried to compile a 32BIT binary on a 64BIT configuration I did
it wrongly for two reasons, for N32 and O32 binaries:
- we need to undefine CONFIG_64BIT and define CONFIG_32BIT
- we need to define CONFIG_GENERIC_ATOMIC64
I have a fix for this (patch in attachment), but I do not have the hardware to
test it. If you could provide some feedback would be appreciated (really want to
see MIPS merged with the other archs in 5.3 :) ).
> Thanks,
> Paul
>
> CC arch/mips/vdso/vgettimeofday-o32.o
> In file included from ./include/linux/bitops.h:19,
> from ./include/linux/kernel.h:12,
> from ./include/linux/list.h:9,
> from ./include/linux/preempt.h:11,
> from ./include/linux/spinlock.h:51,
> from ./include/linux/seqlock.h:36,
> from ./include/linux/time.h:6,
> from arch/mips/vdso/vgettimeofday.c:10:
> ./arch/mips/include/asm/bitops.h: In function '__fls':
> ./arch/mips/include/asm/bitops.h:518:21: warning: left shift count >= width of type [-Wshift-count-overflow]
> if (!(word & (~0ul << 32))) {
> ^~
> ./arch/mips/include/asm/bitops.h:520:8: warning: left shift count >= width of type [-Wshift-count-overflow]
> word <<= 32;
> ^~~
> ./arch/mips/include/asm/bitops.h:523:21: warning: left shift count >= width of type [-Wshift-count-overflow]
> if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
> ^~
> ./arch/mips/include/asm/bitops.h:527:21: warning: left shift count >= width of type [-Wshift-count-overflow]
> if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
> ^~
> ./arch/mips/include/asm/bitops.h:531:21: warning: left shift count >= width of type [-Wshift-count-overflow]
> if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
> ^~
> ./arch/mips/include/asm/bitops.h:535:21: warning: left shift count >= width of type [-Wshift-count-overflow]
> if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
> ^~
> ./arch/mips/include/asm/bitops.h:539:21: warning: left shift count >= width of type [-Wshift-count-overflow]
> if (!(word & (~0ul << (BITS_PER_LONG-1))))
> ^~
> In file included from ./arch/mips/include/asm/mmiowb.h:5,
> from ./include/linux/spinlock.h:60,
> from ./include/linux/seqlock.h:36,
> from ./include/linux/time.h:6,
> from arch/mips/vdso/vgettimeofday.c:10:
> ./arch/mips/include/asm/io.h: In function 'phys_to_virt':
> ./arch/mips/include/asm/io.h:136:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
> return (void *)(address + PAGE_OFFSET - PHYS_OFFSET);
> ^
> In file included from ./include/linux/bitops.h:5,
> from ./include/linux/kernel.h:12,
> from ./include/linux/list.h:9,
> from ./include/linux/preempt.h:11,
> from ./include/linux/spinlock.h:51,
> from ./include/linux/seqlock.h:36,
> from ./include/linux/time.h:6,
> from arch/mips/vdso/vgettimeofday.c:10:
> ./arch/mips/include/asm/mips-cm.h: In function 'mips_cm_max_vp_width':
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:152:28: note: in expansion of macro 'GENMASK'
> #define CM_GCR_REV_MAJOR GENMASK(15, 8)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:156:22: note: in expansion of macro 'CM_GCR_REV_MAJOR'
> (((major) << __ffs(CM_GCR_REV_MAJOR)) | \
> ^~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:161:23: note: in expansion of macro 'CM_ENCODE_REV'
> #define CM_REV_CM3 CM_ENCODE_REV(8, 0)
> ^~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:367:28: note: in expansion of macro 'CM_REV_CM3'
> if (mips_cm_revision() >= CM_REV_CM3)
> ^~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:153:28: note: in expansion of macro 'GENMASK'
> #define CM_GCR_REV_MINOR GENMASK(7, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:157:22: note: in expansion of macro 'CM_GCR_REV_MINOR'
> ((minor) << __ffs(CM_GCR_REV_MINOR)))
> ^~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:161:23: note: in expansion of macro 'CM_ENCODE_REV'
> #define CM_REV_CM3 CM_ENCODE_REV(8, 0)
> ^~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:367:28: note: in expansion of macro 'CM_REV_CM3'
> if (mips_cm_revision() >= CM_REV_CM3)
> ^~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:239:36: note: in expansion of macro 'GENMASK'
> #define CM_GCR_SYS_CONFIG2_MAXVPW GENMASK(3, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:368:35: note: in expansion of macro 'CM_GCR_SYS_CONFIG2_MAXVPW'
> return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW;
> ^~~~~~~~~~~~~~~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:293:33: note: in expansion of macro 'GENMASK'
> #define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:376:32: note: in expansion of macro 'CM_GCR_Cx_CONFIG_PVPE'
> cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE;
> ^~~~~~~~~~~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:293:33: note: in expansion of macro 'GENMASK'
> #define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:377:24: note: in expansion of macro 'CM_GCR_Cx_CONFIG_PVPE'
> return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1;
> ^~~~~~~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_numclusters':
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:152:28: note: in expansion of macro 'GENMASK'
> #define CM_GCR_REV_MAJOR GENMASK(15, 8)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:156:22: note: in expansion of macro 'CM_GCR_REV_MAJOR'
> (((major) << __ffs(CM_GCR_REV_MAJOR)) | \
> ^~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
> #define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
> ^~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h:117:27: note: in expansion of macro 'CM_REV_CM3_5'
> if (mips_cm_revision() < CM_REV_CM3_5)
> ^~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:153:28: note: in expansion of macro 'GENMASK'
> #define CM_GCR_REV_MINOR GENMASK(7, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:157:22: note: in expansion of macro 'CM_GCR_REV_MINOR'
> ((minor) << __ffs(CM_GCR_REV_MINOR)))
> ^~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
> #define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
> ^~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h:117:27: note: in expansion of macro 'CM_REV_CM3_5'
> if (mips_cm_revision() < CM_REV_CM3_5)
> ^~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:133:37: note: in expansion of macro 'GENMASK'
> #define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cps.h:120:37: note: in expansion of macro 'CM_GCR_CONFIG_NUM_CLUSTERS'
> num_clusters = read_gcr_config() & CM_GCR_CONFIG_NUM_CLUSTERS;
> ^~~~~~~~~~~~~~~~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:133:37: note: in expansion of macro 'GENMASK'
> #define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cps.h:121:25: note: in expansion of macro 'CM_GCR_CONFIG_NUM_CLUSTERS'
> num_clusters >>= __ffs(CM_GCR_CONFIG_NUM_CLUSTERS);
> ^~~~~~~~~~~~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_cluster_config':
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:152:28: note: in expansion of macro 'GENMASK'
> #define CM_GCR_REV_MAJOR GENMASK(15, 8)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:156:22: note: in expansion of macro 'CM_GCR_REV_MAJOR'
> (((major) << __ffs(CM_GCR_REV_MAJOR)) | \
> ^~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
> #define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
> ^~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h:137:27: note: in expansion of macro 'CM_REV_CM3_5'
> if (mips_cm_revision() < CM_REV_CM3_5) {
> ^~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:153:28: note: in expansion of macro 'GENMASK'
> #define CM_GCR_REV_MINOR GENMASK(7, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:157:22: note: in expansion of macro 'CM_GCR_REV_MINOR'
> ((minor) << __ffs(CM_GCR_REV_MINOR)))
> ^~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
> #define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
> ^~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h:137:27: note: in expansion of macro 'CM_REV_CM3_5'
> if (mips_cm_revision() < CM_REV_CM3_5) {
> ^~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_numcores':
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:135:32: note: in expansion of macro 'GENMASK'
> #define CM_GCR_CONFIG_PCORES GENMASK(7, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cps.h:172:50: note: in expansion of macro 'CM_GCR_CONFIG_PCORES'
> return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
> ^~~~~~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_numiocu':
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:134:33: note: in expansion of macro 'GENMASK'
> #define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cps.h:189:48: note: in expansion of macro 'CM_GCR_CONFIG_NUMIOCU'
> num_iocu = mips_cps_cluster_config(cluster) & CM_GCR_CONFIG_NUMIOCU;
> ^~~~~~~~~~~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:134:33: note: in expansion of macro 'GENMASK'
> #define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cps.h:190:21: note: in expansion of macro 'CM_GCR_CONFIG_NUMIOCU'
> num_iocu >>= __ffs(CM_GCR_CONFIG_NUMIOCU);
> ^~~~~~~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h: In function 'mips_cps_numvps':
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:152:28: note: in expansion of macro 'GENMASK'
> #define CM_GCR_REV_MAJOR GENMASK(15, 8)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:156:22: note: in expansion of macro 'CM_GCR_REV_MAJOR'
> (((major) << __ffs(CM_GCR_REV_MAJOR)) | \
> ^~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
> #define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
> ^~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h:216:27: note: in expansion of macro 'CM_REV_CM3_5'
> if (mips_cm_revision() < CM_REV_CM3_5) {
> ^~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:153:28: note: in expansion of macro 'GENMASK'
> #define CM_GCR_REV_MINOR GENMASK(7, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cm.h:157:22: note: in expansion of macro 'CM_GCR_REV_MINOR'
> ((minor) << __ffs(CM_GCR_REV_MINOR)))
> ^~~~~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cm.h:162:25: note: in expansion of macro 'CM_ENCODE_REV'
> #define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
> ^~~~~~~~~~~~~
> ./arch/mips/include/asm/mips-cps.h:216:27: note: in expansion of macro 'CM_REV_CM3_5'
> if (mips_cm_revision() < CM_REV_CM3_5) {
> ^~~~~~~~~~~~
> ./include/linux/bits.h:20:39: warning: right shift count >= width of type [-Wshift-count-overflow]
> (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> ^~
> ./arch/mips/include/asm/mips-cm.h:293:33: note: in expansion of macro 'GENMASK'
> #define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0)
> ^~~~~~~
> ./arch/mips/include/asm/mips-cps.h:233:21: note: in expansion of macro 'CM_GCR_Cx_CONFIG_PVPE'
> return (cfg + 1) & CM_GCR_Cx_CONFIG_PVPE;
> ^~~~~~~~~~~~~~~~~~~~~
> arch/mips/vdso/vgettimeofday.c: In function '__vdso_clock_gettime':
> arch/mips/vdso/vgettimeofday.c:17:9: error: implicit declaration of function '__cvdso_clock_gettime32'; did you mean '__vdso_clock_gettime'? [-Werror=implicit-function-declaration]
> return __cvdso_clock_gettime32(clock, ts);
> ^~~~~~~~~~~~~~~~~~~~~~~
> __vdso_clock_gettime
> arch/mips/vdso/vgettimeofday.c: In function '__vdso_gettimeofday':
> arch/mips/vdso/vgettimeofday.c:23:9: error: implicit declaration of function '__cvdso_gettimeofday'; did you mean '__vdso_gettimeofday'? [-Werror=implicit-function-declaration]
> return __cvdso_gettimeofday(tv, tz);
> ^~~~~~~~~~~~~~~~~~~~
> __vdso_gettimeofday
> arch/mips/vdso/vgettimeofday.c: In function '__vdso_clock_getres':
> arch/mips/vdso/vgettimeofday.c:29:9: error: implicit declaration of function '__cvdso_clock_getres_time32'; did you mean '__vdso_clock_gettime'? [-Werror=implicit-function-declaration]
> return __cvdso_clock_getres_time32(clock_id, res);
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~
> __vdso_clock_gettime
> arch/mips/vdso/vgettimeofday.c: In function '__vdso_clock_gettime64':
> arch/mips/vdso/vgettimeofday.c:35:9: error: implicit declaration of function '__cvdso_clock_gettime'; did you mean '__vdso_clock_gettime'? [-Werror=implicit-function-declaration]
> return __cvdso_clock_gettime(clock, ts);
> ^~~~~~~~~~~~~~~~~~~~~
> __vdso_clock_gettime
> cc1: some warnings being treated as errors
> make[1]: *** [arch/mips/vdso/Makefile:148: arch/mips/vdso/vgettimeofday-o32.o] Error 1
> make: *** [Makefile:1746: arch/mips/vdso/vgettimeofday-o32.o] Error 2
>
--
Regards,
Vincenzo
[-- Attachment #2: 0001-mips-Fix-o32-and-n32-vDSO-compilation.patch --]
[-- Type: text/x-patch, Size: 2153 bytes --]
From 7bf2f8fe3b412e922f7d6d193763bee94b5b76c5 Mon Sep 17 00:00:00 2001
From: Vincenzo Frascino <vincenzo.frascino@arm.com>
Date: Mon, 24 Jun 2019 23:46:57 +0100
Subject: [PATCH] mips: Fix o32 and n32 vDSO compilation
The Unified vDSO implementation does not compile correctly for n32 and
o32 type of binaries on mips64 because the environment is not set
correctly.
Restore the correct behaviour addressing the configuration issues for
the generation of these types of binaries.
[ To be squashed with the "[PATCH v7 19/25] mips: Add support for generic
vDSO" ]
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/mips/vdso/Makefile | 6 ++++++
arch/mips/vdso/config-n32-o32-env.c | 17 +++++++++++++++++
2 files changed, 23 insertions(+)
create mode 100644 arch/mips/vdso/config-n32-o32-env.c
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index 95df49402a53..47316964150c 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -36,6 +36,12 @@ aflags-vdso := $(ccflags-vdso) \
ifneq ($(c-gettimeofday-y),)
CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
+
+# config-n32-o32-env.c prepares the environment to build a 32bit vDSO
+# library on a 64bit kernel.
+# Note: Needs to be included before than the generic library.
+CFLAGS_vgettimeofday-o32.o = -include config-n32-o32-env.c -include $(c-gettimeofday-y)
+CFLAGS_vgettimeofday-n32.o = -include config-n32-o32-env.c -include $(c-gettimeofday-y)
endif
CFLAGS_REMOVE_vgettimeofday.o = -pg
diff --git a/arch/mips/vdso/config-n32-o32-env.c b/arch/mips/vdso/config-n32-o32-env.c
new file mode 100644
index 000000000000..da4994b2b3e5
--- /dev/null
+++ b/arch/mips/vdso/config-n32-o32-env.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Configuration file for O32 and N32 binaries.
+ * Note: To be included before lib/vdso/gettimeofday.c
+ */
+#if defined(CONFIG_MIPS32_O32) || defined(CONFIG_MIPS32_N32)
+/*
+ * In case of a 32 bit VDSO for a 64 bit kernel fake a 32 bit kernel
+ * configuration.
+ */
+#undef CONFIG_64BIT
+
+#define CONFIG_32BIT 1
+#define CONFIG_GENERIC_ATOMIC64 1
+
+#endif
+
--
2.22.0
^ permalink raw reply related [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-24 23:16 ` Vincenzo Frascino
@ 2019-06-25 17:11 ` Paul Burton
2019-06-25 17:17 ` Vincenzo Frascino
0 siblings, 1 reply; 108+ messages in thread
From: Paul Burton @ 2019-06-25 17:11 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: Thomas Gleixner, linux-arch, LAK, LKML, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Daniel Lezcano, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara,
Dmitry Safonov, Andrei Vagin, Linus Torvalds, Andy Lutomirski,
Michael Kelley, Sasha Levin
Hi Vincenzo,
On Tue, Jun 25, 2019 at 12:16:55AM +0100, Vincenzo Frascino wrote:
> In the end I concluded that all the errors seen here depend on the fact that I
> tested my vdso implementation on MIPS32el only (as stated in the cover letter)
> and that when I tried to compile a 32BIT binary on a 64BIT configuration I did
> it wrongly for two reasons, for N32 and O32 binaries:
> - we need to undefine CONFIG_64BIT and define CONFIG_32BIT
> - we need to define CONFIG_GENERIC_ATOMIC64
>
> I have a fix for this (patch in attachment), but I do not have the hardware to
> test it. If you could provide some feedback would be appreciated (really want to
> see MIPS merged with the other archs in 5.3 :) ).
Thanks for the quick turnaround on your patch!
I'm certainly willing to test it, but in a few hours I'll be spending
the bulk of a day on airplanes[1] so it might take a few days until I
get to it.
Thanks,
Paul
[1] ...and travel isn't the hackathon it used to be with my 9 month old
son around :)
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-25 17:11 ` Paul Burton
@ 2019-06-25 17:17 ` Vincenzo Frascino
0 siblings, 0 replies; 108+ messages in thread
From: Vincenzo Frascino @ 2019-06-25 17:17 UTC (permalink / raw)
To: Paul Burton
Cc: Thomas Gleixner, linux-arch, LAK, LKML, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Daniel Lezcano, Mark Salyzyn,
Peter Collingbourne, Shuah Khan, Dmitry Safonov,
Rasmus Villemoes, Huw Davies, Shijith Thotton, Andre Przywara,
Dmitry Safonov, Andrei Vagin, Linus Torvalds, Andy Lutomirski,
Michael Kelley, Sasha Levin
Hi Paul,
On 25/06/2019 18:11, Paul Burton wrote:
> Hi Vincenzo,
>
> On Tue, Jun 25, 2019 at 12:16:55AM +0100, Vincenzo Frascino wrote:
>> In the end I concluded that all the errors seen here depend on the fact that I
>> tested my vdso implementation on MIPS32el only (as stated in the cover letter)
>> and that when I tried to compile a 32BIT binary on a 64BIT configuration I did
>> it wrongly for two reasons, for N32 and O32 binaries:
>> - we need to undefine CONFIG_64BIT and define CONFIG_32BIT
>> - we need to define CONFIG_GENERIC_ATOMIC64
>>
>> I have a fix for this (patch in attachment), but I do not have the hardware to
>> test it. If you could provide some feedback would be appreciated (really want to
>> see MIPS merged with the other archs in 5.3 :) ).
>
> Thanks for the quick turnaround on your patch!
>
> I'm certainly willing to test it, but in a few hours I'll be spending
> the bulk of a day on airplanes[1] so it might take a few days until I
> get to it.
>
Sounds like a plan. Let us know when you have an update.
> Thanks,
> Paul
>
> [1] ...and travel isn't the hackathon it used to be with my 9 month old
> son around :)
>
--
Regards,
Vincenzo
^ permalink raw reply [flat|nested] 108+ messages in thread
* Re: [PATCH v7 00/25] Unify vDSOs across more architectures
2019-06-21 9:52 [PATCH v7 00/25] Unify vDSOs across more architectures Vincenzo Frascino
` (25 preceding siblings ...)
2019-06-24 0:34 ` [PATCH v7 00/25] Unify vDSOs across more architectures Thomas Gleixner
@ 2019-06-24 12:50 ` Andre Przywara
26 siblings, 0 replies; 108+ messages in thread
From: Andre Przywara @ 2019-06-24 12:50 UTC (permalink / raw)
To: Vincenzo Frascino
Cc: linux-arch, linux-arm-kernel, linux-kernel, linux-mips,
linux-kselftest, Catalin Marinas, Will Deacon, Arnd Bergmann,
Russell King, Ralf Baechle, Paul Burton, Daniel Lezcano,
Thomas Gleixner, Mark Salyzyn, Peter Collingbourne, Shuah Khan,
Dmitry Safonov, Rasmus Villemoes, Huw Davies, Shijith Thotton
On Fri, 21 Jun 2019 10:52:27 +0100
Vincenzo Frascino <vincenzo.frascino@arm.com> wrote:
Hi,
> vDSO (virtual dynamic shared object) is a mechanism that the Linux
> kernel provides as an alternative to system calls to reduce where
> possible the costs in terms of cycles.
[ ... ]
Some numbers for the ARM(32) part:
I booted my trusted old Calxeda Midway server (Cortex A-15 cores) and ran
the vdsotest benchmark on it. The results are:
(vdso: times, in nsec/call; n/t: "not tested" (=not implemented))
call 5.2-rc3 5.2-rc3-vdso
clock-gettime-monotonic: 147 142
clock-getres-monotonic: n/t 34
clock-gettime-monotonic-coarse: 90 96
clock-getres-monotonic-coarse: n/t 36
clock-gettime-monotonic-raw: 431 142
clock-getres-monotonic-raw: n/t 35
clock-gettime-tai: 598 150
clock-getres-tai: n/t 34
clock-gettime-boottime: 592 142
clock-getres-boottime: n/t 34
clock-gettime-realtime: 149 142
clock-getres-realtime: n/t 34
clock-gettime-realtime-coarse: 86 96
clock-getres-realtime-coarse: n/t 36
getcpu: n/t n/t
gettimeofday: 133 110
So there are some minor improvements, two minor regressions, some
significant improvements (factor 3-4), and some dramatic improvements
(where we actually gained VDSO support).
Overall a pretty impressive outcome for an "Odd fixes" architecture,
especially as it should reduce the future maintenance burden.
Cheers,
Andre.
^ permalink raw reply [flat|nested] 108+ messages in thread