mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									e1bdb22ebe
								
							
						
					
					
						commit
						5e3c6a312a
					
				
					 11 changed files with 29 additions and 57 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,18 +11,6 @@
 | 
			
		|||
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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue