bitkeeper revision 1.947 (40c84719Ozi8_o69nGYdNuJ6OQd4eQ)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 10 Jun 2004 11:33:45 +0000 (11:33 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 10 Jun 2004 11:33:45 +0000 (11:33 +0000)
Cleanup domain stop/crash. Provide notification to DOM0 so that
cleanup/postmortem can occur before domain is killed.

17 files changed:
extras/mini-os/h/hypervisor.h
extras/mini-os/kernel.c
linux-2.4.26-xen-sparse/arch/xen/kernel/process.c
linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c
linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h
tools/xc/lib/xc_domain.c
tools/xc/lib/xc_linux_build.c
tools/xc/lib/xc_netbsd_build.c
tools/xc/lib/xc_private.c
tools/xend/lib/domain_controller.h
xen/arch/i386/entry.S
xen/common/dom0_ops.c
xen/common/domain.c
xen/common/schedule.c
xen/include/hypervisor-ifs/dom0_ops.h
xen/include/hypervisor-ifs/hypervisor-if.h
xen/include/xen/sched.h

index b1cfd60dc65b4aa315ce9338839f0d82ee193369..500dcdf99ed1c0a91b68869000b95e439d623a29 100644 (file)
@@ -15,7 +15,7 @@
 #include <hypervisor-ifs/network.h>
 #include <hypervisor-ifs/block.h>
 #include <hypervisor-ifs/hypervisor-if.h>
-
+#include "../../../tools/xend/lib/domain_controller.h"
 
 /*
  * a placeholder for the start of day information passed up from the hypervisor
@@ -155,25 +155,39 @@ static __inline__ int HYPERVISOR_block(void)
     return ret;
 }
 
-static __inline__ int HYPERVISOR_exit(void)
+static inline int HYPERVISOR_shutdown(void)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
+        "b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift))
+        : "memory" );
+
+    return ret;
+}
+
+static inline int HYPERVISOR_reboot(void)
 {
     int ret;
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
-        "b" (SCHEDOP_exit) : "memory" );
+        "b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift))
+        : "memory" );
 
     return ret;
 }
 
-static __inline__ int HYPERVISOR_stop(unsigned long srec)
+static inline int HYPERVISOR_suspend(unsigned long srec)
 {
     int ret;
     /* NB. On suspend, control software expects a suspend record in %esi. */
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
-        "b" (SCHEDOP_stop), "S" (srec) : "memory" );
+        "b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)), 
+        "S" (srec) : "memory" );
 
     return ret;
 }
index 0afd864cf5d93d1f52d64a0e624e4548dfa467f6..f1d46fbf7d2c7250e33e8350b48d87f1d0971d2e 100644 (file)
@@ -153,7 +153,7 @@ void start_kernel(start_info_t *si)
 void do_exit(void)
 {
     printk("do_exit called!\n");
-    for ( ;; ) HYPERVISOR_exit();
+    for ( ;; ) HYPERVISOR_shutdown();
 }
 static void exit_handler(int ev, struct pt_regs *regs) {
     do_exit();
index 1ef8521fcb9d9f9e21f09ba0f1dae9fed53b788c..aa59c377907db82a0a0de285cb7d0c1787b26502 100644 (file)
@@ -120,17 +120,23 @@ void machine_restart(char * __unused)
     /* We really want to get pending console data out before we die. */
     extern void xencons_force_flush(void);
     xencons_force_flush();
-    HYPERVISOR_exit();
+    HYPERVISOR_reboot();
 }
 
 void machine_halt(void)
 {
-    machine_restart(NULL);
+    /* We really want to get pending console data out before we die. */
+    extern void xencons_force_flush(void);
+    xencons_force_flush();
+    HYPERVISOR_shutdown();
 }
 
 void machine_power_off(void)
 {
-    machine_restart(NULL);
+    /* We really want to get pending console data out before we die. */
+    extern void xencons_force_flush(void);
+    xencons_force_flush();
+    HYPERVISOR_shutdown();
 }
 
 extern void show_trace(unsigned long* esp);
