ARM/arm64: vdso: Use common vdso clock mode storage

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
This commit is contained in:
Thomas Gleixner 2020-02-07 13:38:58 +01:00
parent e1bdb22ebe
commit 5e3c6a312a
11 changed files with 29 additions and 57 deletions

View File

@ -3,7 +3,6 @@ config ARM
bool bool
default y default y
select ARCH_32BIT_OFF_T select ARCH_32BIT_OFF_T
select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_DEBUG_VIRTUAL if MMU select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_DEVMEM_IS_ALLOWED

View File

@ -1,8 +1,7 @@
#ifndef _ASM_CLOCKSOURCE_H #ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H #define _ASM_CLOCKSOURCE_H
struct arch_clocksource_data { #define VDSO_ARCH_CLOCKMODES \
bool vdso_direct; /* Usable for direct VDSO access? */ VDSO_CLOCKMODE_ARCHTIMER
};
#endif #endif

View File

@ -117,15 +117,21 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode)
#ifdef CONFIG_ARM_ARCH_TIMER #ifdef CONFIG_ARM_ARCH_TIMER
u64 cycle_now; 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(); isb();
cycle_now = read_sysreg(CNTVCT); cycle_now = read_sysreg(CNTVCT);
return cycle_now; return cycle_now;
#else #else
return -EINVAL; /* use fallback */ /* Make GCC happy. This is compiled out anyway */
return 0;
#endif #endif
} }

View File

@ -11,18 +11,6 @@
extern struct vdso_data *vdso_data; extern struct vdso_data *vdso_data;
extern bool cntvct_ok; 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. * 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 #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 static __always_inline
void __arm_sync_vdso_data(struct vdso_data *vdata) void __arm_sync_vdso_data(struct vdso_data *vdata)
{ {

View File

@ -900,6 +900,7 @@ config VDSO
select GENERIC_TIME_VSYSCALL select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_32 select GENERIC_VDSO_32
select GENERIC_GETTIMEOFDAY select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_CLOCK_MODE
help help
Place in the process address space an ELF shared object Place in the process address space an ELF shared object
providing fast implementations of gettimeofday and providing fast implementations of gettimeofday and

View File

@ -9,7 +9,6 @@ config ARM64
select ACPI_MCFG if (ACPI && PCI) select ACPI_MCFG if (ACPI && PCI)
select ACPI_SPCR_TABLE if ACPI select ACPI_SPCR_TABLE if ACPI
select ACPI_PPTT if ACPI select ACPI_PPTT if ACPI
select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_DEBUG_VIRTUAL select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_PREP_COHERENT select ARCH_HAS_DMA_PREP_COHERENT
@ -111,6 +110,7 @@ config ARM64
select GENERIC_STRNLEN_USER select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_CLOCK_MODE
select HANDLE_DOMAIN_IRQ select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND select HARDIRQS_SW_RESEND
select HAVE_PCI select HAVE_PCI

View File

@ -2,8 +2,7 @@
#ifndef _ASM_CLOCKSOURCE_H #ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H #define _ASM_CLOCKSOURCE_H
struct arch_clocksource_data { #define VDSO_ARCH_CLOCKMODES \
bool vdso_direct; /* Usable for direct VDSO access? */ VDSO_CLOCKMODE_ARCHTIMER
};
#endif #endif

View File

@ -12,8 +12,6 @@
#include <asm/vdso/compat_barrier.h> #include <asm/vdso/compat_barrier.h>
#define __VDSO_USE_SYSCALL ULLONG_MAX
#define VDSO_HAS_CLOCK_GETRES 1 #define VDSO_HAS_CLOCK_GETRES 1
#define BUILD_VDSO32 1 #define BUILD_VDSO32 1
@ -117,11 +115,12 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
u64 res; u64 res;
/* /*
* clock_mode == 0 implies that vDSO are enabled otherwise * Core checks for mode already, so this raced against a concurrent
* fallback on syscall. * update. Return something. Core will do another round and then
* see the mode change and fallback to the syscall.
*/ */
if (clock_mode) if (clock_mode == VDSO_CLOCKMODE_NONE)
return __VDSO_USE_SYSCALL; return 0;
/* /*
* This isb() is required to prevent that the counter value * This isb() is required to prevent that the counter value

View File

@ -10,8 +10,6 @@
#include <asm/unistd.h> #include <asm/unistd.h>
#include <uapi/linux/time.h> #include <uapi/linux/time.h>
#define __VDSO_USE_SYSCALL ULLONG_MAX
#define VDSO_HAS_CLOCK_GETRES 1 #define VDSO_HAS_CLOCK_GETRES 1
static __always_inline static __always_inline
@ -71,11 +69,12 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
u64 res; u64 res;
/* /*
* clock_mode == 0 implies that vDSO are enabled otherwise * Core checks for mode already, so this raced against a concurrent
* fallback on syscall. * update. Return something. Core will do another round and then
* see the mode change and fallback to the syscall.
*/ */
if (clock_mode) if (clock_mode == VDSO_CLOCKMODE_NONE)
return __VDSO_USE_SYSCALL; return 0;
/* /*
* This isb() is required to prevent that the counter value * This isb() is required to prevent that the counter value

View 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 #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 static __always_inline
void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk) void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
{ {

View 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_c3stop;
static bool arch_timer_mem_use_virtual; static bool arch_timer_mem_use_virtual;
static bool arch_counter_suspend_stop; 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 cpumask_t evtstrm_available = CPU_MASK_NONE;
static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); 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. * change both the default value and the vdso itself.
*/ */
if (wa->read_cntvct_el0) { if (wa->read_cntvct_el0) {
clocksource_counter.archdata.vdso_direct = false; clocksource_counter.vdso_clock_mode = VDSO_CLOCKMODE_NONE;
vdso_default = false; vdso_default = VDSO_CLOCKMODE_NONE;
} }
} }
@ -979,7 +979,7 @@ static void __init arch_counter_register(unsigned type)
} }
arch_timer_read_counter = rd; arch_timer_read_counter = rd;
clocksource_counter.archdata.vdso_direct = vdso_default; clocksource_counter.vdso_clock_mode = vdso_default;
} else { } else {
arch_timer_read_counter = arch_counter_get_cntvct_mem; arch_timer_read_counter = arch_counter_get_cntvct_mem;
} }