linux-kselftest.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 00/25] Unify vDSOs across more architectures
@ 2019-06-21  9:52 Vincenzo Frascino
  2019-06-21  9:52 ` [PATCH v7 01/25] kernel: Standardize vdso_datapage Vincenzo Frascino
                   ` (26 more replies)
  0 siblings, 27 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 (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.

The purpose of this patch-set is to identify the commonalities in
between the architectures and try to consolidate the common code
paths, starting with gettimeofday().

This implementation contains the following design choices:
 * Every architecture defines the arch specific code in an header in
   "asm/vdso/".
 * The generic implementation includes the arch specific one and lives
   in "lib/vdso".
 * The arch specific code for gettimeofday lives in
   "<arch path>/vdso/gettimeofday.c" and includes the generic code only.
 * The generic implementation of update_vsyscall and update_vsyscall_tz
   lives in kernel/vdso and provide the bindings that can be implemented
   by each architecture.
 * Each architecture provides its implementation of the bindings in
   "asm/vdso/vsyscall.h".
 * This approach allows to consolidate the common code in a single place
   with the benefit of avoiding code duplication.

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.

The mips porting has been tested on qemu for mips32el. A configuration to
repeat the tests can be found at [4].

The x86_64 porting has been tested on an Intel Xeon 5120T based machine
running Ubuntu 18.04 and using the Ubuntu provided defconfig.

The i386 porting has been tested on qemu using the i386_defconfig
configuration.

Last but not least from this porting arm64, compat arm64, arm and mips gain
the support for:
 * CLOCK_BOOTTIME that can be useful in certain scenarios since it keeps
   track of the time during sleep as well.
 * CLOCK_TAI that is like CLOCK_REALTIME, but uses the International
   Atomic Time (TAI) reference instead of UTC to avoid jumping on leap
   second updates.
for both clock_gettime and clock_getres.

The porting has been validated using the vdsotest test-suite [1] extended
to cover all the clock ids [2].

A new test has been added to the linux kselftest in order to validate the
newly added library.

The porting has been benchmarked and the performance results are
provided as part of this cover letter.

To simplify the testing, a copy of the patchset on top of a recent linux
tree can be found at [3] and [4].

The v7 of this patchseries has been rebased on [5].

[1] https://github.com/nathanlynch/vdsotest
[2] https://github.com/fvincenzo/vdsotest
[3] git://linux-arm.org/linux-vf.git vdso/v7
[4] git://linux-arm.org/linux-vf.git vdso-mips/v7
[5] git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git hyperv-next

Changes:
--------
v7:
  - Rebased on [5] (5.2-rc3).
  - Added performance numbers for arm64 provided by Shijith Thotton.
  - Aimed at 1:1 replacement for pre-exisiting vDSO libraries.
  - Provided separate patches for newly added API.
  - Addressed review comments.
v6:
  - Rebased on 5.2-rc2.
  - Added performance numbers.
  - Removed vdso_types.h.
  - Unified update_vsyscall and update_vsyscall_tz.
  - Reworked the kselftest included in this patchset.
  - Addressed review comments.
v5:
  - Rebased on 5.0-rc7.
  - Added x86_64, compat mode for x86_64 and i386 portings.
  - Extended vDSO kselftest.
  - Addressed review comments.
v4:
  - Rebased on 5.0-rc2.
  - Addressed review comments.
  - Disabled compat vdso on arm64 when the kernel is compiled with
    clang.
v3:
  - Ported the latest fixes and optimizations done on the x86
    architecture to the generic library.
  - Addressed review comments.
  - Improved the documentation of the interfaces.
  - Changed the HAVE_ARCH_TIMER config option to a more generic
    HAVE_HW_COUNTER.
v2:
  - Added -ffixed-x18 to arm64
  - Repleced occurrences of timeval and timespec
  - Modified datapage.h to be compliant with y2038 on all the architectures
  - Removed __u_vdso type

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Mark Salyzyn <salyzyn@android.com>
Cc: Peter Collingbourne <pcc@google.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Huw Davies <huw@codeweavers.com>
Cc: Shijith Thotton <sthotton@marvell.com>
Cc: Andre Przywara <andre.przywara@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>

Performance Numbers: Linux 5.2.0-rc2 - Xeon Gold 5120T
======================================================

Unified vDSO:
-------------

clock-gettime-monotonic: syscall: 342 nsec/call
clock-gettime-monotonic:    libc: 25 nsec/call
clock-gettime-monotonic:    vdso: 24 nsec/call
clock-getres-monotonic: syscall: 296 nsec/call
clock-getres-monotonic:    libc: 296 nsec/call
clock-getres-monotonic:    vdso: 3 nsec/call
clock-gettime-monotonic-coarse: syscall: 294 nsec/call
clock-gettime-monotonic-coarse:    libc: 5 nsec/call
clock-gettime-monotonic-coarse:    vdso: 5 nsec/call
clock-getres-monotonic-coarse: syscall: 295 nsec/call
clock-getres-monotonic-coarse:    libc: 292 nsec/call
clock-getres-monotonic-coarse:    vdso: 5 nsec/call
clock-gettime-monotonic-raw: syscall: 343 nsec/call
clock-gettime-monotonic-raw:    libc: 25 nsec/call
clock-gettime-monotonic-raw:    vdso: 23 nsec/call
clock-getres-monotonic-raw: syscall: 290 nsec/call
clock-getres-monotonic-raw:    libc: 290 nsec/call
clock-getres-monotonic-raw:    vdso: 4 nsec/call
clock-gettime-tai: syscall: 332 nsec/call
clock-gettime-tai:    libc: 24 nsec/call
clock-gettime-tai:    vdso: 23 nsec/call
clock-getres-tai: syscall: 288 nsec/call
clock-getres-tai:    libc: 288 nsec/call
clock-getres-tai:    vdso: 3 nsec/call
clock-gettime-boottime: syscall: 342 nsec/call
clock-gettime-boottime:    libc: 24 nsec/call
clock-gettime-boottime:    vdso: 23 nsec/call
clock-getres-boottime: syscall: 284 nsec/call
clock-getres-boottime:    libc: 291 nsec/call
clock-getres-boottime:    vdso: 3 nsec/call
clock-gettime-realtime: syscall: 337 nsec/call
clock-gettime-realtime:    libc: 24 nsec/call
clock-gettime-realtime:    vdso: 23 nsec/call
clock-getres-realtime: syscall: 287 nsec/call
clock-getres-realtime:    libc: 284 nsec/call
clock-getres-realtime:    vdso: 3 nsec/call
clock-gettime-realtime-coarse: syscall: 307 nsec/call
clock-gettime-realtime-coarse:    libc: 4 nsec/call
clock-gettime-realtime-coarse:    vdso: 4 nsec/call
clock-getres-realtime-coarse: syscall: 294 nsec/call
clock-getres-realtime-coarse:    libc: 291 nsec/call
clock-getres-realtime-coarse:    vdso: 4 nsec/call
getcpu: syscall: 246 nsec/call
getcpu:    libc: 14 nsec/call
getcpu:    vdso: 11 nsec/call
gettimeofday: syscall: 293 nsec/call
gettimeofday:    libc: 26 nsec/call
gettimeofday:    vdso: 25 nsec/call

Stock Kernel:
-------------

clock-gettime-monotonic: syscall: 338 nsec/call
clock-gettime-monotonic:    libc: 24 nsec/call
clock-gettime-monotonic:    vdso: 23 nsec/call
clock-getres-monotonic: syscall: 291 nsec/call
clock-getres-monotonic:    libc: 304 nsec/call
clock-getres-monotonic:    vdso: not tested
Note: vDSO version of clock_getres not found
clock-gettime-monotonic-coarse: syscall: 297 nsec/call
clock-gettime-monotonic-coarse:    libc: 5 nsec/call
clock-gettime-monotonic-coarse:    vdso: 4 nsec/call
clock-getres-monotonic-coarse: syscall: 281 nsec/call
clock-getres-monotonic-coarse:    libc: 286 nsec/call
clock-getres-monotonic-coarse:    vdso: not tested
Note: vDSO version of clock_getres not found
clock-gettime-monotonic-raw: syscall: 336 nsec/call
clock-gettime-monotonic-raw:    libc: 340 nsec/call
clock-gettime-monotonic-raw:    vdso: 346 nsec/call
clock-getres-monotonic-raw: syscall: 297 nsec/call
clock-getres-monotonic-raw:    libc: 301 nsec/call
clock-getres-monotonic-raw:    vdso: not tested
Note: vDSO version of clock_getres not found
clock-gettime-tai: syscall: 351 nsec/call
clock-gettime-tai:    libc: 24 nsec/call
clock-gettime-tai:    vdso: 23 nsec/call
clock-getres-tai: syscall: 298 nsec/call
clock-getres-tai:    libc: 290 nsec/call
clock-getres-tai:    vdso: not tested
Note: vDSO version of clock_getres not found
clock-gettime-boottime: syscall: 342 nsec/call
clock-gettime-boottime:    libc: 347 nsec/call
clock-gettime-boottime:    vdso: 355 nsec/call
clock-getres-boottime: syscall: 296 nsec/call
clock-getres-boottime:    libc: 295 nsec/call
clock-getres-boottime:    vdso: not tested
Note: vDSO version of clock_getres not found
clock-gettime-realtime: syscall: 346 nsec/call
clock-gettime-realtime:    libc: 24 nsec/call
clock-gettime-realtime:    vdso: 22 nsec/call
clock-getres-realtime: syscall: 295 nsec/call
clock-getres-realtime:    libc: 291 nsec/call
clock-getres-realtime:    vdso: not tested
Note: vDSO version of clock_getres not found
clock-gettime-realtime-coarse: syscall: 292 nsec/call
clock-gettime-realtime-coarse:    libc: 5 nsec/call
clock-gettime-realtime-coarse:    vdso: 4 nsec/call
clock-getres-realtime-coarse: syscall: 300 nsec/call
clock-getres-realtime-coarse:    libc: 301 nsec/call
clock-getres-realtime-coarse:    vdso: not tested
Note: vDSO version of clock_getres not found
getcpu: syscall: 252 nsec/call
getcpu:    libc: 14 nsec/call
getcpu:    vdso: 11 nsec/call
gettimeofday: syscall: 293 nsec/call
gettimeofday:    libc: 24 nsec/call
gettimeofday:    vdso: 25 nsec/call

Performance Numbers: Linux 5.2.0-rc2 - ThunderX2 (arm64)
========================================================

Provided by: Shijith Thotton <sthotton@marvell.com>

Unified vDSO:
-------------

clock-gettime-monotonic: syscall: 346 nsec/call
clock-gettime-monotonic:    libc: 38 nsec/call
clock-gettime-monotonic:    vdso: 36 nsec/call
clock-getres-monotonic: syscall: 262 nsec/call
clock-getres-monotonic:    libc: 6 nsec/call
clock-getres-monotonic:    vdso: 5 nsec/call
clock-gettime-monotonic-coarse: syscall: 296 nsec/call
clock-gettime-monotonic-coarse:    libc: 39 nsec/call
clock-gettime-monotonic-coarse:    vdso: 38 nsec/call
clock-getres-monotonic-coarse: syscall: 260 nsec/call
clock-getres-monotonic-coarse:    libc: 8 nsec/call
clock-getres-monotonic-coarse:    vdso: 5 nsec/call
clock-gettime-monotonic-raw: syscall: 345 nsec/call
clock-gettime-monotonic-raw:    libc: 35 nsec/call
clock-gettime-monotonic-raw:    vdso: 34 nsec/call
clock-getres-monotonic-raw: syscall: 261 nsec/call
clock-getres-monotonic-raw:    libc: 7 nsec/call
clock-getres-monotonic-raw:    vdso: 5 nsec/call
clock-gettime-tai: syscall: 357 nsec/call
clock-gettime-tai:    libc: 38 nsec/call
clock-gettime-tai:    vdso: 36 nsec/call
clock-getres-tai: syscall: 257 nsec/call
clock-getres-tai:    libc: 7 nsec/call
clock-getres-tai:    vdso: 5 nsec/call
clock-gettime-boottime: syscall: 356 nsec/call
clock-gettime-boottime:    libc: 38 nsec/call
clock-gettime-boottime:    vdso: 36 nsec/call
clock-getres-boottime: syscall: 257 nsec/call
clock-getres-boottime:    libc: 6 nsec/call
clock-getres-boottime:    vdso: 5 nsec/call
clock-gettime-realtime: syscall: 345 nsec/call
clock-gettime-realtime:    libc: 38 nsec/call
clock-gettime-realtime:    vdso: 36 nsec/call
clock-getres-realtime: syscall: 257 nsec/call
clock-getres-realtime:    libc: 7 nsec/call
clock-getres-realtime:    vdso: 5 nsec/call
clock-gettime-realtime-coarse: syscall: 295 nsec/call
clock-gettime-realtime-coarse:    libc: 39 nsec/call
clock-gettime-realtime-coarse:    vdso: 38 nsec/call
clock-getres-realtime-coarse: syscall: 260 nsec/call
clock-getres-realtime-coarse:    libc: 8 nsec/call
clock-getres-realtime-coarse:    vdso: 5 nsec/call
getcpu: syscall: 244 nsec/call
getcpu:    libc: 247 nsec/call
getcpu:    vdso: not tested
Note: vDSO version of getcpu not found
gettimeofday: syscall: 383 nsec/call
gettimeofday:    libc: 39 nsec/call
gettimeofday:    vdso: 35 nsec/call

Stock Kernel:
-------------

clock-gettime-monotonic: syscall: 344 nsec/call
clock-gettime-monotonic:    libc: 74 nsec/call
clock-gettime-monotonic:    vdso: 73 nsec/call
clock-getres-monotonic: syscall: 258 nsec/call
clock-getres-monotonic:    libc: 6 nsec/call
clock-getres-monotonic:    vdso: 4 nsec/call
clock-gettime-monotonic-coarse: syscall: 300 nsec/call
clock-gettime-monotonic-coarse:    libc: 36 nsec/call
clock-gettime-monotonic-coarse:    vdso: 34 nsec/call
clock-getres-monotonic-coarse: syscall: 261 nsec/call
clock-getres-monotonic-coarse:    libc: 6 nsec/call
clock-getres-monotonic-coarse:    vdso: 4 nsec/call
clock-gettime-monotonic-raw: syscall: 346 nsec/call
clock-gettime-monotonic-raw:    libc: 74 nsec/call
clock-gettime-monotonic-raw:    vdso: 72 nsec/call
clock-getres-monotonic-raw: syscall: 254 nsec/call
clock-getres-monotonic-raw:    libc: 6 nsec/call
clock-getres-monotonic-raw:    vdso: 4 nsec/call
clock-gettime-tai: syscall: 345 nsec/call
clock-gettime-tai:    libc: 361 nsec/call
clock-gettime-tai:    vdso: 359 nsec/call
clock-getres-tai: syscall: 259 nsec/call
clock-getres-tai:    libc: 262 nsec/call
clock-getres-tai:    vdso: 258 nsec/call
clock-gettime-boottime: syscall: 353 nsec/call
clock-gettime-boottime:    libc: 365 nsec/call
clock-gettime-boottime:    vdso: 362 nsec/call
clock-getres-boottime: syscall: 260 nsec/call
clock-getres-boottime:    libc: 267 nsec/call
clock-getres-boottime:    vdso: 259 nsec/call
clock-gettime-realtime: syscall: 344 nsec/call
clock-gettime-realtime:    libc: 73 nsec/call
clock-gettime-realtime:    vdso: 72 nsec/call
clock-getres-realtime: syscall: 255 nsec/call
clock-getres-realtime:    libc: 7 nsec/call
clock-getres-realtime:    vdso: 4 nsec/call
clock-gettime-realtime-coarse: syscall: 296 nsec/call
clock-gettime-realtime-coarse:    libc: 35 nsec/call
clock-gettime-realtime-coarse:    vdso: 33 nsec/call
clock-getres-realtime-coarse: syscall: 258 nsec/call
clock-getres-realtime-coarse:    libc: 6 nsec/call
clock-getres-realtime-coarse:    vdso: 4 nsec/call
getcpu: syscall: 237 nsec/call
getcpu:    libc: 242 nsec/call
getcpu:    vdso: not tested
Note: vDSO version of getcpu not found
gettimeofday: syscall: 378 nsec/call
gettimeofday:    libc: 73 nsec/call
gettimeofday:    vdso: 70 nsec/call

Peter Collingbourne (1):
  arm64: Build vDSO with -ffixed-x18

Vincenzo Frascino (24):
  kernel: Standardize vdso_datapage
  kernel: Define gettimeofday vdso common code
  kernel: Unify update_vsyscall implementation
  arm64: Substitute gettimeofday with C implementation
  arm64: compat: Add missing syscall numbers
  arm64: compat: Expose signal related structures
  arm64: compat: Generate asm offsets for signals
  lib: vdso: Add compat support
  arm64: compat: Add vDSO
  arm64: Refactor vDSO code
  arm64: compat: vDSO setup for compat layer
  arm64: elf: vDSO code page discovery
  arm64: compat: Get sigreturn trampolines from vDSO
  arm64: Add vDSO compat support
  arm: Add support for generic vDSO
  arm: Add clock_getres entry point
  arm: Add clock_gettime64 entry point
  mips: Add support for generic vDSO
  mips: Add clock_getres entry point
  mips: Add clock_gettime64 entry point
  x86: Add support for generic vDSO
  x86: Add clock_getres entry point
  x86: Add clock_gettime64 entry point
  kselftest: Extend vDSO selftest

 arch/arm/Kconfig                              |   3 +
 arch/arm/include/asm/vdso/gettimeofday.h      |  94 +++++
 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/vdso.lds.S                      |   2 +
 arch/arm/vdso/vgettimeofday.c                 | 256 +------------
 arch/arm64/Kconfig                            |   3 +
 arch/arm64/Makefile                           |  23 +-
 arch/arm64/include/asm/elf.h                  |  14 +
 arch/arm64/include/asm/signal32.h             |  46 +++
 arch/arm64/include/asm/unistd.h               |   5 +
 arch/arm64/include/asm/vdso.h                 |   3 +
 arch/arm64/include/asm/vdso/compat_barrier.h  |  51 +++
 .../include/asm/vdso/compat_gettimeofday.h    | 110 ++++++
 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/Makefile                    |   6 +-
 arch/arm64/kernel/asm-offsets.c               |  39 +-
 arch/arm64/kernel/signal32.c                  |  72 ++--
 arch/arm64/kernel/vdso.c                      | 356 ++++++++++++------
 arch/arm64/kernel/vdso/Makefile               |  34 +-
 arch/arm64/kernel/vdso/gettimeofday.S         | 334 ----------------
 arch/arm64/kernel/vdso/vgettimeofday.c        |  28 ++
 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 +++
 arch/mips/Kconfig                             |   2 +
 arch/mips/include/asm/vdso.h                  |  78 +---
 arch/mips/include/asm/vdso/gettimeofday.h     | 177 +++++++++
 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/vdso.lds.S                     |   4 +
 arch/mips/vdso/vgettimeofday.c                |  58 +++
 arch/x86/Kconfig                              |   3 +
 arch/x86/entry/vdso/Makefile                  |   9 +
 arch/x86/entry/vdso/vclock_gettime.c          | 249 +++---------
 arch/x86/entry/vdso/vdso.lds.S                |   2 +
 arch/x86/entry/vdso/vdso32/vdso32.lds.S       |   2 +
 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      | 205 ++++++++++
 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 +
 include/asm-generic/vdso/vsyscall.h           |  56 +++
 include/linux/hrtimer.h                       |  15 +-
 include/linux/hrtimer_defs.h                  |  25 ++
 include/linux/timekeeper_internal.h           |   9 +
 include/vdso/datapage.h                       |  93 +++++
 include/vdso/helpers.h                        |  56 +++
 include/vdso/vsyscall.h                       |  11 +
 kernel/Makefile                               |   1 +
 kernel/vdso/Makefile                          |   2 +
 kernel/vdso/vsyscall.c                        | 131 +++++++
 lib/Kconfig                                   |   5 +
 lib/vdso/Kconfig                              |  36 ++
 lib/vdso/Makefile                             |  22 ++
 lib/vdso/gettimeofday.c                       | 231 ++++++++++++
 tools/testing/selftests/vDSO/Makefile         |   2 +
 tools/testing/selftests/vDSO/vdso_config.h    |  90 +++++
 tools/testing/selftests/vDSO/vdso_full_test.c | 244 ++++++++++++
 76 files changed, 3044 insertions(+), 1412 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
 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/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
 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
 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
 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
 create mode 100644 include/asm-generic/vdso/vsyscall.h
 create mode 100644 include/linux/hrtimer_defs.h
 create mode 100644 include/vdso/datapage.h
 create mode 100644 include/vdso/helpers.h
 create mode 100644 include/vdso/vsyscall.h
 create mode 100644 kernel/vdso/Makefile
 create mode 100644 kernel/vdso/vsyscall.c
 create mode 100644 lib/vdso/Kconfig
 create mode 100644 lib/vdso/Makefile
 create mode 100644 lib/vdso/gettimeofday.c
 create mode 100644 tools/testing/selftests/vDSO/vdso_config.h
 create mode 100644 tools/testing/selftests/vDSO/vdso_full_test.c

-- 
2.21.0


^ permalink raw reply	[flat|nested] 108+ messages in thread

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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 = &gtod->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 = &gtod->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 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

* 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-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

* 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 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 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

* 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-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

* 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 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  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 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

* [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 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

* [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

* 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

* [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

* 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

* 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

* 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  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  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

* [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 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

* 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

* 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

* 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

* 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 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

* 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 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

end of thread, other threads:[~2019-12-05 14:56 UTC | newest]

Thread overview: 108+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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-24 13:56   ` Catalin Marinas
2019-06-21  9:52 ` [PATCH v7 02/25] kernel: Define gettimeofday vdso common code Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 03/25] kernel: Unify update_vsyscall implementation 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
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-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       ` [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-25 22:24             ` Thomas Gleixner
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
2019-06-26 11:08               ` Vincenzo Frascino
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-26 16:14       ` Dave Martin
2019-06-26 19:01         ` Vincenzo Frascino
2019-06-27 10:01           ` Dave Martin
2019-06-27 10:57             ` Vincenzo Frascino
2019-06-27 11:27               ` Dave Martin
2019-06-27 11:59                 ` Vincenzo Frascino
2019-06-27 14:38                   ` Dave Martin
2019-06-27 15:34                     ` Vincenzo Frascino
2019-06-25 17:43   ` [PATCH] arm64: vdso: Fix compilation with clang < 8 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>
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
2019-06-29  6:58           ` Vincenzo Frascino
2019-07-08 12:57             ` Sylwester Nawrocki
2019-07-08 13:09               ` Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 05/25] arm64: Build vDSO with -ffixed-x18 Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 06/25] arm64: compat: Add missing syscall numbers Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 07/25] arm64: compat: Expose signal related structures Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 08/25] arm64: compat: Generate asm offsets for signals Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 09/25] lib: vdso: Add compat support Vincenzo Frascino
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
2019-07-10  9:48       ` Vincenzo Frascino
2019-07-10  8:27     ` Will Deacon
2019-07-10  8:58       ` Thomas Gleixner
2019-07-10  9:12         ` Will Deacon
2019-07-10  9:47     ` Vincenzo Frascino
2019-07-10 13:41       ` Vincenzo Frascino
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
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
2019-07-11 10:34       ` Thomas Gleixner
2019-07-11 11:32         ` Will Deacon
2019-06-21  9:52 ` [PATCH v7 11/25] arm64: Refactor vDSO code Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 12/25] arm64: compat: vDSO setup for compat layer Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 13/25] arm64: elf: vDSO code page discovery Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 14/25] arm64: compat: Get sigreturn trampolines from vDSO Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 15/25] arm64: Add vDSO compat support Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 16/25] arm: Add support for generic vDSO Vincenzo Frascino
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
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
2019-12-05 11:02               ` Arnd Bergmann
2019-12-05 14:56                 ` Philippe Mathieu-Daudé
2019-06-21  9:52 ` [PATCH v7 17/25] arm: Add clock_getres entry point Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 18/25] arm: Add clock_gettime64 " Vincenzo Frascino
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
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       ` [PATCH 0/2] mips: vdso: Fix Makefile Paul Burton
2019-06-21  9:52 ` [PATCH v7 20/25] mips: Add clock_getres entry point Vincenzo Frascino
2019-07-26  5:15   ` Paul Burton
2019-06-21  9:52 ` [PATCH v7 21/25] mips: Add clock_gettime64 " 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
2019-06-21  9:52 ` [PATCH v7 23/25] x86: Add clock_getres entry point Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 24/25] x86: Add clock_gettime64 " Vincenzo Frascino
2019-06-21  9:52 ` [PATCH v7 25/25] kselftest: Extend vDSO selftest Vincenzo Frascino
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
2019-06-24 14:18   ` Thomas Gleixner
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
2019-06-24 18:41   ` Paul Burton
2019-06-24 23:16     ` Vincenzo Frascino
2019-06-25 17:11       ` Paul Burton
2019-06-25 17:17         ` Vincenzo Frascino
2019-06-24 12:50 ` Andre Przywara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).