|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 7/7] xen/arm: phys_timer fixes
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 <stefano.stabellini@xxxxxxxxxxxxx>
---
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 <xen/config.h>
+#include <xen/init.h>
#include <xen/lib.h>
#include <xen/timer.h>
#include <xen/sched.h>
@@ -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
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |