Skip to contentSkip to conversation

arm_arch_timer: VDSO preparation, code consolidation

PATCH New Nathan Lynch 2 participants 7 messages Aug 22, 2014 – Sep 3, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover arm_arch_timer: VDSO preparation, code consolidation

This series contains the necessary changes to allow architected timer access from user-space on 32-bit ARM. This allows the VDSO to support high resolution timestamps for clock_gettime and gettimeofday. This also merges substantially similar code from arm and arm64 into the core arm_arch_timer driver.

These patches have been carried as part of the ARM VDSO patch set over the last several months, but I am splitting them out here as I assume they should go through the clocksource maintainer.

Nathan Lynch (4):
clocksource: arm_arch_timer: change clocksource name if CP15
unavailable
clocksource: arm_arch_timer: enable counter access for 32-bit ARM
ARM: arch_timer: remove unused functions
arm64: arch_timer: remove unused functions

 arch/arm/include/asm/arch_timer.h    | 25 -------------------
 arch/arm64/include/asm/arch_timer.h  | 31 -----------------------
 drivers/clocksource/arm_arch_timer.c | 48 +++++++++++++++++++++++++++++++++---
 3 files changed, 44 insertions(+), 60 deletions(-)
Signature · 1 line
1.9.3
#1 lore raw

PATCH 1/4 clocksource: arm_arch_timer: change clocksource name if CP15 unavailable

The arm and arm64 VDSOs need CP15 access to the architected counter. If this is unavailable (which is allowed by ARM v7), indicate this by changing the clocksource name to "arch_mem_counter" before registering the clocksource.

Suggested by Stephen Boyd.

---
 drivers/clocksource/arm_arch_timer.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/clocksource/arm_arch_timer.c +10 -2
index 5163ec13429d..c99afdf12e98 100644
@@ -429,11 +429,19 @@ static void __init arch_counter_register(unsigned type)
 	u64 start_count;
 
 	/* Register the CP15 based counter if we have one */
-	if (type & ARCH_CP15_TIMER)
+	if (type & ARCH_CP15_TIMER) {
 		arch_timer_read_counter = arch_counter_get_cntvct;
-	else
+	} else {
 		arch_timer_read_counter = arch_counter_get_cntvct_mem;
 
+		/* If the clocksource name is "arch_sys_counter" the
+		 * VDSO will attempt to read the CP15-based counter.
+		 * Ensure this does not happen when CP15-based
+		 * counter is not available.
+		 */
+		clocksource_counter.name = "arch_mem_counter";
+	}
+
 	start_count = arch_timer_read_counter();
 	clocksource_register_hz(&clocksource_counter, arch_timer_rate);
 	cyclecounter.mult = clocksource_counter.mult;
Signature · 1 line
1.9.3
#2 lore raw

PATCH 2/4 clocksource: arm_arch_timer: enable counter access for 32-bit ARM

In reply to Nathan Lynch

The only difference between arm and arm64's implementations of arch_counter_set_user_access is that 32-bit ARM does not enable user access to the virtual counter. We want to enable this access for the 32-bit ARM VDSO, so copy the arm64 version to the driver itself, giving it a slightly different name (arch_counter_set_access) to avoid redefinition.

The arch_timer_evtstrm_enable hooks are also substantially similar, the only difference being a CONFIG_COMPAT-conditional section which is relevant only for arm64. Copy the arm64 version to the driver, again slightly renaming (arch_timer_evtstrm_enable => arch_timer_enable_evtstrm).

With this change, the arch_counter_set_user_access and arch_timer_evtstrm_enable hooks in both arm and arm64 become unused, to be removed in followup patches.

---
 drivers/clocksource/arm_arch_timer.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)
drivers/clocksource/arm_arch_timer.c +34 -2
index c99afdf12e98..0188332ad24b 100644
@@ -23,6 +23,7 @@
 #include <linux/sched_clock.h>
 
 #include <asm/arch_timer.h>
+#include <asm/hwcap.h>
 #include <asm/virt.h>
 
 #include <clocksource/arm_arch_timer.h>
@@ -299,6 +300,20 @@ static void __arch_timer_setup(unsigned type,
 	clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
 }
 
+static void arch_timer_enable_evtstrm(int divider)
+{
+	u32 cntkctl = arch_timer_get_cntkctl();
+	cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
+	/* Set the divider and enable virtual event stream */
+	cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
+			| ARCH_TIMER_VIRT_EVT_EN;
+	arch_timer_set_cntkctl(cntkctl);
+	elf_hwcap |= HWCAP_EVTSTRM;
+#ifdef CONFIG_COMPAT
+	compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
+#endif
+}
+
 static void arch_timer_configure_evtstream(void)
 {
 	int evt_stream_div, pos;
@@ -309,7 +324,24 @@ static void arch_timer_configure_evtstream(void)
 	if (pos > 1 && !(evt_stream_div & (1 << (pos - 2))))
 		pos--;
 	/* enable event stream */
-	arch_timer_evtstrm_enable(min(pos, 15));
+	arch_timer_enable_evtstrm(min(pos, 15));
+}
+
+static void arch_counter_set_access(void)
+{
+	u32 cntkctl = arch_timer_get_cntkctl();
+
+	/* Disable user access to the timers and the physical counter */
+	/* Also disable virtual event stream */
+	cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
+			| ARCH_TIMER_USR_VT_ACCESS_EN
+			| ARCH_TIMER_VIRT_EVT_EN
+			| ARCH_TIMER_USR_PCT_ACCESS_EN);
+
+	/* Enable user access to the virtual counter */
+	cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
+
+	arch_timer_set_cntkctl(cntkctl);
 }
 
 static int arch_timer_setup(struct clock_event_device *clk)
