|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v8 5/7] 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>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Changes in v5:
- don't change the init value of phys_timer's cval.
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 | 24 ++++++++++++++++--------
xen/arch/arm/vtimer.h | 1 +
xen/include/asm-arm/domain.h | 24 +++++++++++++++---------
4 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index df42d82..b22d902 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..97fe8ce 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -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);
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 |