ARM/arm64: vdso: Use common vdso clock mode storage
authorThomas Gleixner <tglx@linutronix.de>
Fri, 7 Feb 2020 12:38:58 +0000 (13:38 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 17 Feb 2020 19:12:16 +0000 (20:12 +0100)
Convert ARM/ARM64 to the generic VDSO clock mode storage. This needs to
happen in one go as they share the clocksource driver.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Link: https://lkml.kernel.org/r/20200207124403.363235229@linutronix.de
arch/arm/Kconfig
arch/arm/include/asm/clocksource.h
arch/arm/include/asm/vdso/gettimeofday.h
arch/arm/include/asm/vdso/vsyscall.h
arch/arm/mm/Kconfig
arch/arm64/Kconfig
arch/arm64/include/asm/clocksource.h
arch/arm64/include/asm/vdso/compat_gettimeofday.h
arch/arm64/include/asm/vdso/gettimeofday.h
arch/arm64/include/asm/vdso/vsyscall.h
drivers/clocksource/arm_arch_timer.c

index 97864aabc2a6fa2aa7c86df3b19454b7e68c3dda..03bbfc312fe72f5f2b731b45fe4f896940c083a8 100644 (file)
@@ -3,7 +3,6 @@ config ARM
        bool
        default y
        select ARCH_32BIT_OFF_T
-       select ARCH_CLOCKSOURCE_DATA
        select ARCH_HAS_BINFMT_FLAT
        select ARCH_HAS_DEBUG_VIRTUAL if MMU
        select ARCH_HAS_DEVMEM_IS_ALLOWED
index 0b350a7e26f37c1dfec80cb85610add6b9bbef99..73beb7f131deed4e10bc8c053a83362d109a6f2b 100644 (file)
@@ -1,8 +1,7 @@
 #ifndef _ASM_CLOCKSOURCE_H
 #define _ASM_CLOCKSOURCE_H
 
-struct arch_clocksource_data {
-       bool vdso_direct;       /* Usable for direct VDSO access? */
-};
+#define VDSO_ARCH_CLOCKMODES   \
+       VDSO_CLOCKMODE_ARCHTIMER
 
 #endif
index f4757d327f432ed8986ea653c9cf1003d3c12556..07d791c65cf74aab032f5f218a6caafa2672bac3 100644 (file)
@@ -117,15 +117,21 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode)
 #ifdef CONFIG_ARM_ARCH_TIMER
        u64 cycle_now;
 
-       if (!clock_mode)
-               return -EINVAL;
+       /*
+        * Core checks for mode already, so this raced against a concurrent
+        * update. Return something. Core will do another round and then
+        * see the mode change and fallback to the syscall.
+        */
+       if (clock_mode == VDSO_CLOCKMODE_NONE)
+               return 0;
 
        isb();
        cycle_now = read_sysreg(CNTVCT);
 
        return cycle_now;
 #else
-       return -EINVAL; /* use fallback */
+       /* Make GCC happy. This is compiled out anyway */
+       return 0;
 #endif
 }
 
index 85a7e58b722810798b40423b057b5a2507aacf15..002f9edd8a2b37d936076c875fdbc438a921cc4b 100644 (file)
 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.
  */
