virt_vtimer_save is calculating the new time for the vtimer and has a potential risk of timer flip in: "v->arch.virt_timer.cval + v->domain->arch.virt_timer_base.offset - boot_count". In this formula, "cval + offset" could make uint64_t overflow. Generally speaking, this is difficult to trigger. But unfortunately the problem was encountered with a platform where the timer started with a very huge initial value, like 0xF333899122223333. On this platform cval + offset is overflowing after running for a while.
So in this patch, we adjust the formula to use "offset - boot_count" first, and then use the result to plus cval. This will avoid the uint64_t overflow. Signed-off-by: Wei Chen <[email protected]> --- xen/arch/arm/vtimer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c index 5bb5970f58..86e63303c8 100644 --- a/xen/arch/arm/vtimer.c +++ b/xen/arch/arm/vtimer.c @@ -144,8 +144,9 @@ void virt_timer_save(struct vcpu *v) if ( (v->arch.virt_timer.ctl & CNTx_CTL_ENABLE) && !(v->arch.virt_timer.ctl & CNTx_CTL_MASK)) { - set_timer(&v->arch.virt_timer.timer, ticks_to_ns(v->arch.virt_timer.cval + - v->domain->arch.virt_timer_base.offset - boot_count)); + set_timer(&v->arch.virt_timer.timer, + ticks_to_ns(v->domain->arch.virt_timer_base.offset - + boot_count + v->arch.virt_timer.cval)); } } -- 2.25.1
