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@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Stefano Stabellini authored and Ian Campbell committed 2013-05-08 12:59:41 +01:00
1 parent 43e39ffc70
commit afb2edfc32
4 files changed
+35 -17

No files matched your search

+3
View File
@@ -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;
+16 -8
View File
@@ -44,13 +44,20 @@ 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->irq = 30;
t->v = v;
@@ -58,7 +65,6 @@ int vcpu_vtimer_init(struct vcpu *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);
+1
View File
@@ -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);
+15 -9
View File
@@ -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
@@ -61,6 +69,13 @@ struct arch_domain
uint32_t vpidr;
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
@@ -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 {
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.