index 1d1306df2b63217173bf8d1c1469b92040e199b2..a787a5c78c9e3d4aca54e22d2f203bf26d357365 100644 (file)
@@ -1205,7 +1205,7 @@ static void stop_task(void *unused)
 
     memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info));
 
-    HYPERVISOR_stop(virt_to_machine(suspend_record) >> PAGE_SHIFT);
+    HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
 
     suspending = 0; 
 
index 3ace0bae8a865ce1c0a755f827366f1de87d0e30..c341fe59908f7e0a3e5ce7dfca0a12c8ddd59d85 100644 (file)
@@ -253,25 +253,39 @@ static inline int HYPERVISOR_block(void)
     return ret;
 }
 
-static inline int HYPERVISOR_exit(void)
+static inline int HYPERVISOR_shutdown(void)
 {
     int ret;
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
-        "b" (SCHEDOP_exit) : "memory" );
+        "b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift))
+        : "memory" );
 
     return ret;
 }
 
-static inline int HYPERVISOR_stop(unsigned long srec)
+static inline int HYPERVISOR_reboot(void)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
+        "b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift))
+        : "memory" );
+
+    return ret;
+}
+
+static inline int HYPERVISOR_suspend(unsigned long srec)
 {
     int ret;
     /* NB. On suspend, control software expects a suspend record in %esi. */
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
-        "b" (SCHEDOP_stop), "S" (srec) : "memory" );
+        "b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)), 
+        "S" (srec) : "memory" );
 
     return ret;
 }
