[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvm: Fix destroy_periodic_time() to not race destruction of one-shot timers.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1197457701 0 # Node ID f2f7c92bf1c15206aa7072f6a4e470a132d528e2 # Parent 686b75b31f3cc10453119dd23eac4e7ac3f9e9ad hvm: Fix destroy_periodic_time() to not race destruction of one-shot timers. This bug was tracked down by Dexuan Cui <dexuan.cui@xxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/hvm/vioapic.c | 2 +- xen/arch/x86/hvm/vlapic.c | 13 +++++-------- xen/arch/x86/hvm/vpt.c | 15 +++++++++------ xen/include/asm-x86/hvm/vpt.h | 19 +++++++++++++++---- 4 files changed, 30 insertions(+), 19 deletions(-) diff -r 686b75b31f3c -r f2f7c92bf1c1 xen/arch/x86/hvm/vioapic.c --- a/xen/arch/x86/hvm/vioapic.c Wed Dec 12 10:40:02 2007 +0000 +++ b/xen/arch/x86/hvm/vioapic.c Wed Dec 12 11:08:21 2007 +0000 @@ -300,7 +300,7 @@ static inline int pit_channel0_enabled(v static inline int pit_channel0_enabled(void) { PITState *pit = ¤t->domain->arch.hvm_domain.pl_time.vpit; - return pit->pt0.enabled; + return pt_active(&pit->pt0); } static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq) diff -r 686b75b31f3c -r f2f7c92bf1c1 xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Wed Dec 12 10:40:02 2007 +0000 +++ b/xen/arch/x86/hvm/vlapic.c Wed Dec 12 11:08:21 2007 +0000 @@ -977,15 +977,12 @@ void vlapic_destroy(struct vcpu *v) int is_lvtt(struct vcpu *v, int vector) { - return vcpu_vlapic(v)->pt.enabled && - vector == vlapic_lvt_vector(vcpu_vlapic(v), APIC_LVTT); + return (pt_active(&vcpu_vlapic(v)->pt) && + (vector == vlapic_lvt_vector(vcpu_vlapic(v), APIC_LVTT))); } int is_lvtt_enabled(struct vcpu *v) { - if ( unlikely(!vlapic_enabled(vcpu_vlapic(v))) || - !vlapic_lvt_enabled(vcpu_vlapic(v), APIC_LVTT)) - return 0; - - return 1; -} + return (vlapic_enabled(vcpu_vlapic(v)) && + vlapic_lvt_enabled(vcpu_vlapic(v), APIC_LVTT)); +} diff -r 686b75b31f3c -r f2f7c92bf1c1 xen/arch/x86/hvm/vpt.c --- a/xen/arch/x86/hvm/vpt.c Wed Dec 12 10:40:02 2007 +0000 +++ b/xen/arch/x86/hvm/vpt.c Wed Dec 12 11:08:21 2007 +0000 @@ -225,8 +225,9 @@ void pt_intr_post(struct vcpu *v, struct if ( pt->one_shot ) { - pt->enabled = 0; - list_del(&pt->list); + if ( pt->on_list ) + list_del(&pt->list); + pt->on_list = 0; } else { @@ -294,7 +295,6 @@ void create_periodic_time( spin_lock(&v->arch.hvm_vcpu.tm_lock); - pt->enabled = 1; pt->pending_intr_nr = 0; pt->do_not_freeze = 0; @@ -324,6 +324,7 @@ void create_periodic_time( pt->cb = cb; pt->priv = data; + pt->on_list = 1; list_add(&pt->list, &v->arch.hvm_vcpu.tm_list); init_timer(&pt->timer, pt_timer_fn, pt, v->processor); @@ -334,12 +335,14 @@ void create_periodic_time( void destroy_periodic_time(struct periodic_time *pt) { - if ( !pt->enabled ) + /* Was this structure previously initialised by create_periodic_time()? */ + if ( pt->vcpu == NULL ) return; pt_lock(pt); - pt->enabled = 0; - list_del(&pt->list); + if ( pt->on_list ) + list_del(&pt->list); + pt->on_list = 0; pt_unlock(pt); /* diff -r 686b75b31f3c -r f2f7c92bf1c1 xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Wed Dec 12 10:40:02 2007 +0000 +++ b/xen/include/asm-x86/hvm/vpt.h Wed Dec 12 11:08:21 2007 +0000 @@ -72,12 +72,12 @@ typedef void time_cb(struct vcpu *v, voi struct periodic_time { struct list_head list; - char enabled; - char one_shot; /* one shot time */ - char do_not_freeze; + bool_t on_list; + bool_t one_shot; + bool_t do_not_freeze; u8 irq; struct vcpu *vcpu; /* vcpu timer interrupt delivers to */ - u32 pending_intr_nr; /* the couner for pending timer interrupts */ + u32 pending_intr_nr; /* pending timer interrupts */ u64 period; /* frequency in ns */ u64 period_cycles; /* frequency in cpu cycles */ s_time_t scheduled; /* scheduled timer interrupt */ @@ -140,6 +140,17 @@ void pt_intr_post(struct vcpu *v, struct void pt_intr_post(struct vcpu *v, struct hvm_intack intack); void pt_reset(struct vcpu *v); void pt_migrate(struct vcpu *v); + +/* Is given periodic timer active? */ +#define pt_active(pt) ((pt)->on_list) + +/* + * Create/destroy a periodic (or one-shot!) timer. + * The given periodic timer structure must be initialised with zero bytes or + * have been initialised by a previous invocation of create_periodic_time(). + * Note that, for a given periodic timer, invocations of these functions MUST + * be serialised. + */ void create_periodic_time( struct vcpu *v, struct periodic_time *pt, uint64_t period, uint8_t irq, char one_shot, time_cb *cb, void *data); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |