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

[Xen-devel] [PATCH v5 12/14] xen/arm: initialize virt_timer and phys_timer with the same values on all vcpus



Introduce a domain wide vtimer initialization function to initialize
the phys_timer and the virt_timer offsets.

Use the domain phys_timer and virt_timer offsets throughout the vtimer
code instead of the per-vcpu offsets.

Remove the per-vcpu offsets from struct vtimer altogether.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>

Changes in v5:
- don't change the init value of phys_timer's cval.

Changes in v4:
- introduce vcpu_domain_init;
- inline phys_timer_base and virt_timer_base in arch_domain;
- use phys_timer_base.offset and virt_timer_base.offset directly in
vtimer code (remove offset field from struct vtimer).
---
 xen/arch/arm/domain.c        |    3 +++
 xen/arch/arm/vtimer.c        |   24 ++++++++++++++++--------
 xen/arch/arm/vtimer.h        |    1 +
 xen/include/asm-arm/domain.h |   24 +++++++++++++++---------
 4 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index da8f77c..2d018cf 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -485,6 +485,9 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags)
     if ( (rc = domain_vgic_init(d)) != 0 )
         goto fail;
 
+    if ( (rc = vcpu_domain_init(d)) != 0 )
+        goto fail;
+
     /* Domain 0 gets a real UART not an emulated one */
     if ( d->domain_id && (rc = domain_uart0_init(d)) != 0 )
         goto fail;
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index 393aac3..97fe8ce 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -44,13 +44,20 @@ static void virt_timer_expired(void *data)
     vgic_vcpu_inject_irq(t->v, 27, 1);
 }
 
+int vcpu_domain_init(struct domain *d)
+{
+    d->arch.phys_timer_base.offset = NOW();
+    d->arch.virt_timer_base.offset = READ_SYSREG64(CNTVCT_EL0) +
+                                     READ_SYSREG64(CNTVOFF_EL2);
+    return 0;
+}
+
 int vcpu_vtimer_init(struct vcpu *v)
 {
     struct vtimer *t = &v->arch.phys_timer;
 
     init_timer(&t->timer, phys_timer_expired, t, v->processor);
     t->ctl = 0;
-    t->offset = NOW();
     t->cval = NOW();
     t->irq = 30;
     t->v = v;
@@ -58,7 +65,6 @@ int vcpu_vtimer_init(struct vcpu *v)
     t = &v->arch.virt_timer;
     init_timer(&t->timer, virt_timer_expired, t, v->processor);
     t->ctl = 0;
-    t->offset = READ_SYSREG64(CNTVCT_EL0) + READ_SYSREG64(CNTVOFF_EL2);
     t->cval = 0;
     t->irq = 27;
     t->v = v;
@@ -84,7 +90,7 @@ int virt_timer_save(struct vcpu *v)
          !(v->arch.virt_timer.ctl & CNTx_CTL_MASK))
     {
         set_timer(&v->arch.virt_timer.timer, 
ticks_to_ns(v->arch.virt_timer.cval +
-                  v->arch.virt_timer.offset - boot_count));
+                  v->domain->arch.virt_timer_base.offset - boot_count));
     }
     return 0;
 }
@@ -98,7 +104,7 @@ int virt_timer_restore(struct vcpu *v)
     migrate_timer(&v->arch.virt_timer.timer, v->processor);
     migrate_timer(&v->arch.phys_timer.timer, v->processor);
 
-    WRITE_SYSREG64(v->arch.virt_timer.offset, CNTVOFF_EL2);
+    WRITE_SYSREG64(v->domain->arch.virt_timer_base.offset, CNTVOFF_EL2);
     WRITE_SYSREG64(v->arch.virt_timer.cval, CNTV_CVAL_EL0);
     WRITE_SYSREG32(v->arch.virt_timer.ctl, CNTV_CTL_EL0);
     return 0;
@@ -128,7 +134,8 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, 
union hsr hsr)
             if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
             {
                 set_timer(&v->arch.phys_timer.timer,
-                          v->arch.phys_timer.cval + v->arch.phys_timer.offset);
+                          v->arch.phys_timer.cval +
+                          v->domain->arch.phys_timer_base.offset);
             }
             else
                 stop_timer(&v->arch.phys_timer.timer);
@@ -137,7 +144,7 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, 
union hsr hsr)
         return 1;
 
     case HSR_CPREG32(CNTP_TVAL):
-        now = NOW() - v->arch.phys_timer.offset;
+        now = NOW() - v->domain->arch.phys_timer_base.offset;
         if ( cp32.read )
         {
             *r = (uint32_t)(ns_to_ticks(v->arch.phys_timer.cval - now) & 
0xffffffffull);
@@ -149,7 +156,8 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, 
union hsr hsr)
             {
                 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);
+                          v->arch.phys_timer.cval +
+                          v->domain->arch.phys_timer_base.offset);
             }
         }
 
@@ -174,7 +182,7 @@ static int vtimer_emulate_64(struct cpu_user_regs *regs, 
union hsr hsr)
     case HSR_CPREG64(CNTPCT):
         if ( cp64.read )
         {
-            now = NOW() - v->arch.phys_timer.offset;
+            now = NOW() - v->domain->arch.phys_timer_base.offset;
             ticks = ns_to_ticks(now);
             *r1 = (uint32_t)(ticks & 0xffffffff);
             *r2 = (uint32_t)(ticks >> 32);
diff --git a/xen/arch/arm/vtimer.h b/xen/arch/arm/vtimer.h
index 690231d..bcf910e 100644
--- a/xen/arch/arm/vtimer.h
+++ b/xen/arch/arm/vtimer.h
@@ -20,6 +20,7 @@
 #ifndef __ARCH_ARM_VTIMER_H__
 #define __ARCH_ARM_VTIMER_H__
 
+extern int vcpu_domain_init(struct domain *d);
 extern int vcpu_vtimer_init(struct vcpu *v);
 extern int vtimer_emulate(struct cpu_user_regs *regs, union hsr hsr);
 extern int virt_timer_save(struct vcpu *v);
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 3fa266c2..cca7416 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -47,6 +47,14 @@ enum domain_type {
 #define is_pv64_domain(d) (0)
 #endif
 
+struct vtimer {
+        struct vcpu *v;
+        int irq;
+        struct timer timer;
+        uint32_t ctl;
+        uint64_t cval;
+};
+
 struct arch_domain
 {
 #ifdef CONFIG_ARM_64
@@ -62,6 +70,13 @@ struct arch_domain
     register_t vmpidr;
 
     struct {
+        uint64_t offset;
+    } phys_timer_base;
+    struct {
+        uint64_t offset;
+    } virt_timer_base;
+
+    struct {
         /*
          * Covers access to other members of this struct _except_ for
          * shared_irqs where each member contains its own locking.
@@ -91,15 +106,6 @@ struct arch_domain
 
 }  __cacheline_aligned;
 
-struct vtimer {
-        struct vcpu *v;
-        int irq;
-        struct timer timer;
-        uint32_t ctl;
-        uint64_t offset;
-        uint64_t cval;
-};
-
 struct arch_vcpu
 {
     struct {
-- 
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®.