index 97a919f8d6f7076d171f3d7e29cc90de115feb48..41c004ed6e81920611b694fbcac4899e54269a61 100644 (file)
@@ -91,9 +91,14 @@ int xc_domain_getinfo(int xc_handle,
         if ( do_dom0_op(xc_handle, &op) < 0 )
             break;
         info->domid   = (u32)op.u.getdomaininfo.domain;
-        info->cpu     = op.u.getdomaininfo.processor;
-        info->has_cpu = op.u.getdomaininfo.has_cpu;
-        info->stopped = (op.u.getdomaininfo.state == DOMSTATE_STOPPED);
+
+        info->cpu     =
+            (op.u.getdomaininfo.flags>>DOMFLAGS_CPUSHIFT) & DOMFLAGS_CPUMASK;
+        info->has_cpu =
+            (op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_RUNNING;
+        info->stopped = 
+            (op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_STOPPED;
+
         info->nr_pages = op.u.getdomaininfo.tot_pages;
         info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT-10);
         info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
index 899d6c5329bbbf83bfbae129767105ece2879f6d..c5329231c4ae5216b0765007aa65350a3d2fcad8 100644 (file)
@@ -436,7 +436,7 @@ int xc_linux_build(int xc_handle,
         PERROR("Could not get info on domain");
         goto error_out;
     }
-    if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) ||
+    if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) ||
          (ctxt->pt_base != 0) )
     {
         ERROR("Domain is already constructed");
index b3dfcc7314247e05a79dd9e04fb6e97f838878ec..991edb06341e71aab766970b1e442af0005efb16 100644 (file)
@@ -258,7 +258,7 @@ int xc_netbsd_build(int xc_handle,
         PERROR("Could not get info on domain");
         goto error_out;
     }
-    if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) ||
+    if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) ||
          (op.u.getdomaininfo.ctxt->pt_base != 0) )
     {
         ERROR("Domain is already constructed");
index c602a56630c37a45f25462a648fb62e1aeed5823..23d30a464aca341e57a200cf66c6691e95ecd00a 100644 (file)
@@ -229,7 +229,8 @@ int xc_domain_stop_sync( int xc_handle, domid_t domid,
             goto out;
         }
 
-        if ( op->u.getdomaininfo.state == DOMSTATE_STOPPED )
+        if ( (op->u.getdomaininfo.flags & DOMFLAGS_STATEMASK) == 
+             DOMSTATE_STOPPED )
         {
             printf("Domain %u stopped\n",domid);
             return 0;
index 2bf01eff5359a9bd581023e3b8320780f0aae276..a21fdb24462bee226fe3f23f5028795b5454fa51 100644 (file)
@@ -28,6 +28,16 @@ typedef struct {
 #define SIF_NET_BE_DOMAIN (1<<5)  /* Is this a net backend domain? */
 
 
+/*
+ * Stop codes for SCHEDOP_stop. These are opaque to Xen but interpreted by
+ * control software to determine appropriate action.
+ */
+
+#define STOPCODE_shutdown   0  /* Domain exited normally. Clean up and kill. */
+#define STOPCODE_reboot     1  /* Clean up, kill, and then restart. */
+#define STOPCODE_suspend    2  /* Clean up, save suspend info, kill. */
+
+
 /*
  * CONTROLLER MESSAGING INTERFACE.
  */
index d7600ade075357364cada3d5907ada0f0d95f145..3493ff641a13d85a4653795910ec901c0d8d12dc 100644 (file)
@@ -446,34 +446,34 @@ FAULT12:movl %eax,8(%esi)
                               
 .section __ex_table,"a"
         .align 4
-        .long FAULT1, kill_domain_fixup3 # Fault writing to ring-1 stack
-        .long FAULT2, kill_domain_fixup3 # Fault writing to ring-1 stack
-        .long FAULT3, kill_domain_fixup3 # Fault writing to ring-1 stack
-        .long FAULT4, kill_domain_fixup3 # Fault writing to ring-1 stack
-        .long FAULT5, kill_domain_fixup1 # Fault executing failsafe iret
-        .long FAULT6, kill_domain_fixup2 # Fault loading ring-1 stack selector
-        .long FAULT7, kill_domain_fixup2 # Fault writing to ring-1 stack
-        .long FAULT8, kill_domain_fixup2 # Fault writing to ring-1 stack
-        .long FAULT9, kill_domain_fixup2 # Fault loading ring-1 stack selector
-        .long FAULT10,kill_domain_fixup2 # Fault writing to ring-1 stack
-        .long FAULT11,kill_domain_fixup2 # Fault writing to ring-1 stack
-        .long FAULT12,kill_domain_fixup2 # Fault writing to ring-1 stack
-        .long FAULT13,kill_domain_fixup3 # Fault writing to ring-1 stack
-        .long FAULT14,kill_domain_fixup3 # Fault writing to ring-1 stack
+        .long FAULT1, crash_domain_fixup3 # Fault writing to ring-1 stack
+        .long FAULT2, crash_domain_fixup3 # Fault writing to ring-1 stack
+        .long FAULT3, crash_domain_fixup3 # Fault writing to ring-1 stack
+        .long FAULT4, crash_domain_fixup3 # Fault writing to ring-1 stack
+        .long FAULT5, crash_domain_fixup1 # Fault executing failsafe iret
+        .long FAULT6, crash_domain_fixup2 # Fault loading ring-1 stack selector
+        .long FAULT7, crash_domain_fixup2 # Fault writing to ring-1 stack
+        .long FAULT8, crash_domain_fixup2 # Fault writing to ring-1 stack
+        .long FAULT9, crash_domain_fixup2 # Fault loading ring-1 stack selector
+        .long FAULT10,crash_domain_fixup2 # Fault writing to ring-1 stack
+        .long FAULT11,crash_domain_fixup2 # Fault writing to ring-1 stack
+        .long FAULT12,crash_domain_fixup2 # Fault writing to ring-1 stack
+        .long FAULT13,crash_domain_fixup3 # Fault writing to ring-1 stack
+        .long FAULT14,crash_domain_fixup3 # Fault writing to ring-1 stack
 .previous
                
 # This handler kills domains which experience unrecoverable faults.
 .section .fixup,"ax"
-kill_domain_fixup1:
+crash_domain_fixup1:
         subl  $4,%esp
         SAVE_ALL
-        jmp   kill_domain
-kill_domain_fixup2:
+        jmp   crash_domain
+crash_domain_fixup2:
         addl  $4,%esp                     
-kill_domain_fixup3:
+crash_domain_fixup3:
         pushl %ss
         popl  %ds
-        jmp   kill_domain
+        jmp   crash_domain
 .previous
 
         ALIGN
index 39847e58f1da9c09803948e4db3681c08a85896a..666942301d68ecac4293c37f0b1b705f6bc8fdce 100644 (file)
@@ -282,11 +282,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     case DOM0_GETDOMAININFO:
     { 
-        struct task_struct *p;
-        u_long flags;
-        int i;
+        full_execution_context_t *c;
+        struct task_struct       *p;
+        unsigned long             flags;
+        int                       i;
 
-        read_lock_irqsave (&tasklist_lock, flags);
+        read_lock_irqsave(&tasklist_lock, flags);
 
         for_each_domain ( p )
         {
@@ -294,7 +295,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
                 break;
         }
 
-        if ( p == NULL )
+        if ( (p == NULL) || (p->state == TASK_DYING) )
         {
             ret = -ESRCH;
             goto gdi_out;
@@ -302,12 +303,23 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         else
         {
             op->u.getdomaininfo.domain      = p->domain;
-            strcpy (op->u.getdomaininfo.name, p->name);
-            op->u.getdomaininfo.processor   = p->processor;
-            op->u.getdomaininfo.has_cpu     = p->has_cpu;
-            op->u.getdomaininfo.state       = DOMSTATE_ACTIVE;
-            if ( (p->state == TASK_STOPPED) || (p->state == TASK_DYING) )
-                op->u.getdomaininfo.state = DOMSTATE_STOPPED;
+            strcpy(op->u.getdomaininfo.name, p->name);
+
+            if ( p->state == TASK_RUNNING )
+                op->u.getdomaininfo.flags = 
+                    p->has_cpu ? DOMSTATE_RUNNING : DOMSTATE_RUNNABLE;
+            else if ( (p->state == TASK_INTERRUPTIBLE) || 
+                      (p->state == TASK_UNINTERRUPTIBLE) )
+                op->u.getdomaininfo.flags = DOMSTATE_BLOCKED;
+            else if ( p->state == TASK_PAUSED )
+                op->u.getdomaininfo.flags = DOMSTATE_PAUSED;
+            else if ( p->state == TASK_CRASHED )
+                op->u.getdomaininfo.flags = DOMSTATE_CRASHED;
+            else
+                op->u.getdomaininfo.flags = DOMSTATE_STOPPED;
+            op->u.getdomaininfo.flags |= p->processor << DOMFLAGS_CPUSHIFT;
+            op->u.getdomaininfo.flags |= p->stop_code << DOMFLAGS_GUESTSHIFT;
+
             op->u.getdomaininfo.hyp_events  = p->hyp_events;
             op->u.getdomaininfo.tot_pages   = p->tot_pages;
             op->u.getdomaininfo.max_pages   = p->max_pages;
@@ -315,13 +327,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
             op->u.getdomaininfo.shared_info_frame = 
                 __pa(p->shared_info) >> PAGE_SHIFT;
 
-            if ( p->state == TASK_STOPPED && op->u.getdomaininfo.ctxt )
+            if ( (p->state == TASK_STOPPED) &&
+                 (op->u.getdomaininfo.ctxt != NULL) )
             {
-                full_execution_context_t *c=NULL;
-
                 if ( (c = kmalloc(sizeof(*c), GFP_KERNEL)) == NULL )
                 {
-                    ret= -ENOMEM;
+                    ret = -ENOMEM;
                     goto gdi_out;
                 }
 
@@ -373,12 +384,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
                 c->failsafe_callback_eip = 
                     p->failsafe_address;
 
-                if( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
-                {
+                if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
                     ret = -EINVAL;
-                }
 
-                if (c) kfree(c);
+                if ( c != NULL )
+                    kfree(c);
             }
         }
 
@@ -387,7 +397,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     gdi_out:
         read_unlock_irqrestore(&tasklist_lock, flags);
-
     }
     break;
 
index 6c0dccc8ac557379836480ab094f930f65166497..3da5d7913a66156dcaff7b031d5213b97cb922fc 100644 (file)
@@ -170,13 +170,6 @@ struct task_struct *find_last_domain(void)
 }
 
 
-void kill_domain_with_errmsg(const char *err)
-{
-    printk("DOM%u FATAL ERROR: %s\n", current->domain, err);
-    kill_domain();
-}
-
-
 void __kill_domain(struct task_struct *p)
 {
     int i;
@@ -245,7 +238,7 @@ long kill_other_domain(domid_t dom, int force)
     if ( (p = find_domain_by_id(dom)) == NULL )
         return -ESRCH;
 
-    if ( p->state == TASK_STOPPED )
+    if ( (p->state == TASK_STOPPED) || (p->state == TASK_CRASHED) )
         __kill_domain(p);
     else if ( force )
         send_hyp_event(p, _HYP_EVENT_DIE);
@@ -256,8 +249,27 @@ long kill_other_domain(domid_t dom, int force)
     return 0;
 }
 
-void stop_domain(void)
+
+void crash_domain(void)
 {
+    struct task_struct *p;
+
+    set_current_state(TASK_CRASHED);
+    
+    p = find_domain_by_id(0);
+    send_guest_virq(p, VIRQ_DOM_EXC);
+    put_task_struct(p);
+    
+    __enter_scheduler();
+    BUG();
+}
+
+
+void stop_domain(u8 reason)
+{
+    struct task_struct *p;
+
+    current->stop_code = reason;
     memcpy(&current->shared_info->execution_context, 
            get_execution_context(), 
            sizeof(execution_context_t));
@@ -265,13 +277,9 @@ void stop_domain(void)
     wmb(); /* All CPUs must see saved info in state TASK_STOPPED. */
     set_current_state(TASK_STOPPED);
 
-    /* OK, this is grim, but helps speed up live migrate. When a domain stops,
-       kick Dom0 */
-    {
-        struct task_struct *p;
-        guest_schedule_to_run( p = find_domain_by_id(0ULL) );
-        put_task_struct(p);
-    }
+    p = find_domain_by_id(0);
+    send_guest_virq(p, VIRQ_DOM_EXC);
+    put_task_struct(p);
 
     __enter_scheduler();
 }
index 00929ffc93be04b6ccb773cf7969bde34f809725..116ee145745b14475213321045e9c23c6392d779 100644 (file)
@@ -244,7 +244,7 @@ long do_sched_op(unsigned long op)
 {
     long ret = 0;
 
-    switch( op ) 
+    switch ( op & SCHEDOP_cmdmask ) 
     {
 
     case SCHEDOP_yield:
@@ -259,19 +259,9 @@ long do_sched_op(unsigned long op)
         break;
     }
 
-    case SCHEDOP_exit:
-    {
-        DPRINTK("DOM%u killed itself!\n", current->domain);
-        DPRINTK(" EIP == %08lx\n", get_execution_context()->eip);
-        kill_domain();
-        break;
-    }
-
     case SCHEDOP_stop:
     {
-        DPRINTK("DOM%u stopped itself!\n", current->domain);
-        DPRINTK(" EIP == %08lx\n", get_execution_context()->eip);
-        stop_domain();
+        stop_domain((u8)(op >> SCHEDOP_reasonshift));
         break;
     }
 
@@ -284,9 +274,9 @@ long do_sched_op(unsigned long op)
 
 
 /*
- * sched_pause_sync - synchronously pause a domain's execution 
- * XXXX This is horibly broken -- here just as a place holder at present,
- *                                do not use.
+ * sched_pause_sync - synchronously pause a domain's execution.
+ * XXXX This is horribly broken -- here just as a place holder at present,
+ *                                 do not use.
  */
 void sched_pause_sync(struct task_struct *p)
 {
index cb16d58afa9bc47c2180946254445bc388a6c11e..2693dcd5669a8d7704735f27e2bb5f189f0f3fde 100644 (file)
@@ -19,7 +19,7 @@
  * This makes sure that old versions of dom0 tools will stop working in a
  * well-defined way (rather than crashing the machine, for instance).
  */
-#define DOM0_INTERFACE_VERSION   0xAAAA000E
+#define DOM0_INTERFACE_VERSION   0xAAAA000F
 
 #define MAX_DOMAIN_NAME    16
 
@@ -84,24 +84,33 @@ typedef struct {
 #define DOM0_GETDOMAININFO    12
 typedef struct {
     /* IN variables. */
-    domid_t domain;                   /*  0 */
-    u32     __pad;
-    full_execution_context_t *ctxt;   /*  8 */
-    MEMORY_PADDING;
+    domid_t  domain;                  /*  0 */ /* NB. IN/OUT variable. */
     /* OUT variables. */
-    u8      name[MAX_DOMAIN_NAME];    /* 16 */
-    u32     processor;                /* 32 */
-    u32     has_cpu;                  /* 36 */
-#define DOMSTATE_ACTIVE              0
-#define DOMSTATE_STOPPED             1
-    u32     state;                    /* 40 */
-    u32     hyp_events;               /* 44 */
-    u32     tot_pages;                /* 48 */
-    u32     max_pages;                /* 52 */
-    u64     cpu_time;                 /* 56 */
-    memory_t shared_info_frame;       /* 64: MFN of shared_info struct */
+#define DOMSTATE_CRASHED     0 /* Crashed domain; frozen for postmortem.     */
+#define DOMSTATE_STOPPED     1 /* Domain voluntarily halted it execution.    */
+#define DOMSTATE_PAUSED      2 /* Currently paused (forced non-schedulable). */
+#define DOMSTATE_BLOCKED     3 /* Currently blocked pending a wake-up event. */
+#define DOMSTATE_RUNNABLE    4 /* Currently runnable.                        */
+#define DOMSTATE_RUNNING     5 /* Currently running.                         */
+#define DOMFLAGS_STATEMASK   7 /* One of the DOMSTATE_??? values.            */
+#define DOMFLAGS_STATESHIFT  0
+#define DOMFLAGS_CPUMASK   255 /* CPU to which this domain is bound.         */
+#define DOMFLAGS_CPUSHIFT    3
+#define DOMFLAGS_GUESTMASK 255 /* DOMSTATE_STOPPED -> Guest-supplied code.   */
+#define DOMFLAGS_GUESTSHIFT 11
+    u32      flags;                   /*  4 */
+    u8       name[MAX_DOMAIN_NAME];   /*  8 */
+    full_execution_context_t *ctxt;   /* 24 */ /* NB. IN/OUT variable. */
+    MEMORY_PADDING;
+    memory_t tot_pages;               /* 32 */
+    MEMORY_PADDING;
+    memory_t max_pages;               /* 40 */
+    MEMORY_PADDING;
+    memory_t shared_info_frame;       /* 48: MFN of shared_info struct */
     MEMORY_PADDING;
-} PACKED dom0_getdomaininfo_t; /* 72 bytes */
+    u64      cpu_time;                /* 56 */
+    u32      hyp_events;              /* 64 */
+} PACKED dom0_getdomaininfo_t; /* 68 bytes */
 
 #define DOM0_BUILDDOMAIN      13
 typedef struct {
@@ -314,7 +323,7 @@ typedef struct {
     u32 cmd;                          /* 0 */
     u32 interface_version;            /* 4 */ /* DOM0_INTERFACE_VERSION */
     union {                           /* 8 */
-       u32                      dummy[14]; /* 56 bytes */
+       u32                      dummy[18]; /* 72 bytes */
         dom0_createdomain_t      createdomain;
         dom0_startdomain_t       startdomain;
         dom0_stopdomain_t        stopdomain;
@@ -341,6 +350,6 @@ typedef struct {
        dom0_setdomainmaxmem_t   setdomainmaxmem;
        dom0_getpageframeinfo2_t getpageframeinfo2;
     } PACKED u;
-} PACKED dom0_op_t; /* 64 bytes */
+} PACKED dom0_op_t; /* 80 bytes */
 
 #endif /* __DOM0_OPS_H__ */
index 3e9aa19d0779af78ef97459c63a4e61b5ed4e096..0c41fd71b54e004276ce71911e268277e56f840b 100644 (file)
  * 
  * Virtual interrupts that a guest OS may receive from the hypervisor.
  */
-#define VIRQ_BLKDEV     0  /* A block device response has been queued. */
+#define VIRQ_BLKDEV     0  /* (OBS) A block device response has been queued. */
 #define VIRQ_TIMER      1  /* A timeout has been updated. */
-#define VIRQ_DIE        2  /* OS is about to be killed. Clean up please! */
+#define VIRQ_DIE        2  /* (OBS) OS is about to be killed. Clean up! */
 #define VIRQ_DEBUG      3  /* Request guest to dump debug info (gross!) */
-#define VIRQ_NET        4  /* There are packets for transmission. */
-#define VIRQ_PS2        5  /* PS/2 keyboard or mouse event(s) */
-#define VIRQ_STOP       6  /* Prepare for stopping and possible pickling */
+#define VIRQ_NET        4  /* (OBS) There are packets for transmission. */
+#define VIRQ_PS2        5  /* (OBS) PS/2 keyboard or mouse event(s) */
+#define VIRQ_STOP       6  /* (OBS) Prepare for stopping and pickling */
 #define VIRQ_EVTCHN     7  /* Event pending on an event channel */
-#define VIRQ_VBD_UPD    8  /* Event to signal VBDs should be reprobed */
-#define VIRQ_CONSOLE    9  /* This is only for domain-0 initial console. */
-#define VIRQ_PHYSIRQ   10  /* Event to signal pending physical IRQs. */
+#define VIRQ_VBD_UPD    8  /* (OBS) Event to signal VBDs should be reprobed */
+#define VIRQ_CONSOLE    9  /* (DOM0) bytes received on master console. */
+#define VIRQ_PHYSIRQ   10  /* Pending physical IRQs. */
 #define VIRQ_MISDIRECT 11  /* Catch-all virtual interrupt. */
-#define NR_VIRQS       12
+#define VIRQ_DOM_EXC   12  /* (DOM0) Exceptional event for some domain. */
+#define NR_VIRQS       13
 
 /*
  * MMU-UPDATE REQUESTS
  */
 #define SCHEDOP_yield           0   /* Give up the CPU voluntarily.      */
 #define SCHEDOP_block           1   /* Block until an event is received. */
-#define SCHEDOP_exit            3   /* Exit and kill this domain.        */
 #define SCHEDOP_stop            4   /* Stop executing this domain.       */
+#define SCHEDOP_cmdmask       255   /* 8-bit command. */
+#define SCHEDOP_reasonshift     8   /* 8-bit stop code. (SCHEDOP_stop only) */
 
 /*
  * Commands to HYPERVISOR_console_io().
index a9464415fc04bdd3a9407a21fc1ef558c631573d..4df89804443b691a0e0070532c3cee931f0ff5c4 100644 (file)
@@ -123,6 +123,7 @@ struct task_struct
     struct list_head run_list;
     int              has_cpu;
     int              state;         /* current run state */
+    int              stop_code;     /* stop code from OS (if TASK_STOPPED). */
     int              cpupinned;     /* true if pinned to curent CPU */
     s_time_t         lastschd;      /* time this domain was last scheduled */
     s_time_t         lastdeschd;    /* time this domain was last descheduled */
@@ -207,6 +208,7 @@ struct task_struct
 #define TASK_STOPPED             4
 #define TASK_DYING               8
 #define TASK_PAUSED             16
+#define TASK_CRASHED            32
 
 #include <asm/uaccess.h> /* for KERNEL_DS */
 
@@ -255,9 +257,8 @@ struct task_struct *find_last_domain(void);
 extern void release_task(struct task_struct *);
 extern void __kill_domain(struct task_struct *p);
 extern void kill_domain(void);
-extern void kill_domain_with_errmsg(const char *err);
 extern long kill_other_domain(domid_t dom, int force);
-extern void stop_domain(void);
+extern void stop_domain(u8 reason);
 extern long stop_other_domain(domid_t dom);
 
 /* arch/process.c */