@@ -324,7 +356,7 @@ static int arch_timer_setup(struct clock_event_device *clk)
 			enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0);
 	}
 
-	arch_counter_set_user_access();
+	arch_counter_set_access();
 	if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM))
 		arch_timer_configure_evtstream();
 
Signature · 1 line
1.9.3
#3 lore raw

PATCH 3/4 ARM: arch_timer: remove unused functions

In reply to Nathan Lynch

The counter access and evtstream configuration are now done in common code, so remove the now-unused arch_counter_set_user_access and arch_timer_evtstrm_enable.

---
 arch/arm/include/asm/arch_timer.h | 25 -------------------------
 1 file changed, 25 deletions(-)
arch/arm/include/asm/arch_timer.h +0 -25
index 0704e0cf5571..92793ba69c40 100644
@@ -99,31 +99,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
 	asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
 }
 
-static inline void arch_counter_set_user_access(void)
-{
-	u32 cntkctl = arch_timer_get_cntkctl();
-
-	/* Disable user access to both physical/virtual counters/timers */
-	/* Also disable virtual event stream */
-	cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
-			| ARCH_TIMER_USR_VT_ACCESS_EN
-			| ARCH_TIMER_VIRT_EVT_EN
-			| ARCH_TIMER_USR_VCT_ACCESS_EN
-			| ARCH_TIMER_USR_PCT_ACCESS_EN);
-	arch_timer_set_cntkctl(cntkctl);
-}
-
-static inline void arch_timer_evtstrm_enable(int divider)
-{
-	u32 cntkctl = arch_timer_get_cntkctl();
-	cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
-	/* Set the divider and enable virtual event stream */
-	cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
-			| ARCH_TIMER_VIRT_EVT_EN;
-	arch_timer_set_cntkctl(cntkctl);
-	elf_hwcap |= HWCAP_EVTSTRM;
-}
-
 #endif
 
 #endif
Signature · 1 line
1.9.3
#4 lore raw

PATCH 4/4 arm64: arch_timer: remove unused functions

In reply to Nathan Lynch

The counter access and evtstream configuration are now done in common code, so remove the now-unused arch_counter_set_user_access and arch_timer_evtstrm_enable.

---
 arch/arm64/include/asm/arch_timer.h | 31 -------------------------------
 1 file changed, 31 deletions(-)
arch/arm64/include/asm/arch_timer.h +0 -31
index 9400596a0f39..f19097134b02 100644
@@ -104,37 +104,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
 	asm volatile("msr	cntkctl_el1, %0" : : "r" (cntkctl));
 }
 
-static inline void arch_counter_set_user_access(void)
-{
-	u32 cntkctl = arch_timer_get_cntkctl();
-
-	/* Disable user access to the timers and the physical counter */
-	/* Also disable virtual event stream */
-	cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
-			| ARCH_TIMER_USR_VT_ACCESS_EN
-			| ARCH_TIMER_VIRT_EVT_EN
-			| ARCH_TIMER_USR_PCT_ACCESS_EN);
-
-	/* Enable user access to the virtual counter */
-	cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
-
-	arch_timer_set_cntkctl(cntkctl);
-}
-
-static inline void arch_timer_evtstrm_enable(int divider)
-{
-	u32 cntkctl = arch_timer_get_cntkctl();
-	cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
-	/* Set the divider and enable virtual event stream */
-	cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
-			| ARCH_TIMER_VIRT_EVT_EN;
-	arch_timer_set_cntkctl(cntkctl);
-	elf_hwcap |= HWCAP_EVTSTRM;
-#ifdef CONFIG_COMPAT
-	compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
-#endif
-}
-
 static inline u64 arch_counter_get_cntvct(void)
 {
 	u64 cval;
Signature · 1 line
1.9.3
#6 lore raw

cover arm_arch_timer: VDSO preparation, code consolidation

In reply to Nathan Lynch
Quoted 17 lines · Nathan Lynch

This series contains the necessary changes to allow architected timer access from user-space on 32-bit ARM. This allows the VDSO to support high resolution timestamps for clock_gettime and gettimeofday. This also merges substantially similar code from arm and arm64 into the core arm_arch_timer driver.

These patches have been carried as part of the ARM VDSO patch set over the last several months, but I am splitting them out here as I assume they should go through the clocksource maintainer.

Nathan Lynch (4):
clocksource: arm_arch_timer: change clocksource name if CP15
unavailable
clocksource: arm_arch_timer: enable counter access for 32-bit ARM
ARM: arch_timer: remove unused functions
arm64: arch_timer: remove unused functions

Quoted 4 lines
 arch/arm/include/asm/arch_timer.h    | 25 -------------------
 arch/arm64/include/asm/arch_timer.h  | 31 -----------------------
 drivers/clocksource/arm_arch_timer.c | 48 +++++++++++++++++++++++++++++++++---
 3 files changed, 44 insertions(+), 60 deletions(-)

Daniel, do you plan to take this series for 3.18?