@@ -40,15 +28,6 @@ bool __arm_update_vdso_data(void)
 }
 #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
 void __arm_sync_vdso_data(struct vdso_data *vdata)
 {
index 65e4482e384981e260f9e52a21d2abceaac1caae..865e888bb84f74e6ad9bdebe1fa9c45ed6969e9a 100644 (file)
@@ -900,6 +900,7 @@ config VDSO
        select GENERIC_TIME_VSYSCALL
        select GENERIC_VDSO_32
        select GENERIC_GETTIMEOFDAY
+       select GENERIC_VDSO_CLOCK_MODE
        help
          Place in the process address space an ELF shared object
          providing fast implementations of gettimeofday and
index 0b30e884e0889ae0203258360e76d849dc2f133e..7809d4976269683125cdd1c4a0a6da7c2bd12caf 100644 (file)
@@ -9,7 +9,6 @@ config ARM64
        select ACPI_MCFG if (ACPI && PCI)
        select ACPI_SPCR_TABLE if ACPI
        select ACPI_PPTT if ACPI
-       select ARCH_CLOCKSOURCE_DATA
        select ARCH_HAS_DEBUG_VIRTUAL
        select ARCH_HAS_DEVMEM_IS_ALLOWED
        select ARCH_HAS_DMA_PREP_COHERENT
@@ -111,6 +110,7 @@ config ARM64
        select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select GENERIC_GETTIMEOFDAY
+       select GENERIC_VDSO_CLOCK_MODE
        select HANDLE_DOMAIN_IRQ
        select HARDIRQS_SW_RESEND
        select HAVE_PCI
index 0ece64a26c8c94d04c7aac8a35b7bc8dd0000b85..eb82e9d95c5d4422844d6fc895a6ddbac4a72ec5 100644 (file)
@@ -2,8 +2,7 @@
 #ifndef _ASM_CLOCKSOURCE_H
 #define _ASM_CLOCKSOURCE_H
 
-struct arch_clocksource_data {
-       bool vdso_direct;       /* Usable for direct VDSO access? */
-};
+#define VDSO_ARCH_CLOCKMODES   \
+       VDSO_CLOCKMODE_ARCHTIMER
 
 #endif
index 537b1e6953659836a25758aa8aeb5c1441286d6d..81b0c394f1d8174d37807c35693883a891171aa7 100644 (file)
@@ -12,8 +12,6 @@
 
 #include <asm/vdso/compat_barrier.h>
 
-#define __VDSO_USE_SYSCALL             ULLONG_MAX
-
 #define VDSO_HAS_CLOCK_GETRES          1
 
 #define BUILD_VDSO32                   1
@@ -117,11 +115,12 @@ 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.
+        * Core checks for mode already, so this raced against a concurrent
+        * update. Return something. Core will do another round and then
+        * see the mode change and fallback to the syscall.
         */
-       if (clock_mode)
-               return __VDSO_USE_SYSCALL;
+       if (clock_mode == VDSO_CLOCKMODE_NONE)
+               return 0;
 
        /*
         * This isb() is required to prevent that the counter value
index b08f476b72b4d917d93edc5c61bae1c6178bf5f5..5a534432aa5dfe9be881ff063f0f08ce7d1840a7 100644 (file)
@@ -10,8 +10,6 @@
 #include <asm/unistd.h>
 #include <uapi/linux/time.h>
 
-#define __VDSO_USE_SYSCALL             ULLONG_MAX
-
 #define VDSO_HAS_CLOCK_GETRES          1
 
 static __always_inline
@@ -71,11 +69,12 @@ 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.
+        * Core checks for mode already, so this raced against a concurrent
+        * update. Return something. Core will do another round and then
+        * see the mode change and fallback to the syscall.
         */
-       if (clock_mode)
-               return __VDSO_USE_SYSCALL;
+       if (clock_mode == VDSO_CLOCKMODE_NONE)
+               return 0;
 
        /*
         * This isb() is required to prevent that the counter value
index 0c20a7c1bee506d453c7635dedf887a5b0c77e33..f94b1457c117d4d3e94b1fe04bc0e097b2dfeaf1 100644 (file)
@@ -21,15 +21,6 @@ struct vdso_data *__arm64_get_k_vdso_data(void)
 }
 #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
 void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
 {
index 9a5464c625b45a04d7f52d6bc8b96bbfd99066b8..ee2420d56f67da8c93eece2d0439f378a6d86bc5 100644 (file)
@@ -69,7 +69,7 @@ static enum arch_timer_ppi_nr arch_timer_uses_ppi = ARCH_TIMER_VIRT_PPI;
 static bool arch_timer_c3stop;
 static bool arch_timer_mem_use_virtual;
 static bool arch_counter_suspend_stop;
-static bool vdso_default = true;
+static enum vdso_clock_mode vdso_default = VDSO_CLOCKMODE_ARCHTIMER;
 
 static cpumask_t evtstrm_available = CPU_MASK_NONE;
 static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
@@ -560,8 +560,8 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
         * change both the default value and the vdso itself.
         */
        if (wa->read_cntvct_el0) {
-               clocksource_counter.archdata.vdso_direct = false;
-               vdso_default = false;
+               clocksource_counter.vdso_clock_mode = VDSO_CLOCKMODE_NONE;
+               vdso_default = VDSO_CLOCKMODE_NONE;
        }
 }
 
@@ -979,7 +979,7 @@ static void __init arch_counter_register(unsigned type)
                }
 
                arch_timer_read_counter = rd;
-               clocksource_counter.archdata.vdso_direct = vdso_default;
+               clocksource_counter.vdso_clock_mode = vdso_default;
        } else {
                arch_timer_read_counter = arch_counter_get_cntvct_mem;
        }