xen/arm: phys_timer fixes
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>
Wed, 20 Feb 2013 18:16:37 +0000 (18:16 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Wed, 10 Apr 2013 15:12:38 +0000 (16:12 +0100)
Do not unmask the emulated phys_timer when the related Xen timer
expires.
Do not inject the phys_timer interrupt if it is masked.

Do not let the user set CNTx_CTL_PENDING directly.

Set CNTx_CTL_PENDING when the phys_timer expires and clear it when the
phys_timer is disabled or the compare value is changed.

Define offset and cval as uint64_t given that they can't be negative and
they are used as uint64_t arguments.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/vtimer.c
xen/include/asm-arm/domain.h

index a68f66272a3dcf7a0d51793bfc9c1fd260ebf5ea..1cb365e23483db0b97120ef5980f5cf0a737776b 100644 (file)
@@ -33,8 +33,8 @@ static void phys_timer_expired(void *data)
 {
     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)
@@ -118,7 +118,10 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr)
         }
         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 )
             {
@@ -142,6 +145,7 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr)
             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);
             }
index bf9caffc79d905246ecf3d15222ff0cb5c50ceab..3fa266c202d1c9ab4f9e085b7e4c1819b60c822a 100644 (file)
@@ -96,8 +96,8 @@ struct vtimer {
         int irq;
         struct timer timer;
         uint32_t ctl;
-        s_time_t offset;
-        s_time_t cval;
+        uint64_t offset;
+        uint64_t cval;
 };
 
 struct arch_vcpu