direct-io.hg

changeset 882:bb30fa014b9d

bitkeeper revision 1.553 (3fa68dcd5yXksUZ7k12Hq41k_eQIOw)

Many files:
More cleanups for suspend/resume. STOP requests are now routed thru the guestos to allow preparation for pickling.
author kaf24@scramble.cl.cam.ac.uk
date Mon Nov 03 17:18:05 2003 +0000 (2003-11-03)
parents e6d36e3e7847
children 6cde5e25c56f
files tools/internal/xi_build.c tools/internal/xi_list.c xen/arch/i386/process.c xen/common/debug.c xen/common/dom0_ops.c xen/common/domain.c xen/common/event.c xen/common/schedule.c xen/include/asm-i386/processor.h xen/include/asm-i386/system.h xen/include/hypervisor-ifs/dom0_ops.h xen/include/hypervisor-ifs/hypervisor-if.h xen/include/xeno/sched.h xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h
line diff
     1.1 --- a/tools/internal/xi_build.c	Mon Nov 03 15:16:47 2003 +0000
     1.2 +++ b/tools/internal/xi_build.c	Mon Nov 03 17:18:05 2003 +0000
     1.3 @@ -147,7 +147,8 @@ static int copy_to_domain_page(unsigned 
     1.4  static int setup_guestos(
     1.5      int dom, int kernel_fd, int initrd_fd, unsigned long tot_pages,
     1.6      unsigned long virt_load_addr, size_t ksize, 
     1.7 -    dom0_builddomain_t *builddomain, int argc, char **argv, int args_start)
     1.8 +    dom0_builddomain_t *builddomain, int argc, char **argv, int args_start,
     1.9 +    unsigned long shared_info_frame)
    1.10  {
    1.11      l1_pgentry_t *vl1tab = NULL, *vl1e = NULL;
    1.12      l2_pgentry_t *vl2tab = NULL, *vl2e = NULL;
    1.13 @@ -160,6 +161,7 @@ static int setup_guestos(
    1.14      unsigned long count, pt_start, i, j;
    1.15      unsigned long initrd_addr = 0, initrd_len = 0;
    1.16      start_info_t *start_info;
    1.17 +    shared_info_t *shared_info;
    1.18      int cmd_len;
    1.19  
    1.20      memset(builddomain, 0, sizeof(*builddomain));
    1.21 @@ -319,6 +321,10 @@ static int setup_guestos(
    1.22      start_info->pt_base     = virt_load_addr + ((tot_pages-1) << PAGE_SHIFT);
    1.23      start_info->mod_start   = initrd_addr;
    1.24      start_info->mod_len     = initrd_len;
    1.25 +    start_info->nr_pages    = tot_pages;
    1.26 +    start_info->shared_info = shared_info_frame << PAGE_SHIFT;
    1.27 +    start_info->dom_id      = dom;
    1.28 +    start_info->flags       = 0;
    1.29      cmd_len = 0;
    1.30      for ( i = args_start; i < argc; i++ )
    1.31      {
    1.32 @@ -333,6 +339,11 @@ static int setup_guestos(
    1.33      }
    1.34      unmap_pfn(start_info);
    1.35  
    1.36 +    /* shared_info page starts its life empty. */
    1.37 +    shared_info = map_pfn(shared_info_frame);
    1.38 +    memset(shared_info, 0, PAGE_SIZE);
    1.39 +    unmap_pfn(shared_info);
    1.40 +
    1.41      /* Send the page update requests down to the hypervisor. */
    1.42      if ( send_pgupdates(pgt_update_arr, num_pgt_updates) < 0 )
    1.43          goto error_out;
    1.44 @@ -356,7 +367,7 @@ int main(int argc, char **argv)
    1.45       * the 8-byte signature and 4-byte load address.
    1.46       */
    1.47      size_t ksize;
    1.48 -    dom0_op_t launch_op;
    1.49 +    dom0_op_t launch_op, op;
    1.50      unsigned long load_addr;
    1.51      long tot_pages;
    1.52      int kernel_fd, initrd_fd = -1;
    1.53 @@ -418,9 +429,24 @@ int main(int argc, char **argv)
    1.54          }
    1.55      }
    1.56  
    1.57 +    op.cmd = DOM0_GETDOMAININFO;
    1.58 +    op.u.getdomaininfo.domain = domain_id;
    1.59 +    if ( (do_dom0_op(&op) < 0) || (op.u.getdomaininfo.domain != domain_id) )
    1.60 +    {
    1.61 +        PERROR("Could not get info on domain");
    1.62 +        return 1;
    1.63 +    }
    1.64 +    if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) ||
    1.65 +         (op.u.getdomaininfo.ctxt.pt_base != 0) )
    1.66 +    {
    1.67 +        ERROR("Domain is already constructed");
    1.68 +        return 1;
    1.69 +    }
    1.70 +
    1.71      if ( setup_guestos(domain_id, kernel_fd, initrd_fd, tot_pages,
    1.72                         load_addr, ksize, &launch_op.u.builddomain,
    1.73 -                       argc, argv, args_start) < 0 )
    1.74 +                       argc, argv, args_start, 
    1.75 +                       op.u.getdomaininfo.shared_info_frame) < 0 )
    1.76          return 1;
    1.77  
    1.78      if ( initrd_fd >= 0 )
    1.79 @@ -429,6 +455,8 @@ int main(int argc, char **argv)
    1.80  
    1.81      ctxt = &launch_op.u.builddomain.ctxt;
    1.82  
    1.83 +    ctxt->flags = 0;
    1.84 +
    1.85      /*
    1.86       * Initial register values:
    1.87       *  DS,ES,FS,GS = FLAT_RING1_DS
    1.88 @@ -473,8 +501,11 @@ int main(int argc, char **argv)
    1.89      /* No debugging. */
    1.90      memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
    1.91  
    1.92 -    /* Domain time counts from zero. */
    1.93 -    ctxt->domain_time = 0;
    1.94 +    /* No callback handlers. */
    1.95 +    ctxt->event_callback_cs     = FLAT_RING1_CS;
    1.96 +    ctxt->event_callback_eip    = 0;
    1.97 +    ctxt->failsafe_callback_cs  = FLAT_RING1_CS;
    1.98 +    ctxt->failsafe_callback_eip = 0;
    1.99  
   1.100      launch_op.u.builddomain.domain   = domain_id;
   1.101      launch_op.u.builddomain.num_vifs = atoi(argv[3]);
     2.1 --- a/tools/internal/xi_list.c	Mon Nov 03 15:16:47 2003 +0000
     2.2 +++ b/tools/internal/xi_list.c	Mon Nov 03 17:18:05 2003 +0000
     2.3 @@ -30,12 +30,9 @@ static char *statestr(int state)
     2.4  {
     2.5      switch ( state )
     2.6      {
     2.7 -    case 0: return "RUNNING";
     2.8 -    case 1: return "INTERRUPTIBLE";
     2.9 -    case 2: return "UNINTERRUPTIBLE";
    2.10 -    case 4: return "STOPPED";
    2.11 -    case 8: return "DYING";
    2.12 -    default: return "UNKNOWN";
    2.13 +    case DOMSTATE_ACTIVE:  return "ACTIVE";
    2.14 +    case DOMSTATE_STOPPED: return "STOPPED";
    2.15 +    default:               return "UNKNOWN";
    2.16      }
    2.17      return NULL;
    2.18  }
     3.1 --- a/xen/arch/i386/process.c	Mon Nov 03 15:16:47 2003 +0000
     3.2 +++ b/xen/arch/i386/process.c	Mon Nov 03 17:18:05 2003 +0000
     3.3 @@ -188,27 +188,6 @@ void machine_power_off(void)
     3.4      machine_restart(0);
     3.5  }
     3.6  
     3.7 -void exit_thread(void)
     3.8 -{
     3.9 -    /* nothing to do ... */
    3.10 -}
    3.11 -
    3.12 -void flush_thread(void)
    3.13 -{
    3.14 -    struct task_struct *tsk = current;
    3.15 -
    3.16 -    memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
    3.17 -    /*
    3.18 -     * Forget coprocessor state..
    3.19 -     */
    3.20 -    clear_fpu(tsk);
    3.21 -    tsk->flags &= ~PF_DONEFPUINIT;
    3.22 -}
    3.23 -
    3.24 -void release_thread(struct task_struct *dead_task)
    3.25 -{
    3.26 -}
    3.27 -
    3.28  void new_thread(struct task_struct *p,
    3.29                  unsigned long start_pc,
    3.30                  unsigned long start_stack,
     4.1 --- a/xen/common/debug.c	Mon Nov 03 15:16:47 2003 +0000
     4.2 +++ b/xen/common/debug.c	Mon Nov 03 17:18:05 2003 +0000
     4.3 @@ -63,8 +63,8 @@ void pdb_do_debug (dom0_op_t *op)
     4.4  	    {
     4.5  	        if (p->state != TASK_STOPPED)
     4.6  		{
     4.7 -		    cpu_mask = mark_hyp_event(p, _HYP_EVENT_STOP);
     4.8 -		    hyp_event_notify(cpu_mask);
     4.9 +		    cpu_mask = mark_guest_event(p, _EVENT_STOP);
    4.10 +		    guest_event_notify(cpu_mask);
    4.11  		}
    4.12  		put_task_struct(p);
    4.13  	    }
     5.1 --- a/xen/common/dom0_ops.c	Mon Nov 03 15:16:47 2003 +0000
     5.2 +++ b/xen/common/dom0_ops.c	Mon Nov 03 17:18:05 2003 +0000
     5.3 @@ -267,17 +267,24 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     5.4              strcpy (op.u.getdomaininfo.name, p->name);
     5.5              op.u.getdomaininfo.processor   = p->processor;
     5.6              op.u.getdomaininfo.has_cpu     = p->has_cpu;
     5.7 -            op.u.getdomaininfo.state       = p->state;
     5.8 +            op.u.getdomaininfo.state       = DOMSTATE_ACTIVE;
     5.9 +            if ( (p->state == TASK_STOPPED) || (p->state == TASK_DYING) )
    5.10 +                op.u.getdomaininfo.state = DOMSTATE_STOPPED;
    5.11              op.u.getdomaininfo.hyp_events  = p->hyp_events;
    5.12              op.u.getdomaininfo.mcu_advance = p->mcu_advance;
    5.13              op.u.getdomaininfo.tot_pages   = p->tot_pages;
    5.14              op.u.getdomaininfo.cpu_time    = p->cpu_time;
    5.15 +            op.u.getdomaininfo.shared_info_frame = 
    5.16 +                __pa(p->shared_info) >> PAGE_SHIFT;
    5.17              if ( p->state == TASK_STOPPED )
    5.18              {
    5.19                  rmb(); /* Ensure that we see saved register state. */
    5.20 +                op.u.getdomaininfo.ctxt.flags = 0;
    5.21                  memcpy(&op.u.getdomaininfo.ctxt.i386_ctxt, 
    5.22                         &p->shared_info->execution_context,
    5.23                         sizeof(p->shared_info->execution_context));
    5.24 +                if ( p->flags & PF_DONEFPUINIT )
    5.25 +                    op.u.getdomaininfo.ctxt.flags |= ECF_I387_VALID;
    5.26                  memcpy(&op.u.getdomaininfo.ctxt.i387_ctxt,
    5.27                         &p->thread.i387,
    5.28                         sizeof(p->thread.i387));
    5.29 @@ -308,8 +315,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    5.30                  memcpy(op.u.getdomaininfo.ctxt.debugreg, 
    5.31                         p->thread.debugreg, 
    5.32                         sizeof(p->thread.debugreg));
    5.33 -                op.u.getdomaininfo.ctxt.domain_time = 
    5.34 -                    p->shared_info->domain_time;
    5.35 +                op.u.getdomaininfo.ctxt.event_callback_cs  = p->event_selector;
    5.36 +                op.u.getdomaininfo.ctxt.event_callback_eip = p->event_address;
    5.37 +                op.u.getdomaininfo.ctxt.failsafe_callback_cs  = 
    5.38 +                    p->failsafe_selector;
    5.39 +                op.u.getdomaininfo.ctxt.failsafe_callback_eip = 
    5.40 +                    p->failsafe_address;
    5.41              }
    5.42          }
    5.43          read_unlock_irqrestore(&tasklist_lock, flags);
     6.1 --- a/xen/common/domain.c	Mon Nov 03 15:16:47 2003 +0000
     6.2 +++ b/xen/common/domain.c	Mon Nov 03 17:18:05 2003 +0000
     6.3 @@ -32,12 +32,9 @@
     6.4  rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;
     6.5  struct task_struct *task_hash[TASK_HASH_SIZE];
     6.6  
     6.7 -/*
     6.8 - * create a new domain
     6.9 - */
    6.10  struct task_struct *do_createdomain(unsigned int dom_id, unsigned int cpu)
    6.11  {
    6.12 -    int retval, i;
    6.13 +    int retval;
    6.14      struct task_struct *p = NULL;
    6.15      unsigned long flags;
    6.16  
    6.17 @@ -68,20 +65,8 @@ struct task_struct *do_createdomain(unsi
    6.18  
    6.19      INIT_LIST_HEAD(&p->physdisk_aces);
    6.20  
    6.21 -    SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES);
    6.22 -    SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS);
    6.23 -
    6.24      p->addr_limit = USER_DS;
    6.25  
    6.26 -    /*
    6.27 -     * We're basically forcing default RPLs to 1, so that our "what privilege
    6.28 -     * level are we returning to?" logic works.
    6.29 -     */
    6.30 -    p->failsafe_selector = FLAT_RING1_CS;
    6.31 -    p->event_selector    = FLAT_RING1_CS;
    6.32 -    p->thread.ss1        = FLAT_RING1_DS;
    6.33 -    for ( i = 0; i < 256; i++ ) p->thread.traps[i].cs = FLAT_RING1_CS;
    6.34 -
    6.35      sched_add_domain(p);
    6.36  
    6.37      INIT_LIST_HEAD(&p->pg_head);
    6.38 @@ -139,9 +124,11 @@ void __kill_domain(struct task_struct *p
    6.39          machine_restart(0);
    6.40      }
    6.41  
    6.42 -    printk("Killing domain %d\n", p->domain);
    6.43 +    /* Only allow the domain to be destroyed once. */
    6.44 +    if ( !sched_rem_domain(p) )
    6.45 +        return;
    6.46  
    6.47 -    sched_rem_domain(p);
    6.48 +    printk("Killing domain %d\n", p->domain);
    6.49  
    6.50      unlink_blkdev_info(p);
    6.51  
    6.52 @@ -215,7 +202,6 @@ void stop_domain(void)
    6.53      unlazy_fpu(current);
    6.54      wmb(); /* All CPUs must see saved info in state TASK_STOPPED. */
    6.55      set_current_state(TASK_STOPPED);
    6.56 -    clear_bit(_HYP_EVENT_STOP, &current->hyp_events);
    6.57      __enter_scheduler();
    6.58  }
    6.59  
    6.60 @@ -229,8 +215,8 @@ long stop_other_domain(unsigned int dom)
    6.61      
    6.62      if ( p->state != TASK_STOPPED )
    6.63      {
    6.64 -        cpu_mask = mark_hyp_event(p, _HYP_EVENT_STOP);
    6.65 -        hyp_event_notify(cpu_mask);
    6.66 +        cpu_mask = mark_guest_event(p, _EVENT_STOP);
    6.67 +        guest_event_notify(cpu_mask);
    6.68      }
    6.69      
    6.70      put_task_struct(p);
    6.71 @@ -332,13 +318,14 @@ void release_task(struct task_struct *p)
    6.72  }
    6.73  
    6.74  
    6.75 -/* final_setup_guestos is used for final setup and launching of domains other
    6.76 +/*
    6.77 + * final_setup_guestos is used for final setup and launching of domains other
    6.78   * than domain 0. ie. the domains that are being built by the userspace dom0
    6.79   * domain builder.
    6.80   */
    6.81  int final_setup_guestos(struct task_struct *p, dom0_builddomain_t *builddomain)
    6.82  {
    6.83 -    start_info_t * virt_startinfo_addr;
    6.84 +    start_info_t *virt_startinfo_addr;
    6.85      unsigned long phys_l2tab;
    6.86      net_ring_t *shared_rings;
    6.87      net_vif_t *net_vif;
    6.88 @@ -346,7 +333,10 @@ int final_setup_guestos(struct task_stru
    6.89  
    6.90      if ( (p->flags & PF_CONSTRUCTED) )
    6.91          return -EINVAL;
    6.92 -
    6.93 +    
    6.94 +    p->flags &= ~PF_DONEFPUINIT;
    6.95 +    if ( builddomain->ctxt.flags & ECF_I387_VALID )
    6.96 +        p->flags |= PF_DONEFPUINIT;
    6.97      memcpy(&p->shared_info->execution_context,
    6.98             &builddomain->ctxt.i386_ctxt,
    6.99             sizeof(p->shared_info->execution_context));
   6.100 @@ -371,6 +361,10 @@ int final_setup_guestos(struct task_stru
   6.101      memcpy(p->thread.debugreg,
   6.102             builddomain->ctxt.debugreg,
   6.103             sizeof(p->thread.debugreg));
   6.104 +    p->event_selector    = builddomain->ctxt.event_callback_cs;
   6.105 +    p->event_address     = builddomain->ctxt.event_callback_eip;
   6.106 +    p->failsafe_selector = builddomain->ctxt.failsafe_callback_cs;
   6.107 +    p->failsafe_address  = builddomain->ctxt.failsafe_callback_eip;
   6.108      
   6.109      /* NB. Page base must already be pinned! */
   6.110      phys_l2tab = builddomain->ctxt.pt_base;
   6.111 @@ -378,25 +372,19 @@ int final_setup_guestos(struct task_stru
   6.112      get_page_type(&frame_table[phys_l2tab>>PAGE_SHIFT]);
   6.113      get_page_tot(&frame_table[phys_l2tab>>PAGE_SHIFT]);
   6.114  
   6.115 -    /* set up the shared info structure */
   6.116 +    /* Set up the shared info structure. */
   6.117      update_dom_time(p->shared_info);
   6.118 -    p->shared_info->domain_time = builddomain->ctxt.domain_time;
   6.119  
   6.120 -    /* we pass start info struct to guest os as function parameter on stack */
   6.121      virt_startinfo_addr = (start_info_t *)builddomain->virt_startinfo_addr;
   6.122  
   6.123 -    /* we need to populate start_info struct within the context of the
   6.124 -     * new domain. thus, temporarely install its pagetables.
   6.125 +    /*
   6.126 +     * We need to populate start_info struct within the context of the new
   6.127 +     * domain. Thus temporarely install its pagetables.
   6.128       */
   6.129      __cli();
   6.130      __asm__ __volatile__ ( 
   6.131          "mov %%eax,%%cr3" : : "a" (pagetable_val(p->mm.pagetable)));
   6.132  
   6.133 -    virt_startinfo_addr->nr_pages = p->tot_pages;
   6.134 -    virt_startinfo_addr->shared_info = virt_to_phys(p->shared_info);   
   6.135 -    virt_startinfo_addr->dom_id = p->domain;
   6.136 -    virt_startinfo_addr->flags  = IS_PRIV(p) ? SIF_PRIVILEGED : 0;
   6.137 -
   6.138      /* Add virtual network interfaces and point to them in startinfo. */
   6.139      while (builddomain->num_vifs-- > 0) {
   6.140          net_vif = create_net_vif(p->domain);
   6.141 @@ -437,7 +425,8 @@ static unsigned long alloc_page_from_dom
   6.142      return ret;
   6.143  }
   6.144  
   6.145 -/* setup_guestos is used for building dom0 solely. other domains are built in
   6.146 +/*
   6.147 + * setup_guestos is used for building dom0 solely. other domains are built in
   6.148   * userspace dom0 and final setup is being done by final_setup_guestos.
   6.149   */
   6.150  int setup_guestos(struct task_struct *p, dom0_createdomain_t *params, 
   6.151 @@ -513,6 +502,19 @@ int setup_guestos(struct task_struct *p,
   6.152      printk("DOM%d: Guest OS virtual load address is %08lx\n", dom,
   6.153             virt_load_address);
   6.154      
   6.155 +    SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES);
   6.156 +    SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS);
   6.157 +
   6.158 +    /*
   6.159 +     * We're basically forcing default RPLs to 1, so that our "what privilege
   6.160 +     * level are we returning to?" logic works.
   6.161 +     */
   6.162 +    p->failsafe_selector = FLAT_RING1_CS;
   6.163 +    p->event_selector    = FLAT_RING1_CS;
   6.164 +    p->thread.ss1        = FLAT_RING1_DS;
   6.165 +    for ( i = 0; i < 256; i++ ) 
   6.166 +        p->thread.traps[i].cs = FLAT_RING1_CS;
   6.167 +
   6.168      /*
   6.169       * WARNING: The new domain must have its 'processor' field
   6.170       * filled in by now !!
     7.1 --- a/xen/common/event.c	Mon Nov 03 15:16:47 2003 +0000
     7.2 +++ b/xen/common/event.c	Mon Nov 03 17:18:05 2003 +0000
     7.3 @@ -18,7 +18,6 @@ static hyp_event_callback_fn_t event_cal
     7.4  {
     7.5      __enter_scheduler,
     7.6      kill_domain,
     7.7 -    stop_domain
     7.8  };
     7.9  
    7.10  /* Handle outstanding events for the currently-executing domain. */
     8.1 --- a/xen/common/schedule.c	Mon Nov 03 15:16:47 2003 +0000
     8.2 +++ b/xen/common/schedule.c	Mon Nov 03 17:18:05 2003 +0000
     8.3 @@ -24,7 +24,6 @@
     8.4  #include <xeno/timer.h>
     8.5  #include <xeno/perfc.h>
     8.6  
     8.7 -
     8.8  #undef SCHEDULER_TRACE
     8.9  #ifdef SCHEDULER_TRACE
    8.10  #define TRC(_x) _x
    8.11 @@ -138,9 +137,13 @@ void sched_add_domain(struct task_struct
    8.12      }
    8.13  }
    8.14  
    8.15 -void sched_rem_domain(struct task_struct *p) 
    8.16 +int sched_rem_domain(struct task_struct *p) 
    8.17  {
    8.18 -    p->state = TASK_DYING;
    8.19 +    int x, y = p->state;
    8.20 +    do {
    8.21 +        if ( (x = y) == TASK_DYING ) return 0;
    8.22 +    } while ( (y = cmpxchg(&p->state, x, TASK_DYING)) != x );
    8.23 +    return 1;
    8.24  }
    8.25  
    8.26  
    8.27 @@ -227,6 +230,12 @@ long do_sched_op(unsigned long op)
    8.28          break;
    8.29      }
    8.30  
    8.31 +    case SCHEDOP_stop:
    8.32 +    {
    8.33 +        stop_domain();
    8.34 +        break;
    8.35 +    }
    8.36 +
    8.37      default:
    8.38          ret = -ENOSYS;
    8.39      }
     9.1 --- a/xen/include/asm-i386/processor.h	Mon Nov 03 15:16:47 2003 +0000
     9.2 +++ b/xen/include/asm-i386/processor.h	Mon Nov 03 17:18:05 2003 +0000
     9.3 @@ -437,21 +437,6 @@ long set_gdt(struct task_struct *p,
     9.4               unsigned long *frames, 
     9.5               unsigned int entries);
     9.6  
     9.7 -/* Free all resources held by a thread. */
     9.8 -extern void release_thread(struct task_struct *);
     9.9 -/*
    9.10 - * create a kernel thread without removing it from tasklists
    9.11 - */
    9.12 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
    9.13 -
    9.14 -/* Copy and release all segment info associated with a VM */
    9.15 -extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
    9.16 -extern void release_segments(struct mm_struct * mm);
    9.17 -
    9.18 -unsigned long get_wchan(struct task_struct *p);
    9.19 -#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
    9.20 -#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
    9.21 -
    9.22  struct microcode {
    9.23      unsigned int hdrver;
    9.24      unsigned int rev;
    10.1 --- a/xen/include/asm-i386/system.h	Mon Nov 03 15:16:47 2003 +0000
    10.2 +++ b/xen/include/asm-i386/system.h	Mon Nov 03 17:18:05 2003 +0000
    10.3 @@ -63,9 +63,6 @@ static inline unsigned long __xchg(unsig
    10.4   * indicated by comparing RETURN with OLD.
    10.5   */
    10.6  
    10.7 -#ifdef CONFIG_X86_CMPXCHG
    10.8 -#define __HAVE_ARCH_CMPXCHG 1
    10.9 -
   10.10  static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
   10.11  				      unsigned long new, int size)
   10.12  {
   10.13 @@ -97,10 +94,6 @@ static inline unsigned long __cmpxchg(vo
   10.14  	((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
   10.15  					(unsigned long)(n),sizeof(*(ptr))))
   10.16      
   10.17 -#else
   10.18 -/* Compiling for a 386 proper.	Is it worth implementing via cli/sti?  */
   10.19 -#endif
   10.20 -
   10.21  /*
   10.22   * Force strict CPU ordering.
   10.23   * And yes, this is required on UP too when we're talking
    11.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h	Mon Nov 03 15:16:47 2003 +0000
    11.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h	Mon Nov 03 17:18:05 2003 +0000
    11.3 @@ -17,7 +17,7 @@
    11.4   * This makes sure that old versions of dom0 tools will stop working in a
    11.5   * well-defined way (rather than crashing the machine, for instance).
    11.6   */
    11.7 -#define DOM0_INTERFACE_VERSION   0xAAAA0002
    11.8 +#define DOM0_INTERFACE_VERSION   0xAAAA0003
    11.9  
   11.10  
   11.11  /*
   11.12 @@ -26,6 +26,8 @@
   11.13   */
   11.14  typedef struct full_execution_context_st
   11.15  {
   11.16 +#define ECF_I387_VALID (1<<0)
   11.17 +    unsigned long flags;
   11.18      execution_context_t i386_ctxt;          /* User-level CPU registers     */
   11.19      char          i387_ctxt[256];           /* User-level FPU registers     */
   11.20      trap_info_t   trap_ctxt[256];           /* Virtual IDT                  */
   11.21 @@ -35,7 +37,10 @@ typedef struct full_execution_context_st
   11.22      unsigned long ring1_ss, ring1_esp;      /* Virtual TSS (only SS1/ESP1)  */
   11.23      unsigned long pt_base;                  /* CR3 (pagetable base)         */
   11.24      unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
   11.25 -    u64           domain_time;              /* Domain virtual time          */
   11.26 +    unsigned long event_callback_cs;        /* CS:EIP of event callback     */
   11.27 +    unsigned long event_callback_eip;
   11.28 +    unsigned long failsafe_callback_cs;     /* CS:EIP of failsafe callback  */
   11.29 +    unsigned long failsafe_callback_eip;
   11.30  } full_execution_context_t;
   11.31  
   11.32  #define MAX_CMD_LEN       256
   11.33 @@ -121,11 +126,14 @@ typedef struct dom0_getdomaininfo_st
   11.34      char name[MAX_DOMAIN_NAME];
   11.35      int processor;
   11.36      int has_cpu;
   11.37 +#define DOMSTATE_ACTIVE              0
   11.38 +#define DOMSTATE_STOPPED             1
   11.39      int state;
   11.40      int hyp_events;
   11.41      unsigned long mcu_advance;
   11.42      unsigned int tot_pages;
   11.43      long long cpu_time;
   11.44 +    unsigned long shared_info_frame;  /* MFN of shared_info struct */
   11.45      full_execution_context_t ctxt;
   11.46  } dom0_getdomaininfo_t;
   11.47  
    12.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Mon Nov 03 15:16:47 2003 +0000
    12.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Mon Nov 03 17:18:05 2003 +0000
    12.3 @@ -90,6 +90,7 @@
    12.4  #define EVENT_DEBUG    0x08 /* Request guest to dump debug info (gross!) */
    12.5  #define EVENT_NET      0x10 /* There are packets for transmission. */
    12.6  #define EVENT_PS2      0x20 /* PS/2 keyboard or mouse event(s) */
    12.7 +#define EVENT_STOP     0x40 /* Prepare for stopping and possible pickling */
    12.8  
    12.9  /* Bit offsets, as opposed to the above masks. */
   12.10  #define _EVENT_BLKDEV   0
   12.11 @@ -98,6 +99,7 @@
   12.12  #define _EVENT_DEBUG    3
   12.13  #define _EVENT_NET      4
   12.14  #define _EVENT_PS2      5
   12.15 +#define _EVENT_STOP     6
   12.16  
   12.17  /*
   12.18   * Virtual addresses beyond this are not modifiable by guest OSes. The 
   12.19 @@ -156,6 +158,7 @@
   12.20   */
   12.21  #define SCHEDOP_yield           0
   12.22  #define SCHEDOP_exit            1
   12.23 +#define SCHEDOP_stop            2
   12.24  
   12.25   
   12.26  
    13.1 --- a/xen/include/xeno/sched.h	Mon Nov 03 15:16:47 2003 +0000
    13.2 +++ b/xen/include/xeno/sched.h	Mon Nov 03 17:18:05 2003 +0000
    13.3 @@ -31,7 +31,6 @@ extern struct mm_struct init_mm;
    13.4  
    13.5  #define _HYP_EVENT_NEED_RESCHED 0
    13.6  #define _HYP_EVENT_DIE          1
    13.7 -#define _HYP_EVENT_STOP         2
    13.8  
    13.9  #define PF_DONEFPUINIT  0x1  /* Has the FPU been initialised for this task? */
   13.10  #define PF_USEDFPU      0x2  /* Has this task used the FPU since last save? */
   13.11 @@ -148,9 +147,6 @@ struct task_struct
   13.12   *                       arbitrary event or timer.
   13.13   * TASK_STOPPED:         Domain is sopped.
   13.14   * TASK_DYING:           Domain is about to cross over to the land of the dead.
   13.15 - *
   13.16 - * If you update these then please update the mapping to text names in
   13.17 - * xi_list.
   13.18   */
   13.19  
   13.20  #define TASK_RUNNING             0
   13.21 @@ -214,8 +210,6 @@ void new_thread(struct task_struct *p,
   13.22                  unsigned long start_pc,
   13.23                  unsigned long start_stack,
   13.24                  unsigned long start_info);
   13.25 -extern void flush_thread(void);
   13.26 -extern void exit_thread(void);
   13.27  
   13.28  /* Linux puts these here for some reason! */
   13.29  extern int request_irq(unsigned int,
   13.30 @@ -235,7 +229,7 @@ extern unsigned long wait_init_idle;
   13.31  void scheduler_init(void);
   13.32  void schedulers_start(void);
   13.33  void sched_add_domain(struct task_struct *p);
   13.34 -void sched_rem_domain(struct task_struct *p);
   13.35 +int sched_rem_domain(struct task_struct *p);
   13.36  long sched_bvtctl(unsigned long ctx_allow);
   13.37  long sched_adjdom(int dom, unsigned long mcu_adv, unsigned long warp, 
   13.38                    unsigned long warpl, unsigned long warpu);
    14.1 --- a/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c	Mon Nov 03 15:16:47 2003 +0000
    14.2 +++ b/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c	Mon Nov 03 17:18:05 2003 +0000
    14.3 @@ -50,7 +50,7 @@
    14.4   * Point at the empty zero page to start with. We map the real shared_info
    14.5   * page as soon as fixmap is up and running.
    14.6   */
    14.7 -shared_info_t *HYPERVISOR_shared_info = empty_zero_page;
    14.8 +shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
    14.9  
   14.10  unsigned long *phys_to_machine_mapping;
   14.11  
   14.12 @@ -1048,3 +1048,22 @@ static int __init setup_death_event(void
   14.13  }
   14.14  
   14.15  __initcall(setup_death_event);
   14.16 +
   14.17 +
   14.18 +/******************************************************************************
   14.19 + * Stop/pickle callback handling.
   14.20 + */
   14.21 +
   14.22 +static void time_to_stop(int irq, void *unused, struct pt_regs *regs)
   14.23 +{
   14.24 +    HYPERVISOR_stop();
   14.25 +}
   14.26 +
   14.27 +static int __init setup_stop_event(void)
   14.28 +{
   14.29 +    (void)request_irq(_EVENT_STOP, time_to_stop, 0, "stop", NULL);
   14.30 +    return 0;
   14.31 +}
   14.32 +
   14.33 +__initcall(setup_stop_event);
   14.34 +
    15.1 --- a/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h	Mon Nov 03 15:16:47 2003 +0000
    15.2 +++ b/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h	Mon Nov 03 17:18:05 2003 +0000
    15.3 @@ -263,6 +263,17 @@ static inline int HYPERVISOR_exit(void)
    15.4      return ret;
    15.5  }
    15.6  
    15.7 +static inline int HYPERVISOR_stop(void)
    15.8 +{
    15.9 +    int ret;
   15.10 +    __asm__ __volatile__ (
   15.11 +        TRAP_INSTR
   15.12 +        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
   15.13 +        "b" (SCHEDOP_stop) );
   15.14 +
   15.15 +    return ret;
   15.16 +}
   15.17 +
   15.18  static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
   15.19  {
   15.20      int ret;