From c265861af2af0f667e88b1b70acc234f8c61e0ae Mon Sep 17 00:00:00 2001 From: Ionela Voinescu Date: Thu, 5 Mar 2020 09:06:27 +0000 Subject: clocksource/drivers/arm_arch_timer: validate arch_timer_rate Using an arch timer with a frequency of less than 1MHz can potentially result in incorrect functionality in systems that assume a reasonable rate of the arch timer of 1 to 50MHz, described as typical in the architecture specification. Therefore, warn if the arch timer rate is below 1MHz, which is considered atypical and worth emphasizing. Suggested-by: Valentin Schneider Signed-off-by: Ionela Voinescu Acked-by: Marc Zyngier Cc: Marc Zyngier Cc: Mark Rutland Signed-off-by: Catalin Marinas --- drivers/clocksource/arm_arch_timer.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 9a5464c625b4..4faa930eabf8 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -885,6 +885,17 @@ static int arch_timer_starting_cpu(unsigned int cpu) return 0; } +static int validate_timer_rate(void) +{ + if (!arch_timer_rate) + return -EINVAL; + + /* Arch timer frequency < 1MHz can cause trouble */ + WARN_ON(arch_timer_rate < 1000000); + + return 0; +} + /* * For historical reasons, when probing with DT we use whichever (non-zero) * rate was probed first, and don't verify that others match. If the first node @@ -900,7 +911,7 @@ static void arch_timer_of_configure_rate(u32 rate, struct device_node *np) arch_timer_rate = rate; /* Check the timer frequency. */ - if (arch_timer_rate == 0) + if (validate_timer_rate()) pr_warn("frequency not available\n"); } @@ -1594,9 +1605,10 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) * CNTFRQ value. This *must* be correct. */ arch_timer_rate = arch_timer_get_cntfrq(); - if (!arch_timer_rate) { + ret = validate_timer_rate(); + if (ret) { pr_err(FW_BUG "frequency not available.\n"); - return -EINVAL; + return ret; } arch_timer_uses_ppi = arch_timer_select_ppi(); -- cgit v1.2.3