mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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:
1 parent
c95d4af5bb
commit
3606cdc804
2 files changed
+24
-11
No files matched your search
+12
-2
@@ -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
@@ -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);
|
||||
|
||||