[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 12/12] xen/arm: initialize virt_timer and phys_timer with the same values on all vcpus
Introduce a domain wide vtimer initialization function to initialize the phys_timer and the virt_timer offsets. Use the domain phys_timer and virt_timer offsets throughout the vtimer code instead of the per-vcpu offsets. Remove the per-vcpu offsets from struct vtimer altogether. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Changes in v4: - introduce vcpu_domain_init; - inline phys_timer_base and virt_timer_base in arch_domain; - use phys_timer_base.offset and virt_timer_base.offset directly in vtimer code (remove offset field from struct vtimer). --- xen/arch/arm/domain.c | 3 +++ xen/arch/arm/vtimer.c | 26 +++++++++++++++++--------- xen/arch/arm/vtimer.h | 1 + xen/include/asm-arm/domain.h | 24 +++++++++++++++--------- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index f7ec979..f26222a 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -485,6 +485,9 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags) if ( (rc = domain_vgic_init(d)) != 0 ) goto fail; + if ( (rc = vcpu_domain_init(d)) != 0 ) + goto fail; + /* Domain 0 gets a real UART not an emulated one */ if ( d->domain_id && (rc = domain_uart0_init(d)) != 0 ) goto fail; diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c index 393aac3..782a255 100644 --- a/xen/arch/arm/vtimer.c +++ b/xen/arch/arm/vtimer.c @@ -44,21 +44,27 @@ static void virt_timer_expired(void *data) vgic_vcpu_inject_irq(t->v, 27, 1); } +int vcpu_domain_init(struct domain *d) +{ + d->arch.phys_timer_base.offset = NOW(); + d->arch.virt_timer_base.offset = READ_SYSREG64(CNTVCT_EL0) + + READ_SYSREG64(CNTVOFF_EL2); + return 0; +} + int vcpu_vtimer_init(struct vcpu *v) { struct vtimer *t = &v->arch.phys_timer; init_timer(&t->timer, phys_timer_expired, t, v->processor); t->ctl = 0; - t->offset = NOW(); - t->cval = NOW(); + t->cval = 0; t->irq = 30; t->v = v; t = &v->arch.virt_timer; init_timer(&t->timer, virt_timer_expired, t, v->processor); t->ctl = 0; - t->offset = READ_SYSREG64(CNTVCT_EL0) + READ_SYSREG64(CNTVOFF_EL2); t->cval = 0; t->irq = 27; t->v = v; @@ -84,7 +90,7 @@ int virt_timer_save(struct vcpu *v) !(v->arch.virt_timer.ctl & CNTx_CTL_MASK)) { set_timer(&v->arch.virt_timer.timer, ticks_to_ns(v->arch.virt_timer.cval + - v->arch.virt_timer.offset - boot_count)); + v->domain->arch.virt_timer_base.offset - boot_count)); } return 0; } @@ -98,7 +104,7 @@ int virt_timer_restore(struct vcpu *v) migrate_timer(&v->arch.virt_timer.timer, v->processor); migrate_timer(&v->arch.phys_timer.timer, v->processor); - WRITE_SYSREG64(v->arch.virt_timer.offset, CNTVOFF_EL2); + WRITE_SYSREG64(v->domain->arch.virt_timer_base.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; @@ -128,7 +134,8 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr) if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE ) { set_timer(&v->arch.phys_timer.timer, - v->arch.phys_timer.cval + v->arch.phys_timer.offset); + v->arch.phys_timer.cval + + v->domain->arch.phys_timer_base.offset); } else stop_timer(&v->arch.phys_timer.timer); @@ -137,7 +144,7 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr) return 1; case HSR_CPREG32(CNTP_TVAL): - now = NOW() - v->arch.phys_timer.offset; + now = NOW() - v->domain->arch.phys_timer_base.offset; if ( cp32.read ) { *r = (uint32_t)(ns_to_ticks(v->arch.phys_timer.cval - now) & 0xffffffffull); @@ -149,7 +156,8 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr) { v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING; set_timer(&v->arch.phys_timer.timer, - v->arch.phys_timer.cval + v->arch.phys_timer.offset); + v->arch.phys_timer.cval + + v->domain->arch.phys_timer_base.offset); } } @@ -174,7 +182,7 @@ static int vtimer_emulate_64(struct cpu_user_regs *regs, union hsr hsr) case HSR_CPREG64(CNTPCT): if ( cp64.read ) { - now = NOW() - v->arch.phys_timer.offset; + now = NOW() - v->domain->arch.phys_timer_base.offset; ticks = ns_to_ticks(now); *r1 = (uint32_t)(ticks & 0xffffffff); *r2 = (uint32_t)(ticks >> 32); diff --git a/xen/arch/arm/vtimer.h b/xen/arch/arm/vtimer.h index 690231d..bcf910e 100644 --- a/xen/arch/arm/vtimer.h +++ b/xen/arch/arm/vtimer.h @@ -20,6 +20,7 @@ #ifndef __ARCH_ARM_VTIMER_H__ #define __ARCH_ARM_VTIMER_H__ +extern int vcpu_domain_init(struct domain *d); extern int vcpu_vtimer_init(struct vcpu *v); extern int vtimer_emulate(struct cpu_user_regs *regs, union hsr hsr); extern int virt_timer_save(struct vcpu *v); diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 3fa266c2..cca7416 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -47,6 +47,14 @@ enum domain_type { #define is_pv64_domain(d) (0) #endif +struct vtimer { + struct vcpu *v; + int irq; + struct timer timer; + uint32_t ctl; + uint64_t cval; +}; + struct arch_domain { #ifdef CONFIG_ARM_64 @@ -62,6 +70,13 @@ struct arch_domain register_t vmpidr; struct { + uint64_t offset; + } phys_timer_base; + struct { + uint64_t offset; + } virt_timer_base; + + struct { /* * Covers access to other members of this struct _except_ for * shared_irqs where each member contains its own locking. @@ -91,15 +106,6 @@ struct arch_domain } __cacheline_aligned; -struct vtimer { - struct vcpu *v; - int irq; - struct timer timer; - uint32_t ctl; - uint64_t offset; - uint64_t cval; -}; - struct arch_vcpu { struct { -- 1.7.2.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |