{
struct vtimer *t = data;
t->ctl |= CNTx_CTL_PENDING;
- t->ctl &= ~CNTx_CTL_MASK;
- vgic_vcpu_inject_irq(t->v, 30, 1);
+ if ( !(t->ctl & CNTx_CTL_MASK) )
+ vgic_vcpu_inject_irq(t->v, 30, 1);
}
static void virt_timer_expired(void *data)
}
else
{
- v->arch.phys_timer.ctl = *r;
+ uint32_t ctl = *r & ~CNTx_CTL_PENDING;
+ if ( ctl & CNTx_CTL_ENABLE )
+ ctl |= v->arch.phys_timer.ctl & CNTx_CTL_PENDING;
+ v->arch.phys_timer.ctl = ctl;
if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
{
v->arch.phys_timer.cval = now + ticks_to_ns(*r);
if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
{
+ v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING;
set_timer(&v->arch.phys_timer.timer,
v->arch.phys_timer.cval + v->arch.phys_timer.offset);
}