From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-v5.16-rc1 commit 72f47a3f0ea4 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4QCBG CVE: NA
----------------------
The MMIO timer base address gets published after we have registered the callbacks and the interrupt handler, which is... a bit dangerous.
Fix this by moving the base address publication to the point where we register the timer, and expose a pointer to the timer structure itself rather than a naked value.
Reviewed-by: Oliver Upton oupton@google.com Reviewed-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211017124225.3018098-7-maz@kernel.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org
Conflicts: drivers/clocksource/arm_arch_timer.c [fix conflicts caused by extra '__ro_after_init'] Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/clocksource/arm_arch_timer.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 035e108bcee3..cfcdc4b24ee4 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -51,13 +51,13 @@
static unsigned arch_timers_present __initdata;
-static void __iomem *arch_counter_base; - struct arch_timer { void __iomem *base; struct clock_event_device evt; };
+static struct arch_timer *arch_timer_mem __ro_after_init; + #define to_arch_timer(e) container_of(e, struct arch_timer, evt)
static u32 arch_timer_rate; @@ -972,9 +972,9 @@ static u64 arch_counter_get_cntvct_mem(void) u32 vct_lo, vct_hi, tmp_hi;
do { - vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); - vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO); - tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); + vct_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI); + vct_lo = readl_relaxed(arch_timer_mem->base + CNTVCT_LO); + tmp_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI); } while (vct_hi != tmp_hi);
return ((u64) vct_hi << 32) | vct_lo; @@ -1167,25 +1167,25 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq) { int ret; irq_handler_t func; - struct arch_timer *t;
- t = kzalloc(sizeof(*t), GFP_KERNEL); - if (!t) + arch_timer_mem = kzalloc(sizeof(*arch_timer_mem), GFP_KERNEL); + if (!arch_timer_mem) return -ENOMEM;
- t->base = base; - t->evt.irq = irq; - __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &t->evt); + arch_timer_mem->base = base; + arch_timer_mem->evt.irq = irq; + __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &arch_timer_mem->evt);
if (arch_timer_mem_use_virtual) func = arch_timer_handler_virt_mem; else func = arch_timer_handler_phys_mem;
- ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &t->evt); + ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &arch_timer_mem->evt); if (ret) { pr_err("Failed to request mem timer irq\n"); - kfree(t); + kfree(arch_timer_mem); + arch_timer_mem = NULL; }
return ret; @@ -1433,7 +1433,6 @@ arch_timer_mem_frame_register(struct arch_timer_mem_frame *frame) return ret; }
- arch_counter_base = base; arch_timers_present |= ARCH_TIMER_TYPE_MEM;
return 0;