All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 7/7] xen/arm: phys_timer fixes
@ 2013-02-14 16:37 Stefano Stabellini
  2013-02-15 13:04 ` Ian Campbell
  0 siblings, 1 reply; 8+ messages in thread
From: Stefano Stabellini @ 2013-02-14 16:37 UTC (permalink / raw)
  To: xen-devel; +Cc: tim, Ian.Campbell, stefano.stabellini

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@eu.citrix.com>
---
 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

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-02-18 16:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-14 16:37 [PATCH 7/7] xen/arm: phys_timer fixes Stefano Stabellini
2013-02-15 13:04 ` Ian Campbell
2013-02-18 14:44   ` Stefano Stabellini
2013-02-18 15:01     ` Ian Campbell
2013-02-18 15:31       ` Stefano Stabellini
2013-02-18 15:54         ` Ian Campbell
2013-02-18 16:14           ` Stefano Stabellini
2013-02-18 16:23             ` Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.