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 97864aa..03bbfc3 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 0b350a7..73beb7f 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 f4757d3..07d791c 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 85a7e58..002f9ed 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.
  */
@@ -41,15 +29,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)
 {
        flush_dcache_page(virt_to_page(vdata));
index 65e4482..865e888 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 0b30e88..7809d49 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 0ece64a..eb82e9d 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 537b1e6..81b0c39 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 b08f476..5a53443 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 0c20a7c..f94b145 100644 (file)
@@ -22,15 +22,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)
 {
        vdata[CS_HRES_COARSE].mask      = VDSO_PRECISION_MASK;
index 9a5464c..ee2420d 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;
        }