direct-io.hg

changeset 4342:fac5011f75be

bitkeeper revision 1.1236.1.131 (4244e3f9gcG_CR3IOZykct93jfo08w)

Merge bk://xen.bkbits.net/xeno-unstable.bk
into bkbits.net:/repos/x/xen-ia64/xeno-unstable-ia64.bk
author xen-ia64.adm@bkbits.net
date Fri Mar 25 22:20:40 2005 +0000 (2005-03-25)
parents ed530b24ab7c f71b1114a5c3
children 11d6e8d32546
files .rootkeys linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c tools/blktap/blockstore.c tools/blktap/blockstore.h tools/examples/vnc/Xservers tools/examples/vnc/Xvnc-xen tools/examples/xend-config.sxp tools/libxutil/sxpr.c tools/libxutil/sxpr.h tools/python/xen/lowlevel/xu/xu.c tools/python/xen/xend/Vifctl.py tools/python/xen/xend/XendMigrate.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/netif.py tools/python/xen/xm/create.py xen/Makefile xen/arch/ia64/domain.c xen/arch/ia64/patch/linux-2.6.7/time.c xen/arch/x86/domain.c xen/arch/x86/mm.c xen/arch/x86/shadow.c xen/arch/x86/time.c xen/arch/x86/traps.c xen/arch/x86/vmx.c xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_platform.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/entry.S xen/common/domain.c xen/common/page_alloc.c xen/common/sched_atropos.c xen/common/sched_bvt.c xen/common/sched_rrobin.c xen/common/schedule.c xen/drivers/char/console.c xen/include/asm-x86/debugger.h xen/include/asm-x86/flushtlb.h xen/include/asm-x86/vmx_vmcs.h xen/include/public/io/domain_controller.h xen/include/xen/sched-if.h xen/include/xen/sched.h xen/include/xen/time.h
line diff
     1.1 --- a/.rootkeys	Sat Mar 26 04:24:24 2005 +0000
     1.2 +++ b/.rootkeys	Fri Mar 25 22:20:40 2005 +0000
     1.3 @@ -465,6 +465,8 @@ 41e661e1giIEKbJ25qfiP-ke8u8hFA tools/exa
     1.4  40ee75a967sxgcRY4Q7zXoVUaJ4flA tools/examples/vif-bridge
     1.5  41fc0c18AFAVXA1uGm1JFWHMeeznVw tools/examples/vif-nat
     1.6  41e661e1ooiRKlOfwumG6wwzc0PdhQ tools/examples/vif-route
     1.7 +423ab2eaNCzxk3c-9yU1BwzxWvsDCQ tools/examples/vnc/Xservers
     1.8 +423ab2ea7ajZLdZOI-8Z-bpNdNhhAQ tools/examples/vnc/Xvnc-xen
     1.9  40ee75a93cqxHp6MiYXxxwR5j2_8QQ tools/examples/xend-config.sxp
    1.10  41dde8af6M2Pm1Rrv_f5jEFC_BIOIA tools/examples/xmexample.vmx
    1.11  41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1
     2.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c	Sat Mar 26 04:24:24 2005 +0000
     2.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c	Fri Mar 25 22:20:40 2005 +0000
     2.3 @@ -672,6 +672,7 @@ int set_timeout_timer(void)
     2.4  {
     2.5  	u64 alarm = 0;
     2.6  	int ret = 0;
     2.7 +	unsigned long j;
     2.8  #ifdef CONFIG_SMP
     2.9  	unsigned long seq;
    2.10  #endif
    2.11 @@ -685,13 +686,14 @@ int set_timeout_timer(void)
    2.12  #ifdef CONFIG_SMP
    2.13  	do {
    2.14  		seq = read_seqbegin(&xtime_lock);
    2.15 -		if (smp_processor_id())
    2.16 -			alarm = __jiffies_to_st(jiffies + 1);
    2.17 -		else
    2.18 -			alarm = __jiffies_to_st(jiffies + 1);
    2.19 +		j = jiffies + 1;
    2.20 +		alarm = __jiffies_to_st(j);
    2.21  	} while (read_seqretry(&xtime_lock, seq));
    2.22  #else
    2.23 -	alarm = __jiffies_to_st(next_timer_interrupt());
    2.24 +	j = next_timer_interrupt();
    2.25 +	if (j < (jiffies + 1))
    2.26 +		j = jiffies + 1;
    2.27 +	alarm = __jiffies_to_st(j);
    2.28  #endif
    2.29  
    2.30  	/* Failure is pretty bad, but we'd best soldier on. */
    2.31 @@ -726,7 +728,6 @@ void time_resume(void)
    2.32  }
    2.33  
    2.34  #ifdef CONFIG_SMP
    2.35 -#define xxprint(msg) HYPERVISOR_console_io(CONSOLEIO_write, strlen(msg), msg)
    2.36  
    2.37  static irqreturn_t local_timer_interrupt(int irq, void *dev_id,
    2.38  					 struct pt_regs *regs)
    2.39 @@ -764,11 +765,6 @@ static irqreturn_t local_timer_interrupt
    2.40  #endif
    2.41  	}
    2.42  
    2.43 -	if (smp_processor_id() == 0) {
    2.44 -	    xxprint("bug bug\n");
    2.45 -	    BUG();
    2.46 -	}
    2.47 -
    2.48  	return IRQ_HANDLED;
    2.49  }
    2.50  
     3.1 --- a/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c	Sat Mar 26 04:24:24 2005 +0000
     3.2 +++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c	Fri Mar 25 22:20:40 2005 +0000
     3.3 @@ -119,7 +119,7 @@ void netif_create(netif_be_create_t *cre
     3.4      unsigned int       handle = create->netif_handle;
     3.5      struct net_device *dev;
     3.6      netif_t          **pnetif, *netif;
     3.7 -    char               name[IFNAMSIZ];
     3.8 +    char               name[IFNAMSIZ] = {};
     3.9  
    3.10      snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
    3.11      dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
     4.1 --- a/tools/blktap/blockstore.c	Sat Mar 26 04:24:24 2005 +0000
     4.2 +++ b/tools/blktap/blockstore.c	Fri Mar 25 22:20:40 2005 +0000
     4.3 @@ -15,10 +15,11 @@
     4.4  #include <sys/stat.h>
     4.5  #include <stdarg.h>
     4.6  #include "blockstore.h"
     4.7 +#include <pthread.h>
     4.8  #include "parallax-threaded.h"
     4.9  
    4.10  #define BLOCKSTORE_REMOTE
    4.11 -//#define BSDEBUG
    4.12 +#define BSDEBUG
    4.13  
    4.14  /*****************************************************************************
    4.15   * Debugging
    4.16 @@ -27,7 +28,7 @@
    4.17  void DB(char *format, ...)
    4.18  {
    4.19      va_list args;
    4.20 -    
    4.21 +    fprintf(stderr, "[%05u] ", (int)pthread_getspecific(tid_key));
    4.22      va_start(args, format);
    4.23      vfprintf(stderr, format, args);
    4.24      va_end(args);
    4.25 @@ -44,10 +45,6 @@ void DB(char *format, ...)
    4.26  #include <netdb.h>
    4.27  
    4.28  /*****************************************************************************
    4.29 - *                                                                           *
    4.30 - *****************************************************************************/
    4.31 -
    4.32 -/*****************************************************************************
    4.33   * Network state                                                             *
    4.34   *****************************************************************************/
    4.35  
    4.36 @@ -71,8 +68,30 @@ int bssock = 0;
    4.37  
    4.38  /* Protects the queue manipulation critcal regions.
    4.39   */
    4.40 -#define ENTER_QUEUE_CR (void)0
    4.41 -#define LEAVE_QUEUE_CR (void)0
    4.42 +pthread_mutex_t ptmutex_queue;
    4.43 +#define ENTER_QUEUE_CR pthread_mutex_lock(&ptmutex_queue)
    4.44 +#define LEAVE_QUEUE_CR pthread_mutex_unlock(&ptmutex_queue)
    4.45 +
    4.46 +pthread_mutex_t ptmutex_recv;
    4.47 +#define ENTER_RECV_CR pthread_mutex_lock(&ptmutex_recv)
    4.48 +#define LEAVE_RECV_CR pthread_mutex_unlock(&ptmutex_recv)
    4.49 +
    4.50 +int notify = 0;
    4.51 +pthread_mutex_t ptmutex_notify;
    4.52 +pthread_cond_t ptcv_notify;
    4.53 +#define RECV_NOTIFY { \
    4.54 +    pthread_mutex_lock(&ptmutex_notify); \
    4.55 +    notify = 1; \
    4.56 +    pthread_cond_signal(&ptcv_notify); \
    4.57 +    pthread_mutex_unlock(&ptmutex_notify); }
    4.58 +#define RECV_AWAIT { \
    4.59 +    pthread_mutex_lock(&ptmutex_notify); \
    4.60 +    if (notify) \
    4.61 +        notify = 0; \
    4.62 +    else \
    4.63 +        pthread_cond_wait(&ptcv_notify, &ptmutex_notify); \
    4.64 +    pthread_mutex_unlock(&ptmutex_notify); }
    4.65 +    
    4.66  
    4.67  /* A message queue entry. We allocate one of these for every request we send.
    4.68   * Asynchronous reply reception also used one of these.
    4.69 @@ -91,8 +110,9 @@ typedef struct bsq_t_struct {
    4.70  
    4.71  #define BSQ_STATUS_MATCHED 1
    4.72  
    4.73 -#define ENTER_LUID_CR (void)0
    4.74 -#define LEAVE_LUID_CR (void)0
    4.75 +pthread_mutex_t ptmutex_luid;
    4.76 +#define ENTER_LUID_CR pthread_mutex_lock(&ptmutex_luid)
    4.77 +#define LEAVE_LUID_CR pthread_mutex_unlock(&ptmutex_luid)
    4.78  
    4.79  static u64 luid_cnt = 0x1000ULL;
    4.80  u64 new_luid(void) {
    4.81 @@ -218,6 +238,10 @@ bsq_t *queuesearch(bsq_t *qe) {
    4.82      return q;
    4.83  }
    4.84  
    4.85 +/*****************************************************************************
    4.86 + * Network communication                                                     *
    4.87 + *****************************************************************************/
    4.88 +
    4.89  int send_message(bsq_t *qe) {
    4.90      int rc;
    4.91  
    4.92 @@ -331,7 +355,7 @@ bsq_t rx_qe;
    4.93  bsq_t *recv_any(void) {
    4.94      struct sockaddr_in from;
    4.95      int rc;
    4.96 -
    4.97 +    
    4.98      DB("ENTER recv_any\n");
    4.99  
   4.100      rx_qe.msghdr.msg_name = &from;
   4.101 @@ -361,6 +385,7 @@ bsq_t *recv_any(void) {
   4.102          perror("recv_any");
   4.103          return NULL;
   4.104      }
   4.105 +
   4.106      rx_qe.length = rc;    
   4.107      rx_qe.server = get_server_number(&from);
   4.108  
   4.109 @@ -395,8 +420,13 @@ int wait_recv(bsq_t **reqs, int numreqs)
   4.110          return numreqs;
   4.111      }
   4.112  
   4.113 +    RECV_AWAIT;
   4.114 +
   4.115 +    /*
   4.116      rxagain:
   4.117 +    ENTER_RECV_CR;
   4.118      q = recv_any();
   4.119 +    LEAVE_RECV_CR;
   4.120      if (!q)
   4.121          return -1;
   4.122  
   4.123 @@ -406,11 +436,42 @@ int wait_recv(bsq_t **reqs, int numreqs)
   4.124          fprintf(stderr, "Unmatched RX\n");
   4.125          goto rxagain;
   4.126      }
   4.127 +    */
   4.128  
   4.129      goto checkmatch;
   4.130  
   4.131  }
   4.132  
   4.133 +/* receive loop
   4.134 + */
   4.135 +void *receive_loop(void *arg)
   4.136 +{
   4.137 +    bsq_t *q, *m;
   4.138 +
   4.139 +    for(;;) {
   4.140 +        q = recv_any();
   4.141 +        if (!q) {
   4.142 +            fprintf(stderr, "recv_any error\n");
   4.143 +        }
   4.144 +        else {
   4.145 +            m = queuesearch(q);
   4.146 +            recv_recycle_buffer(q);
   4.147 +            if (!m) {
   4.148 +                fprintf(stderr, "Unmatched RX\n");
   4.149 +            }
   4.150 +            else {
   4.151 +                DB("RX MATCH");
   4.152 +                RECV_NOTIFY;
   4.153 +            }
   4.154 +        }
   4.155 +    }
   4.156 +}
   4.157 +pthread_t pthread_recv;
   4.158 +
   4.159 +/*****************************************************************************
   4.160 + * Reading                                                                   *
   4.161 + *****************************************************************************/
   4.162 +
   4.163  void *readblock_indiv(int server, u64 id) {
   4.164      void *block;
   4.165      bsq_t *qe;
   4.166 @@ -538,6 +599,10 @@ void *readblock(u64 id) {
   4.167      return block;
   4.168  }
   4.169  
   4.170 +/*****************************************************************************
   4.171 + * Writing                                                                   *
   4.172 + *****************************************************************************/
   4.173 +
   4.174  bsq_t *writeblock_indiv(int server, u64 id, void *block) {
   4.175  
   4.176      bsq_t *qe;
   4.177 @@ -663,6 +728,10 @@ int writeblock(u64 id, void *block) {
   4.178      return -1;
   4.179  }
   4.180  
   4.181 +/*****************************************************************************
   4.182 + * Allocation                                                                *
   4.183 + *****************************************************************************/
   4.184 +
   4.185  /**
   4.186   * allocblock: write a new block to disk
   4.187   *   @block: pointer to block
   4.188 @@ -791,6 +860,9 @@ u64 allocblock_hint(void *block, u64 hin
   4.189  
   4.190  #else /* /BLOCKSTORE_REMOTE */
   4.191  
   4.192 +/*****************************************************************************
   4.193 + * Local storage version                                                     *
   4.194 + *****************************************************************************/
   4.195   
   4.196  /**
   4.197   * readblock: read a block from disk
   4.198 @@ -923,6 +995,10 @@ u64 allocblock_hint(void *block, u64 hin
   4.199  
   4.200  #endif /* BLOCKSTORE_REMOTE */
   4.201  
   4.202 +/*****************************************************************************
   4.203 + * Memory management                                                         *
   4.204 + *****************************************************************************/
   4.205 +
   4.206  /**
   4.207   * newblock: get a new in-memory block set to zeros
   4.208   *
   4.209 @@ -1053,6 +1129,10 @@ void freelist_count(int print_each)
   4.210      printf("Total of %Ld ids on freelist.\n", total);
   4.211  }
   4.212  
   4.213 +/*****************************************************************************
   4.214 + * Initialisation                                                            *
   4.215 + *****************************************************************************/
   4.216 +
   4.217  int __init_blockstore(void)
   4.218  {
   4.219      int i;
   4.220 @@ -1062,6 +1142,13 @@ int __init_blockstore(void)
   4.221      
   4.222  #ifdef BLOCKSTORE_REMOTE
   4.223      struct hostent *addr;
   4.224 +
   4.225 +    pthread_mutex_init(&ptmutex_queue, NULL);
   4.226 +    pthread_mutex_init(&ptmutex_luid, NULL);
   4.227 +    pthread_mutex_init(&ptmutex_recv, NULL);
   4.228 +    pthread_mutex_init(&ptmutex_notify, NULL);
   4.229 +    pthread_cond_init(&ptcv_notify, NULL);
   4.230 +
   4.231      bsservers[0].hostname = "firebug.cl.cam.ac.uk";
   4.232      bsservers[1].hostname = "planb.cl.cam.ac.uk";
   4.233      bsservers[2].hostname = "simcity.cl.cam.ac.uk";
   4.234 @@ -1137,6 +1224,8 @@ int __init_blockstore(void)
   4.235          return -1;
   4.236      }
   4.237  
   4.238 +    pthread_create(&pthread_recv, NULL, receive_loop, NULL);
   4.239 +
   4.240  #else /* /BLOCKSTORE_REMOTE */
   4.241      block_fp = open("blockstore.dat", O_RDWR | O_CREAT | O_LARGEFILE, 0644);
   4.242  
   4.243 @@ -1170,3 +1259,12 @@ int __init_blockstore(void)
   4.244  #endif /*  BLOCKSTORE_REMOTE */   
   4.245      return 0;
   4.246  }
   4.247 +
   4.248 +void __exit_blockstore(void)
   4.249 +{
   4.250 +    pthread_mutex_destroy(&ptmutex_recv);
   4.251 +    pthread_mutex_destroy(&ptmutex_luid);
   4.252 +    pthread_mutex_destroy(&ptmutex_queue);
   4.253 +    pthread_mutex_destroy(&ptmutex_notify);
   4.254 +    pthread_cond_destroy(&ptcv_notify);
   4.255 +}
     5.1 --- a/tools/blktap/blockstore.h	Sat Mar 26 04:24:24 2005 +0000
     5.2 +++ b/tools/blktap/blockstore.h	Fri Mar 25 22:20:40 2005 +0000
     5.3 @@ -22,7 +22,7 @@
     5.4  #endif
     5.5  
     5.6  #define FREEBLOCK_SIZE  (BLOCK_SIZE / sizeof(u64)) - (3 * sizeof(u64))
     5.7 -#define FREEBLOCK_MAGIC 0x0fee0fee0fee0fee
     5.8 +#define FREEBLOCK_MAGIC 0x0fee0fee0fee0feeULL
     5.9  
    5.10  typedef struct {
    5.11      u64 magic;
    5.12 @@ -31,7 +31,7 @@ typedef struct {
    5.13      u64 list[FREEBLOCK_SIZE];
    5.14  } freeblock_t; 
    5.15  
    5.16 -#define BLOCKSTORE_MAGIC 0xaaaaaaa00aaaaaaa
    5.17 +#define BLOCKSTORE_MAGIC 0xaaaaaaa00aaaaaaaULL
    5.18  #define BLOCKSTORE_SUPER 1ULL
    5.19  
    5.20  typedef struct {
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/examples/vnc/Xservers	Fri Mar 25 22:20:40 2005 +0000
     6.3 @@ -0,0 +1,5 @@
     6.4 +# Configuration lines to go in /etc/X11/xdm/Xservers to
     6.5 +# start Xvnc and connect back to a vncviewer in domain-0.
     6.6 +# See 'man xdm' under 'LOCAL SERVER SPECIFICATION' for format details.
     6.7 +
     6.8 +:1 Xvnc local /usr/X11R6/bin/Xvnc-xen :1
     6.9 \ No newline at end of file
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/examples/vnc/Xvnc-xen	Fri Mar 25 22:20:40 2005 +0000
     7.3 @@ -0,0 +1,53 @@
     7.4 +#!/bin/bash
     7.5 +#============================================================================
     7.6 +# This script should be installed in /usr/X11R6/bin/Xvnc-xen.
     7.7 +#============================================================================
     7.8 +#
     7.9 +# Start Xvnc and use vncconnect to connect back to a vncviewer listening in
    7.10 +# domain 0. The host and port to connect to are given by
    7.11 +#
    7.12 +#    VNC_VIEWER=<host>:<port>
    7.13 +#
    7.14 +# in the kernel command line (/proc/cmdline). 
    7.15 +#
    7.16 +# The '--vnc' option to 'xm create' will start a vncviewer and
    7.17 +# pass its address in VNC_VIEWER for this script to find.
    7.18 +#
    7.19 +# Usage:
    7.20 +#        Xvnc-xen [args]
    7.21 +#
    7.22 +# Any arguments are passed to Xvnc.
    7.23 +#
    7.24 +#============================================================================
    7.25 +
    7.26 +# Prefix for messages.
    7.27 +M="[$(basename $0)]"
    7.28 +
    7.29 +# Usage: vnc_addr
    7.30 +# Print <host>:<port> for the vncviewer given in
    7.31 +# the kernel command line.
    7.32 +vnc_addr () {
    7.33 +    sed -n -e "s/.*VNC_VIEWER=\([^ ]*\).*/\1/p" /proc/cmdline
    7.34 +}
    7.35 +
    7.36 +# Usage: vnc_connect
    7.37 +# If a vncviewer address was given on the kernel command line,
    7.38 +# run vncconnect for it.
    7.39 +vnc_connect () {
    7.40 +    local addr=$(vnc_addr)
    7.41 +
    7.42 +    if [ -n "${addr}" ] ; then
    7.43 +        echo "$M Connecting to ${addr}."
    7.44 +        vncconnect ${addr}
    7.45 +    else
    7.46 +        echo "$M No VNC_VIEWER in kernel command line."
    7.47 +        echo "$M Create the domain with 'xm create --vnc <display>'."
    7.48 +        return 1
    7.49 +    fi
    7.50 +}
    7.51 +
    7.52 +# Start the vnc server.
    7.53 +Xvnc "$@" >/dev/null 2>&1 &
    7.54 +
    7.55 +# Connect back to the viewer in domain-0.
    7.56 +vnc_connect
     9.1 --- a/tools/libxutil/sxpr.c	Sat Mar 26 04:24:24 2005 +0000
     9.2 +++ b/tools/libxutil/sxpr.c	Fri Mar 25 22:20:40 2005 +0000
     9.3 @@ -82,6 +82,30 @@ static SxprType types[1024] = {
     9.4  /** Number of entries in the types array. */
     9.5  static int type_sup = sizeof(types)/sizeof(types[0]);
     9.6  
     9.7 +/** Define a type.
     9.8 + * The tydef must have a non-zero type code.
     9.9 + * It is an error if the type code is out of range or already defined.
    9.10 + *
    9.11 + * @param tydef type definition
    9.12 + * @return 0 on success, error code otherwise
    9.13 + */
    9.14 +int def_sxpr_type(SxprType *tydef){
    9.15 +    int err = 0;
    9.16 +    int ty = tydef->type;
    9.17 +    if(ty < 0 || ty >= type_sup){
    9.18 +        err = -EINVAL;
    9.19 +        goto exit;
    9.20 +    }
    9.21 +    if(types[ty].type){
    9.22 +        err = -EEXIST;
    9.23 +        goto exit;
    9.24 +    }
    9.25 +    types[ty] = *tydef;
    9.26 +  exit:
    9.27 +    return err;
    9.28 +    
    9.29 +}
    9.30 +
    9.31  /** Get the type definition for a given type code.
    9.32   *
    9.33   * @param ty type code
    10.1 --- a/tools/libxutil/sxpr.h	Sat Mar 26 04:24:24 2005 +0000
    10.2 +++ b/tools/libxutil/sxpr.h	Fri Mar 25 22:20:40 2005 +0000
    10.3 @@ -307,6 +307,7 @@ typedef struct SxprType {
    10.4  } SxprType;
    10.5  
    10.6  
    10.7 +extern int def_sxpr_type(SxprType *tydef);
    10.8  extern SxprType *get_sxpr_type(int ty);
    10.9  
   10.10  /** Free the pointer in an sxpr.
    11.1 --- a/tools/python/xen/lowlevel/xu/xu.c	Sat Mar 26 04:24:24 2005 +0000
    11.2 +++ b/tools/python/xen/lowlevel/xu/xu.c	Fri Mar 25 22:20:40 2005 +0000
    11.3 @@ -477,6 +477,7 @@ static PyTypeObject xu_notifier_type = {
    11.4   */
    11.5  
    11.6  #define TYPE(_x,_y) (((_x)<<8)|(_y))
    11.7 +
    11.8  #define P2C(_struct, _field, _ctype)                                      \
    11.9      do {                                                                  \
   11.10          PyObject *obj;                                                    \
   11.11 @@ -497,6 +498,29 @@ static PyTypeObject xu_notifier_type = {
   11.12          }                                                                 \
   11.13          xum->msg.length = sizeof(_struct);                                \
   11.14      } while ( 0 )
   11.15 +
   11.16 +/** Set a char[] field in a struct from a Python string.
   11.17 + * Can't do this in P2C because of the typing.
   11.18 + */
   11.19 +#define P2CSTRING(_struct, _field)                                        \
   11.20 +    do {                                                                  \
   11.21 +        PyObject *obj;                                                    \
   11.22 +        if ( (obj = PyDict_GetItemString(payload, #_field)) != NULL )     \
   11.23 +        {                                                                 \
   11.24 +            if ( PyString_Check(obj) )                                    \
   11.25 +            {                                                             \
   11.26 +                _struct * _cobj = (_struct *)&xum->msg.msg[0];            \
   11.27 +                int _field_n = sizeof(_cobj->_field);                     \
   11.28 +                memset(_cobj->_field, 0, _field_n);                       \
   11.29 +                strncpy(_cobj->_field,                                    \
   11.30 +                        PyString_AsString(obj),                           \
   11.31 +                        _field_n - 1);                                    \
   11.32 +                dict_items_parsed++;                                      \
   11.33 +            }                                                             \
   11.34 +        }                                                                 \
   11.35 +        xum->msg.length = sizeof(_struct);                                \
   11.36 +    } while ( 0 )
   11.37 +
   11.38  #define C2P(_struct, _field, _pytype, _ctype)                             \
   11.39      do {                                                                  \
   11.40          PyObject *obj = Py ## _pytype ## _From ## _ctype                  \
    12.1 --- a/tools/python/xen/xend/Vifctl.py	Sat Mar 26 04:24:24 2005 +0000
    12.2 +++ b/tools/python/xen/xend/Vifctl.py	Fri Mar 25 22:20:40 2005 +0000
    12.3 @@ -37,6 +37,20 @@ def network(op, script=None, bridge=None
    12.4      args = ' '.join(args)
    12.5      os.system(script + ' ' + args)
    12.6  
    12.7 +def set_vif_name(vif_old, vif_new):
    12.8 +    if vif_old == vif_new:
    12.9 +        vif = vif_new
   12.10 +        return vif
   12.11 +    if os.system("ip link show %s" % vif_old) == 0:
   12.12 +        os.system("ip link set %s down" % vif_old)
   12.13 +        os.system("ip link set %s name %s" % (vif_old, vif_new))
   12.14 +        os.system("ip link set %s up" % vif_new)
   12.15 +    if os.system("ip link show %s" % vif_new) == 0:
   12.16 +        vif = vif_new
   12.17 +    else:
   12.18 +        vif = vif_old
   12.19 +    return vif
   12.20 +
   12.21  def vifctl(op, vif=None, script=None, domain=None, mac=None, bridge=None, ipaddr=[]):
   12.22      """Call a vif control script.
   12.23      Xend calls this when bringing vifs up or down.
    13.1 --- a/tools/python/xen/xend/XendMigrate.py	Sat Mar 26 04:24:24 2005 +0000
    13.2 +++ b/tools/python/xen/xend/XendMigrate.py	Fri Mar 25 22:20:40 2005 +0000
    13.3 @@ -6,12 +6,14 @@ import errno
    13.4  import sys
    13.5  import socket
    13.6  import time
    13.7 +import types
    13.8  
    13.9  from twisted.internet import reactor
   13.10  from twisted.internet import defer
   13.11  #defer.Deferred.debug = 1
   13.12  from twisted.internet.protocol import Protocol
   13.13  from twisted.internet.protocol import ClientFactory
   13.14 +from twisted.python.failure import Failure
   13.15  
   13.16  import sxp
   13.17  import XendDB
   13.18 @@ -45,11 +47,9 @@ class Xfrd(Protocol):
   13.19          sxp.show(req, out=self.transport)
   13.20  
   13.21      def loseConnection(self):
   13.22 -        print 'Xfrd>loseConnection>'
   13.23          self.transport.loseConnection()
   13.24  
   13.25      def connectionLost(self, reason):
   13.26 -        print 'Xfrd>connectionLost>', reason
   13.27          self.xinfo.connectionLost(reason)
   13.28  
   13.29      def dataReceived(self, data):
   13.30 @@ -70,17 +70,15 @@ class XfrdClientFactory(ClientFactory):
   13.31          self.xinfo = xinfo
   13.32  
   13.33      def startedConnecting(self, connector):
   13.34 -        print 'Started to connect', 'self=', self, 'connector=', connector
   13.35 +        pass
   13.36  
   13.37      def buildProtocol(self, addr):
   13.38 -        print 'buildProtocol>', addr
   13.39          return Xfrd(self.xinfo)
   13.40  
   13.41      def clientConnectionLost(self, connector, reason):
   13.42 -        print 'clientConnectionLost>', 'connector=', connector, 'reason=', reason
   13.43 +        pass
   13.44  
   13.45      def clientConnectionFailed(self, connector, reason):
   13.46 -        print 'clientConnectionFailed>', 'connector=', connector, 'reason=', reason
   13.47          self.xinfo.error(reason)
   13.48  
   13.49  class XfrdInfo:
   13.50 @@ -90,7 +88,7 @@ class XfrdInfo:
   13.51  
   13.52      """Suspend timeout (seconds).
   13.53      We set a timeout because suspending a domain can hang."""
   13.54 -    timeout = 30
   13.55 +    timeout = 10
   13.56  
   13.57      def __init__(self):
   13.58          from xen.xend import XendDomain
   13.59 @@ -98,6 +96,9 @@ class XfrdInfo:
   13.60          self.deferred = defer.Deferred()
   13.61          self.suspended = {}
   13.62          self.paused = {}
   13.63 +        self.state = 'init'
   13.64 +        # List of errors encountered.
   13.65 +        self.errors = []
   13.66          
   13.67      def vmconfig(self):
   13.68          dominfo = self.xd.domain_get(self.src_dom)
   13.69 @@ -107,12 +108,38 @@ class XfrdInfo:
   13.70              val = None
   13.71          return val
   13.72  
   13.73 +    def add_error(self, err):
   13.74 +        """Add an error to the error list.
   13.75 +        Returns the error added (which may have been unwrapped if it
   13.76 +        was a Twisted Failure).
   13.77 +        """
   13.78 +        while isinstance(err, Failure):
   13.79 +            err = err.value
   13.80 +        if err not in self.errors:
   13.81 +            self.errors.append(err)
   13.82 +        return err
   13.83 +
   13.84 +    def error_summary(self, msg=None):
   13.85 +        """Get a XendError summarising the errors (if any).
   13.86 +        """
   13.87 +        if msg is None:
   13.88 +            msg = "errors"
   13.89 +        if self.errors:
   13.90 +            errmsg = msg + ': ' + ', '.join(map(str, self.errors))
   13.91 +        else:
   13.92 +            errmsg = msg
   13.93 +        return XendError(errmsg)
   13.94 +
   13.95 +    def get_errors(self):
   13.96 +        """Get the list of errors.
   13.97 +        """
   13.98 +        return self.errors
   13.99 +
  13.100      def error(self, err):
  13.101 -        print 'Error>', err
  13.102          self.state = 'error'
  13.103 +        self.add_error(err)
  13.104          if not self.deferred.called:
  13.105 -            print 'Error> calling errback'
  13.106 -            self.deferred.errback(err)
  13.107 +            self.deferred.errback(self.error_summary())
  13.108  
  13.109      def dispatch(self, xfrd, val):
  13.110          
  13.111 @@ -139,28 +166,23 @@ class XfrdInfo:
  13.112              cbok(val)
  13.113  
  13.114      def unknown(self, xfrd, val):
  13.115 -        print 'unknown>', val
  13.116          xfrd.loseConnection()
  13.117          return None
  13.118  
  13.119      def xfr_err(self, xfrd, val):
  13.120          # If we get an error with non-zero code the operation failed.
  13.121          # An error with code zero indicates hello success.
  13.122 -        print 'xfr_err>', val
  13.123          v = sxp.child0(val)
  13.124 -        print 'xfr_err>', type(v), v
  13.125          err = int(sxp.child0(val))
  13.126          if not err: return
  13.127 -        self.error(err);
  13.128 +        self.error("transfer daemon (xfrd) error: " + str(err))
  13.129          xfrd.loseConnection()
  13.130          return None
  13.131  
  13.132      def xfr_progress(self, xfrd, val):
  13.133 -        print 'xfr_progress>', val
  13.134          return None
  13.135  
  13.136      def xfr_vm_destroy(self, xfrd, val):
  13.137 -        print 'xfr_vm_destroy>', val
  13.138          try:
  13.139              vmid = sxp.child0(val)
  13.140              val = self.xd.domain_destroy(vmid)
  13.141 @@ -168,28 +190,32 @@ class XfrdInfo:
  13.142                  del self.paused[vmid]
  13.143              if vmid in self.suspended:
  13.144                  del self.suspended[vmid]
  13.145 -        except:
  13.146 +        except StandardError, err:
  13.147 +            self.add_error("vm_destroy failed")
  13.148 +            self.add_error(err)
  13.149              val = errno.EINVAL
  13.150          return ['xfr.err', val]
  13.151      
  13.152      def xfr_vm_pause(self, xfrd, val):
  13.153 -        print 'xfr_vm_pause>', val
  13.154          try:
  13.155              vmid = sxp.child0(val)
  13.156              val = self.xd.domain_pause(vmid)
  13.157              self.paused[vmid] = 1
  13.158 -        except:
  13.159 +        except StandardError, err:
  13.160 +            self.add_error("vm_pause failed")
  13.161 +            self.add_error(err)
  13.162              val = errno.EINVAL
  13.163          return ['xfr.err', val]
  13.164  
  13.165      def xfr_vm_unpause(self, xfrd, val):
  13.166 -        print 'xfr_vm_unpause>', val
  13.167          try:
  13.168              vmid = sxp.child0(val)
  13.169              val = self.xd.domain_unpause(vmid)
  13.170              if vmid in self.paused:
  13.171                  del self.paused[vmid]
  13.172 -        except:
  13.173 +        except StandardError, err:
  13.174 +            self.add_error("vm_unpause failed")
  13.175 +            self.add_error(err)
  13.176              val = errno.EINVAL
  13.177          return ['xfr.err', val]
  13.178  
  13.179 @@ -199,7 +225,6 @@ class XfrdInfo:
  13.180          Suspending can hang, so we set a timeout and fail if it
  13.181          takes too long.
  13.182          """
  13.183 -        print 'xfr_vm_suspend>', val
  13.184          try:
  13.185              vmid = sxp.child0(val)
  13.186              d = defer.Deferred()
  13.187 @@ -208,15 +233,15 @@ class XfrdInfo:
  13.188              # the domain died. Set a timeout and error handler so the subscriptions
  13.189              # will be cleaned up if suspending hangs or there is an error.
  13.190              def onSuspended(e, v):
  13.191 -                print 'xfr_vm_suspend>onSuspended>', e, v
  13.192                  if v[1] != vmid: return
  13.193                  subscribe(on=0)
  13.194 -                d.callback(v)
  13.195 +                if not d.called:
  13.196 +                    d.callback(v)
  13.197                  
  13.198              def onDied(e, v):
  13.199 -                print 'xfr_vm_suspend>onDied>', e, v
  13.200                  if v[1] != vmid: return
  13.201 -                d.errback(XendError('Domain died'))
  13.202 +                if not d.called:
  13.203 +                    d.errback(XendError('Domain %s died while suspending' % vmid))
  13.204                  
  13.205              def subscribe(on=1):
  13.206                  if on:
  13.207 @@ -227,24 +252,25 @@ class XfrdInfo:
  13.208                  action('xend.domain.died', onDied)
  13.209  
  13.210              def cberr(err):
  13.211 -                print 'xfr_vm_suspend>cberr>', err
  13.212                  subscribe(on=0)
  13.213 +                self.add_error("suspend failed")
  13.214 +                self.add_error(err)
  13.215                  return err
  13.216  
  13.217 +            d.addErrback(cberr)
  13.218 +            d.setTimeout(self.timeout)
  13.219              subscribe()
  13.220              val = self.xd.domain_shutdown(vmid, reason='suspend')
  13.221              self.suspended[vmid] = 1
  13.222 -            d.addErrback(cberr)
  13.223 -            d.setTimeout(self.timeout)
  13.224              return d
  13.225          except Exception, err:
  13.226 -            print 'xfr_vm_suspend> Exception', err
  13.227 +            self.add_error("suspend failed")
  13.228 +            self.add_error(err)
  13.229              traceback.print_exc()
  13.230              val = errno.EINVAL
  13.231          return ['xfr.err', val]
  13.232  
  13.233      def connectionLost(self, reason=None):
  13.234 -        print 'XfrdInfo>connectionLost>', reason
  13.235          for vmid in self.suspended:
  13.236              try:
  13.237                  self.xd.domain_destroy(vmid)
  13.238 @@ -279,7 +305,7 @@ class XendMigrateInfo(XfrdInfo):
  13.239                  ['id',    self.xid   ],
  13.240                  ['state', self.state ],
  13.241                  ['live',  self.live  ],
  13.242 -                ['resource', self.resource] ]
  13.243 +                ['resource', self.resource ] ]
  13.244          sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
  13.245          sxpr.append(sxpr_src)
  13.246          sxpr_dst = ['dst', ['host', self.dst_host] ]
  13.247 @@ -291,12 +317,12 @@ class XendMigrateInfo(XfrdInfo):
  13.248      def request(self, xfrd):
  13.249          vmconfig = self.vmconfig()
  13.250          if not vmconfig:
  13.251 +            self.error(XendError("vm config not found"))
  13.252              xfrd.loseConnection()
  13.253              return
  13.254 -        log.info('Migrate BEGIN: ' + str(self.sxpr()))
  13.255 +        log.info('Migrate BEGIN: %s' % str(self.sxpr()))
  13.256          eserver.inject('xend.domain.migrate',
  13.257 -                       [ self.dominfo.name, self.dominfo.id,
  13.258 -                         "begin", self.sxpr() ])
  13.259 +                       [ self.dominfo.name, self.dominfo.id, "begin", self.sxpr() ])
  13.260          xfrd.request(['xfr.migrate',
  13.261                        self.src_dom,
  13.262                        vmconfig,
  13.263 @@ -305,19 +331,6 @@ class XendMigrateInfo(XfrdInfo):
  13.264                        self.live,
  13.265                        self.resource ])
  13.266          
  13.267 -##     def xfr_vm_suspend(self, xfrd, val):
  13.268 -##         def cbok(val):
  13.269 -##             # Special case for localhost: destroy devices early.
  13.270 -##             if self.dst_host in ["localhost", "127.0.0.1"]:
  13.271 -##                 self.dominfo.restart_cancel()
  13.272 -##                 self.dominfo.cleanup()
  13.273 -##                 self.dominfo.destroy_console()
  13.274 -##             return val
  13.275 -            
  13.276 -##         d = XfrdInfo.xfr_vm_suspend(self, xfrd, val)
  13.277 -##         d.addCallback(cbok)
  13.278 -##         return d
  13.279 -    
  13.280      def xfr_migrate_ok(self, xfrd, val):
  13.281          dom = int(sxp.child0(val))
  13.282          self.state = 'ok'
  13.283 @@ -327,17 +340,15 @@ class XendMigrateInfo(XfrdInfo):
  13.284              self.deferred.callback(self)
  13.285  
  13.286      def connectionLost(self, reason=None):
  13.287 -        print 'XfrdMigrateInfo>connectionLost>', reason
  13.288          XfrdInfo.connectionLost(self, reason)
  13.289          if self.state =='ok':
  13.290              log.info('Migrate OK: ' + str(self.sxpr()))
  13.291          else:
  13.292              self.state = 'error'
  13.293 -            self.error(XendError("migrate failed"))
  13.294 +            self.error("migrate failed")
  13.295              log.info('Migrate ERROR: ' + str(self.sxpr()))
  13.296          eserver.inject('xend.domain.migrate',
  13.297 -                       [ self.dominfo.name, self.dominfo.id,
  13.298 -                         self.state, self.sxpr() ])
  13.299 +                       [ self.dominfo.name, self.dominfo.id, self.state, self.sxpr() ])
  13.300  
  13.301  class XendSaveInfo(XfrdInfo):
  13.302      """Representation of a save in-progress and its interaction with xfrd.
  13.303 @@ -361,16 +372,15 @@ class XendSaveInfo(XfrdInfo):
  13.304          return sxpr
  13.305  
  13.306      def request(self, xfrd):
  13.307 -        print '***request>', self.vmconfig()
  13.308          vmconfig = self.vmconfig()
  13.309          if not vmconfig:
  13.310 +            self.error(XendError("vm config not found"))
  13.311              xfrd.loseConnection()
  13.312              return
  13.313 -        print '***request> begin'
  13.314          log.info('Save BEGIN: ' + str(self.sxpr()))
  13.315          eserver.inject('xend.domain.save',
  13.316 -                       [self.dominfo.name, self.dominfo.id,
  13.317 -                        "begin", self.sxpr()])
  13.318 +                       [ self.dominfo.name, self.dominfo.id,
  13.319 +                         "begin", self.sxpr() ])
  13.320          xfrd.request(['xfr.save', self.src_dom, vmconfig, self.file ])
  13.321          
  13.322      def xfr_save_ok(self, xfrd, val):
  13.323 @@ -380,13 +390,12 @@ class XendSaveInfo(XfrdInfo):
  13.324              self.deferred.callback(self)
  13.325  
  13.326      def connectionLost(self, reason=None):
  13.327 -        print 'XfrdSaveInfo>connectionLost>', reason
  13.328          XfrdInfo.connectionLost(self, reason)
  13.329          if self.state =='ok':
  13.330              log.info('Save OK: ' + str(self.sxpr()))
  13.331          else:
  13.332              self.state = 'error'
  13.333 -            self.error(XendError("save failed"))
  13.334 +            self.error("save failed")
  13.335              log.info('Save ERROR: ' + str(self.sxpr()))
  13.336          eserver.inject('xend.domain.save',
  13.337                         [ self.dominfo.name, self.dominfo.id,
  13.338 @@ -409,8 +418,9 @@ class XendRestoreInfo(XfrdInfo):
  13.339           return sxpr
  13.340  
  13.341      def request(self, xfrd):
  13.342 -        print '***request>', self.file
  13.343          log.info('restore BEGIN: ' + str(self.sxpr()))
  13.344 +        eserver.inject('xend.restore', [ 'begin', self.sxpr()])
  13.345 +                       
  13.346          xfrd.request(['xfr.restore', self.file ])
  13.347          
  13.348      def xfr_restore_ok(self, xfrd, val):
  13.349 @@ -419,8 +429,17 @@ class XendRestoreInfo(XfrdInfo):
  13.350          self.state = 'ok'
  13.351          if not self.deferred.called:
  13.352              self.deferred.callback(dominfo)
  13.353 +         
  13.354 +    def connectionLost(self, reason=None):
  13.355 +        XfrdInfo.connectionLost(self, reason)
  13.356 +        if self.state =='ok':
  13.357 +            log.info('Restore OK: ' + self.file)
  13.358 +        else:
  13.359 +            self.state = 'error'
  13.360 +            self.error("restore failed")
  13.361 +            log.info('Restore ERROR: ' + str(self.sxpr()))
  13.362 +        eserver.inject('xend.restore', [ self.state,  self.sxpr()])
  13.363  
  13.364 -         
  13.365  class XendMigrate:
  13.366      """External api for interaction with xfrd for migrate and save.
  13.367      Singleton.
  13.368 @@ -445,7 +464,6 @@ class XendMigrate:
  13.369          self.db.saveall("", self.session_db)
  13.370  
  13.371      def sync_session(self, xid):
  13.372 -        print 'sync_session>', type(xid), xid, self.session_db[xid]
  13.373          self.db.save(xid, self.session_db[xid])
  13.374  
  13.375      def close(self):
  13.376 @@ -458,7 +476,6 @@ class XendMigrate:
  13.377          self.sync_session(xid)
  13.378  
  13.379      def _delete_session(self, xid):
  13.380 -        print '***_delete_session>', xid
  13.381          if xid in self.session:
  13.382              del self.session[xid]
  13.383          if xid in self.session_db:
  13.384 @@ -482,16 +499,23 @@ class XendMigrate:
  13.385          @param info: session
  13.386          @return: deferred
  13.387          """
  13.388 -        def cbremove(val):
  13.389 -            print '***cbremove>', val
  13.390 +        dfr = defer.Deferred()
  13.391 +        def cbok(val):
  13.392              self._delete_session(info.xid)
  13.393 +            if not dfr.called:
  13.394 +                dfr.callback(val)
  13.395              return val
  13.396 +        def cberr(err):
  13.397 +            self._delete_session(info.xid)
  13.398 +            if not dfr.called:
  13.399 +                dfr.errback(err)
  13.400 +            return err
  13.401          self._add_session(info)
  13.402 -        info.deferred.addCallback(cbremove)
  13.403 -        info.deferred.addErrback(cbremove)
  13.404 +        info.deferred.addCallback(cbok)
  13.405 +        info.deferred.addErrback(cberr)
  13.406          xcf = XfrdClientFactory(info)
  13.407          reactor.connectTCP('localhost', XFRD_PORT, xcf)
  13.408 -        return info.deferred
  13.409 +        return dfr
  13.410      
  13.411      def migrate_begin(self, dominfo, host, port=XFRD_PORT, live=0, resource=0):
  13.412          """Begin to migrate a domain to another host.
    14.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Sat Mar 26 04:24:24 2005 +0000
    14.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Fri Mar 25 22:20:40 2005 +0000
    14.3 @@ -29,13 +29,8 @@ class SrvDomain(SrvDir):
    14.4                      [['dom', 'int'],
    14.5                       ['config', 'sxpr']])
    14.6          deferred = fn(req.args, {'dom': self.dom.dom})
    14.7 -        deferred.addErrback(self._op_configure_err, req)
    14.8          return deferred
    14.9  
   14.10 -    def _op_configure_err(self, err, req):
   14.11 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
   14.12 -        return str(err)
   14.13 -        
   14.14      def op_unpause(self, op, req):
   14.15          val = self.xd.domain_unpause(self.dom.name)
   14.16          return val
   14.17 @@ -68,16 +63,11 @@ class SrvDomain(SrvDir):
   14.18                       ['file', 'str']])
   14.19          deferred = fn(req.args, {'dom': self.dom.id})
   14.20          deferred.addCallback(self._op_save_cb, req)
   14.21 -        deferred.addErrback(self._op_save_err, req)
   14.22          return deferred
   14.23  
   14.24      def _op_save_cb(self, val, req):
   14.25          return 0
   14.26  
   14.27 -    def _op_save_err(self, err, req):
   14.28 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
   14.29 -        return str(err)
   14.30 -        
   14.31      def op_migrate(self, op, req):
   14.32          fn = FormFn(self.xd.domain_migrate,
   14.33                      [['dom', 'str'],
   14.34 @@ -85,9 +75,7 @@ class SrvDomain(SrvDir):
   14.35                       ['live', 'int'],
   14.36                       ['resource', 'int']])
   14.37          deferred = fn(req.args, {'dom': self.dom.id})
   14.38 -        print 'op_migrate>', deferred
   14.39          deferred.addCallback(self._op_migrate_cb, req)
   14.40 -        deferred.addErrback(self._op_migrate_err, req)
   14.41          return deferred
   14.42  
   14.43      def _op_migrate_cb(self, info, req):
   14.44 @@ -101,11 +89,6 @@ class SrvDomain(SrvDir):
   14.45          print '_op_migrate_cb> url=', url
   14.46          return url
   14.47  
   14.48 -    def _op_migrate_err(self, err, req):
   14.49 -        print '_op_migrate_err>', err, req
   14.50 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
   14.51 -        return str(err)
   14.52 -
   14.53      def op_pincpu(self, op, req):
   14.54          fn = FormFn(self.xd.domain_pincpu,
   14.55                      [['dom', 'str'],
    15.1 --- a/tools/python/xen/xend/server/blkif.py	Sat Mar 26 04:24:24 2005 +0000
    15.2 +++ b/tools/python/xen/xend/server/blkif.py	Fri Mar 25 22:20:40 2005 +0000
    15.3 @@ -181,6 +181,8 @@ class BlkifBackendInterface(controller.B
    15.4              self.close()
    15.5          d = defer.Deferred()
    15.6          d.addCallback(cb_destroy)
    15.7 +        if self.evtchn:
    15.8 +            channel.eventChannelClose(self.evtchn)
    15.9          self.send_be_disconnect(response=d)
   15.10          
   15.11      def send_be_disconnect(self, response=None):
    16.1 --- a/tools/python/xen/xend/server/channel.py	Sat Mar 26 04:24:24 2005 +0000
    16.2 +++ b/tools/python/xen/xend/server/channel.py	Fri Mar 25 22:20:40 2005 +0000
    16.3 @@ -11,7 +11,31 @@ VIRQ_CONSOLE    = 3  # (DOM0) bytes rece
    16.4  VIRQ_DOM_EXC    = 4  # (DOM0) Exceptional event for some domain.
    16.5  
    16.6  def eventChannel(dom1, dom2):
    16.7 -    return xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
    16.8 +    """Create an event channel between domains.
    16.9 +    The returned dict contains dom1, dom2, port1 and port2 on success.
   16.10 +
   16.11 +    @return dict (empty on error)
   16.12 +    """
   16.13 +    evtchn = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
   16.14 +    if evtchn:
   16.15 +        evtchn['dom1'] = dom1
   16.16 +        evtchn['dom2'] = dom2
   16.17 +    return evtchn
   16.18 +
   16.19 +def eventChannelClose(evtchn):
   16.20 +    """Close an event channel that was opened by eventChannel().
   16.21 +    """
   16.22 +    def evtchn_close(dom, port):
   16.23 +        if (dom is None) or (port is None): return
   16.24 +        try:
   16.25 +            xc.evtchn_close(dom=dom, port=port)
   16.26 +        except Exception, ex:
   16.27 +            pass
   16.28 +        
   16.29 +    if not evtchn: return
   16.30 +    evtchn_close(evtchn.get('dom1'), evtchn.get('port1'))
   16.31 +    evtchn_close(evtchn.get('dom2'), evtchn.get('port2'))
   16.32 +    
   16.33  
   16.34  class ChannelFactory:
   16.35      """Factory for creating channels.
    17.1 --- a/tools/python/xen/xend/server/netif.py	Sat Mar 26 04:24:24 2005 +0000
    17.2 +++ b/tools/python/xen/xend/server/netif.py	Fri Mar 25 22:20:40 2005 +0000
    17.3 @@ -138,7 +138,13 @@ class NetDev(controller.SplitDev):
    17.4          self.bridge = None
    17.5          self.script = None
    17.6          self.ipaddr = []
    17.7 +        self.vifname = None
    17.8  
    17.9 +        self.vifname = sxp.child_value(config, 'vifname')
   17.10 +        if self.vifname is None:
   17.11 +            self.vifname = self.default_vifname()
   17.12 +        if len(self.vifname) > 15:
   17.13 +            raise XendError('invalid vifname: too long: ' + self.vifname)
   17.14          mac = self._get_config_mac(config)
   17.15          if mac is None:
   17.16              raise XendError("invalid mac")
   17.17 @@ -201,7 +207,10 @@ class NetDev(controller.SplitDev):
   17.18          val = ['vif',
   17.19                 ['idx', self.idx],
   17.20                 ['vif', vif],
   17.21 -               ['mac', mac]]
   17.22 +               ['mac', mac],
   17.23 +               ['vifname', self.vifname],
   17.24 +               ]
   17.25 +
   17.26          if self.be_mac:
   17.27              val.append(['be_mac', self.get_be_mac()])
   17.28          if self.bridge:
   17.29 @@ -221,8 +230,11 @@ class NetDev(controller.SplitDev):
   17.30      def get_vifname(self):
   17.31          """Get the virtual interface device name.
   17.32          """
   17.33 +        return self.vifname
   17.34 +
   17.35 +    def default_vifname(self):
   17.36          return "vif%d.%d" % (self.controller.dom, self.vif)
   17.37 -
   17.38 +    
   17.39      def get_mac(self):
   17.40          """Get the MAC address as a string.
   17.41          """
   17.42 @@ -259,6 +271,8 @@ class NetDev(controller.SplitDev):
   17.43          @param op: operation name (up, down)
   17.44          @param vmname: vmname
   17.45          """
   17.46 +        if op == 'up':
   17.47 +            Vifctl.set_vif_name(self.default_vifname(), self.vifname)
   17.48          Vifctl.vifctl(op, **self.vifctl_params(vmname=vmname))
   17.49          vnet = XendVnet.instance().vnet_of_bridge(self.bridge)
   17.50          if vnet:
   17.51 @@ -287,7 +301,9 @@ class NetDev(controller.SplitDev):
   17.52                        { 'domid'        : self.controller.dom,
   17.53                          'netif_handle' : self.vif,
   17.54                          'be_mac'       : self.be_mac or [0, 0, 0, 0, 0, 0],
   17.55 -                        'mac'          : self.mac })
   17.56 +                        'mac'          : self.mac,
   17.57 +                        #'vifname'      : self.vifname
   17.58 +                        })
   17.59          self.getBackendInterface().writeRequest(msg, response=d)
   17.60          return d
   17.61  
   17.62 @@ -308,6 +324,8 @@ class NetDev(controller.SplitDev):
   17.63              if change:
   17.64                  self.reportStatus()
   17.65          log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
   17.66 +        if self.evtchn:
   17.67 +            channel.eventChannelClose(self.evtchn)
   17.68          self.vifctl('down')
   17.69          d = self.send_be_disconnect()
   17.70          d.addCallback(cb_destroy)
    18.1 --- a/tools/python/xen/xm/create.py	Sat Mar 26 04:24:24 2005 +0000
    18.2 +++ b/tools/python/xen/xm/create.py	Fri Mar 25 22:20:40 2005 +0000
    18.3 @@ -5,6 +5,7 @@
    18.4  import random
    18.5  import string
    18.6  import sys
    18.7 +import socket
    18.8  
    18.9  from xen.xend import sxp
   18.10  from xen.xend import PrettyPrint
   18.11 @@ -81,6 +82,14 @@ gopts.opt('console_autoconnect', short='
   18.12            fn=set_true, default=0,
   18.13            use="Connect to the console after the domain is created.")
   18.14  
   18.15 +gopts.var('vnc', val='no|yes',
   18.16 +          fn=set_bool, default=None,
   18.17 +          use="""Spawn a vncviewer listening for a vnc server in the domain.
   18.18 +          The address of the vncviewer is passed to the domain on the kernel command
   18.19 +          line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY.
   18.20 +          A display value with a free port is chosen if possible.
   18.21 +          """)
   18.22 +
   18.23  gopts.var('name', val='NAME',
   18.24            fn=set_value, default=None,
   18.25            use="Domain name. Must be unique.")
   18.26 @@ -160,7 +169,7 @@ gopts.var('ipaddr', val="IPADDR",
   18.27            fn=append_value, default=[],
   18.28            use="Add an IP address to the domain.")
   18.29  
   18.30 -gopts.var('vif', val="mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
   18.31 +gopts.var('vif', val="mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM,vifname=NAME",
   18.32            fn=append_value, default=[],
   18.33            use="""Add a network interface with the given MAC address and bridge.
   18.34            The vif is configured by calling the given configuration script.
   18.35 @@ -170,6 +179,8 @@ gopts.var('vif', val="mac=MAC,be_mac=MAC
   18.36            If bridge is not specified the default bridge is used.
   18.37            If script is not specified the default script is used.
   18.38            If backend is not specified the default backend driver domain is used.
   18.39 +          If vifname is not specified the backend virtual interface will have name vifD.N
   18.40 +          where D is the domain id and N is the interface id.
   18.41            This option may be repeated to add more than one vif.
   18.42            Specifying vifs will increase the number of interfaces as needed.""")
   18.43  
   18.44 @@ -321,6 +332,7 @@ def configure_vifs(config_devs, vals):
   18.45              script = d.get('script')
   18.46              backend = d.get('backend')
   18.47              ip = d.get('ip')
   18.48 +            vifname = d.get('vifname')
   18.49          else:
   18.50              mac = randomMAC()
   18.51              be_mac = None
   18.52 @@ -328,8 +340,11 @@ def configure_vifs(config_devs, vals):
   18.53              script = None
   18.54              backend = None
   18.55              ip = None
   18.56 +            vifname = None
   18.57          config_vif = ['vif']
   18.58          config_vif.append(['mac', mac])
   18.59 +        if vifname:
   18.60 +            config_vif.append(['vifname', vifname])
   18.61          if be_mac:
   18.62              config_vif.append(['be_mac', be_mac])
   18.63          if bridge:
   18.64 @@ -429,7 +444,7 @@ def preprocess_vifs(opts, vals):
   18.65              (k, v) = b.strip().split('=', 1)
   18.66              k = k.strip()
   18.67              v = v.strip()
   18.68 -            if k not in ['mac', 'be_mac', 'bridge', 'script', 'backend', 'ip']:
   18.69 +            if k not in ['mac', 'be_mac', 'bridge', 'script', 'backend', 'ip', 'vifname']:
   18.70                  opts.err('Invalid vif specifier: ' + vif)
   18.71              d[k] = v
   18.72          vifs.append(d)
   18.73 @@ -455,6 +470,58 @@ def preprocess_nfs(opts, vals):
   18.74          opts.err('Must set nfs root and nfs server')
   18.75      nfs = 'nfsroot=' + vals.nfs_server + ':' + vals.nfs_root
   18.76      vals.extra = nfs + ' ' + vals.extra
   18.77 +
   18.78 +
   18.79 +def get_host_addr():
   18.80 +    host = socket.gethostname()
   18.81 +    addr = socket.gethostbyname(host)
   18.82 +    return addr
   18.83 +
   18.84 +VNC_BASE_PORT = 5500
   18.85 +
   18.86 +def choose_vnc_display():
   18.87 +    """Try to choose a free vnc display.
   18.88 +    """
   18.89 +    def netstat_local_ports():
   18.90 +        """Run netstat to get a list of the local ports in use.
   18.91 +        """
   18.92 +        l = os.popen("netstat -nat").readlines()
   18.93 +        r = []
   18.94 +        # Skip 2 lines of header.
   18.95 +        for x in l[2:]:
   18.96 +            # Local port is field 3.
   18.97 +            y = x.split()[3]
   18.98 +            # Field is addr:port, split off the port.
   18.99 +            y = y.split(':')[1]
  18.100 +            r.append(int(y))
  18.101 +        return r
  18.102 +
  18.103 +    ports = netstat_local_ports()
  18.104 +    for d in range(1, 100):
  18.105 +        port = VNC_BASE_PORT + d
  18.106 +        if port in ports: continue
  18.107 +        return d
  18.108 +    return None
  18.109 +
  18.110 +def spawn_vnc(display):
  18.111 +    os.system("vncviewer -listen %d &" % display)
  18.112 +    return VNC_BASE_PORT + display
  18.113 +    
  18.114 +def preprocess_vnc(opts, vals):
  18.115 +    """If vnc was specified, spawn a vncviewer in listen mode
  18.116 +    and pass its address to the domain on the kernel command line.
  18.117 +    """
  18.118 +    if not vals.vnc: return
  18.119 +    vnc_display = choose_vnc_display()
  18.120 +    if not vnc_display:
  18.121 +        opts.warn("No free vnc display")
  18.122 +        return
  18.123 +    print 'VNC=', vnc_display
  18.124 +    vnc_port = spawn_vnc(vnc_display)
  18.125 +    if vnc_port > 0:
  18.126 +        vnc_host = get_host_addr()
  18.127 +        vnc = 'VNC_VIEWER=%s:%d' % (vnc_host, vnc_port)
  18.128 +        vals.extra = vnc + ' ' + vals.extra
  18.129      
  18.130  def preprocess(opts, vals):
  18.131      if not vals.kernel:
  18.132 @@ -464,6 +531,7 @@ def preprocess(opts, vals):
  18.133      preprocess_vifs(opts, vals)
  18.134      preprocess_ip(opts, vals)
  18.135      preprocess_nfs(opts, vals)
  18.136 +    preprocess_vnc(opts, vals)
  18.137           
  18.138  def make_domain(opts, config):
  18.139      """Create, build and start a domain.
    19.1 --- a/xen/Makefile	Sat Mar 26 04:24:24 2005 +0000
    19.2 +++ b/xen/Makefile	Fri Mar 25 22:20:40 2005 +0000
    19.3 @@ -105,7 +105,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h
    19.4  
    19.5  .PHONY: default debug install dist clean delete-unfresh-files TAGS
    19.6  
    19.7 -SUBDIRS = arch common drivers 
    19.8 +SUBDIRS = arch/$(TARGET_ARCH) common drivers 
    19.9  TAGS: 
   19.10  	( find include/asm-$(TARGET_ARCH) -name '*.h'; \
   19.11  	  find include -type d \( -name "asm-*" -o -name config \) -prune -o \
    21.1 --- a/xen/arch/ia64/patch/linux-2.6.7/time.c	Sat Mar 26 04:24:24 2005 +0000
    21.2 +++ b/xen/arch/ia64/patch/linux-2.6.7/time.c	Fri Mar 25 22:20:40 2005 +0000
    21.3 @@ -70,11 +70,11 @@
    21.4  +    return now; 
    21.5  +}
    21.6  +
    21.7 -+int update_dom_time(struct exec_domain *ed)
    21.8 ++void update_dom_time(struct exec_domain *ed)
    21.9  +{
   21.10  +// FIXME: implement this?
   21.11  +//	printf("update_dom_time: called, not implemented, skipping\n");
   21.12 -+	return 0;
   21.13 ++	return;
   21.14  +}
   21.15  +
   21.16  +/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
    22.1 --- a/xen/arch/x86/domain.c	Sat Mar 26 04:24:24 2005 +0000
    22.2 +++ b/xen/arch/x86/domain.c	Fri Mar 25 22:20:40 2005 +0000
    22.3 @@ -74,7 +74,8 @@ void startup_cpu_idle_loop(void)
    22.4      /* Just some sanity to ensure that the scheduler is set up okay. */
    22.5      ASSERT(current->domain->id == IDLE_DOMAIN_ID);
    22.6      domain_unpause_by_systemcontroller(current->domain);
    22.7 -    __enter_scheduler();
    22.8 +    raise_softirq(SCHEDULE_SOFTIRQ);
    22.9 +    do_softirq();
   22.10  
   22.11      /*
   22.12       * Declares CPU setup done to the boot processor.
    23.1 --- a/xen/arch/x86/mm.c	Sat Mar 26 04:24:24 2005 +0000
    23.2 +++ b/xen/arch/x86/mm.c	Fri Mar 25 22:20:40 2005 +0000
    23.3 @@ -1147,13 +1147,16 @@ int get_page_type(struct pfn_info *page,
    23.4                   * may be unnecessary (e.g., page was GDT/LDT) but those
    23.5                   * circumstances should be very rare.
    23.6                   */
    23.7 -                struct domain *d = page_get_owner(page);
    23.8 -                if ( unlikely(NEED_FLUSH(tlbflush_time[d->exec_domain[0]->
    23.9 -                                                      processor],
   23.10 -                                         page->tlbflush_timestamp)) )
   23.11 +                struct exec_domain *ed;
   23.12 +                unsigned long mask = 0;
   23.13 +                for_each_exec_domain ( page_get_owner(page), ed )
   23.14 +                    mask |= 1 << ed->processor;
   23.15 +                mask = tlbflush_filter_cpuset(mask, page->tlbflush_timestamp);
   23.16 +
   23.17 +                if ( unlikely(mask != 0) )
   23.18                  {
   23.19 -                    perfc_incr(need_flush_tlb_flush);
   23.20 -                    flush_tlb_cpu(d->exec_domain[0]->processor);
   23.21 +                    perfc_incrc(need_flush_tlb_flush);
   23.22 +                    flush_tlb_mask(mask);
   23.23                  }
   23.24  
   23.25                  /* We lose existing type, back pointer, and validity. */
   23.26 @@ -1666,8 +1669,8 @@ int do_mmu_update(
   23.27      if ( unlikely(shadow_mode_enabled(d)) )
   23.28          check_pagetable(d, ed->arch.guest_table, "pre-mmu"); /* debug */
   23.29  
   23.30 -    if ( unlikely(shadow_mode_translate(d) ) )
   23.31 -        domain_crash();
   23.32 +    if ( unlikely(shadow_mode_translate(d)) )
   23.33 +        domain_crash_synchronous();
   23.34  
   23.35      /*
   23.36       * If we are resuming after preemption, read how much work we have already
   23.37 @@ -2030,8 +2033,8 @@ int do_update_va_mapping(unsigned long v
   23.38      if ( unlikely(!__addr_ok(va)) )
   23.39          return -EINVAL;
   23.40  
   23.41 -    if ( unlikely(shadow_mode_translate(d) ) )
   23.42 -        domain_crash();
   23.43 +    if ( unlikely(shadow_mode_translate(d)) )
   23.44 +        domain_crash_synchronous();
   23.45  
   23.46      LOCK_BIGLOCK(d);
   23.47  
   23.48 @@ -2309,7 +2312,7 @@ void ptwr_flush(const int which)
   23.49          MEM_LOG("ptwr: Could not read pte at %p\n", ptep);
   23.50          /*
   23.51           * Really a bug. We could read this PTE during the initial fault,
   23.52 -         * and pagetables can't have changed meantime. XXX Multi-CPU guests?
   23.53 +         * and pagetables can't have changed meantime.
   23.54           */
   23.55          BUG();
   23.56      }
   23.57 @@ -2336,7 +2339,7 @@ void ptwr_flush(const int which)
   23.58          MEM_LOG("ptwr: Could not update pte at %p\n", ptep);
   23.59          /*
   23.60           * Really a bug. We could write this PTE during the initial fault,
   23.61 -         * and pagetables can't have changed meantime. XXX Multi-CPU guests?
   23.62 +         * and pagetables can't have changed meantime.
   23.63           */
   23.64          BUG();
   23.65      }
   23.66 @@ -2389,9 +2392,8 @@ void ptwr_flush(const int which)
   23.67               */
   23.68              memcpy(&pl1e[i], &ptwr_info[cpu].ptinfo[which].page[i],
   23.69                     (L1_PAGETABLE_ENTRIES - i) * sizeof(l1_pgentry_t));
   23.70 -            unmap_domain_mem(pl1e);
   23.71 -            ptwr_info[cpu].ptinfo[which].l1va = 0;
   23.72              domain_crash();
   23.73 +            break;
   23.74          }
   23.75          
   23.76          if ( unlikely(sl1e != NULL) )
   23.77 @@ -2685,6 +2687,7 @@ int ptwr_do_page_fault(unsigned long add
   23.78          unmap_domain_mem(ptwr_info[cpu].ptinfo[which].pl1e);
   23.79          ptwr_info[cpu].ptinfo[which].l1va = 0;
   23.80          domain_crash();
   23.81 +        return 0;
   23.82      }
   23.83      
   23.84      return EXCRET_fault_fixed;
   23.85 @@ -2722,40 +2725,6 @@ static __init int ptwr_init(void)
   23.86  
   23.87  #ifndef NDEBUG
   23.88  
   23.89 -void ptwr_status(void)
   23.90 -{
   23.91 -    unsigned long pte, *ptep, pfn;
   23.92 -    struct pfn_info *page;
   23.93 -    int cpu = smp_processor_id();
   23.94 -
   23.95 -    ptep = (unsigned long *)&linear_pg_table
   23.96 -        [ptwr_info[cpu].ptinfo[PTWR_PT_INACTIVE].l1va>>PAGE_SHIFT];
   23.97 -
   23.98 -    if ( __get_user(pte, ptep) ) {
   23.99 -        MEM_LOG("ptwr: Could not read pte at %p\n", ptep);
  23.100 -        domain_crash();
  23.101 -    }
  23.102 -
  23.103 -    pfn = pte >> PAGE_SHIFT;
  23.104 -    page = &frame_table[pfn];
  23.105 -    printk("need to alloc l1 page %p\n", page);
  23.106 -    /* make pt page writable */
  23.107 -    printk("need to make read-only l1-page at %p is %p\n",
  23.108 -           ptep, pte);
  23.109 -
  23.110 -    if ( ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va == 0 )
  23.111 -        return;
  23.112 -
  23.113 -    if ( __get_user(pte, (unsigned long *)
  23.114 -                    ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va) ) {
  23.115 -        MEM_LOG("ptwr: Could not read pte at %p\n", (unsigned long *)
  23.116 -                ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va);
  23.117 -        domain_crash();
  23.118 -    }
  23.119 -    pfn = pte >> PAGE_SHIFT;
  23.120 -    page = &frame_table[pfn];
  23.121 -}
  23.122 -
  23.123  void audit_pagelist(struct domain *d)
  23.124  {
  23.125      struct list_head *list_ent;
    24.1 --- a/xen/arch/x86/shadow.c	Sat Mar 26 04:24:24 2005 +0000
    24.2 +++ b/xen/arch/x86/shadow.c	Fri Mar 25 22:20:40 2005 +0000
    24.3 @@ -655,15 +655,13 @@ int shadow_fault(unsigned long va, struc
    24.4                               &linear_pg_table[va >> PAGE_SHIFT])) )
    24.5      {
    24.6          SH_VVLOG("shadow_fault - EXIT: read gpte faulted2" );
    24.7 -        shadow_unlock(d);
    24.8 -        return 0;
    24.9 +        goto fail;
   24.10      }
   24.11  
   24.12      if ( unlikely(!(gpte & _PAGE_PRESENT)) )
   24.13      {
   24.14          SH_VVLOG("shadow_fault - EXIT: gpte not present2 (%lx)",gpte );
   24.15 -        shadow_unlock(d);
   24.16 -        return 0;
   24.17 +        goto fail;
   24.18      }
   24.19  
   24.20      /* Write fault? */
   24.21 @@ -673,8 +671,7 @@ int shadow_fault(unsigned long va, struc
   24.22          {
   24.23              /* Write fault on a read-only mapping. */
   24.24              SH_VVLOG("shadow_fault - EXIT: wr fault on RO page (%lx)", gpte);
   24.25 -            shadow_unlock(d);
   24.26 -            return 0;
   24.27 +            goto fail;
   24.28          }
   24.29  
   24.30          l1pte_write_fault(d, &gpte, &spte);
   24.31 @@ -691,7 +688,10 @@ int shadow_fault(unsigned long va, struc
   24.32      /* XXX Watch out for read-only L2 entries! (not used in Linux). */
   24.33      if ( unlikely(__put_user(gpte, (unsigned long *)
   24.34                               &linear_pg_table[va >> PAGE_SHIFT])) )
   24.35 +    {
   24.36          domain_crash();
   24.37 +        goto fail;
   24.38 +    }
   24.39  
   24.40      /*
   24.41       * Update of shadow PTE can fail because the L1 p.t. is not shadowed,
   24.42 @@ -712,6 +712,10 @@ int shadow_fault(unsigned long va, struc
   24.43  
   24.44      check_pagetable(d, ed->arch.guest_table, "post-sf");
   24.45      return EXCRET_fault_fixed;
   24.46 +
   24.47 + fail:
   24.48 +    shadow_unlock(d);
   24.49 +    return 0;
   24.50  }
   24.51  
   24.52  
    25.1 --- a/xen/arch/x86/time.c	Sat Mar 26 04:24:24 2005 +0000
    25.2 +++ b/xen/arch/x86/time.c	Fri Mar 25 22:20:40 2005 +0000
    25.3 @@ -296,18 +296,16 @@ static inline void __update_dom_time(str
    25.4      spin_unlock(&d->time_lock);
    25.5  }
    25.6  
    25.7 -int update_dom_time(struct exec_domain *ed)
    25.8 +void update_dom_time(struct exec_domain *ed)
    25.9  {
   25.10      unsigned long flags;
   25.11  
   25.12 -    if ( ed->domain->shared_info->tsc_timestamp == full_tsc_irq )
   25.13 -        return 0;
   25.14 -
   25.15 -    read_lock_irqsave(&time_lock, flags);
   25.16 -    __update_dom_time(ed);
   25.17 -    read_unlock_irqrestore(&time_lock, flags);
   25.18 -
   25.19 -    return 1;
   25.20 +    if ( ed->domain->shared_info->tsc_timestamp != full_tsc_irq )
   25.21 +    {
   25.22 +        read_lock_irqsave(&time_lock, flags);
   25.23 +        __update_dom_time(ed);
   25.24 +        read_unlock_irqrestore(&time_lock, flags);
   25.25 +    }
   25.26  }
   25.27  
   25.28  /* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
    26.1 --- a/xen/arch/x86/traps.c	Sat Mar 26 04:24:24 2005 +0000
    26.2 +++ b/xen/arch/x86/traps.c	Fri Mar 25 22:20:40 2005 +0000
    26.3 @@ -223,18 +223,7 @@ asmlinkage int do_int3(struct xen_regs *
    26.4          show_registers(regs);
    26.5          panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n", smp_processor_id());
    26.6      } 
    26.7 -#ifdef DOMU_DEBUG
    26.8 -    else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 ) 
    26.9 -    {
   26.10 -        if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) {
   26.11 -            while (ed == current)
   26.12 -                __enter_scheduler();
   26.13 -            domain_pause_by_systemcontroller(ed->domain);
   26.14 -        }
   26.15 -        
   26.16 -        return 0;
   26.17 -    }
   26.18 -#endif /* DOMU_DEBUG */
   26.19 +
   26.20      ti = current->arch.traps + 3;
   26.21      tb->flags = TBF_EXCEPTION;
   26.22      tb->cs    = ti->cs;
   26.23 @@ -950,8 +939,6 @@ asmlinkage int do_debug(struct xen_regs 
   26.24      struct exec_domain *ed = current;
   26.25      struct trap_bounce *tb = &ed->arch.trap_bounce;
   26.26  
   26.27 -    DEBUGGER_trap_entry(TRAP_debug, regs);
   26.28 -
   26.29      __asm__ __volatile__("mov %%db6,%0" : "=r" (condition));
   26.30  
   26.31      /* Mask out spurious debug traps due to lazy DR7 setting */
   26.32 @@ -962,6 +949,8 @@ asmlinkage int do_debug(struct xen_regs 
   26.33          goto out;
   26.34      }
   26.35  
   26.36 +    DEBUGGER_trap_entry(TRAP_debug, regs);
   26.37 +
   26.38      if ( !GUEST_MODE(regs) )
   26.39      {
   26.40          /* Clear TF just for absolute sanity. */
   26.41 @@ -974,19 +963,7 @@ asmlinkage int do_debug(struct xen_regs 
   26.42           */
   26.43          goto out;
   26.44      } 
   26.45 -#ifdef DOMU_DEBUG
   26.46 -    else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 ) 
   26.47 -    {
   26.48 -        regs->eflags &= ~EF_TF;
   26.49 -        if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) {
   26.50 -            while (ed == current)
   26.51 -                __enter_scheduler();
   26.52 -            domain_pause_by_systemcontroller(ed->domain);
   26.53 -        }
   26.54  
   26.55 -        goto out;
   26.56 -    }    
   26.57 -#endif /* DOMU_DEBUG */
   26.58      /* Save debug status register where guest OS can peek at it */
   26.59      ed->arch.debugreg[6] = condition;
   26.60  
    27.1 --- a/xen/arch/x86/vmx.c	Sat Mar 26 04:24:24 2005 +0000
    27.2 +++ b/xen/arch/x86/vmx.c	Fri Mar 25 22:20:40 2005 +0000
    27.3 @@ -22,6 +22,7 @@
    27.4  #include <xen/lib.h>
    27.5  #include <xen/trace.h>
    27.6  #include <xen/sched.h>
    27.7 +#include <xen/softirq.h>
    27.8  #include <asm/current.h>
    27.9  #include <asm/io.h>
   27.10  #include <asm/irq.h>
   27.11 @@ -314,7 +315,7 @@ static void vmx_io_instruction(struct xe
   27.12      vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va;
   27.13      if (vio == 0) {
   27.14          VMX_DBG_LOG(DBG_LEVEL_1, "bad shared page: %lx", (unsigned long) vio);
   27.15 -        domain_crash(); 
   27.16 +        domain_crash_synchronous(); 
   27.17      }
   27.18      p = &vio->vp_ioreq;
   27.19      p->dir = test_bit(3, &exit_qualification);  
   27.20 @@ -340,7 +341,7 @@ static void vmx_io_instruction(struct xe
   27.21              printk("stringio crosses page boundary!\n");
   27.22              if (p->u.data & (p->size - 1)) {
   27.23                  printk("Not aligned I/O!\n");
   27.24 -                domain_crash();     
   27.25 +                domain_crash_synchronous();     
   27.26              }
   27.27              p->count = (PAGE_SIZE - (p->u.data & ~PAGE_MASK)) / p->size;
   27.28          } else {
   27.29 @@ -424,7 +425,7 @@ static void mov_to_cr(int gp, int cr, st
   27.30              {
   27.31                  VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value = %lx", 
   27.32                          d->arch.arch_vmx.cpu_cr3);
   27.33 -                domain_crash(); /* need to take a clean path */
   27.34 +                domain_crash_synchronous(); /* need to take a clean path */
   27.35              }
   27.36              old_base_mfn = pagetable_val(d->arch.guest_table) >> PAGE_SHIFT;
   27.37  
   27.38 @@ -494,7 +495,7 @@ static void mov_to_cr(int gp, int cr, st
   27.39              {
   27.40                  VMX_DBG_LOG(DBG_LEVEL_VMMU, 
   27.41                          "Invalid CR3 value=%lx", value);
   27.42 -                domain_crash(); /* need to take a clean path */
   27.43 +                domain_crash_synchronous(); /* need to take a clean path */
   27.44              }
   27.45              mfn = phys_to_machine_mapping(value >> PAGE_SHIFT);
   27.46              vmx_shadow_clear_state(d->domain);
   27.47 @@ -620,24 +621,24 @@ static inline void vmx_do_msr_read(struc
   27.48  /*
   27.49   * Need to use this exit to rescheule
   27.50   */
   27.51 -static inline void vmx_vmexit_do_hlt()
   27.52 +static inline void vmx_vmexit_do_hlt(void)
   27.53  {
   27.54  #if VMX_DEBUG
   27.55      unsigned long eip;
   27.56      __vmread(GUEST_EIP, &eip);
   27.57  #endif
   27.58      VMX_DBG_LOG(DBG_LEVEL_1, "vmx_vmexit_do_hlt:eip=%p", eip);
   27.59 -    __enter_scheduler();
   27.60 +    raise_softirq(SCHEDULE_SOFTIRQ);
   27.61  }
   27.62  
   27.63 -static inline void vmx_vmexit_do_mwait()
   27.64 +static inline void vmx_vmexit_do_mwait(void)
   27.65  {
   27.66  #if VMX_DEBUG
   27.67      unsigned long eip;
   27.68      __vmread(GUEST_EIP, &eip);
   27.69  #endif
   27.70      VMX_DBG_LOG(DBG_LEVEL_1, "vmx_vmexit_do_mwait:eip=%p", eip);
   27.71 -    __enter_scheduler();
   27.72 +    raise_softirq(SCHEDULE_SOFTIRQ);
   27.73  }
   27.74  
   27.75  #define BUF_SIZ     256
   27.76 @@ -736,7 +737,7 @@ asmlinkage void vmx_vmexit_handler(struc
   27.77          VMX_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
   27.78  
   27.79      if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
   27.80 -        domain_crash();         
   27.81 +        domain_crash_synchronous();         
   27.82          return;
   27.83      }
   27.84  
    28.1 --- a/xen/arch/x86/vmx_intercept.c	Sat Mar 26 04:24:24 2005 +0000
    28.2 +++ b/xen/arch/x86/vmx_intercept.c	Fri Mar 25 22:20:40 2005 +0000
    28.3 @@ -56,7 +56,7 @@ int register_io_handler(unsigned long ad
    28.4  
    28.5      if (num >= MAX_IO_HANDLER) {
    28.6          printk("no extra space, register io interceptor failed!\n");
    28.7 -        domain_crash();
    28.8 +        domain_crash_synchronous();
    28.9      }
   28.10  
   28.11      handler->hdl_list[num].addr = addr;
    29.1 --- a/xen/arch/x86/vmx_io.c	Sat Mar 26 04:24:24 2005 +0000
    29.2 +++ b/xen/arch/x86/vmx_io.c	Fri Mar 25 22:20:40 2005 +0000
    29.3 @@ -195,7 +195,7 @@ void vmx_io_assist(struct exec_domain *e
    29.4      if (vio == 0) {
    29.5          VMX_DBG_LOG(DBG_LEVEL_1, 
    29.6                      "bad shared page: %lx", (unsigned long) vio);
    29.7 -        domain_crash();
    29.8 +        domain_crash_synchronous();
    29.9      }
   29.10      p = &vio->vp_ioreq;
   29.11  
   29.12 @@ -314,7 +314,7 @@ static inline int find_highest_pending_i
   29.13      if (vio == 0) {
   29.14          VMX_DBG_LOG(DBG_LEVEL_1, 
   29.15                      "bad shared page: %lx", (unsigned long) vio);
   29.16 -        domain_crash();
   29.17 +        domain_crash_synchronous();
   29.18      }
   29.19          
   29.20      return find_highest_irq(&vio->vp_intr[0]);
   29.21 @@ -328,7 +328,7 @@ static inline void clear_highest_bit(str
   29.22      if (vio == 0) {
   29.23          VMX_DBG_LOG(DBG_LEVEL_1, 
   29.24                      "bad shared page: %lx", (unsigned long) vio);
   29.25 -        domain_crash();
   29.26 +        domain_crash_synchronous();
   29.27      }
   29.28          
   29.29      clear_bit(vector, &vio->vp_intr[0]);
    30.1 --- a/xen/arch/x86/vmx_platform.c	Sat Mar 26 04:24:24 2005 +0000
    30.2 +++ b/xen/arch/x86/vmx_platform.c	Fri Mar 25 22:20:40 2005 +0000
    30.3 @@ -436,7 +436,7 @@ static void send_mmio_req(unsigned long 
    30.4          
    30.5      if (vio == NULL) {
    30.6          printk("bad shared page\n");
    30.7 -        domain_crash(); 
    30.8 +        domain_crash_synchronous(); 
    30.9      }
   30.10      p = &vio->vp_ioreq;
   30.11          
   30.12 @@ -490,13 +490,13 @@ void handle_mmio(unsigned long va, unsig
   30.13      ret = inst_copy_from_guest(inst, eip, inst_len);
   30.14      if (ret != inst_len) {
   30.15          printk("handle_mmio - EXIT: get guest instruction fault\n");
   30.16 -        domain_crash();
   30.17 +        domain_crash_synchronous();
   30.18      }
   30.19  
   30.20      init_instruction(&mmio_inst);
   30.21      
   30.22      if (vmx_decode(check_prefix(inst, &mmio_inst), &mmio_inst) == DECODE_failure)
   30.23 -        domain_crash();
   30.24 +        domain_crash_synchronous();
   30.25  
   30.26      __vmwrite(GUEST_EIP, eip + inst_len);
   30.27      store_xen_regs(inst_decoder_regs);
   30.28 @@ -510,7 +510,7 @@ void handle_mmio(unsigned long va, unsig
   30.29              return ;
   30.30          } else {
   30.31              printk("handle_mmio - EXIT: movz error!\n");
   30.32 -            domain_crash();
   30.33 +            domain_crash_synchronous();
   30.34          }
   30.35      }
   30.36  
   30.37 @@ -539,14 +539,14 @@ void handle_mmio(unsigned long va, unsig
   30.38                  index = operand_index(mmio_inst.operand[0]);
   30.39                  value = get_reg_value(size, index, 0, inst_decoder_regs);
   30.40              } else {
   30.41 -                domain_crash();
   30.42 +                domain_crash_synchronous();
   30.43              }
   30.44              send_mmio_req(gpa, &mmio_inst, value, 0, 0);
   30.45              return;
   30.46          }
   30.47 -        domain_crash();
   30.48      }
   30.49 -    domain_crash();
   30.50 +
   30.51 +    domain_crash_synchronous();
   30.52  }
   30.53  
   30.54  #endif /* CONFIG_VMX */
    31.1 --- a/xen/arch/x86/x86_32/entry.S	Sat Mar 26 04:24:24 2005 +0000
    31.2 +++ b/xen/arch/x86/x86_32/entry.S	Fri Mar 25 22:20:40 2005 +0000
    31.3 @@ -385,13 +385,17 @@ nvm86_3:/* Rewrite our stack frame and r
    31.4          movb $0,TRAPBOUNCE_flags(%edx)
    31.5          ret
    31.6  .section __ex_table,"a"
    31.7 -	.long  FLT6,domain_crash ,  FLT7,domain_crash ,  FLT8,domain_crash
    31.8 -        .long  FLT9,domain_crash , FLT10,domain_crash , FLT11,domain_crash
    31.9 -        .long FLT12,domain_crash , FLT13,domain_crash , FLT14,domain_crash
   31.10 -        .long FLT15,domain_crash , FLT16,domain_crash , FLT17,domain_crash
   31.11 -	.long FLT18,domain_crash , FLT19,domain_crash , FLT20,domain_crash
   31.12 -        .long FLT21,domain_crash , FLT22,domain_crash , FLT23,domain_crash
   31.13 -        .long FLT24,domain_crash , FLT25,domain_crash , FLT26,domain_crash
   31.14 +	.long  FLT6,domain_crash_synchronous ,  FLT7,domain_crash_synchronous
   31.15 +        .long  FLT8,domain_crash_synchronous ,  FLT9,domain_crash_synchronous
   31.16 +        .long FLT10,domain_crash_synchronous , FLT11,domain_crash_synchronous
   31.17 +        .long FLT12,domain_crash_synchronous , FLT13,domain_crash_synchronous
   31.18 +        .long FLT14,domain_crash_synchronous , FLT15,domain_crash_synchronous
   31.19 +        .long FLT16,domain_crash_synchronous , FLT17,domain_crash_synchronous
   31.20 +	.long FLT18,domain_crash_synchronous , FLT19,domain_crash_synchronous
   31.21 +        .long FLT20,domain_crash_synchronous , FLT21,domain_crash_synchronous
   31.22 +        .long FLT22,domain_crash_synchronous , FLT23,domain_crash_synchronous
   31.23 +        .long FLT24,domain_crash_synchronous , FLT25,domain_crash_synchronous
   31.24 +        .long FLT26,domain_crash_synchronous
   31.25  .previous
   31.26  
   31.27          ALIGN
   31.28 @@ -682,9 +686,9 @@ VFLT3:  movl %gs:(%esi),%eax
   31.29          jmp test_all_events
   31.30  
   31.31  .section __ex_table,"a"
   31.32 -        .long VFLT1,domain_crash
   31.33 -        .long VFLT2,domain_crash
   31.34 -        .long VFLT3,domain_crash
   31.35 +        .long VFLT1,domain_crash_synchronous
   31.36 +        .long VFLT2,domain_crash_synchronous
   31.37 +        .long VFLT3,domain_crash_synchronous
   31.38  .previous
   31.39  
   31.40  .data
    32.1 --- a/xen/arch/x86/x86_64/entry.S	Sat Mar 26 04:24:24 2005 +0000
    32.2 +++ b/xen/arch/x86/x86_64/entry.S	Fri Mar 25 22:20:40 2005 +0000
    32.3 @@ -179,7 +179,7 @@ 2:      movq  $HYPERVISOR_VIRT_START,%ra
    32.4          jb    1f                        # In +ve address space? Then okay.
    32.5          movq  $HYPERVISOR_VIRT_END+60,%rax
    32.6          cmpq  %rax,%rsi
    32.7 -        jb    domain_crash              # Above Xen private area? Then okay.
    32.8 +        jb    domain_crash_synchronous  # Above Xen private area? Then okay.
    32.9  1:      subq  $40,%rsi
   32.10          movq  XREGS_ss+8(%rsp),%rax
   32.11  FLT2:   movq  %rax,32(%rsi)             # SS
   32.12 @@ -230,11 +230,13 @@ FLT14:  movq  %rax,(%rsi)               
   32.13          movb  $0,TRAPBOUNCE_flags(%rdx)
   32.14          ret
   32.15  .section __ex_table,"a"
   32.16 -        .quad  FLT2,domain_crash ,  FLT3,domain_crash ,  FLT4,domain_crash
   32.17 -        .quad  FLT5,domain_crash ,  FLT6,domain_crash ,  FLT7,domain_crash
   32.18 -        .quad  FLT8,domain_crash ,  FLT9,domain_crash , FLT10,domain_crash
   32.19 -        .quad FLT11,domain_crash , FLT12,domain_crash , FLT13,domain_crash
   32.20 -        .quad FLT14,domain_crash
   32.21 +        .quad  FLT2,domain_crash_synchronous ,  FLT3,domain_crash_synchronous
   32.22 +        .quad  FLT4,domain_crash_synchronous ,  FLT5,domain_crash_synchronous
   32.23 +        .quad  FLT6,domain_crash_synchronous ,  FLT7,domain_crash_synchronous
   32.24 +        .quad  FLT8,domain_crash_synchronous ,  FLT9,domain_crash_synchronous
   32.25 +        .quad FLT10,domain_crash_synchronous , FLT11,domain_crash_synchronous
   32.26 +        .quad FLT12,domain_crash_synchronous , FLT13,domain_crash_synchronous
   32.27 +        .quad FLT14,domain_crash_synchronous
   32.28  .previous
   32.29  
   32.30          ALIGN
    33.1 --- a/xen/common/domain.c	Sat Mar 26 04:24:24 2005 +0000
    33.2 +++ b/xen/common/domain.c	Fri Mar 25 22:20:40 2005 +0000
    33.3 @@ -41,7 +41,6 @@ struct domain *do_createdomain(domid_t d
    33.4  
    33.5      d->id          = dom_id;
    33.6      ed->processor  = cpu;
    33.7 -    d->create_time = NOW();
    33.8   
    33.9      spin_lock_init(&d->time_lock);
   33.10  
   33.11 @@ -107,28 +106,6 @@ struct domain *find_domain_by_id(domid_t
   33.12  }
   33.13  
   33.14  
   33.15 -/* Return the most recently created domain. */
   33.16 -struct domain *find_last_domain(void)
   33.17 -{
   33.18 -    struct domain *d, *dlast;
   33.19 -
   33.20 -    read_lock(&domlist_lock);
   33.21 -    dlast = domain_list;
   33.22 -    d = dlast->next_list;
   33.23 -    while ( d != NULL )
   33.24 -    {
   33.25 -        if ( d->create_time > dlast->create_time )
   33.26 -            dlast = d;
   33.27 -        d = d->next_list;
   33.28 -    }
   33.29 -    if ( !get_domain(dlast) )
   33.30 -        dlast = NULL;
   33.31 -    read_unlock(&domlist_lock);
   33.32 -
   33.33 -    return dlast;
   33.34 -}
   33.35 -
   33.36 -
   33.37  #ifndef CONFIG_IA64
   33.38  extern void physdev_destroy_state(struct domain *d);
   33.39  #else
   33.40 @@ -161,12 +138,18 @@ void domain_crash(void)
   33.41      set_bit(DF_CRASHED, &d->d_flags);
   33.42  
   33.43      send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC);
   33.44 -    
   33.45 -    __enter_scheduler();
   33.46 -    BUG();
   33.47 +
   33.48 +    raise_softirq(SCHEDULE_SOFTIRQ);
   33.49  }
   33.50  
   33.51 -extern void trap_to_xendbg(void);
   33.52 +
   33.53 +void domain_crash_synchronous(void)
   33.54 +{
   33.55 +    domain_crash();
   33.56 +    for ( ; ; )
   33.57 +        do_softirq();
   33.58 +}
   33.59 +
   33.60  
   33.61  void domain_shutdown(u8 reason)
   33.62  {
   33.63 @@ -191,20 +174,17 @@ void domain_shutdown(u8 reason)
   33.64          }
   33.65      }
   33.66  
   33.67 -    if ( reason == SHUTDOWN_crash )
   33.68 -    {
   33.69 -        domain_crash();
   33.70 -        BUG();
   33.71 -    }
   33.72 -
   33.73 -    d->shutdown_code = reason;
   33.74 -    set_bit(DF_SHUTDOWN, &d->d_flags);
   33.75 +    if ( (d->shutdown_code = reason) == SHUTDOWN_crash )
   33.76 +        set_bit(DF_CRASHED, &d->d_flags);
   33.77 +    else
   33.78 +        set_bit(DF_SHUTDOWN, &d->d_flags);
   33.79  
   33.80      send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC);
   33.81  
   33.82 -    __enter_scheduler();
   33.83 +    raise_softirq(SCHEDULE_SOFTIRQ);
   33.84  }
   33.85  
   33.86 +
   33.87  unsigned int alloc_new_dom_mem(struct domain *d, unsigned int kbytes)
   33.88  {
   33.89      unsigned int alloc_pfns, nr_pages;
   33.90 @@ -347,7 +327,8 @@ long do_boot_vcpu(unsigned long vcpu, fu
   33.91  
   33.92      sched_add_domain(ed);
   33.93  
   33.94 -    if ( (rc = arch_set_info_guest(ed, c)) != 0 ) {
   33.95 +    if ( (rc = arch_set_info_guest(ed, c)) != 0 )
   33.96 +    {
   33.97          sched_rem_domain(ed);
   33.98          goto out;
   33.99      }
    34.1 --- a/xen/common/page_alloc.c	Sat Mar 26 04:24:24 2005 +0000
    34.2 +++ b/xen/common/page_alloc.c	Fri Mar 25 22:20:40 2005 +0000
    34.3 @@ -470,43 +470,30 @@ void init_domheap_pages(unsigned long ps
    34.4  struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order)
    34.5  {
    34.6      struct pfn_info *pg;
    34.7 -    unsigned long mask, flushed_mask, pfn_stamp, cpu_stamp;
    34.8 -    int i, j;
    34.9 +    unsigned long mask = 0;
   34.10 +    int i;
   34.11  
   34.12      ASSERT(!in_irq());
   34.13  
   34.14      if ( unlikely((pg = alloc_heap_pages(MEMZONE_DOM, order)) == NULL) )
   34.15          return NULL;
   34.16  
   34.17 -    flushed_mask = 0;
   34.18      for ( i = 0; i < (1 << order); i++ )
   34.19      {
   34.20 -        if ( (mask = (pg[i].u.free.cpu_mask & ~flushed_mask)) != 0 )
   34.21 -        {
   34.22 -            pfn_stamp = pg[i].tlbflush_timestamp;
   34.23 -            for ( j = 0; (mask != 0) && (j < smp_num_cpus); j++ )
   34.24 -            {
   34.25 -                if ( mask & (1UL<<j) )
   34.26 -                {
   34.27 -                    cpu_stamp = tlbflush_time[j];
   34.28 -                    if ( !NEED_FLUSH(cpu_stamp, pfn_stamp) )
   34.29 -                        mask &= ~(1UL<<j);
   34.30 -                }
   34.31 -            }
   34.32 -            
   34.33 -            if ( unlikely(mask != 0) )
   34.34 -            {
   34.35 -                flush_tlb_mask(mask);
   34.36 -                perfc_incrc(need_flush_tlb_flush);
   34.37 -                flushed_mask |= mask;
   34.38 -            }
   34.39 -        }
   34.40 +        mask |= tlbflush_filter_cpuset(
   34.41 +            pg[i].u.free.cpu_mask & ~mask, pg[i].tlbflush_timestamp);
   34.42  
   34.43          pg[i].count_info        = 0;
   34.44          pg[i].u.inuse._domain   = 0;
   34.45          pg[i].u.inuse.type_info = 0;
   34.46      }
   34.47  
   34.48 +    if ( unlikely(mask != 0) )
   34.49 +    {
   34.50 +        perfc_incrc(need_flush_tlb_flush);
   34.51 +        flush_tlb_mask(mask);
   34.52 +    }
   34.53 +
   34.54      if ( d == NULL )
   34.55          return pg;
   34.56  
   34.57 @@ -570,7 +557,7 @@ void free_domheap_pages(struct pfn_info 
   34.58          /* NB. May recursively lock from domain_relinquish_memory(). */
   34.59          spin_lock_recursive(&d->page_alloc_lock);
   34.60  
   34.61 -        for_each_exec_domain(d, ed)
   34.62 +        for_each_exec_domain ( d, ed )
   34.63              cpu_mask |= 1 << ed->processor;
   34.64  
   34.65          for ( i = 0; i < (1 << order); i++ )
    35.1 --- a/xen/common/sched_atropos.c	Sat Mar 26 04:24:24 2005 +0000
    35.2 +++ b/xen/common/sched_atropos.c	Fri Mar 25 22:20:40 2005 +0000
    35.3 @@ -325,7 +325,7 @@ static void block(struct domain* sdom)
    35.4  /**
    35.5   * ATROPOS - main scheduler function
    35.6   */
    35.7 -task_slice_t ksched_scheduler(s_time_t time)
    35.8 +struct task_slice ksched_scheduler(s_time_t time)
    35.9  {
   35.10      struct domain *cur_sdom = current;  /* Current sdom           */
   35.11      s_time_t       newtime;
   35.12 @@ -335,7 +335,7 @@ task_slice_t ksched_scheduler(s_time_t t
   35.13      struct at_dom_info *cur_info;
   35.14      static unsigned long waitq_rrobin = 0;
   35.15      int i;
   35.16 -    task_slice_t ret;
   35.17 +    struct task_slice ret;
   35.18  
   35.19  
   35.20      cur_info = DOM_INFO(cur_sdom);
    36.1 --- a/xen/common/sched_bvt.c	Sat Mar 26 04:24:24 2005 +0000
    36.2 +++ b/xen/common/sched_bvt.c	Fri Mar 25 22:20:40 2005 +0000
    36.3 @@ -363,7 +363,7 @@ static int bvt_adjdom(
    36.4   *   i.e., the domain with lowest EVT.
    36.5   *   The runqueue should be ordered by EVT so that is easy.
    36.6   */
    36.7 -static task_slice_t bvt_do_schedule(s_time_t now)
    36.8 +static struct task_slice bvt_do_schedule(s_time_t now)
    36.9  {
   36.10      struct domain *d;
   36.11      struct exec_domain      *prev = current, *next = NULL, *next_prime, *ed; 
   36.12 @@ -375,7 +375,7 @@ static task_slice_t bvt_do_schedule(s_ti
   36.13      struct bvt_edom_info *p_einf          = NULL;
   36.14      struct bvt_edom_info *next_einf       = NULL;
   36.15      struct bvt_edom_info *next_prime_einf = NULL;
   36.16 -    task_slice_t        ret;
   36.17 +    struct task_slice     ret;
   36.18  
   36.19      ASSERT(prev->ed_sched_priv != NULL);
   36.20      ASSERT(prev_einf != NULL);
    37.1 --- a/xen/common/sched_rrobin.c	Sat Mar 26 04:24:24 2005 +0000
    37.2 +++ b/xen/common/sched_rrobin.c	Fri Mar 25 22:20:40 2005 +0000
    37.3 @@ -99,11 +99,11 @@ static int rr_init_idle_task(struct doma
    37.4  }
    37.5  
    37.6  /* Main scheduling function */
    37.7 -static task_slice_t rr_do_schedule(s_time_t now)
    37.8 +static struct task_slice rr_do_schedule(s_time_t now)
    37.9  {
   37.10      struct domain *prev = current;
   37.11      int cpu = current->processor;
   37.12 -    task_slice_t ret;
   37.13 +    struct task_slice ret;
   37.14      
   37.15      if ( !is_idle_task(prev) )
   37.16      {
    38.1 --- a/xen/common/schedule.c	Sat Mar 26 04:24:24 2005 +0000
    38.2 +++ b/xen/common/schedule.c	Fri Mar 25 22:20:40 2005 +0000
    38.3 @@ -13,6 +13,15 @@
    38.4   *
    38.5   */
    38.6  
    38.7 +/*#define WAKE_HISTO*/
    38.8 +/*#define BLOCKTIME_HISTO*/
    38.9 +
   38.10 +#if defined(WAKE_HISTO)
   38.11 +#define BUCKETS 31
   38.12 +#elif defined(BLOCKTIME_HISTO)
   38.13 +#define BUCKETS 200
   38.14 +#endif
   38.15 +
   38.16  #include <xen/config.h>
   38.17  #include <xen/init.h>
   38.18  #include <xen/lib.h>
   38.19 @@ -31,15 +40,6 @@
   38.20  static char opt_sched[10] = "bvt";
   38.21  string_param("sched", opt_sched);
   38.22  
   38.23 -/*#define WAKE_HISTO*/
   38.24 -/*#define BLOCKTIME_HISTO*/
   38.25 -
   38.26 -#if defined(WAKE_HISTO)
   38.27 -#define BUCKETS 31
   38.28 -#elif defined(BLOCKTIME_HISTO)
   38.29 -#define BUCKETS 200
   38.30 -#endif
   38.31 -
   38.32  #define TIME_SLOP      (s32)MICROSECS(50)     /* allow time to slip a bit */
   38.33  
   38.34  /*
   38.35 @@ -66,19 +66,16 @@ static void t_timer_fn(unsigned long unu
   38.36  static void dom_timer_fn(unsigned long data);
   38.37  
   38.38  /* This is global for now so that private implementations can reach it */
   38.39 -schedule_data_t schedule_data[NR_CPUS];
   38.40 +struct schedule_data schedule_data[NR_CPUS];
   38.41  
   38.42  extern struct scheduler sched_bvt_def;
   38.43 -// extern struct scheduler sched_rrobin_def;
   38.44 -// extern struct scheduler sched_atropos_def;
   38.45  static struct scheduler *schedulers[] = { 
   38.46      &sched_bvt_def,
   38.47 -//     &sched_rrobin_def,
   38.48 -//     &sched_atropos_def,
   38.49      NULL
   38.50  };
   38.51  
   38.52 -/* Operations for the current scheduler. */
   38.53 +static void __enter_scheduler(void);
   38.54 +
   38.55  static struct scheduler ops;
   38.56  
   38.57  #define SCHED_OP(fn, ...)                                 \
   38.58 @@ -366,12 +363,12 @@ long sched_adjdom(struct sched_adjdom_cm
   38.59   * - deschedule the current domain (scheduler independent).
   38.60   * - pick a new domain (scheduler dependent).
   38.61   */
   38.62 -void __enter_scheduler(void)
   38.63 +static void __enter_scheduler(void)
   38.64  {
   38.65      struct exec_domain *prev = current, *next = NULL;
   38.66      int                 cpu = prev->processor;
   38.67      s_time_t            now;
   38.68 -    task_slice_t        next_slice;
   38.69 +    struct task_slice   next_slice;
   38.70      s32                 r_time;     /* time for new dom to run */
   38.71  
   38.72      perfc_incrc(sched_run);
   38.73 @@ -446,9 +443,15 @@ void __enter_scheduler(void)
   38.74  
   38.75      TRACE_2D(TRC_SCHED_SWITCH, next->domain->id, next);
   38.76  
   38.77 +    prev->sleep_tick = schedule_data[cpu].tick;
   38.78 +
   38.79      /* Ensure that the domain has an up-to-date time base. */
   38.80 -    if ( !is_idle_task(next->domain) && update_dom_time(next) )
   38.81 -        send_guest_virq(next, VIRQ_TIMER);
   38.82 +    if ( !is_idle_task(next->domain) )
   38.83 +    {
   38.84 +        update_dom_time(next);
   38.85 +        if ( next->sleep_tick != schedule_data[cpu].tick )
   38.86 +            send_guest_virq(next, VIRQ_TIMER);
   38.87 +    }
   38.88  
   38.89      context_switch(prev, next);
   38.90  }
   38.91 @@ -468,7 +471,7 @@ int idle_cpu(int cpu)
   38.92   * - dom_timer: per domain timer to specifiy timeout values
   38.93   ****************************************************************************/
   38.94  
   38.95 -/* The scheduler timer: force a run through the scheduler*/
   38.96 +/* The scheduler timer: force a run through the scheduler */
   38.97  static void s_timer_fn(unsigned long unused)
   38.98  {
   38.99      TRACE_0D(TRC_SCHED_S_TIMER_FN);
  38.100 @@ -476,20 +479,26 @@ static void s_timer_fn(unsigned long unu
  38.101      perfc_incrc(sched_irq);
  38.102  }
  38.103  
  38.104 -/* Periodic tick timer: send timer event to current domain*/
  38.105 +/* Periodic tick timer: send timer event to current domain */
  38.106  static void t_timer_fn(unsigned long unused)
  38.107  {
  38.108 -    struct exec_domain *ed = current;
  38.109 +    struct exec_domain *ed  = current;
  38.110 +    unsigned int        cpu = ed->processor;
  38.111  
  38.112      TRACE_0D(TRC_SCHED_T_TIMER_FN);
  38.113  
  38.114 -    if ( !is_idle_task(ed->domain) && update_dom_time(ed) )
  38.115 +    schedule_data[cpu].tick++;
  38.116 +
  38.117 +    if ( !is_idle_task(ed->domain) )
  38.118 +    {
  38.119 +        update_dom_time(ed);
  38.120          send_guest_virq(ed, VIRQ_TIMER);
  38.121 +    }
  38.122  
  38.123      page_scrub_schedule_work();
  38.124  
  38.125 -    t_timer[ed->processor].expires = NOW() + MILLISECS(10);
  38.126 -    add_ac_timer(&t_timer[ed->processor]);
  38.127 +    t_timer[cpu].expires = NOW() + MILLISECS(10);
  38.128 +    add_ac_timer(&t_timer[cpu]);
  38.129  }
  38.130  
  38.131  /* Domain timer function, sends a virtual timer interrupt to domain */
  38.132 @@ -498,7 +507,8 @@ static void dom_timer_fn(unsigned long d
  38.133      struct exec_domain *ed = (struct exec_domain *)data;
  38.134  
  38.135      TRACE_0D(TRC_SCHED_DOM_TIMER_FN);
  38.136 -    (void)update_dom_time(ed);
  38.137 +    
  38.138 +    update_dom_time(ed);
  38.139      send_guest_virq(ed, VIRQ_TIMER);
  38.140  }
  38.141  
    39.1 --- a/xen/drivers/char/console.c	Sat Mar 26 04:24:24 2005 +0000
    39.2 +++ b/xen/drivers/char/console.c	Fri Mar 25 22:20:40 2005 +0000
    39.3 @@ -594,8 +594,6 @@ static int __init debugtrace_init(void)
    39.4   * **************************************************************
    39.5   */
    39.6  
    39.7 -extern void trap_to_xendbg(void);
    39.8 -
    39.9  void panic(const char *fmt, ...)
   39.10  {
   39.11      va_list args;
    40.1 --- a/xen/include/asm-x86/debugger.h	Sat Mar 26 04:24:24 2005 +0000
    40.2 +++ b/xen/include/asm-x86/debugger.h	Fri Mar 25 22:20:40 2005 +0000
    40.3 @@ -30,6 +30,7 @@
    40.4  #ifndef __X86_DEBUGGER_H__
    40.5  #define __X86_DEBUGGER_H__
    40.6  
    40.7 +#include <xen/softirq.h>
    40.8  #include <asm/processor.h>
    40.9  
   40.10  /* The main trap handlers use these helper macros which include early bail. */
   40.11 @@ -40,78 +41,39 @@
   40.12  
   40.13  int call_with_registers(int (*f)(struct xen_regs *r));
   40.14  
   40.15 -#ifdef XEN_DEBUGGER
   40.16 -
   40.17 -#include <asm/pdb.h>
   40.18 -
   40.19 -static inline int debugger_trap_entry(
   40.20 -    unsigned int vector, struct xen_regs *regs)
   40.21 -{
   40.22 -    int ret = 0;
   40.23 -
   40.24 -    switch ( vector )
   40.25 -    {
   40.26 -    case TRAP_debug:
   40.27 -        if ( pdb_initialized )
   40.28 -        {
   40.29 -            pdb_handle_debug_trap(regs, regs->error_code);
   40.30 -            ret = 1; /* early exit */
   40.31 -        }
   40.32 -        break;
   40.33 -
   40.34 -    case TRAP_int3:
   40.35 -        if ( pdb_initialized && (pdb_handle_exception(vector, regs) == 0) )
   40.36 -            ret = 1; /* early exit */
   40.37 -        break;
   40.38 -
   40.39 -    case TRAP_gp_fault:        
   40.40 -        if ( (VM86_MODE(regs) || !RING_0(regs)) &&
   40.41 -             ((regs->error_code & 3) == 2) &&
   40.42 -             pdb_initialized && (pdb_ctx.system_call != 0) )
   40.43 -        {
   40.44 -            unsigned long cr3 = read_cr3();
   40.45 -            if ( cr3 == pdb_ctx.ptbr )
   40.46 -                pdb_linux_syscall_enter_bkpt(
   40.47 -                    regs, regs->error_code, 
   40.48 -                    current->thread.traps + (regs->error_code>>3));
   40.49 -        }
   40.50 -        break;
   40.51 -    }
   40.52 -
   40.53 -    return ret;
   40.54 -}
   40.55 -
   40.56 -static inline int debugger_trap_fatal(
   40.57 -    unsigned int vector, struct xen_regs *regs)
   40.58 -{
   40.59 -    int ret = 0;
   40.60 -
   40.61 -    switch ( vector )
   40.62 -    {
   40.63 -    case TRAP_page_fault:
   40.64 -        if ( pdb_page_fault_possible )
   40.65 -        {
   40.66 -            pdb_page_fault = 1;
   40.67 -            /* make eax & edx valid to complete the instruction */
   40.68 -            regs->eax = (long)&pdb_page_fault_scratch;
   40.69 -            regs->edx = (long)&pdb_page_fault_scratch;
   40.70 -            ret = 1; /* exit - do not crash! */
   40.71 -        }
   40.72 -        break;
   40.73 -    }
   40.74 -
   40.75 -    return ret;
   40.76 -}
   40.77 -
   40.78 -#define debugger_trap_immediate() ()
   40.79 -
   40.80 -#elif defined(CRASH_DEBUG)
   40.81 +#if defined(CRASH_DEBUG)
   40.82  
   40.83  extern int __trap_to_cdb(struct xen_regs *r);
   40.84  #define debugger_trap_entry(_v, _r) (0)
   40.85  #define debugger_trap_fatal(_v, _r) __trap_to_cdb(_r)
   40.86  #define debugger_trap_immediate() call_with_registers(__trap_to_cdb)
   40.87  
   40.88 +#elif defined(DOMU_DEBUG)
   40.89 +
   40.90 +static inline int debugger_trap_entry(
   40.91 +    unsigned int vector, struct xen_regs *regs)
   40.92 +{
   40.93 +    struct exec_domain *ed = current;
   40.94 +
   40.95 +    if ( !KERNEL_MODE(ed, regs) || (ed->domain->id == 0) )
   40.96 +        return 0;
   40.97 +    
   40.98 +    switch ( vector )
   40.99 +    {
  40.100 +    case TRAP_int3:
  40.101 +    case TRAP_debug:
  40.102 +        set_bit(EDF_CTRLPAUSE, &ed->ed_flags);
  40.103 +        raise_softirq(SCHEDULE_SOFTIRQ);
  40.104 +        return 1;
  40.105 +    }
  40.106 +
  40.107 +    return 0;
  40.108 +}
  40.109 +
  40.110 +#define debugger_trap_fatal(_v, _r) (0)
  40.111 +#define debugger_trap_immediate()
  40.112 +
  40.113 +
  40.114  #elif 0
  40.115  
  40.116  extern int kdb_trap(int, int, struct xen_regs *);
    41.1 --- a/xen/include/asm-x86/flushtlb.h	Sat Mar 26 04:24:24 2005 +0000
    41.2 +++ b/xen/include/asm-x86/flushtlb.h	Fri Mar 25 22:20:40 2005 +0000
    41.3 @@ -43,6 +43,26 @@ static inline int NEED_FLUSH(u32 cpu_sta
    41.4               (lastuse_stamp <= curr_time)));
    41.5  }
    41.6  
    41.7 +/*
    41.8 + * Filter the given set of CPUs, returning only those that may not have
    41.9 + * flushed their TLBs since @page_timestamp.
   41.10 + */
   41.11 +static inline unsigned long tlbflush_filter_cpuset(
   41.12 +    unsigned long cpuset, u32 page_timestamp)
   41.13 +{
   41.14 +    int i;
   41.15 +    unsigned long remain;
   41.16 +
   41.17 +    for ( i = 0, remain = ~0UL; (cpuset & remain) != 0; i++, remain <<= 1 )
   41.18 +    {
   41.19 +        if ( (cpuset & (1UL << i)) &&
   41.20 +             !NEED_FLUSH(tlbflush_time[i], page_timestamp) )
   41.21 +            cpuset &= ~(1UL << i);
   41.22 +    }
   41.23 +
   41.24 +    return cpuset;
   41.25 +}
   41.26 +
   41.27  extern void new_tlbflush_clock_period(void);
   41.28  
   41.29  /* Read pagetable base. */
    42.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Sat Mar 26 04:24:24 2005 +0000
    42.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Fri Mar 25 22:20:40 2005 +0000
    42.3 @@ -207,7 +207,7 @@ extern unsigned int opt_vmx_debug_level;
    42.4      do {                                                        \
    42.5          printk("__vmx_bug at %s:%d\n", __FILE__, __LINE__);     \
    42.6          show_registers(regs);                                   \
    42.7 -        domain_crash();                                         \
    42.8 +        domain_crash_synchronous();                             \
    42.9      } while (0)
   42.10  
   42.11  #endif /* ASM_X86_VMX_VMCS_H__ */
    44.1 --- a/xen/include/xen/sched-if.h	Sat Mar 26 04:24:24 2005 +0000
    44.2 +++ b/xen/include/xen/sched-if.h	Fri Mar 25 22:20:40 2005 +0000
    44.3 @@ -1,36 +1,31 @@
    44.4 -#include <asm/types.h>
    44.5 -
    44.6 -/*
    44.7 +/******************************************************************************
    44.8   * Additional declarations for the generic scheduler interface.  This should
    44.9   * only be included by files that implement conforming schedulers.
   44.10   *
   44.11   * Portions by Mark Williamson are (C) 2004 Intel Research Cambridge
   44.12   */
   44.13  
   44.14 -#define BUCKETS 10
   44.15 +#ifndef __XEN_SCHED_IF_H__
   44.16 +#define __XEN_SCHED_IF_H__
   44.17  
   44.18 -typedef struct schedule_data_st
   44.19 -{
   44.20 -    spinlock_t          schedule_lock;  /* spinlock protecting curr pointer
   44.21 -                                            TODO check this */
   44.22 -    struct exec_domain  *curr;          /* current task */
   44.23 -    struct exec_domain  *idle;          /* idle task for this cpu */
   44.24 -    void *              sched_priv;
   44.25 -    struct ac_timer     s_timer;        /* scheduling timer  */
   44.26 +struct schedule_data {
   44.27 +    spinlock_t          schedule_lock;  /* spinlock protecting curr        */
   44.28 +    struct exec_domain *curr;           /* current task                    */
   44.29 +    struct exec_domain *idle;           /* idle task for this cpu          */
   44.30 +    void               *sched_priv;
   44.31 +    struct ac_timer     s_timer;        /* scheduling timer                */
   44.32 +    unsigned long       tick;           /* current periodic 'tick'         */
   44.33  #ifdef BUCKETS
   44.34      u32                 hist[BUCKETS];  /* for scheduler latency histogram */
   44.35  #endif
   44.36 -} __cacheline_aligned schedule_data_t;
   44.37 -
   44.38 +} __cacheline_aligned;
   44.39  
   44.40 -typedef struct task_slice_st
   44.41 -{
   44.42 +struct task_slice {
   44.43      struct exec_domain *task;
   44.44      s_time_t            time;
   44.45 -} task_slice_t;
   44.46 +};
   44.47  
   44.48 -struct scheduler
   44.49 -{
   44.50 +struct scheduler {
   44.51      char *name;             /* full name for this scheduler      */
   44.52      char *opt_name;         /* option name for this scheduler    */
   44.53      unsigned int sched_id;  /* ID for this scheduler             */
   44.54 @@ -44,7 +39,7 @@ struct scheduler
   44.55      void         (*sleep)          (struct exec_domain *);
   44.56      void         (*wake)           (struct exec_domain *);
   44.57      void         (*do_block)       (struct exec_domain *);
   44.58 -    task_slice_t (*do_schedule)    (s_time_t);
   44.59 +    struct task_slice (*do_schedule) (s_time_t);
   44.60      int          (*control)        (struct sched_ctl_cmd *);
   44.61      int          (*adjdom)         (struct domain *,
   44.62                                      struct sched_adjdom_cmd *);
   44.63 @@ -53,7 +48,6 @@ struct scheduler
   44.64      int          (*prn_state)      (int);
   44.65  };
   44.66  
   44.67 -/* per CPU scheduler information */
   44.68 -extern schedule_data_t schedule_data[];
   44.69 +extern struct schedule_data schedule_data[];
   44.70  
   44.71 -
   44.72 +#endif /* __XEN_SCHED_IF_H__ */
    45.1 --- a/xen/include/xen/sched.h	Sat Mar 26 04:24:24 2005 +0000
    45.2 +++ b/xen/include/xen/sched.h	Fri Mar 25 22:20:40 2005 +0000
    45.3 @@ -73,6 +73,7 @@ struct exec_domain
    45.4  #endif
    45.5  
    45.6      struct ac_timer  timer;         /* one-shot timer for timeout values */
    45.7 +    unsigned long    sleep_tick;    /* tick at which this vcpu started sleep */
    45.8  
    45.9      s_time_t         lastschd;      /* time this domain was last scheduled */
   45.10      s_time_t         lastdeschd;    /* time this domain was last descheduled */
   45.11 @@ -96,7 +97,6 @@ struct exec_domain
   45.12  struct domain
   45.13  {
   45.14      domid_t          id;
   45.15 -    s_time_t         create_time;
   45.16  
   45.17      shared_info_t   *shared_info;     /* shared data area */
   45.18      spinlock_t       time_lock;
   45.19 @@ -214,11 +214,21 @@ extern int construct_dom0(
   45.20  extern int set_info_guest(struct domain *d, dom0_setdomaininfo_t *);
   45.21  
   45.22  struct domain *find_domain_by_id(domid_t dom);
   45.23 -struct domain *find_last_domain(void);
   45.24  extern void domain_destruct(struct domain *d);
   45.25  extern void domain_kill(struct domain *d);
   45.26 +extern void domain_shutdown(u8 reason);
   45.27 +
   45.28 +/*
   45.29 + * Mark current domain as crashed. This function returns: the domain is not
   45.30 + * synchronously descheduled from any processor.
   45.31 + */
   45.32  extern void domain_crash(void);
   45.33 -extern void domain_shutdown(u8 reason);
   45.34 +
   45.35 +/*
   45.36 + * Mark current domain as crashed and synchronously deschedule from the local
   45.37 + * processor. This function never returns.
   45.38 + */
   45.39 +extern void domain_crash_synchronous(void) __attribute__((noreturn));
   45.40  
   45.41  void new_thread(struct exec_domain *d,
   45.42                  unsigned long start_pc,
   45.43 @@ -240,8 +250,6 @@ void init_idle_task(void);
   45.44  void domain_wake(struct exec_domain *d);
   45.45  void domain_sleep(struct exec_domain *d);
   45.46  
   45.47 -void __enter_scheduler(void);
   45.48 -
   45.49  extern void context_switch(
   45.50      struct exec_domain *prev, 
   45.51      struct exec_domain *next);
   45.52 @@ -391,7 +399,6 @@ static inline void domain_unpause_by_sys
   45.53  #include <xen/slab.h>
   45.54  #include <xen/domain.h>
   45.55  
   45.56 -
   45.57  #endif /* __SCHED_H__ */
   45.58  
   45.59  /*
    46.1 --- a/xen/include/xen/time.h	Sat Mar 26 04:24:24 2005 +0000
    46.2 +++ b/xen/include/xen/time.h	Fri Mar 25 22:20:40 2005 +0000
    46.3 @@ -54,9 +54,9 @@ s_time_t get_s_time(void);
    46.4  #define MILLISECS(_ms)  (((s_time_t)(_ms)) * 1000000ULL )
    46.5  #define MICROSECS(_us)  (((s_time_t)(_us)) * 1000ULL )
    46.6  
    46.7 -extern int update_dom_time(struct exec_domain *ed);
    46.8 -extern void do_settime(unsigned long secs, unsigned long usecs, 
    46.9 -                       u64 system_time_base);
   46.10 +extern void update_dom_time(struct exec_domain *ed);
   46.11 +extern void do_settime(
   46.12 +    unsigned long secs, unsigned long usecs, u64 system_time_base);
   46.13  
   46.14  #endif /* __XEN_TIME_H__ */
   46.15