All OSes we have run on top of Xen use CNTP_TVAL_EL0 but for completeness we really should handle CVAL too.
In vtimer_emulate_cp64 pull the propagation of the 64-bit result into two 32-bit registers out of the switch to avoid duplicating for every register. We also need to initialise x now since previously the only register implemented register was R/O. While adding HSR_SYSREG_CNTP_CVAL_EL0 also move HSR_SYSREG_CNTP_CTL_EL0 so it is sorted correctly. Signed-off-by: Ian Campbell <ian.campb...@citrix.com> --- v3: New patch. This should definitately be backported. --- xen/arch/arm/traps.c | 2 ++ xen/arch/arm/vtimer.c | 49 +++++++++++++++++++++++++++++++++++------ xen/include/asm-arm/sysregs.h | 3 ++- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 50d67aa..9e4a60f 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1670,6 +1670,7 @@ static void do_cp15_64(struct cpu_user_regs *regs, switch ( hsr.bits & HSR_CP64_REGS_MASK ) { case HSR_CPREG64(CNTPCT): + case HSR_CPREG64(CNTP_CVAL): if ( !vtimer_emulate(regs, hsr) ) { dprintk(XENLOG_ERR, @@ -1855,6 +1856,7 @@ static void do_sysreg(struct cpu_user_regs *regs, break; case HSR_SYSREG_CNTP_CTL_EL0: case HSR_SYSREG_CNTP_TVAL_EL0: + case HSR_SYSREG_CNTP_CVAL_EL0: if ( !vtimer_emulate(regs, hsr) ) { dprintk(XENLOG_ERR, diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c index 4427ae5..0c67f20 100644 --- a/xen/arch/arm/vtimer.c +++ b/xen/arch/arm/vtimer.c @@ -202,6 +202,31 @@ static void vtimer_cntp_tval(struct cpu_user_regs *regs, uint32_t *r, int read) } } +static int vtimer_cntp_cval(struct cpu_user_regs *regs, uint64_t *r, int read) +{ + struct vcpu *v = current; + + if ( psr_mode_is_user(regs) && + !(READ_SYSREG(CNTKCTL_EL1) & CNTKCTL_EL1_EL0PTEN) ) + return 0; + + if ( read ) + { + *r = ns_to_ticks(v->arch.phys_timer.cval); + } + else + { + v->arch.phys_timer.cval = ticks_to_ns(*r); + if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE ) + { + v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING; + set_timer(&v->arch.phys_timer.timer, + v->arch.phys_timer.cval + + v->domain->arch.phys_timer_base.offset); + } + } + return 1; +} static int vtimer_cntpct(struct cpu_user_regs *regs, uint64_t *r, int read) { struct vcpu *v = current; @@ -253,7 +278,7 @@ static int vtimer_emulate_cp64(struct cpu_user_regs *regs, union hsr hsr) struct hsr_cp64 cp64 = hsr.cp64; uint32_t *r1 = (uint32_t *)select_user_reg(regs, cp64.reg1); uint32_t *r2 = (uint32_t *)select_user_reg(regs, cp64.reg2); - uint64_t x; + uint64_t x = (uint64_t)(*r1) | ((uint64_t)(*r2) << 32); if ( cp64.read ) perfc_incr(vtimer_cp64_reads); @@ -265,17 +290,24 @@ static int vtimer_emulate_cp64(struct cpu_user_regs *regs, union hsr hsr) case HSR_CPREG64(CNTPCT): if (!vtimer_cntpct(regs, &x, cp64.read)) return 0; + break; - if ( cp64.read ) - { - *r1 = (uint32_t)(x & 0xffffffff); - *r2 = (uint32_t)(x >> 32); - } - return 1; + case HSR_CPREG64(CNTP_CVAL): + if ( !vtimer_cntp_cval(regs, &x, cp64.read) ) + return 0; + break; default: return 0; } + + if ( cp64.read ) + { + *r1 = (uint32_t)(x & 0xffffffff); + *r2 = (uint32_t)(x >> 32); + } + + return 1; } #ifdef CONFIG_ARM_64 @@ -303,6 +335,9 @@ static int vtimer_emulate_sysreg(struct cpu_user_regs *regs, union hsr hsr) *x = r; return 1; + case HSR_SYSREG_CNTP_CVAL_EL0: + return vtimer_cntp_cval(regs, x, sysreg.read); + case HSR_SYSREG_CNTPCT_EL0: return vtimer_cntpct(regs, x, sysreg.read); diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h index 169b7ac..df8e070 100644 --- a/xen/include/asm-arm/sysregs.h +++ b/xen/include/asm-arm/sysregs.h @@ -100,8 +100,9 @@ #define HSR_SYSREG_PMOVSSET_EL0 HSR_SYSREG(3,3,c9,c14,3) #define HSR_SYSREG_CNTPCT_EL0 HSR_SYSREG(3,3,c14,c0,0) -#define HSR_SYSREG_CNTP_CTL_EL0 HSR_SYSREG(3,3,c14,c2,1) #define HSR_SYSREG_CNTP_TVAL_EL0 HSR_SYSREG(3,3,c14,c2,0) +#define HSR_SYSREG_CNTP_CTL_EL0 HSR_SYSREG(3,3,c14,c2,1) +#define HSR_SYSREG_CNTP_CVAL_EL0 HSR_SYSREG(3,3,c14,c2,2) /* * GIC System register assembly aliases picked from kernel -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel