direct-io.hg

changeset 3455:cee684f223ee

bitkeeper revision 1.1159.1.533 (41ecc89bWaePyLiGCXOPZDHk26NUNw)

Merge tempest.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into tempest.cl.cam.ac.uk:/local/scratch/smh22/xen-unstable.bk
author smh22@tempest.cl.cam.ac.uk
date Tue Jan 18 08:28:11 2005 +0000 (2005-01-18)
parents 657d51f27c5b 3c69b6ca4021
children 9e77c2678efa
files linux-2.4.28-xen-sparse/arch/xen/defconfig-xen0 linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c tools/examples/xmexample1 tools/examples/xmexample2 tools/libxc/xc.h tools/libxc/xc_linux_build.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/blkif.py tools/python/xen/xm/create.py xen/arch/x86/domain.c xen/arch/x86/memory.c xen/arch/x86/x86_32/mm.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/linux-2.4.28-xen-sparse/arch/xen/defconfig-xen0	Fri Jan 14 12:28:03 2005 +0000
     1.2 +++ b/linux-2.4.28-xen-sparse/arch/xen/defconfig-xen0	Tue Jan 18 08:28:11 2005 +0000
     1.3 @@ -554,7 +554,7 @@ CONFIG_E100=y
     1.4  # CONFIG_LNE390 is not set
     1.5  # CONFIG_FEALNX is not set
     1.6  # CONFIG_NATSEMI is not set
     1.7 -# CONFIG_NE2K_PCI is not set
     1.8 +CONFIG_NE2K_PCI=y
     1.9  # CONFIG_FORCEDETH is not set
    1.10  # CONFIG_NE3210 is not set
    1.11  # CONFIG_ES3210 is not set
     2.1 --- a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig	Fri Jan 14 12:28:03 2005 +0000
     2.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig	Tue Jan 18 08:28:11 2005 +0000
     2.3 @@ -641,7 +641,7 @@ CONFIG_E100=y
     2.4  # CONFIG_E100_NAPI is not set
     2.5  # CONFIG_FEALNX is not set
     2.6  # CONFIG_NATSEMI is not set
     2.7 -# CONFIG_NE2K_PCI is not set
     2.8 +CONFIG_NE2K_PCI=y
     2.9  # CONFIG_8139CP is not set
    2.10  CONFIG_8139TOO=y
    2.11  CONFIG_8139TOO_PIO=y
     3.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S	Fri Jan 14 12:28:03 2005 +0000
     3.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S	Tue Jan 18 08:28:11 2005 +0000
     3.3 @@ -93,8 +93,9 @@ VM_MASK		= 0x00020000
     3.4  #define XEN_UNLOCK_VCPU_INFO_SMP(reg) preempt_enable(%ebp)
     3.5  #define XEN_UNLOCK_VCPU_INFO_SMP_fixup .byte 0xff,0xff,0xff
     3.6  #define Ux00 0xff
     3.7 +#define XEN_LOCKED_BLOCK_EVENTS(reg)	movb $1,evtchn_upcall_mask(reg)
     3.8  #define XEN_BLOCK_EVENTS(reg)	XEN_LOCK_VCPU_INFO_SMP(reg)		; \
     3.9 -				movb $1,evtchn_upcall_mask(reg)		; \
    3.10 +				XEN_LOCKED_BLOCK_EVENTS(reg)		; \
    3.11      				XEN_UNLOCK_VCPU_INFO_SMP(reg)
    3.12  #define XEN_UNBLOCK_EVENTS(reg)	XEN_LOCK_VCPU_INFO_SMP(reg)		; \
    3.13  				movb $0,evtchn_upcall_mask(reg)		; \
    3.14 @@ -110,7 +111,8 @@ VM_MASK		= 0x00020000
    3.15  #define XEN_UNLOCK_VCPU_INFO_SMP(reg)
    3.16  #define XEN_UNLOCK_VCPU_INFO_SMP_fixup
    3.17  #define Ux00 0x00
    3.18 -#define XEN_BLOCK_EVENTS(reg)	movb $1,evtchn_upcall_mask(reg)
    3.19 +#define XEN_LOCKED_BLOCK_EVENTS(reg)	movb $1,evtchn_upcall_mask(reg)
    3.20 +#define XEN_BLOCK_EVENTS(reg)	XEN_LOCKED_BLOCK_EVENTS(reg)
    3.21  #define XEN_UNBLOCK_EVENTS(reg)	movb $0,evtchn_upcall_mask(reg)
    3.22  #define XEN_SAVE_UPCALL_MASK(reg,tmp,off) \
    3.23  	movb evtchn_upcall_mask(reg), tmp; \
    3.24 @@ -510,7 +512,7 @@ scrit:	/**** START OF CRITICAL REGION **
    3.25  	jnz  14f			# process more events if necessary...
    3.26  	XEN_UNLOCK_VCPU_INFO_SMP(%esi)
    3.27  	RESTORE_ALL
    3.28 -14:	XEN_BLOCK_EVENTS(%esi)
    3.29 +14:	XEN_LOCKED_BLOCK_EVENTS(%esi)
    3.30  	XEN_UNLOCK_VCPU_INFO_SMP(%esi)
    3.31  	jmp  11b
    3.32  ecrit:  /**** END OF CRITICAL REGION ****/
     4.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Jan 14 12:28:03 2005 +0000
     4.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c	Tue Jan 18 08:28:11 2005 +0000
     4.3 @@ -162,7 +162,7 @@ static inline void flush_requests(void)
     4.4  
     4.5  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     4.6  
     4.7 -__initcall(xlblk_init);
     4.8 +module_init(xlblk_init);
     4.9  
    4.10  #if ENABLE_VBD_UPDATE
    4.11  static void vbd_update(void)
     5.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c	Fri Jan 14 12:28:03 2005 +0000
     5.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c	Tue Jan 18 08:28:11 2005 +0000
     5.3 @@ -257,7 +257,7 @@ static int netctrl_connected_count(void)
     5.4   * @param dev device
     5.5   * @return 0 on success, error code otherwise
     5.6   */
     5.7 -static int vif_wake(struct net_device *dev)
     5.8 +static int send_fake_arp(struct net_device *dev)
     5.9  {
    5.10      struct sk_buff *skb;
    5.11      u32             src_ip, dst_ip;
    5.12 @@ -265,10 +265,15 @@ static int vif_wake(struct net_device *d
    5.13      dst_ip = INADDR_BROADCAST;
    5.14      src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK);
    5.15  
    5.16 +    /* No IP? Then nothing to do. */
    5.17 +    if ( src_ip == 0 )
    5.18 +        return 0;
    5.19 +
    5.20      skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
    5.21                       dst_ip, dev, src_ip,
    5.22                       /*dst_hw*/ NULL, /*src_hw*/ NULL, 
    5.23                       /*target_hw*/ dev->dev_addr);
    5.24 +    printk(KERN_ALERT "ARP sent on %08x %08x %p\n", dst_ip, src_ip, skb);
    5.25      if ( skb == NULL )
    5.26          return -ENOMEM;
    5.27  
    5.28 @@ -822,13 +827,11 @@ static void send_interface_connect(struc
    5.29      };
    5.30      netif_fe_interface_connect_t *msg = (void*)cmsg.msg;
    5.31  
    5.32 -    DPRINTK(">\n"); vif_show(np); 
    5.33      msg->handle = np->handle;
    5.34      msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT);
    5.35      msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT);
    5.36          
    5.37      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
    5.38 -    DPRINTK("<\n");
    5.39  }
    5.40  
    5.41  /* Send a driver status notification to the domain controller. */
    5.42 @@ -876,13 +879,12 @@ static void vif_release(struct net_priva
    5.43   */
    5.44  static void vif_close(struct net_private *np)
    5.45  {
    5.46 -    DPRINTK(">\n"); vif_show(np);
    5.47      WPRINTK("Unexpected netif-CLOSED message in state %s\n",
    5.48              be_state_name[np->backend_state]);
    5.49      vif_release(np);
    5.50      np->backend_state = BEST_CLOSED;
    5.51      /* todo: take dev down and free. */
    5.52 -    vif_show(np); DPRINTK("<\n");
    5.53 +    vif_show(np);
    5.54  }
    5.55  
    5.56  /* Move the vif into disconnected state.
    5.57 @@ -891,7 +893,6 @@ static void vif_close(struct net_private
    5.58   */
    5.59  static void vif_disconnect(struct net_private *np)
    5.60  {
    5.61 -    DPRINTK(">\n");
    5.62      if(np->tx) free_page((unsigned long)np->tx);
    5.63      if(np->rx) free_page((unsigned long)np->rx);
    5.64      // Before this np->tx and np->rx had better be null.
    5.65 @@ -901,7 +902,7 @@ static void vif_disconnect(struct net_pr
    5.66      memset(np->rx, 0, PAGE_SIZE);
    5.67      np->backend_state = BEST_DISCONNECTED;
    5.68      send_interface_connect(np);
    5.69 -    vif_show(np); DPRINTK("<\n");
    5.70 +    vif_show(np);
    5.71  }
    5.72  
    5.73  /* Begin interface recovery.
    5.74 @@ -921,12 +922,11 @@ static void
    5.75  vif_reset(
    5.76      struct net_private *np)
    5.77  {
    5.78 -    DPRINTK(">\n");
    5.79      IPRINTK("Attempting to reconnect network interface: handle=%u\n",
    5.80              np->handle);    
    5.81      vif_release(np);
    5.82      vif_disconnect(np);
    5.83 -    vif_show(np); DPRINTK("<\n");
    5.84 +    vif_show(np);
    5.85  }
    5.86  
    5.87  /* Move the vif into connected state.
    5.88 @@ -938,15 +938,14 @@ vif_connect(
    5.89      struct net_private *np, netif_fe_interface_status_t *status)
    5.90  {
    5.91      struct net_device *dev = np->dev;
    5.92 -    DPRINTK(">\n");
    5.93      memcpy(dev->dev_addr, status->mac, ETH_ALEN);
    5.94      network_connect(dev, status);
    5.95      np->evtchn = status->evtchn;
    5.96      np->irq = bind_evtchn_to_irq(np->evtchn);
    5.97      (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
    5.98      netctrl_connected_count();
    5.99 -    vif_wake(dev);
   5.100 -    vif_show(np); DPRINTK("<\n");
   5.101 +    (void)send_fake_arp(dev);
   5.102 +    vif_show(np);
   5.103  }
   5.104  
   5.105  
   5.106 @@ -1058,7 +1057,6 @@ static void netif_interface_status(netif
   5.107      int err = 0;
   5.108      struct net_private *np = NULL;
   5.109      
   5.110 -    DPRINTK(">\n");
   5.111      DPRINTK("> status=%s handle=%d\n",
   5.112              status_name[status->status], status->handle);
   5.113  
   5.114 @@ -1074,8 +1072,6 @@ static void netif_interface_status(netif
   5.115          return;
   5.116      }
   5.117  
   5.118 -    DPRINTK(">\n"); vif_show(np);
   5.119 -
   5.120      switch ( status->status )
   5.121      {
   5.122      case NETIF_INTERFACE_STATUS_CLOSED:
   5.123 @@ -1129,8 +1125,8 @@ static void netif_interface_status(netif
   5.124          WPRINTK("Invalid netif status code %d\n", status->status);
   5.125          break;
   5.126      }
   5.127 +
   5.128      vif_show(np);
   5.129 -    DPRINTK("<\n");
   5.130  }
   5.131  
   5.132  /*
   5.133 @@ -1138,10 +1134,7 @@ static void netif_interface_status(netif
   5.134   */
   5.135  static void netif_driver_status(netif_fe_driver_status_t *status)
   5.136  {
   5.137 -    DPRINTK("> status=%d\n", status->status);
   5.138      netctrl.up = status->status;
   5.139 -    //netctrl.interface_n = status->max_handle;
   5.140 -    //netctrl.connected_n = 0;
   5.141      netctrl_connected_count();
   5.142  }
   5.143  
   5.144 @@ -1266,6 +1259,39 @@ static int probe_interfaces(void)
   5.145  
   5.146  #endif
   5.147  
   5.148 +/*
   5.149 + * We use this notifier to send out a fake ARP reply to reset switches and
   5.150 + * router ARP caches when an IP interface is brought up on a VIF.
   5.151 + */
   5.152 +static int inetdev_notify(struct notifier_block *this, 
   5.153 +                          unsigned long event, 
   5.154 +                          void *ptr)
   5.155 +{
   5.156 +    struct in_ifaddr  *ifa = (struct in_ifaddr *)ptr; 
   5.157 +    struct net_device *dev = ifa->ifa_dev->dev;
   5.158 +    struct list_head  *ent;
   5.159 +    struct net_private *np;
   5.160 +
   5.161 +    if ( event != NETDEV_UP )
   5.162 +        goto out;
   5.163 +
   5.164 +    list_for_each ( ent, &dev_list )
   5.165 +    {
   5.166 +        np = list_entry(ent, struct net_private, list);
   5.167 +        if ( np->dev == dev )
   5.168 +            (void)send_fake_arp(dev);
   5.169 +    }
   5.170 +        
   5.171 + out:
   5.172 +    return NOTIFY_DONE;
   5.173 +}
   5.174 +
   5.175 +static struct notifier_block notifier_inetdev = {
   5.176 +    .notifier_call  = inetdev_notify,
   5.177 +    .next           = NULL,
   5.178 +    .priority       = 0
   5.179 +};
   5.180 +
   5.181  static int __init netif_init(void)
   5.182  {
   5.183      int err = 0;
   5.184 @@ -1276,6 +1302,7 @@ static int __init netif_init(void)
   5.185  
   5.186      IPRINTK("Initialising virtual ethernet driver.\n");
   5.187      INIT_LIST_HEAD(&dev_list);
   5.188 +    (void)register_inetaddr_notifier(&notifier_inetdev);
   5.189      netctrl_init();
   5.190      (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
   5.191                                      CALLBACK_IN_BLOCKING_CONTEXT);
   5.192 @@ -1290,57 +1317,48 @@ static int __init netif_init(void)
   5.193  
   5.194  static void vif_suspend(struct net_private *np)
   5.195  {
   5.196 -    // Avoid having tx/rx stuff happen until we're ready.
   5.197 -    DPRINTK(">\n");
   5.198 +    /* Avoid having tx/rx stuff happen until we're ready. */
   5.199      free_irq(np->irq, np->dev);
   5.200      unbind_evtchn_from_irq(np->evtchn);
   5.201 -    DPRINTK("<\n");
   5.202  }
   5.203  
   5.204  static void vif_resume(struct net_private *np)
   5.205  {
   5.206 -    // Connect regardless of whether IFF_UP flag set.
   5.207 -    // Stop bad things from happening until we're back up.
   5.208 -    DPRINTK(">\n");
   5.209 +    /*
   5.210 +     * Connect regardless of whether IFF_UP flag set.
   5.211 +     * Stop bad things from happening until we're back up.
   5.212 +     */
   5.213      np->backend_state = BEST_DISCONNECTED;
   5.214      memset(np->tx, 0, PAGE_SIZE);
   5.215      memset(np->rx, 0, PAGE_SIZE);
   5.216      
   5.217      send_interface_connect(np);
   5.218 -    DPRINTK("<\n");
   5.219  }
   5.220  
   5.221  void netif_suspend(void)
   5.222  {
   5.223 -#if 1 /* XXX THIS IS TEMPORARY */
   5.224      struct list_head *ent;
   5.225      struct net_private *np;
   5.226      
   5.227 -    DPRINTK(">\n");
   5.228 -    list_for_each(ent, &dev_list){
   5.229 +    list_for_each ( ent, &dev_list )
   5.230 +    {
   5.231          np = list_entry(ent, struct net_private, list);
   5.232          vif_suspend(np);
   5.233      }
   5.234 -    DPRINTK("<\n");
   5.235 -#endif
   5.236  }
   5.237  
   5.238  void netif_resume(void)
   5.239  {
   5.240 -#if 1
   5.241 -    /* XXX THIS IS TEMPORARY */
   5.242      struct list_head *ent;
   5.243      struct net_private *np;
   5.244  
   5.245 -    DPRINTK(">\n");
   5.246      list_for_each ( ent, &dev_list )
   5.247      {
   5.248          np = list_entry(ent, struct net_private, list);
   5.249          vif_resume(np);
   5.250      }
   5.251 -    DPRINTK("<\n");
   5.252 -#endif	    
   5.253  }
   5.254  
   5.255  
   5.256 -__initcall(netif_init);
   5.257 +module_init(netif_init);
   5.258 +
     6.1 --- a/tools/examples/xmexample1	Fri Jan 14 12:28:03 2005 +0000
     6.2 +++ b/tools/examples/xmexample1	Tue Jan 18 08:28:11 2005 +0000
     6.3 @@ -25,6 +25,9 @@ name = "ExampleDomain"
     6.4  # Which CPU to start domain on? 
     6.5  #cpu = -1   # leave to Xen to pick
     6.6  
     6.7 +# Number of Virtual CPUS to use, default is 1
     6.8 +#vcpus = 1
     6.9 +
    6.10  #----------------------------------------------------------------------------
    6.11  # Define network interfaces.
    6.12  
     7.1 --- a/tools/examples/xmexample2	Fri Jan 14 12:28:03 2005 +0000
     7.2 +++ b/tools/examples/xmexample2	Tue Jan 18 08:28:11 2005 +0000
     7.3 @@ -55,6 +55,10 @@ name = "VM%d" % vmid
     7.4  #cpu = -1   # leave to Xen to pick
     7.5  cpu = vmid  # set based on vmid (mod number of CPUs)
     7.6  
     7.7 +# Number of Virtual CPUS to use, default is 1
     7.8 +#vcpus = 1
     7.9 +vcpus = 4 # make your domain a 4-way
    7.10 +
    7.11  #----------------------------------------------------------------------------
    7.12  # Define network interfaces.
    7.13  
     8.1 --- a/tools/libxc/xc.h	Fri Jan 14 12:28:03 2005 +0000
     8.2 +++ b/tools/libxc/xc.h	Tue Jan 18 08:28:11 2005 +0000
     8.3 @@ -25,10 +25,40 @@ typedef int64_t            s64;
     8.4  #include <xen/event_channel.h>
     8.5  #include <xen/sched_ctl.h>
     8.6  
     8.7 -/* Obtain or relinquish a handle on the 'xc' library. */
     8.8 +/*\
     8.9 + *  INITIALIZATION FUNCTIONS
    8.10 +\*/ 
    8.11 +
    8.12 +/**
    8.13 + * This function opens a handle to the hypervisor interface.  This function can
    8.14 + * be called multiple times within a single process.  Multiple processes can
    8.15 + * have an open hypervisor interface at the same time.
    8.16 + *
    8.17 + * Each call to this function should have a corresponding call to
    8.18 + * xc_interface_close().
    8.19 + *
    8.20 + * This function can fail if the caller does not have superuser permission or
    8.21 + * if a Xen-enabled kernel is not currently running.
    8.22 + *
    8.23 + * @return a handle to the hypervisor interface or -1 on failure
    8.24 + */
    8.25  int xc_interface_open(void);
    8.26 +
    8.27 +/**
    8.28 + * This function closes an open hypervisor interface.
    8.29 + *
    8.30 + * This function can fail if the handle does not represent an open interface or
    8.31 + * if there were problems closing the interface.
    8.32 + *
    8.33 + * @parm xc_handle a handle to an open hypervisor interface
    8.34 + * @return 0 on success, -1 otherwise.
    8.35 + */
    8.36  int xc_interface_close(int xc_handle);
    8.37  
    8.38 +/*\
    8.39 + * DOMAIN MANAGEMENT FUNCTIONS
    8.40 +\*/
    8.41 +
    8.42  typedef struct {
    8.43      u32           domid;
    8.44      unsigned int  cpu;
    8.45 @@ -47,19 +77,69 @@ int xc_domain_create(int xc_handle,
    8.46                       int cpu,
    8.47                       float cpu_weight,
    8.48                       u32 *pdomid);
    8.49 +
    8.50 +/**
    8.51 + * This function pauses a domain. A paused domain still exists in memory
    8.52 + * however it does not receive any timeslices from the hypervisor.
    8.53 + *
    8.54 + * @parm xc_handle a handle to an open hypervisor interface
    8.55 + * @parm domid the domain id to pause
    8.56 + * @return 0 on success, -1 on failure.
    8.57 + */
    8.58  int xc_domain_pause(int xc_handle, 
    8.59                      u32 domid);
    8.60 +/**
    8.61 + * This function unpauses a domain.  The domain should have been previously
    8.62 + * paused.
    8.63 + *
    8.64 + * @parm xc_handle a handle to an open hypervisor interface
    8.65 + * @parm domid the domain id to unpause
    8.66 + * return 0 on success, -1 on failure
    8.67 + */
    8.68  int xc_domain_unpause(int xc_handle, 
    8.69                        u32 domid);
    8.70 +
    8.71 +/**
    8.72 + * This function will destroy a domain.  Destroying a domain removes the domain
    8.73 + * completely from memory.  This function should be called after sending the
    8.74 + * domain a SHUTDOWN control message to free up the domain resources.
    8.75 + *
    8.76 + * @parm xc_handle a handle to an open hypervisor interface
    8.77 + * @parm domid the domain id to destroy
    8.78 + * @return 0 on success, -1 on failure
    8.79 + */
    8.80  int xc_domain_destroy(int xc_handle, 
    8.81                        u32 domid);
    8.82  int xc_domain_pincpu(int xc_handle,
    8.83                       u32 domid,
    8.84                       int cpu);
    8.85 +/**
    8.86 + * This function will return information about one or more domains.
    8.87 + *
    8.88 + * @parm xc_handle a handle to an open hypervisor interface
    8.89 + * @parm first_domid the first domain to enumerate information from.  Domains
    8.90 + *                   are currently enumerate in order of creation.
    8.91 + * @parm max_doms the number of elements in info
    8.92 + * @parm info an array of max_doms size that will contain the information for
    8.93 + *            the enumerated domains.
    8.94 + * @return the number of domains enumerated or -1 on error
    8.95 + */
    8.96  int xc_domain_getinfo(int xc_handle,
    8.97                        u32 first_domid, 
    8.98                        unsigned int max_doms,
    8.99                        xc_dominfo_t *info);
   8.100 +
   8.101 +/**
   8.102 + * This function returns information about one domain.  This information is
   8.103 + * more detailed than the information from xc_domain_getinfo().
   8.104 + *
   8.105 + * @parm xc_handle a handle to an open hypervisor interface
   8.106 + * @parm domid the domain to get information from
   8.107 + * @parm info a pointer to an xc_domaininfo_t to store the domain information
   8.108 + * @parm ctxt a pointer to a structure to store the execution context of the
   8.109 + *            domain
   8.110 + * @return 0 on success, -1 on failure
   8.111 + */
   8.112  int xc_domain_getfullinfo(int xc_handle,
   8.113                            u32 domid,
   8.114                            u32 vcpu,
   8.115 @@ -88,7 +168,27 @@ int xc_shadow_control(int xc_handle,
   8.116  #define XCFLAGS_CONFIGURE 8
   8.117  
   8.118  struct XcIOContext;
   8.119 +
   8.120 +/**
   8.121 + * This function will save a domain running Linux to an IO context.  This
   8.122 + * IO context is currently a private interface making this function difficult
   8.123 + * to call.  It's interface will likely change in the future.
   8.124 + *
   8.125 + * @parm xc_handle a handle to an open hypervisor interface
   8.126 + * @parm ioctxt the IO context to save a domain to
   8.127 + * @return 0 on success, -1 on failure
   8.128 + */
   8.129  int xc_linux_save(int xc_handle, struct XcIOContext *ioctxt);
   8.130 +
   8.131 +/**
   8.132 + * This function will restore a saved domain running Linux to an IO context.
   8.133 + * Like xc_linux_save(), this function uses a parameter who's structure is
   8.134 + * privately defined.  It's interface will also likely change.
   8.135 + *
   8.136 + * @parm xc_handle a handle to an open hypervisor interface
   8.137 + * @parm ioctxt the IO context to restore a domain from
   8.138 + * @return 0 on success, -1 on failure
   8.139 + */
   8.140  int xc_linux_restore(int xc_handle, struct XcIOContext *ioctxt);
   8.141  
   8.142  int xc_linux_build(int xc_handle,
   8.143 @@ -97,7 +197,8 @@ int xc_linux_build(int xc_handle,
   8.144                     const char *ramdisk_name,
   8.145                     const char *cmdline,
   8.146                     unsigned int control_evtchn,
   8.147 -                   unsigned long flags);
   8.148 +                   unsigned long flags,
   8.149 +                   unsigned int vcpus);
   8.150  
   8.151  int
   8.152  xc_plan9_build (int xc_handle,
   8.153 @@ -154,20 +255,75 @@ int xc_rrobin_global_set(int xc_handle, 
   8.154  int xc_rrobin_global_get(int xc_handle, u64 *slice);
   8.155  
   8.156  typedef evtchn_status_t xc_evtchn_status_t;
   8.157 +
   8.158 +/*\
   8.159 + * EVENT CHANNEL FUNCTIONS
   8.160 +\*/
   8.161 +
   8.162 +/**
   8.163 + * This function allocates an unbound port.  Ports are named endpoints used for
   8.164 + * interdomain communication.  This function is most useful in opening a
   8.165 + * well-known port within a domain to receive events on.
   8.166 + *
   8.167 + * @parm xc_handle a handle to an open hypervisor interface
   8.168 + * @parm dom the ID of the domain.  This maybe DOMID_SELF
   8.169 + * @parm port a pointer to a port.  This is an in/out parameter.  If *port is
   8.170 + *            0, then a new port will be assigned, if port is > 0 then that
   8.171 + *            port is allocated if the port is unallocated.
   8.172 + * @return 0 on success, -1 on failure
   8.173 + */
   8.174  int xc_evtchn_alloc_unbound(int xc_handle,
   8.175                              u32 dom,
   8.176                              int *port);
   8.177 +
   8.178 +/**
   8.179 + * This function creates a pair of ports between two domains.  A port can only
   8.180 + * be bound once within a domain.
   8.181 + *
   8.182 + * @parm xc_handle a handle to an open hypervisor interface
   8.183 + * @parm dom1 one of the two domains to connect.  Can be DOMID_SELF.
   8.184 + * @parm dom2 the other domain to connect.  Can be DOMID_SELF.
   8.185 + * @parm port1 an in/out parameter.  If > 0, then try to connect *port.  If
   8.186 + *             0, then allocate a new port and store the port in *port.
   8.187 + * @parm port2 the port connected on port2.  This parameter behaves the same
   8.188 + *             way as port1.
   8.189 + * @return 0 on success, -1 on error.
   8.190 + */
   8.191  int xc_evtchn_bind_interdomain(int xc_handle,
   8.192 -                               u32 dom1,   /* may be DOMID_SELF */
   8.193 -                               u32 dom2,   /* may be DOMID_SELF */
   8.194 +                               u32 dom1,
   8.195 +                               u32 dom2,
   8.196                                 int *port1,
   8.197                                 int *port2);
   8.198  int xc_evtchn_bind_virq(int xc_handle,
   8.199                          int virq,
   8.200                          int *port);
   8.201 +
   8.202 +/**
   8.203 + * This function will close a single port on an event channel.
   8.204 + *
   8.205 + * @parm xc_handle a handle to an open hypervisor interface
   8.206 + * @parm dom the domain that the port exists on.  May be DOMID_SELF.
   8.207 + * @parm port the port to close
   8.208 + * @return 0 on success, -1 on error
   8.209 + */
   8.210  int xc_evtchn_close(int xc_handle,
   8.211                      u32 dom,   /* may be DOMID_SELF */
   8.212                      int port);
   8.213 +
   8.214 +/**
   8.215 + * This function generates a notify event on a bound port.
   8.216 + *
   8.217 + * Notifies can be read within Linux by opening /dev/xen/evtchn and reading
   8.218 + * a 16 bit value.  The result will be the port the event occurred on.  When
   8.219 + * events occur, the port is masked until the 16 bit port value is written back
   8.220 + * to the file.  When /dev/xen/evtchn is opened, it has to be bound via an
   8.221 + * ioctl to each port to listen on.  The ioctl for binding is _IO('E', 2).  The
   8.222 + * parameter is the port to listen on.
   8.223 + *
   8.224 + * @parm xc_handle a handle to an open hypervisor interface
   8.225 + * @parm local_port the port to generate the notify on
   8.226 + * @return 0 on success, -1 on error
   8.227 + */
   8.228  int xc_evtchn_send(int xc_handle,
   8.229                     int local_port);
   8.230  int xc_evtchn_status(int xc_handle,
   8.231 @@ -213,6 +369,21 @@ int xc_perfc_control(int xc_handle,
   8.232                       u32 op,
   8.233                       xc_perfc_desc_t *desc);
   8.234  
   8.235 +/**
   8.236 + * Memory maps a range within one domain to a local address range.  Mappings
   8.237 + * should be unmapped with munmap and should follow the same rules as mmap
   8.238 + * regarding page alignment.
   8.239 + *
   8.240 + * In Linux, the ring queue for the control channel is accessible by mapping
   8.241 + * the shared_info_frame (from xc_domain_getinfo()) + 2048.  The structure
   8.242 + * stored there is of type control_if_t.
   8.243 + *
   8.244 + * @parm xc_handle a handle on an open hypervisor interface
   8.245 + * @parm dom the domain to map memory from
   8.246 + * @parm size the amount of memory to map (in multiples of page size)
   8.247 + * @parm prot same flag as in mmap().
   8.248 + * @parm mfn the frame address to map.
   8.249 + */
   8.250  void *xc_map_foreign_range(int xc_handle, u32 dom,
   8.251                              int size, int prot,
   8.252                              unsigned long mfn );
     9.1 --- a/tools/libxc/xc_linux_build.c	Fri Jan 14 12:28:03 2005 +0000
     9.2 +++ b/tools/libxc/xc_linux_build.c	Tue Jan 18 08:28:11 2005 +0000
     9.3 @@ -51,7 +51,8 @@ static int setup_guestos(int xc_handle,
     9.4                           const char *cmdline,
     9.5                           unsigned long shared_info_frame,
     9.6                           unsigned int control_evtchn,
     9.7 -                         unsigned long flags)
     9.8 +                         unsigned long flags,
     9.9 +                         unsigned int vcpus)
    9.10  {
    9.11      l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
    9.12      l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
    9.13 @@ -81,8 +82,6 @@ static int setup_guestos(int xc_handle,
    9.14      unsigned long vpt_end;
    9.15      unsigned long v_end;
    9.16  
    9.17 -    char *n_vcpus;
    9.18 -
    9.19      memset(&dsi, 0, sizeof(struct domain_setup_info));
    9.20  
    9.21      rc = parseelfimage(image, image_size, &dsi);
    9.22 @@ -291,11 +290,10 @@ static int setup_guestos(int xc_handle,
    9.23      /* Mask all upcalls... */
    9.24      for ( i = 0; i < MAX_VIRT_CPUS; i++ )
    9.25          shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
    9.26 -    n_vcpus = getenv("XEN_VCPUS");
    9.27 -    if ( n_vcpus )
    9.28 -	shared_info->n_vcpu = atoi(n_vcpus);
    9.29 -    else
    9.30 -	shared_info->n_vcpu = 1;
    9.31 +
    9.32 +    shared_info->n_vcpu = vcpus;
    9.33 +    printf(" VCPUS:         %d\n", shared_info->n_vcpu);
    9.34 +
    9.35      munmap(shared_info, PAGE_SIZE);
    9.36  
    9.37      /* Send the page update requests down to the hypervisor. */
    9.38 @@ -324,7 +322,8 @@ int xc_linux_build(int xc_handle,
    9.39                     const char *ramdisk_name,
    9.40                     const char *cmdline,
    9.41                     unsigned int control_evtchn,
    9.42 -                   unsigned long flags)
    9.43 +                   unsigned long flags,
    9.44 +                   unsigned int vcpus)
    9.45  {
    9.46      dom0_op_t launch_op, op;
    9.47      int initrd_fd = -1;
    9.48 @@ -390,7 +389,7 @@ int xc_linux_build(int xc_handle,
    9.49                         &vstartinfo_start, &vkern_entry,
    9.50                         ctxt, cmdline,
    9.51                         op.u.getdomaininfo.shared_info_frame,
    9.52 -                       control_evtchn, flags) < 0 )
    9.53 +                       control_evtchn, flags, vcpus) < 0 )
    9.54      {
    9.55          ERROR("Error constructing guest OS");
    9.56          goto error_out;
    10.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Fri Jan 14 12:28:03 2005 +0000
    10.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Tue Jan 18 08:28:11 2005 +0000
    10.3 @@ -348,19 +348,19 @@ static PyObject *pyxc_linux_build(PyObje
    10.4  
    10.5      u32   dom;
    10.6      char *image, *ramdisk = NULL, *cmdline = "";
    10.7 -    int   control_evtchn, flags = 0;
    10.8 +    int   control_evtchn, flags = 0, vcpus = 1;
    10.9  
   10.10      static char *kwd_list[] = { "dom", "control_evtchn", 
   10.11 -                                "image", "ramdisk", "cmdline", "flags",
   10.12 +                                "image", "ramdisk", "cmdline", "flags", "vcpus",
   10.13                                  NULL };
   10.14  
   10.15 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssi", kwd_list, 
   10.16 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssii", kwd_list, 
   10.17                                        &dom, &control_evtchn, 
   10.18 -                                      &image, &ramdisk, &cmdline, &flags) )
   10.19 +                                      &image, &ramdisk, &cmdline, &flags, &vcpus) )
   10.20          return NULL;
   10.21  
   10.22      if ( xc_linux_build(xc->xc_handle, dom, image,
   10.23 -                        ramdisk, cmdline, control_evtchn, flags) != 0 )
   10.24 +                        ramdisk, cmdline, control_evtchn, flags, vcpus) != 0 )
   10.25          return PyErr_SetFromErrno(xc_error);
   10.26      
   10.27      Py_INCREF(zero);
   10.28 @@ -1023,6 +1023,7 @@ static PyMethodDef pyxc_methods[] = {
   10.29        " image   [str]:      Name of kernel image file. May be gzipped.\n"
   10.30        " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
   10.31        " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
   10.32 +      " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
   10.33        "Returns: [int] 0 on success; -1 on error.\n" },
   10.34  
   10.35      { "vmx_build", 
    11.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Jan 14 12:28:03 2005 +0000
    11.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Jan 18 08:28:11 2005 +0000
    11.3 @@ -321,6 +321,7 @@ class XendDomainInfo:
    11.4          self.console_port = None
    11.5          self.savedinfo = None
    11.6          self.is_vmx = 0
    11.7 +        self.vcpus = 1
    11.8  
    11.9      def setdom(self, dom):
   11.10          """Set the domain id.
   11.11 @@ -448,6 +449,11 @@ class XendDomainInfo:
   11.12              cpu = sxp.child_value(config, 'cpu')
   11.13              if self.recreate and self.dom and cpu is not None:
   11.14                  xc.domain_pincpu(self.dom, int(cpu))
   11.15 +            try:
   11.16 +                image = sxp.child_value(self.config, 'image')
   11.17 +                self.vcpus = int(sxp.child_value(image, 'vcpus'))
   11.18 +            except:
   11.19 +                raise VmError('invalid vcpus value')
   11.20  
   11.21              self.init_domain()
   11.22              self.configure_console()
   11.23 @@ -746,12 +752,14 @@ class XendDomainInfo:
   11.24                        	ramdisk        = ramdisk,
   11.25                        	flags          = flags)
   11.26  	else:
   11.27 +        	log.warning('building dom with %d vcpus', self.vcpus)
   11.28          	err = buildfn(dom            = dom,
   11.29                 	      	image          = kernel,
   11.30                        	control_evtchn = self.console.getRemotePort(),
   11.31                        	cmdline        = cmdline,
   11.32                        	ramdisk        = ramdisk,
   11.33 -                      	flags          = flags)
   11.34 +                      	flags          = flags,
   11.35 +                      	vcpus          = self.vcpus)
   11.36          if err != 0:
   11.37              raise VmError('Building domain failed: type=%s dom=%d err=%d'
   11.38                            % (ostype, dom, err))
   11.39 @@ -1280,6 +1288,7 @@ add_config_handler('console',    vm_fiel
   11.40  add_config_handler('image',      vm_field_ignore)
   11.41  add_config_handler('device',     vm_field_ignore)
   11.42  add_config_handler('backend',    vm_field_ignore)
   11.43 +add_config_handler('vcpus',      vm_field_ignore)
   11.44  
   11.45  # Register other config handlers.
   11.46  add_config_handler('maxmem',     vm_field_maxmem)
    12.1 --- a/tools/python/xen/xend/server/blkif.py	Fri Jan 14 12:28:03 2005 +0000
    12.2 +++ b/tools/python/xen/xend/server/blkif.py	Tue Jan 18 08:28:11 2005 +0000
    12.3 @@ -63,6 +63,12 @@ def blkdev_name_to_number(name):
    12.4          log.debug("exception looking up device number for %s: %s", name, ex)
    12.5  	pass
    12.6  
    12.7 +    if re.match( '/dev/sd[a-p]([0-9]|1[0-5])', n):
    12.8 +        return 8 * 256 + 16 * (ord(n[7:8]) - ord('a')) + int(n[8:])
    12.9 +
   12.10 +    if re.match( '/dev/hd[a-p]([0-9]|[1-5][0-9]|6[0-3])', n):
   12.11 +        return 3 * 256 + 16 * (ord(n[7:8]) - ord('a')) + int(n[8:])        
   12.12 +
   12.13      # see if this is a hex device number
   12.14      if re.match( '^(0x)?[0-9a-fA-F]+$', name ):
   12.15  	return string.atoi(name,16)
    13.1 --- a/tools/python/xen/xm/create.py	Fri Jan 14 12:28:03 2005 +0000
    13.2 +++ b/tools/python/xen/xm/create.py	Tue Jan 18 08:28:11 2005 +0000
    13.3 @@ -109,6 +109,10 @@ gopts.var('cpu', val='CPU',
    13.4            fn=set_int, default=None,
    13.5            use="CPU to run the domain on.")
    13.6  
    13.7 +gopts.var('vcpus', val='VCPUS',
    13.8 +          fn=set_int, default=1,
    13.9 +          use="# of Virtual CPUS in domain.")
   13.10 +
   13.11  gopts.var('cpu_weight', val='WEIGHT',
   13.12            fn=set_float, default=None,
   13.13            use="""Set the new domain's cpu weight.
   13.14 @@ -245,7 +249,10 @@ def configure_image(config, vals):
   13.15          config_image.append(['root', cmdline_root])
   13.16      if vals.extra:
   13.17          config_image.append(['args', vals.extra])
   13.18 +    if vals.vcpus:
   13.19 +        config_image.append(['vcpus', vals.vcpus])
   13.20      config.append(['image', config_image ])
   13.21 +
   13.22      
   13.23  def configure_disks(config_devs, vals):
   13.24      """Create the config for disks (virtual block devices).
    14.1 --- a/xen/arch/x86/domain.c	Fri Jan 14 12:28:03 2005 +0000
    14.2 +++ b/xen/arch/x86/domain.c	Tue Jan 18 08:28:11 2005 +0000
    14.3 @@ -236,8 +236,7 @@ void arch_do_createdomain(struct exec_do
    14.4          d->shared_info = (void *)alloc_xenheap_page();
    14.5          memset(d->shared_info, 0, PAGE_SIZE);
    14.6          ed->vcpu_info = &d->shared_info->vcpu_data[ed->eid];
    14.7 -        d->shared_info->arch.mfn_to_pfn_start = 
    14.8 -            virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
    14.9 +        d->shared_info->arch.mfn_to_pfn_start = m2p_start_mfn;
   14.10          SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
   14.11          machine_to_phys_mapping[virt_to_phys(d->shared_info) >> 
   14.12                                 PAGE_SHIFT] = INVALID_P2M_ENTRY;
    15.1 --- a/xen/arch/x86/memory.c	Fri Jan 14 12:28:03 2005 +0000
    15.2 +++ b/xen/arch/x86/memory.c	Tue Jan 18 08:28:11 2005 +0000
    15.3 @@ -168,7 +168,7 @@ void __init init_frametable(void)
    15.4  
    15.5  void arch_init_memory(void)
    15.6  {
    15.7 -    unsigned long mfn, i;
    15.8 +    unsigned long i;
    15.9  
   15.10      /*
   15.11       * We are rather picky about the layout of 'struct pfn_info'. The
   15.12 @@ -211,13 +211,13 @@ void arch_init_memory(void)
   15.13      dom_io->id = DOMID_IO;
   15.14  
   15.15      /* M2P table is mappable read-only by privileged domains. */
   15.16 -    mfn = l2_pgentry_to_pagenr(
   15.17 -        idle_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT]);
   15.18      for ( i = 0; i < 1024; i++ )
   15.19      {
   15.20 -        frame_table[mfn+i].count_info        = PGC_allocated | 1;
   15.21 -        frame_table[mfn+i].u.inuse.type_info = PGT_gdt_page | 1; /* non-RW */
   15.22 -        frame_table[mfn+i].u.inuse.domain    = dom_xen;
   15.23 +        frame_table[m2p_start_mfn+i].count_info        = PGC_allocated | 1;
   15.24 +	/* gdt to make sure it's only mapped read-only by non-privileged
   15.25 +	   domains. */
   15.26 +        frame_table[m2p_start_mfn+i].u.inuse.type_info = PGT_gdt_page | 1;
   15.27 +        frame_table[m2p_start_mfn+i].u.inuse.domain    = dom_xen;
   15.28      }
   15.29  }
   15.30  
    16.1 --- a/xen/arch/x86/x86_32/mm.c	Fri Jan 14 12:28:03 2005 +0000
    16.2 +++ b/xen/arch/x86/x86_32/mm.c	Tue Jan 18 08:28:11 2005 +0000
    16.3 @@ -27,6 +27,8 @@
    16.4  #include <asm/fixmap.h>
    16.5  #include <asm/domain_page.h>
    16.6  
    16.7 +unsigned long m2p_start_mfn;
    16.8 +
    16.9  static inline void set_pte_phys(unsigned long vaddr,
   16.10                                  l1_pgentry_t entry)
   16.11  {
   16.12 @@ -63,6 +65,7 @@ void __init paging_init(void)
   16.13      /* Allocate and map the machine-to-phys table. */
   16.14      if ( (pg = alloc_domheap_pages(NULL, 10)) == NULL )
   16.15          panic("Not enough memory to bootstrap Xen.\n");
   16.16 +    m2p_start_mfn = page_to_pfn(pg);
   16.17      idle_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] =
   16.18          mk_l2_pgentry(page_to_phys(pg) | __PAGE_HYPERVISOR | _PAGE_PSE);
   16.19  
    17.1 --- a/xen/include/asm-x86/mm.h	Fri Jan 14 12:28:03 2005 +0000
    17.2 +++ b/xen/include/asm-x86/mm.h	Tue Jan 18 08:28:11 2005 +0000
    17.3 @@ -226,7 +226,10 @@ void synchronise_pagetables(unsigned lon
    17.4  extern unsigned long *machine_to_phys_mapping;
    17.5  extern unsigned long *phys_to_machine_mapping;
    17.6  #else
    17.7 +/* Don't call virt_to_phys on this: it isn't direct mapped.  Using
    17.8 +   m2p_start_mfn instead. */
    17.9  #define machine_to_phys_mapping ((unsigned long *)RDWR_MPT_VIRT_START)
   17.10 +extern unsigned long m2p_start_mfn;
   17.11  #define phys_to_machine_mapping ((unsigned long *)PERDOMAIN_VIRT_START)
   17.12  #endif
   17.13