ia64/xen-unstable

changeset 1447:a956305055ae

bitkeeper revision 1.947 (40c84719Ozi8_o69nGYdNuJ6OQd4eQ)

Cleanup domain stop/crash. Provide notification to DOM0 so that
cleanup/postmortem can occur before domain is killed.
author kaf24@scramble.cl.cam.ac.uk
date Thu Jun 10 11:33:45 2004 +0000 (2004-06-10)
parents f3123052268f
children 5913b86987c3
files 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
line diff
     1.1 --- a/extras/mini-os/h/hypervisor.h	Wed Jun 09 16:36:08 2004 +0000
     1.2 +++ b/extras/mini-os/h/hypervisor.h	Thu Jun 10 11:33:45 2004 +0000
     1.3 @@ -15,7 +15,7 @@
     1.4  #include <hypervisor-ifs/network.h>
     1.5  #include <hypervisor-ifs/block.h>
     1.6  #include <hypervisor-ifs/hypervisor-if.h>
     1.7 -
     1.8 +#include "../../../tools/xend/lib/domain_controller.h"
     1.9  
    1.10  /*
    1.11   * a placeholder for the start of day information passed up from the hypervisor
    1.12 @@ -155,25 +155,39 @@ static __inline__ int HYPERVISOR_block(v
    1.13      return ret;
    1.14  }
    1.15  
    1.16 -static __inline__ int HYPERVISOR_exit(void)
    1.17 +static inline int HYPERVISOR_shutdown(void)
    1.18  {
    1.19      int ret;
    1.20      __asm__ __volatile__ (
    1.21          TRAP_INSTR
    1.22          : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
    1.23 -        "b" (SCHEDOP_exit) : "memory" );
    1.24 +        "b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift))
    1.25 +        : "memory" );
    1.26  
    1.27      return ret;
    1.28  }
    1.29  
    1.30 -static __inline__ int HYPERVISOR_stop(unsigned long srec)
    1.31 +static inline int HYPERVISOR_reboot(void)
    1.32 +{
    1.33 +    int ret;
    1.34 +    __asm__ __volatile__ (
    1.35 +        TRAP_INSTR
    1.36 +        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
    1.37 +        "b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift))
    1.38 +        : "memory" );
    1.39 +
    1.40 +    return ret;
    1.41 +}
    1.42 +
    1.43 +static inline int HYPERVISOR_suspend(unsigned long srec)
    1.44  {
    1.45      int ret;
    1.46      /* NB. On suspend, control software expects a suspend record in %esi. */
    1.47      __asm__ __volatile__ (
    1.48          TRAP_INSTR
    1.49          : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
    1.50 -        "b" (SCHEDOP_stop), "S" (srec) : "memory" );
    1.51 +        "b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)), 
    1.52 +        "S" (srec) : "memory" );
    1.53  
    1.54      return ret;
    1.55  }
     2.1 --- a/extras/mini-os/kernel.c	Wed Jun 09 16:36:08 2004 +0000
     2.2 +++ b/extras/mini-os/kernel.c	Thu Jun 10 11:33:45 2004 +0000
     2.3 @@ -153,7 +153,7 @@ void start_kernel(start_info_t *si)
     2.4  void do_exit(void)
     2.5  {
     2.6      printk("do_exit called!\n");
     2.7 -    for ( ;; ) HYPERVISOR_exit();
     2.8 +    for ( ;; ) HYPERVISOR_shutdown();
     2.9  }
    2.10  static void exit_handler(int ev, struct pt_regs *regs) {
    2.11      do_exit();
     3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c	Wed Jun 09 16:36:08 2004 +0000
     3.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c	Thu Jun 10 11:33:45 2004 +0000
     3.3 @@ -120,17 +120,23 @@ void machine_restart(char * __unused)
     3.4      /* We really want to get pending console data out before we die. */
     3.5      extern void xencons_force_flush(void);
     3.6      xencons_force_flush();
     3.7 -    HYPERVISOR_exit();
     3.8 +    HYPERVISOR_reboot();
     3.9  }
    3.10  
    3.11  void machine_halt(void)
    3.12  {
    3.13 -    machine_restart(NULL);
    3.14 +    /* We really want to get pending console data out before we die. */
    3.15 +    extern void xencons_force_flush(void);
    3.16 +    xencons_force_flush();
    3.17 +    HYPERVISOR_shutdown();
    3.18  }
    3.19  
    3.20  void machine_power_off(void)
    3.21  {
    3.22 -    machine_restart(NULL);
    3.23 +    /* We really want to get pending console data out before we die. */
    3.24 +    extern void xencons_force_flush(void);
    3.25 +    xencons_force_flush();
    3.26 +    HYPERVISOR_shutdown();
    3.27  }
    3.28  
    3.29  extern void show_trace(unsigned long* esp);
     4.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Wed Jun 09 16:36:08 2004 +0000
     4.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Thu Jun 10 11:33:45 2004 +0000
     4.3 @@ -1205,7 +1205,7 @@ static void stop_task(void *unused)
     4.4  
     4.5      memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info));
     4.6  
     4.7 -    HYPERVISOR_stop(virt_to_machine(suspend_record) >> PAGE_SHIFT);
     4.8 +    HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
     4.9  
    4.10      suspending = 0; 
    4.11  
     5.1 --- a/linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h	Wed Jun 09 16:36:08 2004 +0000
     5.2 +++ b/linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h	Thu Jun 10 11:33:45 2004 +0000
     5.3 @@ -253,25 +253,39 @@ static inline int HYPERVISOR_block(void)
     5.4      return ret;
     5.5  }
     5.6  
     5.7 -static inline int HYPERVISOR_exit(void)
     5.8 +static inline int HYPERVISOR_shutdown(void)
     5.9  {
    5.10      int ret;
    5.11      __asm__ __volatile__ (
    5.12          TRAP_INSTR
    5.13          : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
    5.14 -        "b" (SCHEDOP_exit) : "memory" );
    5.15 +        "b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift))
    5.16 +        : "memory" );
    5.17  
    5.18      return ret;
    5.19  }
    5.20  
    5.21 -static inline int HYPERVISOR_stop(unsigned long srec)
    5.22 +static inline int HYPERVISOR_reboot(void)
    5.23 +{
    5.24 +    int ret;
    5.25 +    __asm__ __volatile__ (
    5.26 +        TRAP_INSTR
    5.27 +        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
    5.28 +        "b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift))
    5.29 +        : "memory" );
    5.30 +
    5.31 +    return ret;
    5.32 +}
    5.33 +
    5.34 +static inline int HYPERVISOR_suspend(unsigned long srec)
    5.35  {
    5.36      int ret;
    5.37      /* NB. On suspend, control software expects a suspend record in %esi. */
    5.38      __asm__ __volatile__ (
    5.39          TRAP_INSTR
    5.40          : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
    5.41 -        "b" (SCHEDOP_stop), "S" (srec) : "memory" );
    5.42 +        "b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)), 
    5.43 +        "S" (srec) : "memory" );
    5.44  
    5.45      return ret;
    5.46  }
     6.1 --- a/tools/xc/lib/xc_domain.c	Wed Jun 09 16:36:08 2004 +0000
     6.2 +++ b/tools/xc/lib/xc_domain.c	Thu Jun 10 11:33:45 2004 +0000
     6.3 @@ -91,9 +91,14 @@ int xc_domain_getinfo(int xc_handle,
     6.4          if ( do_dom0_op(xc_handle, &op) < 0 )
     6.5              break;
     6.6          info->domid   = (u32)op.u.getdomaininfo.domain;
     6.7 -        info->cpu     = op.u.getdomaininfo.processor;
     6.8 -        info->has_cpu = op.u.getdomaininfo.has_cpu;
     6.9 -        info->stopped = (op.u.getdomaininfo.state == DOMSTATE_STOPPED);
    6.10 +
    6.11 +        info->cpu     =
    6.12 +            (op.u.getdomaininfo.flags>>DOMFLAGS_CPUSHIFT) & DOMFLAGS_CPUMASK;
    6.13 +        info->has_cpu =
    6.14 +            (op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_RUNNING;
    6.15 +        info->stopped = 
    6.16 +            (op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_STOPPED;
    6.17 +
    6.18          info->nr_pages = op.u.getdomaininfo.tot_pages;
    6.19          info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT-10);
    6.20          info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
     7.1 --- a/tools/xc/lib/xc_linux_build.c	Wed Jun 09 16:36:08 2004 +0000
     7.2 +++ b/tools/xc/lib/xc_linux_build.c	Thu Jun 10 11:33:45 2004 +0000
     7.3 @@ -436,7 +436,7 @@ int xc_linux_build(int xc_handle,
     7.4          PERROR("Could not get info on domain");
     7.5          goto error_out;
     7.6      }
     7.7 -    if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) ||
     7.8 +    if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) ||
     7.9           (ctxt->pt_base != 0) )
    7.10      {
    7.11          ERROR("Domain is already constructed");
     8.1 --- a/tools/xc/lib/xc_netbsd_build.c	Wed Jun 09 16:36:08 2004 +0000
     8.2 +++ b/tools/xc/lib/xc_netbsd_build.c	Thu Jun 10 11:33:45 2004 +0000
     8.3 @@ -258,7 +258,7 @@ int xc_netbsd_build(int xc_handle,
     8.4          PERROR("Could not get info on domain");
     8.5          goto error_out;
     8.6      }
     8.7 -    if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) ||
     8.8 +    if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) ||
     8.9           (op.u.getdomaininfo.ctxt->pt_base != 0) )
    8.10      {
    8.11          ERROR("Domain is already constructed");
     9.1 --- a/tools/xc/lib/xc_private.c	Wed Jun 09 16:36:08 2004 +0000
     9.2 +++ b/tools/xc/lib/xc_private.c	Thu Jun 10 11:33:45 2004 +0000
     9.3 @@ -229,7 +229,8 @@ int xc_domain_stop_sync( int xc_handle, 
     9.4              goto out;
     9.5          }
     9.6  
     9.7 -        if ( op->u.getdomaininfo.state == DOMSTATE_STOPPED )
     9.8 +        if ( (op->u.getdomaininfo.flags & DOMFLAGS_STATEMASK) == 
     9.9 +             DOMSTATE_STOPPED )
    9.10          {
    9.11              printf("Domain %u stopped\n",domid);
    9.12              return 0;
    10.1 --- a/tools/xend/lib/domain_controller.h	Wed Jun 09 16:36:08 2004 +0000
    10.2 +++ b/tools/xend/lib/domain_controller.h	Thu Jun 10 11:33:45 2004 +0000
    10.3 @@ -29,6 +29,16 @@ typedef struct {
    10.4  
    10.5  
    10.6  /*
    10.7 + * Stop codes for SCHEDOP_stop. These are opaque to Xen but interpreted by
    10.8 + * control software to determine appropriate action.
    10.9 + */
   10.10 +
   10.11 +#define STOPCODE_shutdown   0  /* Domain exited normally. Clean up and kill. */
   10.12 +#define STOPCODE_reboot     1  /* Clean up, kill, and then restart. */
   10.13 +#define STOPCODE_suspend    2  /* Clean up, save suspend info, kill. */
   10.14 +
   10.15 +
   10.16 +/*
   10.17   * CONTROLLER MESSAGING INTERFACE.
   10.18   */
   10.19  
    11.1 --- a/xen/arch/i386/entry.S	Wed Jun 09 16:36:08 2004 +0000
    11.2 +++ b/xen/arch/i386/entry.S	Thu Jun 10 11:33:45 2004 +0000
    11.3 @@ -446,34 +446,34 @@ FAULT12:movl %eax,8(%esi)
    11.4                                
    11.5  .section __ex_table,"a"
    11.6          .align 4
    11.7 -        .long FAULT1, kill_domain_fixup3 # Fault writing to ring-1 stack
    11.8 -        .long FAULT2, kill_domain_fixup3 # Fault writing to ring-1 stack
    11.9 -        .long FAULT3, kill_domain_fixup3 # Fault writing to ring-1 stack
   11.10 -        .long FAULT4, kill_domain_fixup3 # Fault writing to ring-1 stack
   11.11 -        .long FAULT5, kill_domain_fixup1 # Fault executing failsafe iret
   11.12 -        .long FAULT6, kill_domain_fixup2 # Fault loading ring-1 stack selector
   11.13 -        .long FAULT7, kill_domain_fixup2 # Fault writing to ring-1 stack
   11.14 -        .long FAULT8, kill_domain_fixup2 # Fault writing to ring-1 stack
   11.15 -        .long FAULT9, kill_domain_fixup2 # Fault loading ring-1 stack selector
   11.16 -        .long FAULT10,kill_domain_fixup2 # Fault writing to ring-1 stack
   11.17 -        .long FAULT11,kill_domain_fixup2 # Fault writing to ring-1 stack
   11.18 -        .long FAULT12,kill_domain_fixup2 # Fault writing to ring-1 stack
   11.19 -        .long FAULT13,kill_domain_fixup3 # Fault writing to ring-1 stack
   11.20 -        .long FAULT14,kill_domain_fixup3 # Fault writing to ring-1 stack
   11.21 +        .long FAULT1, crash_domain_fixup3 # Fault writing to ring-1 stack
   11.22 +        .long FAULT2, crash_domain_fixup3 # Fault writing to ring-1 stack
   11.23 +        .long FAULT3, crash_domain_fixup3 # Fault writing to ring-1 stack
   11.24 +        .long FAULT4, crash_domain_fixup3 # Fault writing to ring-1 stack
   11.25 +        .long FAULT5, crash_domain_fixup1 # Fault executing failsafe iret
   11.26 +        .long FAULT6, crash_domain_fixup2 # Fault loading ring-1 stack selector
   11.27 +        .long FAULT7, crash_domain_fixup2 # Fault writing to ring-1 stack
   11.28 +        .long FAULT8, crash_domain_fixup2 # Fault writing to ring-1 stack
   11.29 +        .long FAULT9, crash_domain_fixup2 # Fault loading ring-1 stack selector
   11.30 +        .long FAULT10,crash_domain_fixup2 # Fault writing to ring-1 stack
   11.31 +        .long FAULT11,crash_domain_fixup2 # Fault writing to ring-1 stack
   11.32 +        .long FAULT12,crash_domain_fixup2 # Fault writing to ring-1 stack
   11.33 +        .long FAULT13,crash_domain_fixup3 # Fault writing to ring-1 stack
   11.34 +        .long FAULT14,crash_domain_fixup3 # Fault writing to ring-1 stack
   11.35  .previous
   11.36                 
   11.37  # This handler kills domains which experience unrecoverable faults.
   11.38  .section .fixup,"ax"
   11.39 -kill_domain_fixup1:
   11.40 +crash_domain_fixup1:
   11.41          subl  $4,%esp
   11.42          SAVE_ALL
   11.43 -        jmp   kill_domain
   11.44 -kill_domain_fixup2:
   11.45 +        jmp   crash_domain
   11.46 +crash_domain_fixup2:
   11.47          addl  $4,%esp                     
   11.48 -kill_domain_fixup3:
   11.49 +crash_domain_fixup3:
   11.50          pushl %ss
   11.51          popl  %ds
   11.52 -        jmp   kill_domain
   11.53 +        jmp   crash_domain
   11.54  .previous
   11.55  
   11.56          ALIGN
    12.1 --- a/xen/common/dom0_ops.c	Wed Jun 09 16:36:08 2004 +0000
    12.2 +++ b/xen/common/dom0_ops.c	Thu Jun 10 11:33:45 2004 +0000
    12.3 @@ -282,11 +282,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    12.4  
    12.5      case DOM0_GETDOMAININFO:
    12.6      { 
    12.7 -        struct task_struct *p;
    12.8 -        u_long flags;
    12.9 -        int i;
   12.10 +        full_execution_context_t *c;
   12.11 +        struct task_struct       *p;
   12.12 +        unsigned long             flags;
   12.13 +        int                       i;
   12.14  
   12.15 -        read_lock_irqsave (&tasklist_lock, flags);
   12.16 +        read_lock_irqsave(&tasklist_lock, flags);
   12.17  
   12.18          for_each_domain ( p )
   12.19          {
   12.20 @@ -294,7 +295,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   12.21                  break;
   12.22          }
   12.23  
   12.24 -        if ( p == NULL )
   12.25 +        if ( (p == NULL) || (p->state == TASK_DYING) )
   12.26          {
   12.27              ret = -ESRCH;
   12.28              goto gdi_out;
   12.29 @@ -302,12 +303,23 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   12.30          else
   12.31          {
   12.32              op->u.getdomaininfo.domain      = p->domain;
   12.33 -            strcpy (op->u.getdomaininfo.name, p->name);
   12.34 -            op->u.getdomaininfo.processor   = p->processor;
   12.35 -            op->u.getdomaininfo.has_cpu     = p->has_cpu;
   12.36 -            op->u.getdomaininfo.state       = DOMSTATE_ACTIVE;
   12.37 -            if ( (p->state == TASK_STOPPED) || (p->state == TASK_DYING) )
   12.38 -                op->u.getdomaininfo.state = DOMSTATE_STOPPED;
   12.39 +            strcpy(op->u.getdomaininfo.name, p->name);
   12.40 +
   12.41 +            if ( p->state == TASK_RUNNING )
   12.42 +                op->u.getdomaininfo.flags = 
   12.43 +                    p->has_cpu ? DOMSTATE_RUNNING : DOMSTATE_RUNNABLE;
   12.44 +            else if ( (p->state == TASK_INTERRUPTIBLE) || 
   12.45 +                      (p->state == TASK_UNINTERRUPTIBLE) )
   12.46 +                op->u.getdomaininfo.flags = DOMSTATE_BLOCKED;
   12.47 +            else if ( p->state == TASK_PAUSED )
   12.48 +                op->u.getdomaininfo.flags = DOMSTATE_PAUSED;
   12.49 +            else if ( p->state == TASK_CRASHED )
   12.50 +                op->u.getdomaininfo.flags = DOMSTATE_CRASHED;
   12.51 +            else
   12.52 +                op->u.getdomaininfo.flags = DOMSTATE_STOPPED;
   12.53 +            op->u.getdomaininfo.flags |= p->processor << DOMFLAGS_CPUSHIFT;
   12.54 +            op->u.getdomaininfo.flags |= p->stop_code << DOMFLAGS_GUESTSHIFT;
   12.55 +
   12.56              op->u.getdomaininfo.hyp_events  = p->hyp_events;
   12.57              op->u.getdomaininfo.tot_pages   = p->tot_pages;
   12.58              op->u.getdomaininfo.max_pages   = p->max_pages;
   12.59 @@ -315,13 +327,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   12.60              op->u.getdomaininfo.shared_info_frame = 
   12.61                  __pa(p->shared_info) >> PAGE_SHIFT;
   12.62  
   12.63 -            if ( p->state == TASK_STOPPED && op->u.getdomaininfo.ctxt )
   12.64 +            if ( (p->state == TASK_STOPPED) &&
   12.65 +                 (op->u.getdomaininfo.ctxt != NULL) )
   12.66              {
   12.67 -                full_execution_context_t *c=NULL;
   12.68 -
   12.69                  if ( (c = kmalloc(sizeof(*c), GFP_KERNEL)) == NULL )
   12.70                  {
   12.71 -                    ret= -ENOMEM;
   12.72 +                    ret = -ENOMEM;
   12.73                      goto gdi_out;
   12.74                  }
   12.75  
   12.76 @@ -373,12 +384,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   12.77                  c->failsafe_callback_eip = 
   12.78                      p->failsafe_address;
   12.79  
   12.80 -                if( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
   12.81 -                {
   12.82 +                if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
   12.83                      ret = -EINVAL;
   12.84 -                }
   12.85  
   12.86 -                if (c) kfree(c);
   12.87 +                if ( c != NULL )
   12.88 +                    kfree(c);
   12.89              }
   12.90          }
   12.91  
   12.92 @@ -387,7 +397,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   12.93  
   12.94      gdi_out:
   12.95          read_unlock_irqrestore(&tasklist_lock, flags);
   12.96 -
   12.97      }
   12.98      break;
   12.99  
    13.1 --- a/xen/common/domain.c	Wed Jun 09 16:36:08 2004 +0000
    13.2 +++ b/xen/common/domain.c	Thu Jun 10 11:33:45 2004 +0000
    13.3 @@ -170,13 +170,6 @@ struct task_struct *find_last_domain(voi
    13.4  }
    13.5  
    13.6  
    13.7 -void kill_domain_with_errmsg(const char *err)
    13.8 -{
    13.9 -    printk("DOM%u FATAL ERROR: %s\n", current->domain, err);
   13.10 -    kill_domain();
   13.11 -}
   13.12 -
   13.13 -
   13.14  void __kill_domain(struct task_struct *p)
   13.15  {
   13.16      int i;
   13.17 @@ -245,7 +238,7 @@ long kill_other_domain(domid_t dom, int 
   13.18      if ( (p = find_domain_by_id(dom)) == NULL )
   13.19          return -ESRCH;
   13.20  
   13.21 -    if ( p->state == TASK_STOPPED )
   13.22 +    if ( (p->state == TASK_STOPPED) || (p->state == TASK_CRASHED) )
   13.23          __kill_domain(p);
   13.24      else if ( force )
   13.25          send_hyp_event(p, _HYP_EVENT_DIE);
   13.26 @@ -256,8 +249,27 @@ long kill_other_domain(domid_t dom, int 
   13.27      return 0;
   13.28  }
   13.29  
   13.30 -void stop_domain(void)
   13.31 +
   13.32 +void crash_domain(void)
   13.33  {
   13.34 +    struct task_struct *p;
   13.35 +
   13.36 +    set_current_state(TASK_CRASHED);
   13.37 +    
   13.38 +    p = find_domain_by_id(0);
   13.39 +    send_guest_virq(p, VIRQ_DOM_EXC);
   13.40 +    put_task_struct(p);
   13.41 +    
   13.42 +    __enter_scheduler();
   13.43 +    BUG();
   13.44 +}
   13.45 +
   13.46 +
   13.47 +void stop_domain(u8 reason)
   13.48 +{
   13.49 +    struct task_struct *p;
   13.50 +
   13.51 +    current->stop_code = reason;
   13.52      memcpy(&current->shared_info->execution_context, 
   13.53             get_execution_context(), 
   13.54             sizeof(execution_context_t));
   13.55 @@ -265,13 +277,9 @@ void stop_domain(void)
   13.56      wmb(); /* All CPUs must see saved info in state TASK_STOPPED. */
   13.57      set_current_state(TASK_STOPPED);
   13.58  
   13.59 -    /* OK, this is grim, but helps speed up live migrate. When a domain stops,
   13.60 -       kick Dom0 */
   13.61 -    {
   13.62 -        struct task_struct *p;
   13.63 -        guest_schedule_to_run( p = find_domain_by_id(0ULL) );
   13.64 -        put_task_struct(p);
   13.65 -    }
   13.66 +    p = find_domain_by_id(0);
   13.67 +    send_guest_virq(p, VIRQ_DOM_EXC);
   13.68 +    put_task_struct(p);
   13.69  
   13.70      __enter_scheduler();
   13.71  }
    14.1 --- a/xen/common/schedule.c	Wed Jun 09 16:36:08 2004 +0000
    14.2 +++ b/xen/common/schedule.c	Thu Jun 10 11:33:45 2004 +0000
    14.3 @@ -244,7 +244,7 @@ long do_sched_op(unsigned long op)
    14.4  {
    14.5      long ret = 0;
    14.6  
    14.7 -    switch( op ) 
    14.8 +    switch ( op & SCHEDOP_cmdmask ) 
    14.9      {
   14.10  
   14.11      case SCHEDOP_yield:
   14.12 @@ -259,19 +259,9 @@ long do_sched_op(unsigned long op)
   14.13          break;
   14.14      }
   14.15  
   14.16 -    case SCHEDOP_exit:
   14.17 -    {
   14.18 -        DPRINTK("DOM%u killed itself!\n", current->domain);
   14.19 -        DPRINTK(" EIP == %08lx\n", get_execution_context()->eip);
   14.20 -        kill_domain();
   14.21 -        break;
   14.22 -    }
   14.23 -
   14.24      case SCHEDOP_stop:
   14.25      {
   14.26 -        DPRINTK("DOM%u stopped itself!\n", current->domain);
   14.27 -        DPRINTK(" EIP == %08lx\n", get_execution_context()->eip);
   14.28 -        stop_domain();
   14.29 +        stop_domain((u8)(op >> SCHEDOP_reasonshift));
   14.30          break;
   14.31      }
   14.32  
   14.33 @@ -284,9 +274,9 @@ long do_sched_op(unsigned long op)
   14.34  
   14.35  
   14.36  /*
   14.37 - * sched_pause_sync - synchronously pause a domain's execution 
   14.38 - * XXXX This is horibly broken -- here just as a place holder at present,
   14.39 - *                                do not use.
   14.40 + * sched_pause_sync - synchronously pause a domain's execution.
   14.41 + * XXXX This is horribly broken -- here just as a place holder at present,
   14.42 + *                                 do not use.
   14.43   */
   14.44  void sched_pause_sync(struct task_struct *p)
   14.45  {
    15.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h	Wed Jun 09 16:36:08 2004 +0000
    15.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h	Thu Jun 10 11:33:45 2004 +0000
    15.3 @@ -19,7 +19,7 @@
    15.4   * This makes sure that old versions of dom0 tools will stop working in a
    15.5   * well-defined way (rather than crashing the machine, for instance).
    15.6   */
    15.7 -#define DOM0_INTERFACE_VERSION   0xAAAA000E
    15.8 +#define DOM0_INTERFACE_VERSION   0xAAAA000F
    15.9  
   15.10  #define MAX_DOMAIN_NAME    16
   15.11  
   15.12 @@ -84,24 +84,33 @@ typedef struct {
   15.13  #define DOM0_GETDOMAININFO    12
   15.14  typedef struct {
   15.15      /* IN variables. */
   15.16 -    domid_t domain;                   /*  0 */
   15.17 -    u32     __pad;
   15.18 -    full_execution_context_t *ctxt;   /*  8 */
   15.19 -    MEMORY_PADDING;
   15.20 +    domid_t  domain;                  /*  0 */ /* NB. IN/OUT variable. */
   15.21      /* OUT variables. */
   15.22 -    u8      name[MAX_DOMAIN_NAME];    /* 16 */
   15.23 -    u32     processor;                /* 32 */
   15.24 -    u32     has_cpu;                  /* 36 */
   15.25 -#define DOMSTATE_ACTIVE              0
   15.26 -#define DOMSTATE_STOPPED             1
   15.27 -    u32     state;                    /* 40 */
   15.28 -    u32     hyp_events;               /* 44 */
   15.29 -    u32     tot_pages;                /* 48 */
   15.30 -    u32     max_pages;                /* 52 */
   15.31 -    u64     cpu_time;                 /* 56 */
   15.32 -    memory_t shared_info_frame;       /* 64: MFN of shared_info struct */
   15.33 +#define DOMSTATE_CRASHED     0 /* Crashed domain; frozen for postmortem.     */
   15.34 +#define DOMSTATE_STOPPED     1 /* Domain voluntarily halted it execution.    */
   15.35 +#define DOMSTATE_PAUSED      2 /* Currently paused (forced non-schedulable). */
   15.36 +#define DOMSTATE_BLOCKED     3 /* Currently blocked pending a wake-up event. */
   15.37 +#define DOMSTATE_RUNNABLE    4 /* Currently runnable.                        */
   15.38 +#define DOMSTATE_RUNNING     5 /* Currently running.                         */
   15.39 +#define DOMFLAGS_STATEMASK   7 /* One of the DOMSTATE_??? values.            */
   15.40 +#define DOMFLAGS_STATESHIFT  0
   15.41 +#define DOMFLAGS_CPUMASK   255 /* CPU to which this domain is bound.         */
   15.42 +#define DOMFLAGS_CPUSHIFT    3
   15.43 +#define DOMFLAGS_GUESTMASK 255 /* DOMSTATE_STOPPED -> Guest-supplied code.   */
   15.44 +#define DOMFLAGS_GUESTSHIFT 11
   15.45 +    u32      flags;                   /*  4 */
   15.46 +    u8       name[MAX_DOMAIN_NAME];   /*  8 */
   15.47 +    full_execution_context_t *ctxt;   /* 24 */ /* NB. IN/OUT variable. */
   15.48      MEMORY_PADDING;
   15.49 -} PACKED dom0_getdomaininfo_t; /* 72 bytes */
   15.50 +    memory_t tot_pages;               /* 32 */
   15.51 +    MEMORY_PADDING;
   15.52 +    memory_t max_pages;               /* 40 */
   15.53 +    MEMORY_PADDING;
   15.54 +    memory_t shared_info_frame;       /* 48: MFN of shared_info struct */
   15.55 +    MEMORY_PADDING;
   15.56 +    u64      cpu_time;                /* 56 */
   15.57 +    u32      hyp_events;              /* 64 */
   15.58 +} PACKED dom0_getdomaininfo_t; /* 68 bytes */
   15.59  
   15.60  #define DOM0_BUILDDOMAIN      13
   15.61  typedef struct {
   15.62 @@ -314,7 +323,7 @@ typedef struct {
   15.63      u32 cmd;                          /* 0 */
   15.64      u32 interface_version;            /* 4 */ /* DOM0_INTERFACE_VERSION */
   15.65      union {                           /* 8 */
   15.66 -	u32                      dummy[14]; /* 56 bytes */
   15.67 +	u32                      dummy[18]; /* 72 bytes */
   15.68          dom0_createdomain_t      createdomain;
   15.69          dom0_startdomain_t       startdomain;
   15.70          dom0_stopdomain_t        stopdomain;
   15.71 @@ -341,6 +350,6 @@ typedef struct {
   15.72  	dom0_setdomainmaxmem_t   setdomainmaxmem;
   15.73  	dom0_getpageframeinfo2_t getpageframeinfo2;
   15.74      } PACKED u;
   15.75 -} PACKED dom0_op_t; /* 64 bytes */
   15.76 +} PACKED dom0_op_t; /* 80 bytes */
   15.77  
   15.78  #endif /* __DOM0_OPS_H__ */
    16.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Wed Jun 09 16:36:08 2004 +0000
    16.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Thu Jun 10 11:33:45 2004 +0000
    16.3 @@ -59,19 +59,20 @@
    16.4   * 
    16.5   * Virtual interrupts that a guest OS may receive from the hypervisor.
    16.6   */
    16.7 -#define VIRQ_BLKDEV     0  /* A block device response has been queued. */
    16.8 +#define VIRQ_BLKDEV     0  /* (OBS) A block device response has been queued. */
    16.9  #define VIRQ_TIMER      1  /* A timeout has been updated. */
   16.10 -#define VIRQ_DIE        2  /* OS is about to be killed. Clean up please! */
   16.11 +#define VIRQ_DIE        2  /* (OBS) OS is about to be killed. Clean up! */
   16.12  #define VIRQ_DEBUG      3  /* Request guest to dump debug info (gross!) */
   16.13 -#define VIRQ_NET        4  /* There are packets for transmission. */
   16.14 -#define VIRQ_PS2        5  /* PS/2 keyboard or mouse event(s) */
   16.15 -#define VIRQ_STOP       6  /* Prepare for stopping and possible pickling */
   16.16 +#define VIRQ_NET        4  /* (OBS) There are packets for transmission. */
   16.17 +#define VIRQ_PS2        5  /* (OBS) PS/2 keyboard or mouse event(s) */
   16.18 +#define VIRQ_STOP       6  /* (OBS) Prepare for stopping and pickling */
   16.19  #define VIRQ_EVTCHN     7  /* Event pending on an event channel */
   16.20 -#define VIRQ_VBD_UPD    8  /* Event to signal VBDs should be reprobed */
   16.21 -#define VIRQ_CONSOLE    9  /* This is only for domain-0 initial console. */
   16.22 -#define VIRQ_PHYSIRQ   10  /* Event to signal pending physical IRQs. */
   16.23 +#define VIRQ_VBD_UPD    8  /* (OBS) Event to signal VBDs should be reprobed */
   16.24 +#define VIRQ_CONSOLE    9  /* (DOM0) bytes received on master console. */
   16.25 +#define VIRQ_PHYSIRQ   10  /* Pending physical IRQs. */
   16.26  #define VIRQ_MISDIRECT 11  /* Catch-all virtual interrupt. */
   16.27 -#define NR_VIRQS       12
   16.28 +#define VIRQ_DOM_EXC   12  /* (DOM0) Exceptional event for some domain. */
   16.29 +#define NR_VIRQS       13
   16.30  
   16.31  /*
   16.32   * MMU-UPDATE REQUESTS
   16.33 @@ -169,8 +170,9 @@
   16.34   */
   16.35  #define SCHEDOP_yield           0   /* Give up the CPU voluntarily.      */
   16.36  #define SCHEDOP_block           1   /* Block until an event is received. */
   16.37 -#define SCHEDOP_exit            3   /* Exit and kill this domain.        */
   16.38  #define SCHEDOP_stop            4   /* Stop executing this domain.       */
   16.39 +#define SCHEDOP_cmdmask       255   /* 8-bit command. */
   16.40 +#define SCHEDOP_reasonshift     8   /* 8-bit stop code. (SCHEDOP_stop only) */
   16.41  
   16.42  /*
   16.43   * Commands to HYPERVISOR_console_io().
    17.1 --- a/xen/include/xen/sched.h	Wed Jun 09 16:36:08 2004 +0000
    17.2 +++ b/xen/include/xen/sched.h	Thu Jun 10 11:33:45 2004 +0000
    17.3 @@ -123,6 +123,7 @@ struct task_struct
    17.4      struct list_head run_list;
    17.5      int              has_cpu;
    17.6      int              state;         /* current run state */
    17.7 +    int              stop_code;     /* stop code from OS (if TASK_STOPPED). */
    17.8      int              cpupinned;     /* true if pinned to curent CPU */
    17.9      s_time_t         lastschd;      /* time this domain was last scheduled */
   17.10      s_time_t         lastdeschd;    /* time this domain was last descheduled */
   17.11 @@ -207,6 +208,7 @@ struct task_struct
   17.12  #define TASK_STOPPED             4
   17.13  #define TASK_DYING               8
   17.14  #define TASK_PAUSED             16
   17.15 +#define TASK_CRASHED            32
   17.16  
   17.17  #include <asm/uaccess.h> /* for KERNEL_DS */
   17.18  
   17.19 @@ -255,9 +257,8 @@ struct task_struct *find_last_domain(voi
   17.20  extern void release_task(struct task_struct *);
   17.21  extern void __kill_domain(struct task_struct *p);
   17.22  extern void kill_domain(void);
   17.23 -extern void kill_domain_with_errmsg(const char *err);
   17.24  extern long kill_other_domain(domid_t dom, int force);
   17.25 -extern void stop_domain(void);
   17.26 +extern void stop_domain(u8 reason);
   17.27  extern long stop_other_domain(domid_t dom);
   17.28  
   17.29  /* arch/process.c */