[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.