]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
xen: arm: Use 64-bit compatible registers in vtimer.
authorIan Campbell <ian.campbell@citrix.com>
Fri, 22 Feb 2013 08:58:15 +0000 (08:58 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 22 Feb 2013 12:14:55 +0000 (12:14 +0000)
Also, don't crash the host if we fail to emulate a vtimer access,
just kill the guest.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
xen/arch/arm/traps.c
xen/arch/arm/vtimer.c

index 9ed87f8208e0c719f893e78a66cec334b2c1b058..75d42ab2f6470dbcad5afe1e1feaad82128e16f2 100644 (file)
@@ -712,7 +712,12 @@ static void do_cp15_32(struct cpu_user_regs *regs,
         break;
     case HSR_CPREG32(CNTP_CTL):
     case HSR_CPREG32(CNTP_TVAL):
-        BUG_ON(!vtimer_emulate(regs, hsr));
+        if ( !vtimer_emulate(regs, hsr) )
+        {
+            dprintk(XENLOG_ERR,
+                    "failed emulation of 32-bit vtimer CP register access\n");
+            domain_crash_synchronous();
+        }
         break;
     default:
         printk("%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
@@ -742,7 +747,12 @@ static void do_cp15_64(struct cpu_user_regs *regs,
     switch ( hsr.bits & HSR_CP64_REGS_MASK )
     {
     case HSR_CPREG64(CNTPCT):
-        BUG_ON(!vtimer_emulate(regs, hsr));
+        if ( !vtimer_emulate(regs, hsr) )
+        {
+            dprintk(XENLOG_ERR,
+                    "failed emulation of 64-bit vtimer CP register access\n");
+            domain_crash_synchronous();
+        }
         break;
     default:
         printk("%s p15, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
index 802c2bca953071086dfe208745284d6d7a64d87a..dfe3a3ef8df9116ca859ec213815c1956765d0e8 100644 (file)
@@ -43,7 +43,7 @@ static void virt_timer_expired(void *data)
     t->ctl |= CNTx_CTL_MASK;
     vgic_vcpu_inject_irq(t->v, 27, 1);
 }
+
 int vcpu_vtimer_init(struct vcpu *v)
 {
     struct vtimer *t = &v->arch.phys_timer;
@@ -58,7 +58,7 @@ int vcpu_vtimer_init(struct vcpu *v)
     t = &v->arch.virt_timer;
     init_timer(&t->timer, virt_timer_expired, t, smp_processor_id());
     t->ctl = 0;
-    t->offset = READ_CP64(CNTVCT) + READ_CP64(CNTVOFF);
+    t->offset = READ_SYSREG64(CNTVCT_EL0) + READ_SYSREG64(CNTVOFF_EL2);
     t->cval = 0;
     t->irq = 27;
     t->v = v;
@@ -77,9 +77,9 @@ int virt_timer_save(struct vcpu *v)
     if ( is_idle_domain(v->domain) )
         return 0;
 
-    v->arch.virt_timer.ctl = READ_CP32(CNTV_CTL);
-    WRITE_CP32(v->arch.virt_timer.ctl & ~CNTx_CTL_ENABLE, CNTV_CTL);
-    v->arch.virt_timer.cval = READ_CP64(CNTV_CVAL);
+    v->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0);
+    WRITE_SYSREG32(v->arch.virt_timer.ctl & ~CNTx_CTL_ENABLE, CNTV_CTL_EL0);
+    v->arch.virt_timer.cval = READ_SYSREG64(CNTV_CVAL_EL0);
     if ( v->arch.virt_timer.ctl & CNTx_CTL_ENABLE )
     {
         set_timer(&v->arch.virt_timer.timer, ticks_to_ns(v->arch.virt_timer.cval +
@@ -95,12 +95,12 @@ int virt_timer_restore(struct vcpu *v)
 
     stop_timer(&v->arch.virt_timer.timer);
 
-    WRITE_CP64(v->arch.virt_timer.offset, CNTVOFF);
-    WRITE_CP64(v->arch.virt_timer.cval, CNTV_CVAL);
-    WRITE_CP32(v->arch.virt_timer.ctl, CNTV_CTL);
+    WRITE_SYSREG64(v->arch.virt_timer.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;
 }
+
 static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr)
 {
     struct vcpu *v = current;
@@ -186,6 +186,9 @@ static int vtimer_emulate_64(struct cpu_user_regs *regs, union hsr hsr)
 
 int vtimer_emulate(struct cpu_user_regs *regs, union hsr hsr)
 {
+    if ( !is_pv32_domain(current->domain) )
+        return -EINVAL;
+
     switch (hsr.ec) {
     case HSR_EC_CP15_32:
         return vtimer_emulate_32(regs, hsr);