[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Fix HLT with interrupts disabled. Only take down
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID ef41783c664a14334dd5facc31f0cfa254f5cb77 # Parent 184884cfaa0b23e07e1abe007071b5898b0b21c2 [HVM] Fix HLT with interrupts disabled. Only take down the domain if no other VCPUs are online. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 70 +++++++++++++++++++++++++++++++++---------------- 1 files changed, 48 insertions(+), 22 deletions(-) diff -r 184884cfaa0b -r ef41783c664a xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Tue Sep 26 12:17:51 2006 +0100 +++ b/xen/arch/x86/hvm/hvm.c Tue Sep 26 14:01:38 2006 +0100 @@ -337,6 +337,33 @@ int cpu_get_interrupt(struct vcpu *v, in return -1; } +static void hvm_vcpu_down(void) +{ + struct vcpu *v = current; + struct domain *d = v->domain; + int online_count = 0; + + DPRINTK("DOM%d/VCPU%d: going offline.\n", d->domain_id, v->vcpu_id); + + /* Doesn't halt us immediately, but we'll never return to guest context. */ + set_bit(_VCPUF_down, &v->vcpu_flags); + vcpu_sleep_nosync(v); + + /* Any other VCPUs online? ... */ + LOCK_BIGLOCK(d); + for_each_vcpu ( d, v ) + if ( !test_bit(_VCPUF_down, &v->vcpu_flags) ) + online_count++; + UNLOCK_BIGLOCK(d); + + /* ... Shut down the domain if not. */ + if ( online_count == 0 ) + { + DPRINTK("DOM%d: all CPUs offline -- powering off.\n", d->domain_id); + domain_shutdown(d, SHUTDOWN_poweroff); + } +} + void hvm_hlt(unsigned long rflags) { struct vcpu *v = current; @@ -344,18 +371,12 @@ void hvm_hlt(unsigned long rflags) s_time_t next_pit = -1, next_wakeup; /* - * Detect machine shutdown. Only do this for vcpu 0, to avoid potentially - * shutting down the domain early. If we halt with interrupts disabled, - * that's a pretty sure sign that we want to shut down. In a real - * processor, NMIs are the only way to break out of this. + * If we halt with interrupts disabled, that's a pretty sure sign that we + * want to shut down. In a real processor, NMIs are the only way to break + * out of this. */ - if ( (v->vcpu_id == 0) && !(rflags & X86_EFLAGS_IF) ) - { - printk("D%d: HLT with interrupts disabled -- shutting down.\n", - current->domain->domain_id); - domain_shutdown(current->domain, SHUTDOWN_poweroff); - return; - } + if ( unlikely(!(rflags & X86_EFLAGS_IF)) ) + return hvm_vcpu_down(); if ( !v->vcpu_id ) next_pit = get_scheduled(v, pt->irq, pt); @@ -578,17 +599,20 @@ int hvm_bringup_ap(int vcpuid, int tramp struct vcpu_guest_context *ctxt; int rc = 0; - /* current must be HVM domain BSP */ - if ( !(hvm_guest(bsp) && bsp->vcpu_id == 0) ) { - printk("Not calling hvm_bringup_ap from BSP context.\n"); + BUG_ON(!hvm_guest(bsp)); + + if ( bsp->vcpu_id != 0 ) + { + DPRINTK("Not calling hvm_bringup_ap from BSP context.\n"); domain_crash_synchronous(); } if ( (v = d->vcpu[vcpuid]) == NULL ) return -ENOENT; - if ( (ctxt = xmalloc(struct vcpu_guest_context)) == NULL ) { - printk("Failed to allocate memory in hvm_bringup_ap.\n"); + if ( (ctxt = xmalloc(struct vcpu_guest_context)) == NULL ) + { + DPRINTK("Failed to allocate memory in hvm_bringup_ap.\n"); return -ENOMEM; } @@ -601,12 +625,14 @@ int hvm_bringup_ap(int vcpuid, int tramp UNLOCK_BIGLOCK(d); if ( rc != 0 ) - printk("AP %d bringup failed in boot_vcpu %x.\n", vcpuid, rc); - else { - if ( test_and_clear_bit(_VCPUF_down, &d->vcpu[vcpuid]->vcpu_flags) ) - vcpu_wake(d->vcpu[vcpuid]); - printk("AP %d bringup suceeded.\n", vcpuid); - } + { + DPRINTK("AP %d bringup failed in boot_vcpu %x.\n", vcpuid, rc); + return rc; + } + + if ( test_and_clear_bit(_VCPUF_down, &d->vcpu[vcpuid]->vcpu_flags) ) + vcpu_wake(d->vcpu[vcpuid]); + DPRINTK("AP %d bringup suceeded.\n", vcpuid); xfree(ctxt); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |