Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1693890 > unrolled thread
| Started by | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| First post | 2017-07-21 19:20 +0200 |
| Last post | 2017-07-21 19:20 +0200 |
| Articles | 1 — 1 participant |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 16/16] clocksource/arm_arch_timer: Trap user access to CNT{VCT,FRQ} if CNTFRQ is invalid Marc Zyngier <marc.zyngier@arm.com> - 2017-07-21 19:20 +0200
| From | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| Date | 2017-07-21 19:20 +0200 |
| Subject | [PATCH 16/16] clocksource/arm_arch_timer: Trap user access to CNT{VCT,FRQ} if CNTFRQ is invalid |
| Message-ID | <u5JKP-7DO-43@gated-at.bofh.it> |
If we end-up in a situation where any of the CPUs doesn't have its
CNTFRQ register correctly programmed, we cannot reliably expose this
register to userspace. It means that in this case, we have to trap
it, and CNTVCT at the same time (since they are controlled by the
same trapping bit).
It also means that there is no point in enabling the VDSO access to
the counter, since we're going to enter the kernel.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
drivers/clocksource/arm_arch_timer.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 4f4633157978..37404a6a1bfa 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -759,6 +759,25 @@ static void arch_timer_configure_evtstream(void)
arch_timer_evtstrm_enable(min(pos, 15));
}
+static bool cntfrq_valid(void)
+{
+ u32 freq = arch_timer_get_cntfrq();
+
+ if (freq != arch_timer_rate) {
+ /*
+ * If any of the CPUs disagrees on what CNTFRQ should
+ * actually be, we end-up disabling the vdso fastpath
+ * for the whole system.
+ */
+ pr_warn("CPU%d: Invalid CNTFRQ (%u, expected %u)\n",
+ smp_processor_id(), freq, arch_timer_rate);
+ disable_vdso();
+ return false;
+ }
+
+ return true;
+}
+
static void arch_counter_set_user_access(void)
{
u32 cntkctl = arch_timer_get_cntkctl();
@@ -773,11 +792,12 @@ static void arch_counter_set_user_access(void)
/*
* Enable user access to the virtual counter if it doesn't
- * need to be workaround. The vdso may have been already
- * disabled though.
+ * need to be workaround, and that the frequency has been
+ * correctly set. The vdso may have been already disabled
+ * though.
*/
- if (arch_timer_this_cpu_has_cntvct_wa())
- pr_info("CPU%d: Trapping CNTVCT access\n", smp_processor_id());
+ if (arch_timer_this_cpu_has_cntvct_wa() || !cntfrq_valid())
+ pr_info("CPU%d: Trapping CNTVCT/CNTFRQ access\n", smp_processor_id());
else
cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
--
2.11.0
Back to top | Article view | linux.kernel
csiph-web