xen: arm: Use 64-bit compatible registers in vtimer.

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>
This commit is contained in:
Ian Campbell committed 2013-02-22 12:14:55 +00:00
1 parent c95d4af5bb
commit 3606cdc804
2 files changed
+24 -11

No files matched your search

+12 -2
View 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",
+12 -9
View 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);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.