[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 7/7] xen/arm: phys_timer fixes



Do not unmask the emulated phys_timer when the related Xen timer
expires.
Do not inject the phys_timer interrupt if it is masked.

Stop the Xen timer if the pending bit is already set and the phys_timer
is masked.

Register a gic callback to clear the pending bit in the ctl register.

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@xxxxxxxxxxxxx>
---
 xen/arch/arm/setup.c         |    1 +
 xen/arch/arm/vtimer.c        |   30 ++++++++++++++++++++++++------
 xen/arch/arm/vtimer.h        |    2 ++
 xen/include/asm-arm/domain.h |    4 ++--
 4 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 5680c73..f1d15bb 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -398,6 +398,7 @@ void __init start_xen(unsigned long boot_phys_offset,
     init_timer_interrupt();
 
     timer_init();
+    init_ptimer();
 
     init_idle_domain();
 
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index f4326f8..e033191 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -18,6 +18,7 @@
  */
 
 #include <xen/config.h>
+#include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/timer.h>
 #include <xen/sched.h>
@@ -33,8 +34,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)
@@ -44,6 +45,17 @@ static void virt_timer_expired(void *data)
     vgic_vcpu_inject_irq(t->v, 27, 1);
 }
  
+static void phys_timer_gic_callback(struct vcpu *v, int irq)
+{
+    v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING;
+}
+
+int __init init_ptimer(void)
+{
+    register_gic_callback(30, phys_timer_gic_callback);
+    return 0;
+}
+
 int vcpu_vtimer_init(struct vcpu *v)
 {
     struct vtimer *t = &v->arch.phys_timer;
@@ -119,13 +131,15 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, 
union hsr hsr)
         {
             v->arch.phys_timer.ctl = *r;
 
-            if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
+            if ( ((v->arch.phys_timer.ctl & CNTx_CTL_MASK) &&
+                  (v->arch.phys_timer.ctl & CNTx_CTL_PENDING)) ||
+                 !(v->arch.phys_timer.ctl & CNTx_CTL_ENABLE) )
+                stop_timer(&v->arch.phys_timer.timer);
+            else
             {
                 set_timer(&v->arch.phys_timer.timer,
                           v->arch.phys_timer.cval + v->arch.phys_timer.offset);
             }
-            else
-                stop_timer(&v->arch.phys_timer.timer);
         }
 
         return 1;
@@ -139,7 +153,11 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, 
union hsr hsr)
         else
         {
             v->arch.phys_timer.cval = now + ticks_to_ns(*r);
-            if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
+            if ( ((v->arch.phys_timer.ctl & CNTx_CTL_MASK) &&
+                  (v->arch.phys_timer.ctl & CNTx_CTL_PENDING)) ||
+                 !(v->arch.phys_timer.ctl & CNTx_CTL_ENABLE) )
+                stop_timer(&v->arch.phys_timer.timer);
+            else
             {
                 set_timer(&v->arch.phys_timer.timer,
                           v->arch.phys_timer.cval + v->arch.phys_timer.offset);
diff --git a/xen/arch/arm/vtimer.h b/xen/arch/arm/vtimer.h
index 43eef69..cbe0470 100644
--- a/xen/arch/arm/vtimer.h
+++ b/xen/arch/arm/vtimer.h
@@ -26,6 +26,8 @@ extern int virt_timer_save(struct vcpu *v);
 extern int virt_timer_restore(struct vcpu *v);
 extern void vcpu_timer_destroy(struct vcpu *v);
 
+int init_ptimer(void);
+
 #endif
 
 /*
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 577ad19..3e9cc37 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -75,8 +75,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
-- 
1.7.2.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.