From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefano Stabellini Subject: [PATCH 7/7] xen/arm: phys_timer fixes Date: Thu, 14 Feb 2013 16:37:13 +0000 Message-ID: <1360859833-16498-7-git-send-email-stefano.stabellini@eu.citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xensource.com Cc: tim@xen.org, Ian.Campbell@citrix.com, stefano.stabellini@eu.citrix.com List-Id: xen-devel@lists.xenproject.org Do not unmask the emulated phys_timer when the related Xen timer expires. Do not inject the phys_timer interrupt if it is masked. Stop the Xen timer if the pending bit is already set and the phys_timer is masked. Register a gic callback to clear the pending bit in the ctl register. Define offset and cval as uint64_t given that they can't be negative and they are used as uint64_t arguments. Signed-off-by: Stefano Stabellini --- xen/arch/arm/setup.c | 1 + xen/arch/arm/vtimer.c | 30 ++++++++++++++++++++++++------ xen/arch/arm/vtimer.h | 2 ++ xen/include/asm-arm/domain.h | 4 ++-- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 5680c73..f1d15bb 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -398,6 +398,7 @@ void __init start_xen(unsigned long boot_phys_offset, init_timer_interrupt(); timer_init(); + init_ptimer(); init_idle_domain(); diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c index f4326f8..e033191 100644 --- a/xen/arch/arm/vtimer.c +++ b/xen/arch/arm/vtimer.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -33,8 +34,8 @@ static void phys_timer_expired(void *data) { struct vtimer *t = data; t->ctl |= CNTx_CTL_PENDING; - t->ctl &= ~CNTx_CTL_MASK; - vgic_vcpu_inject_irq(t->v, 30, 1); + if ( !(t->ctl & CNTx_CTL_MASK) ) + vgic_vcpu_inject_irq(t->v, 30, 1); } static void virt_timer_expired(void *data) @@ -44,6 +45,17 @@ static void virt_timer_expired(void *data) vgic_vcpu_inject_irq(t->v, 27, 1); } +static void phys_timer_gic_callback(struct vcpu *v, int irq) +{ + v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING; +} + +int __init init_ptimer(void) +{ + register_gic_callback(30, phys_timer_gic_callback); + return 0; +} + int vcpu_vtimer_init(struct vcpu *v) { struct vtimer *t = &v->arch.phys_timer; @@ -119,13 +131,15 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr) { v->arch.phys_timer.ctl = *r; - if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE ) + if ( ((v->arch.phys_timer.ctl & CNTx_CTL_MASK) && + (v->arch.phys_timer.ctl & CNTx_CTL_PENDING)) || + !(v->arch.phys_timer.ctl & CNTx_CTL_ENABLE) ) + stop_timer(&v->arch.phys_timer.timer); + else { set_timer(&v->arch.phys_timer.timer, v->arch.phys_timer.cval + v->arch.phys_timer.offset); } - else - stop_timer(&v->arch.phys_timer.timer); } return 1; @@ -139,7 +153,11 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr) else { v->arch.phys_timer.cval = now + ticks_to_ns(*r); - if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE ) + if ( ((v->arch.phys_timer.ctl & CNTx_CTL_MASK) && + (v->arch.phys_timer.ctl & CNTx_CTL_PENDING)) || + !(v->arch.phys_timer.ctl & CNTx_CTL_ENABLE) ) + stop_timer(&v->arch.phys_timer.timer); + else { set_timer(&v->arch.phys_timer.timer, v->arch.phys_timer.cval + v->arch.phys_timer.offset); diff --git a/xen/arch/arm/vtimer.h b/xen/arch/arm/vtimer.h index 43eef69..cbe0470 100644 --- a/xen/arch/arm/vtimer.h +++ b/xen/arch/arm/vtimer.h @@ -26,6 +26,8 @@ extern int virt_timer_save(struct vcpu *v); extern int virt_timer_restore(struct vcpu *v); extern void vcpu_timer_destroy(struct vcpu *v); +int init_ptimer(void); + #endif /* diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 577ad19..3e9cc37 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -75,8 +75,8 @@ struct vtimer { int irq; struct timer timer; uint32_t ctl; - s_time_t offset; - s_time_t cval; + uint64_t offset; + uint64_t cval; }; struct arch_vcpu -- 1.7.2.5