ia64/xen-unstable

changeset 7364:52b9aca1916a

New dom0_op to set max vcpus for a domain.

Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Oct 12 16:34:49 2005 +0100 (2005-10-12)
parents 29db5bded574
children 9d47f70345a4
files tools/libxc/xc_domain.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendDomainInfo.py xen/arch/ia64/xen/domain.c xen/arch/x86/domain.c xen/arch/x86/domain_build.c xen/arch/x86/mm.c xen/arch/x86/vmx.c xen/common/dom0_ops.c xen/common/domain.c xen/common/sched_sedf.c xen/common/schedule.c xen/include/public/dom0_ops.h xen/include/xen/domain.h xen/include/xen/sched.h
line diff
     1.1 --- a/tools/libxc/xc_domain.c	Wed Oct 12 16:15:02 2005 +0100
     1.2 +++ b/tools/libxc/xc_domain.c	Wed Oct 12 16:34:49 2005 +0100
     1.3 @@ -329,6 +329,15 @@ int xc_domain_memory_decrease_reservatio
     1.4      return err;
     1.5  }
     1.6  
     1.7 +int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
     1.8 +{
     1.9 +    dom0_op_t op;
    1.10 +    op.cmd = DOM0_MAX_VCPUS;
    1.11 +    op.u.max_vcpus.domain = (domid_t)domid;
    1.12 +    op.u.max_vcpus.max    = max;
    1.13 +    return do_dom0_op(xc_handle, &op);
    1.14 +}
    1.15 +
    1.16  /*
    1.17   * Local variables:
    1.18   * mode: C
     2.1 --- a/tools/libxc/xenctrl.h	Wed Oct 12 16:15:02 2005 +0100
     2.2 +++ b/tools/libxc/xenctrl.h	Wed Oct 12 16:34:49 2005 +0100
     2.3 @@ -147,6 +147,17 @@ int xc_domain_dumpcore(int xc_handle,
     2.4                         uint32_t domid,
     2.5                         const char *corename);
     2.6  
     2.7 +/*
     2.8 + * This function sets the maximum number vcpus that a domian may create.
     2.9 + *
    2.10 + * @parm xc_handle a handle to an open hypervisor interface.
    2.11 + * @parm domid the domain id in which vcpus are to be created.
    2.12 + * @parm max the maximum number of vcpus that the domain may create.
    2.13 + * @return 0 on success, -1 on failure.
    2.14 + */
    2.15 +int xc_domain_max_vcpus(int xc_handle,
    2.16 +                        uint32_t domid, 
    2.17 +                        unsigned int max);
    2.18  
    2.19  /**
    2.20   * This function pauses a domain. A paused domain still exists in memory
     3.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Wed Oct 12 16:15:02 2005 +0100
     3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Oct 12 16:34:49 2005 +0100
     3.3 @@ -93,6 +93,26 @@ static PyObject *pyxc_domain_create(PyOb
     3.4      return PyInt_FromLong(dom);
     3.5  }
     3.6  
     3.7 +static PyObject *pyxc_domain_max_vcpus(PyObject *self,
     3.8 +                                            PyObject *args,
     3.9 +                                            PyObject *kwds)
    3.10 +{
    3.11 +    XcObject *xc = (XcObject *)self;
    3.12 +
    3.13 +    uint32_t dom, max;
    3.14 +
    3.15 +    static char *kwd_list[] = { "dom", "max", NULL };
    3.16 +
    3.17 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, &dom, &max) )
    3.18 +        return NULL;
    3.19 +
    3.20 +    if ( xc_domain_max_vcpus(xc->xc_handle, dom, max) != 0 )
    3.21 +        return PyErr_SetFromErrno(xc_error);
    3.22 +    
    3.23 +    Py_INCREF(zero);
    3.24 +    return zero;
    3.25 +}
    3.26 +
    3.27  static PyObject *pyxc_domain_pause(PyObject *self,
    3.28                                     PyObject *args,
    3.29                                     PyObject *kwds)
    3.30 @@ -783,6 +803,14 @@ static PyMethodDef pyxc_methods[] = {
    3.31        " dom    [int, 0]:        Domain identifier to use (allocated if zero).\n"
    3.32        "Returns: [int] new domain identifier; -1 on error.\n" },
    3.33  
    3.34 +    { "domain_max_vcpus", 
    3.35 +      (PyCFunction)pyxc_domain_max_vcpus,
    3.36 +      METH_VARARGS | METH_KEYWORDS, "\n"
    3.37 +      "Set the maximum number of VCPUs a domain may create.\n"
    3.38 +      " dom       [int, 0]:      Domain identifier to use.\n"
    3.39 +      " max     [int, 0]:      New maximum number of VCPUs in domain.\n"
    3.40 +      "Returns: [int] 0 on success; -1 on error.\n" },
    3.41 +
    3.42      { "domain_dumpcore", 
    3.43        (PyCFunction)pyxc_domain_dumpcore, 
    3.44        METH_VARARGS | METH_KEYWORDS, "\n"
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Oct 12 16:15:02 2005 +0100
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Oct 12 16:34:49 2005 +0100
     4.3 @@ -1030,6 +1030,10 @@ class XendDomainInfo:
     4.4              self.image.handleBootloading()
     4.5  
     4.6          xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
     4.7 +
     4.8 +        # Set maximum number of vcpus in domain
     4.9 +        xc.domain_max_vcpus(self.domid, int(self.info['vcpus']));
    4.10 +
    4.11          # XXX Merge with configure_maxmem?
    4.12          m = self.image.getDomainMemory(self.info['memory_KiB'])
    4.13          xc.domain_setmaxmem(self.domid, m)
     5.1 --- a/xen/arch/ia64/xen/domain.c	Wed Oct 12 16:15:02 2005 +0100
     5.2 +++ b/xen/arch/ia64/xen/domain.c	Wed Oct 12 16:34:49 2005 +0100
     5.3 @@ -149,14 +149,24 @@ void startup_cpu_idle_loop(void)
     5.4  	continue_cpu_idle_loop();
     5.5  }
     5.6  
     5.7 -struct vcpu *arch_alloc_vcpu_struct(void)
     5.8 +struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
     5.9  {
    5.10 -	/* Per-vp stack is used here. So we need keep vcpu
    5.11 -	 * same page as per-vp stack */
    5.12 -	return alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER);
    5.13 +	struct vcpu *v;
    5.14 +
    5.15 +	if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
    5.16 +		return NULL;
    5.17 +
    5.18 +	memset(v, 0, sizeof(*v)); 
    5.19 +        memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch));
    5.20 +	v->arch.privregs = 
    5.21 +		alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
    5.22 +	printf("arch_vcpu_info=%p\n", v->arch.privregs);
    5.23 +	memset(v->arch.privregs, 0, PAGE_SIZE);
    5.24 +
    5.25 +	return v;
    5.26  }
    5.27  
    5.28 -void arch_free_vcpu_struct(struct vcpu *v)
    5.29 +void free_vcpu_struct(struct vcpu *v)
    5.30  {
    5.31  	free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER);
    5.32  }
    5.33 @@ -194,12 +204,6 @@ void arch_do_createdomain(struct vcpu *v
    5.34     		while (1);
    5.35  	}
    5.36  	memset(d->shared_info, 0, PAGE_SIZE);
    5.37 -#if 0
    5.38 -	d->vcpu[0].arch.privregs = 
    5.39 -			alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
    5.40 -	printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs);
    5.41 -	memset(d->vcpu.arch.privregs, 0, PAGE_SIZE);
    5.42 -#endif
    5.43  	v->vcpu_info = &(d->shared_info->vcpu_data[0]);
    5.44  
    5.45  	d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
    5.46 @@ -249,13 +253,6 @@ void arch_getdomaininfo_ctxt(struct vcpu
    5.47  	printf("arch_getdomaininfo_ctxt\n");
    5.48  	c->regs = *regs;
    5.49  	c->vcpu.evtchn_vector = v->vcpu_info->arch.evtchn_vector;
    5.50 -#if 0
    5.51 -	if (c->vcpu.privregs && copy_to_user(c->vcpu.privregs,
    5.52 -			v->vcpu_info->arch.privregs, sizeof(mapped_regs_t))) {
    5.53 -		printk("Bad ctxt address: 0x%lx\n", c->vcpu.privregs);
    5.54 -		return -EFAULT;
    5.55 -	}
    5.56 -#endif
    5.57  
    5.58  	c->shared = v->domain->shared_info->arch;
    5.59  }
    5.60 @@ -279,12 +276,7 @@ int arch_set_info_guest(struct vcpu *v, 
    5.61  
    5.62  	    vmx_setup_platform(v, c);
    5.63  	}
    5.64 -    else{
    5.65 -    	v->arch.privregs =
    5.66 -			alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
    5.67 -	    printf("arch_vcpu_info=%p\n", v->arch.privregs);
    5.68 -    	memset(v->arch.privregs, 0, PAGE_SIZE);
    5.69 -    }
    5.70 +
    5.71  	*regs = c->regs;
    5.72  	new_thread(v, regs->cr_iip, 0, 0);
    5.73  
    5.74 @@ -304,18 +296,6 @@ int arch_set_info_guest(struct vcpu *v, 
    5.75  	return 0;
    5.76  }
    5.77  
    5.78 -void arch_do_boot_vcpu(struct vcpu *v)
    5.79 -{
    5.80 -	struct domain *d = v->domain;
    5.81 -	printf("arch_do_boot_vcpu: not implemented\n");
    5.82 -
    5.83 -	d->vcpu[v->vcpu_id]->arch.privregs = 
    5.84 -			alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
    5.85 -	printf("arch_vcpu_info=%p\n", d->vcpu[v->vcpu_id]->arch.privregs);
    5.86 -	memset(d->vcpu[v->vcpu_id]->arch.privregs, 0, PAGE_SIZE);
    5.87 -	return;
    5.88 -}
    5.89 -
    5.90  void domain_relinquish_resources(struct domain *d)
    5.91  {
    5.92  	/* FIXME */
    5.93 @@ -824,12 +804,12 @@ int construct_dom0(struct domain *d,
    5.94  	unsigned long ret, progress = 0;
    5.95  
    5.96  //printf("construct_dom0: starting\n");
    5.97 -	/* Sanity! */
    5.98 +
    5.99  #ifndef CLONE_DOMAIN0
   5.100 -	if ( d != dom0 ) 
   5.101 -	    BUG();
   5.102 -	if ( test_bit(_DOMF_constructed, &d->domain_flags) ) 
   5.103 -	    BUG();
   5.104 +	/* Sanity! */
   5.105 +	BUG_ON(d != dom0);
   5.106 +	BUG_ON(d->vcpu[0] == NULL);
   5.107 +	BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
   5.108  #endif
   5.109  
   5.110  	memset(&dsi, 0, sizeof(struct domain_setup_info));
   5.111 @@ -992,14 +972,8 @@ int construct_dom0(struct domain *d,
   5.112  	printk("Dom0: 0x%lx, domain: 0x%lx\n", (u64)dom0, (u64)d);
   5.113  	if (vmx_dom0)
   5.114  	    vmx_final_setup_domain(dom0);
   5.115 -    else{
   5.116 -    	d->vcpu[0]->arch.privregs = 
   5.117 -			alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
   5.118 -	    printf("arch_vcpu_info=%p\n", d->vcpu[0]->arch.privregs);
   5.119 -    	memset(d->vcpu[0]->arch.privregs, 0, PAGE_SIZE);
   5.120 -    }
   5.121  
   5.122 -	set_bit(_DOMF_constructed, &d->domain_flags);
   5.123 +	set_bit(_VCPUF_initialised, &v->vcpu_flags);
   5.124  
   5.125  	new_thread(v, pkern_entry, 0, 0);
   5.126  	physdev_init_dom0(d);
   5.127 @@ -1031,7 +1005,7 @@ int construct_domU(struct domain *d,
   5.128  	unsigned long pkern_entry;
   5.129  
   5.130  #ifndef DOMU_AUTO_RESTART
   5.131 -	if ( test_bit(_DOMF_constructed, &d->domain_flags) ) BUG();
   5.132 +	BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
   5.133  #endif
   5.134  
   5.135  	printk("*** LOADING DOMAIN %d ***\n",d->domain_id);
   5.136 @@ -1051,7 +1025,7 @@ int construct_domU(struct domain *d,
   5.137  	loaddomainelfimage(d,image_start);
   5.138  	printk("loaddomainelfimage returns\n");
   5.139  
   5.140 -	set_bit(_DOMF_constructed, &d->domain_flags);
   5.141 +	set_bit(_VCPUF_initialised, &v->vcpu_flags);
   5.142  
   5.143  	printk("calling new_thread, entry=%p\n",pkern_entry);
   5.144  #ifdef DOMU_AUTO_RESTART
     6.1 --- a/xen/arch/x86/domain.c	Wed Oct 12 16:15:02 2005 +0100
     6.2 +++ b/xen/arch/x86/domain.c	Wed Oct 12 16:34:49 2005 +0100
     6.3 @@ -212,21 +212,35 @@ void dump_pageframe_info(struct domain *
     6.4             page->u.inuse.type_info);
     6.5  }
     6.6  
     6.7 -struct vcpu *arch_alloc_vcpu_struct(void)
     6.8 +struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
     6.9  {
    6.10 -    return xmalloc(struct vcpu);
    6.11 +    struct vcpu *v;
    6.12 +
    6.13 +    if ( (v = xmalloc(struct vcpu)) == NULL )
    6.14 +        return NULL;
    6.15 +
    6.16 +    memset(v, 0, sizeof(*v));
    6.17 +
    6.18 +    memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch));
    6.19 +    v->arch.flags = TF_kernel_mode;
    6.20 +
    6.21 +    if ( (v->vcpu_id = vcpu_id) != 0 )
    6.22 +    {
    6.23 +        v->arch.schedule_tail = d->vcpu[0]->arch.schedule_tail;
    6.24 +        v->arch.perdomain_ptes =
    6.25 +            d->arch.mm_perdomain_pt + (vcpu_id << PDPT_VCPU_SHIFT);
    6.26 +        v->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] =
    6.27 +            l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR);
    6.28 +    }
    6.29 +
    6.30 +    return v;
    6.31  }
    6.32  
    6.33 -/* We assume that vcpu 0 is always the last one to be freed in a
    6.34 -   domain i.e. if v->vcpu_id == 0, the domain should be
    6.35 -   single-processor. */
    6.36 -void arch_free_vcpu_struct(struct vcpu *v)
    6.37 +void free_vcpu_struct(struct vcpu *v)
    6.38  {
    6.39 -    struct vcpu *p;
    6.40 -    for_each_vcpu(v->domain, p) {
    6.41 -        if (p->next_in_list == v)
    6.42 -            p->next_in_list = v->next_in_list;
    6.43 -    }
    6.44 +    BUG_ON(v->next_in_list != NULL);
    6.45 +    if ( v->vcpu_id != 0 )
    6.46 +        v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL;
    6.47      xfree(v);
    6.48  }
    6.49  
    6.50 @@ -243,8 +257,6 @@ void arch_do_createdomain(struct vcpu *v
    6.51  {
    6.52      struct domain *d = v->domain;
    6.53  
    6.54 -    v->arch.flags = TF_kernel_mode;
    6.55 -
    6.56      if ( is_idle_task(d) )
    6.57          return;
    6.58  
    6.59 @@ -291,20 +303,6 @@ void arch_do_createdomain(struct vcpu *v
    6.60      INIT_LIST_HEAD(&d->arch.free_shadow_frames);
    6.61  }
    6.62  
    6.63 -void arch_do_boot_vcpu(struct vcpu *v)
    6.64 -{
    6.65 -    struct domain *d = v->domain;
    6.66 -
    6.67 -    v->arch.flags = TF_kernel_mode;
    6.68 -
    6.69 -    v->arch.schedule_tail = d->vcpu[0]->arch.schedule_tail;
    6.70 -
    6.71 -    v->arch.perdomain_ptes =
    6.72 -        d->arch.mm_perdomain_pt + (v->vcpu_id << PDPT_VCPU_SHIFT);
    6.73 -    v->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] =
    6.74 -        l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR);
    6.75 -}
    6.76 -
    6.77  void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
    6.78  {
    6.79      if ( v->processor == newcpu )
     7.1 --- a/xen/arch/x86/domain_build.c	Wed Oct 12 16:15:02 2005 +0100
     7.2 +++ b/xen/arch/x86/domain_build.c	Wed Oct 12 16:34:49 2005 +0100
     7.3 @@ -14,6 +14,7 @@
     7.4  #include <xen/event.h>
     7.5  #include <xen/elf.h>
     7.6  #include <xen/kernel.h>
     7.7 +#include <xen/domain.h>
     7.8  #include <asm/regs.h>
     7.9  #include <asm/system.h>
    7.10  #include <asm/io.h>
    7.11 @@ -146,10 +147,9 @@ int construct_dom0(struct domain *d,
    7.12          struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn);
    7.13  
    7.14      /* Sanity! */
    7.15 -    if ( d->domain_id != 0 ) 
    7.16 -        BUG();
    7.17 -    if ( test_bit(_DOMF_constructed, &d->domain_flags) ) 
    7.18 -        BUG();
    7.19 +    BUG_ON(d->domain_id != 0);
    7.20 +    BUG_ON(d->vcpu[0] == NULL);
    7.21 +    BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
    7.22  
    7.23      memset(&dsi, 0, sizeof(struct domain_setup_info));
    7.24      dsi.image_addr = (unsigned long)image_start;
    7.25 @@ -559,6 +559,9 @@ int construct_dom0(struct domain *d,
    7.26          d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
    7.27      d->shared_info->n_vcpu = num_online_cpus();
    7.28  
    7.29 +    for ( i = 1; i < d->shared_info->n_vcpu; i++ )
    7.30 +        (void)alloc_vcpu(d, i);
    7.31 +
    7.32      /* Set up monitor table */
    7.33      update_pagetables(v);
    7.34  
    7.35 @@ -657,7 +660,7 @@ int construct_dom0(struct domain *d,
    7.36  
    7.37      init_domain_time(d);
    7.38  
    7.39 -    set_bit(_DOMF_constructed, &d->domain_flags);
    7.40 +    set_bit(_VCPUF_initialised, &v->vcpu_flags);
    7.41  
    7.42      new_thread(v, dsi.v_kernentry, vstack_end, vstartinfo_start);
    7.43  
     8.1 --- a/xen/arch/x86/mm.c	Wed Oct 12 16:15:02 2005 +0100
     8.2 +++ b/xen/arch/x86/mm.c	Wed Oct 12 16:34:49 2005 +0100
     8.3 @@ -185,7 +185,7 @@ void arch_init_memory(void)
     8.4       * Any Xen-heap pages that we will allow to be mapped will have
     8.5       * their domain field set to dom_xen.
     8.6       */
     8.7 -    dom_xen = alloc_domain_struct();
     8.8 +    dom_xen = alloc_domain();
     8.9      atomic_set(&dom_xen->refcnt, 1);
    8.10      dom_xen->domain_id = DOMID_XEN;
    8.11  
    8.12 @@ -194,7 +194,7 @@ void arch_init_memory(void)
    8.13       * This domain owns I/O pages that are within the range of the pfn_info
    8.14       * array. Mappings occur at the priv of the caller.
    8.15       */
    8.16 -    dom_io = alloc_domain_struct();
    8.17 +    dom_io = alloc_domain();
    8.18      atomic_set(&dom_io->refcnt, 1);
    8.19      dom_io->domain_id = DOMID_IO;
    8.20  
     9.1 --- a/xen/arch/x86/vmx.c	Wed Oct 12 16:15:02 2005 +0100
     9.2 +++ b/xen/arch/x86/vmx.c	Wed Oct 12 16:34:49 2005 +0100
     9.3 @@ -1674,7 +1674,7 @@ asmlinkage void vmx_vmexit_handler(struc
     9.4              store_cpu_user_regs(&regs);
     9.5              __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS, PENDING_DEBUG_EXC_BS);
     9.6  
     9.7 -            set_bit(_VCPUF_ctrl_pause, &current->vcpu_flags);
     9.8 +            domain_pause_for_debugger();
     9.9              do_sched_op(SCHEDOP_yield);
    9.10  
    9.11              break;
    10.1 --- a/xen/common/dom0_ops.c	Wed Oct 12 16:15:02 2005 +0100
    10.2 +++ b/xen/common/dom0_ops.c	Wed Oct 12 16:34:49 2005 +0100
    10.3 @@ -44,28 +44,24 @@ static void getdomaininfo(struct domain 
    10.4      struct vcpu   *v;
    10.5      u64 cpu_time = 0;
    10.6      int vcpu_count = 0;
    10.7 -    int flags = DOMFLAGS_PAUSED | DOMFLAGS_BLOCKED;
    10.8 +    int flags = DOMFLAGS_BLOCKED;
    10.9      
   10.10      info->domain = d->domain_id;
   10.11      
   10.12      memset(&info->vcpu_to_cpu, -1, sizeof(info->vcpu_to_cpu));
   10.13      memset(&info->cpumap, 0, sizeof(info->cpumap));
   10.14 -    
   10.15 +
   10.16      /* 
   10.17 -     * - domain is marked as paused or blocked only if all its vcpus 
   10.18 -     *   are paused or blocked 
   10.19 +     * - domain is marked as blocked only if all its vcpus are blocked
   10.20       * - domain is marked as running if any of its vcpus is running
   10.21       * - only map vcpus that aren't down.  Note, at some point we may
   10.22       *   wish to demux the -1 value to indicate down vs. not-ever-booted
   10.23 -     *   
   10.24       */
   10.25      for_each_vcpu ( d, v ) {
   10.26          /* only map vcpus that are up */
   10.27          if ( !(test_bit(_VCPUF_down, &v->vcpu_flags)) )
   10.28              info->vcpu_to_cpu[v->vcpu_id] = v->processor;
   10.29          info->cpumap[v->vcpu_id] = v->cpumap;
   10.30 -        if ( !(v->vcpu_flags & VCPUF_ctrl_pause) )
   10.31 -            flags &= ~DOMFLAGS_PAUSED;
   10.32          if ( !(v->vcpu_flags & VCPUF_blocked) )
   10.33              flags &= ~DOMFLAGS_BLOCKED;
   10.34          if ( v->vcpu_flags & VCPUF_running )
   10.35 @@ -78,8 +74,9 @@ static void getdomaininfo(struct domain 
   10.36      info->n_vcpu = vcpu_count;
   10.37      
   10.38      info->flags = flags |
   10.39 -        ((d->domain_flags & DOMF_dying)    ? DOMFLAGS_DYING    : 0) |
   10.40 -        ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) |
   10.41 +        ((d->domain_flags & DOMF_dying)      ? DOMFLAGS_DYING    : 0) |
   10.42 +        ((d->domain_flags & DOMF_shutdown)   ? DOMFLAGS_SHUTDOWN : 0) |
   10.43 +        ((d->domain_flags & DOMF_ctrl_pause) ? DOMFLAGS_PAUSED   : 0) |
   10.44          d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT;
   10.45  
   10.46      if (d->ssid != NULL)
   10.47 @@ -97,6 +94,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   10.48      long ret = 0;
   10.49      dom0_op_t curop, *op = &curop;
   10.50      void *ssid = NULL; /* save security ptr between pre and post/fail hooks */
   10.51 +    static spinlock_t dom0_lock = SPIN_LOCK_UNLOCKED;
   10.52  
   10.53      if ( !IS_PRIV(current->domain) )
   10.54          return -EPERM;
   10.55 @@ -110,6 +108,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   10.56      if ( acm_pre_dom0_op(op, &ssid) )
   10.57          return -EACCES;
   10.58  
   10.59 +    spin_lock(&dom0_lock);
   10.60 +
   10.61      switch ( op->cmd )
   10.62      {
   10.63  
   10.64 @@ -150,7 +150,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   10.65          {
   10.66              ret = -EINVAL;
   10.67              if ( (d != current->domain) && 
   10.68 -                 test_bit(_DOMF_constructed, &d->domain_flags) )
   10.69 +                 test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
   10.70              {
   10.71                  domain_unpause_by_systemcontroller(d);
   10.72                  ret = 0;
   10.73 @@ -167,17 +167,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   10.74          domid_t        dom;
   10.75          struct vcpu   *v;
   10.76          unsigned int   i, cnt[NR_CPUS] = { 0 };
   10.77 -        static spinlock_t alloc_lock = SPIN_LOCK_UNLOCKED;
   10.78          static domid_t rover = 0;
   10.79  
   10.80 -        spin_lock(&alloc_lock);
   10.81 -
   10.82          dom = op->u.createdomain.domain;
   10.83          if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
   10.84          {
   10.85              ret = -EINVAL;
   10.86              if ( !is_free_domid(dom) )
   10.87 -                goto alloc_out;
   10.88 +                break;
   10.89          }
   10.90          else
   10.91          {
   10.92 @@ -191,7 +188,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   10.93  
   10.94              ret = -ENOMEM;
   10.95              if ( dom == rover )
   10.96 -                goto alloc_out;
   10.97 +                break;
   10.98  
   10.99              rover = dom;
  10.100          }
  10.101 @@ -215,15 +212,51 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
  10.102  
  10.103          ret = -ENOMEM;
  10.104          if ( (d = do_createdomain(dom, pro)) == NULL )
  10.105 -            goto alloc_out;
  10.106 +            break;
  10.107  
  10.108          ret = 0;
  10.109  
  10.110          op->u.createdomain.domain = d->domain_id;
  10.111          copy_to_user(u_dom0_op, op, sizeof(*op));
  10.112 +    }
  10.113 +    break;
  10.114  
  10.115 -    alloc_out:
  10.116 -        spin_unlock(&alloc_lock);
  10.117 +    case DOM0_MAX_VCPUS:
  10.118 +    {
  10.119 +        struct domain *d;
  10.120 +        unsigned int i, max = op->u.max_vcpus.max;
  10.121 +
  10.122 +        ret = -EINVAL;
  10.123 +        if ( max > MAX_VIRT_CPUS )
  10.124 +            break;
  10.125 +
  10.126 +        ret = -ESRCH;
  10.127 +        if ( (d = find_domain_by_id(op->u.max_vcpus.domain)) == NULL )
  10.128 +            break;
  10.129 +
  10.130 +        /*
  10.131 +         * Can only create new VCPUs while the domain is not fully constructed
  10.132 +         * (and hence not runnable). Xen needs auditing for races before
  10.133 +         * removing this check.
  10.134 +         */
  10.135 +        ret = -EINVAL;
  10.136 +        if ( test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
  10.137 +            goto maxvcpu_out;
  10.138 +
  10.139 +        /* We cannot reduce maximum VCPUs. */
  10.140 +        ret = -EINVAL;
  10.141 +        if ( (max != MAX_VIRT_CPUS) && (d->vcpu[max] != NULL) )
  10.142 +            goto maxvcpu_out;
  10.143 +
  10.144 +        ret = -ENOMEM;
  10.145 +        for ( i = 0; i < max; i++ )
  10.146 +            if ( (d->vcpu[i] == NULL) && (alloc_vcpu(d, i) == NULL) )
  10.147 +                goto maxvcpu_out;
  10.148 +
  10.149 +        ret = 0;
  10.150 +
  10.151 +    maxvcpu_out:
  10.152 +        put_domain(d);
  10.153      }
  10.154      break;
  10.155  
  10.156 @@ -535,10 +568,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
  10.157          ret = arch_do_dom0_op(op,u_dom0_op);
  10.158  
  10.159      }
  10.160 +
  10.161 +    spin_unlock(&dom0_lock);
  10.162 +
  10.163      if (!ret)
  10.164          acm_post_dom0_op(op, ssid);
  10.165      else
  10.166          acm_fail_dom0_op(op, ssid);
  10.167 +
  10.168      return ret;
  10.169  }
  10.170  
    11.1 --- a/xen/common/domain.c	Wed Oct 12 16:15:02 2005 +0100
    11.2 +++ b/xen/common/domain.c	Wed Oct 12 16:34:49 2005 +0100
    11.3 @@ -33,7 +33,7 @@ struct domain *do_createdomain(domid_t d
    11.4      struct domain *d, **pd;
    11.5      struct vcpu *v;
    11.6  
    11.7 -    if ( (d = alloc_domain_struct()) == NULL )
    11.8 +    if ( (d = alloc_domain()) == NULL )
    11.9          return NULL;
   11.10  
   11.11      v = d->vcpu[0];
   11.12 @@ -52,12 +52,14 @@ struct domain *do_createdomain(domid_t d
   11.13  
   11.14      if ( d->domain_id == IDLE_DOMAIN_ID )
   11.15          set_bit(_DOMF_idle_domain, &d->domain_flags);
   11.16 +    else
   11.17 +        set_bit(_DOMF_ctrl_pause, &d->domain_flags);
   11.18  
   11.19      if ( !is_idle_task(d) &&
   11.20           ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
   11.21      {
   11.22          evtchn_destroy(d);
   11.23 -        free_domain_struct(d);
   11.24 +        free_domain(d);
   11.25          return NULL;
   11.26      }
   11.27      
   11.28 @@ -224,11 +226,9 @@ void domain_pause_for_debugger(void)
   11.29       * must issue a PAUSEDOMAIN command to ensure that all execution
   11.30       * has ceased and guest state is committed to memory.
   11.31       */
   11.32 +    set_bit(_DOMF_ctrl_pause, &d->domain_flags);
   11.33      for_each_vcpu ( d, v )
   11.34 -    {
   11.35 -        set_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
   11.36          vcpu_sleep_nosync(v);
   11.37 -    }
   11.38  
   11.39      send_guest_virq(dom0->vcpu[0], VIRQ_DEBUGGER);
   11.40  }
   11.41 @@ -267,7 +267,7 @@ void domain_destruct(struct domain *d)
   11.42      free_perdomain_pt(d);
   11.43      free_xenheap_page(d->shared_info);
   11.44  
   11.45 -    free_domain_struct(d);
   11.46 +    free_domain(d);
   11.47  
   11.48      send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
   11.49  }
   11.50 @@ -310,10 +310,11 @@ void domain_pause_by_systemcontroller(st
   11.51  {
   11.52      struct vcpu *v;
   11.53  
   11.54 -    for_each_vcpu ( d, v )
   11.55 +    BUG_ON(current->domain == d);
   11.56 +
   11.57 +    if ( !test_and_set_bit(_DOMF_ctrl_pause, &d->domain_flags) )
   11.58      {
   11.59 -        BUG_ON(v == current);
   11.60 -        if ( !test_and_set_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) )
   11.61 +        for_each_vcpu ( d, v )
   11.62              vcpu_sleep_sync(v);
   11.63      }
   11.64  }
   11.65 @@ -322,9 +323,9 @@ void domain_unpause_by_systemcontroller(
   11.66  {
   11.67      struct vcpu *v;
   11.68  
   11.69 -    for_each_vcpu ( d, v )
   11.70 +    if ( test_and_clear_bit(_DOMF_ctrl_pause, &d->domain_flags) )
   11.71      {
   11.72 -        if ( test_and_clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) )
   11.73 +        for_each_vcpu ( d, v )
   11.74              vcpu_wake(v);
   11.75      }
   11.76  }
   11.77 @@ -345,61 +346,32 @@ int set_info_guest(struct domain *d, dom
   11.78      if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
   11.79          return -EINVAL;
   11.80      
   11.81 -    if (test_bit(_DOMF_constructed, &d->domain_flags) && 
   11.82 -        !test_bit(_VCPUF_ctrl_pause, &v->vcpu_flags))
   11.83 +    if ( !test_bit(_DOMF_ctrl_pause, &d->domain_flags) )
   11.84          return -EINVAL;
   11.85  
   11.86      if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
   11.87          return -ENOMEM;
   11.88  
   11.89 -    if ( copy_from_user(c, setdomaininfo->ctxt, sizeof(*c)) )
   11.90 -    {
   11.91 -        rc = -EFAULT;
   11.92 -        goto out;
   11.93 -    }
   11.94 -    
   11.95 -    if ( (rc = arch_set_info_guest(v, c)) != 0 )
   11.96 -        goto out;
   11.97 +    rc = -EFAULT;
   11.98 +    if ( copy_from_user(c, setdomaininfo->ctxt, sizeof(*c)) == 0 )
   11.99 +        rc = arch_set_info_guest(v, c);
  11.100  
  11.101 -    set_bit(_DOMF_constructed, &d->domain_flags);
  11.102 -
  11.103 - out:    
  11.104      xfree(c);
  11.105      return rc;
  11.106  }
  11.107  
  11.108  int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) 
  11.109  {
  11.110 -    struct vcpu *v;
  11.111 +    struct vcpu *v = d->vcpu[vcpuid];
  11.112      int rc;
  11.113  
  11.114 -    ASSERT(d->vcpu[vcpuid] == NULL);
  11.115 -
  11.116 -    if ( alloc_vcpu_struct(d, vcpuid) == NULL )
  11.117 -        return -ENOMEM;
  11.118 -
  11.119 -    v = d->vcpu[vcpuid];
  11.120 -
  11.121 -    atomic_set(&v->pausecnt, 0);
  11.122 -    v->cpumap = CPUMAP_RUNANYWHERE;
  11.123 -
  11.124 -    memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch));
  11.125 -
  11.126 -    arch_do_boot_vcpu(v);
  11.127 +    BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
  11.128  
  11.129      if ( (rc = arch_set_info_guest(v, ctxt)) != 0 )
  11.130 -        goto out;
  11.131 +        return rc;
  11.132  
  11.133      sched_add_domain(v);
  11.134  
  11.135 -    set_bit(_VCPUF_down, &v->vcpu_flags);
  11.136 -    clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
  11.137 -
  11.138 -    return 0;
  11.139 -
  11.140 - out:
  11.141 -    arch_free_vcpu_struct(d->vcpu[vcpuid]);
  11.142 -    d->vcpu[vcpuid] = NULL;
  11.143      return rc;
  11.144  }
  11.145  
  11.146 @@ -413,7 +385,7 @@ long do_vcpu_op(int cmd, int vcpuid, voi
  11.147      if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
  11.148          return -EINVAL;
  11.149  
  11.150 -    if ( ((v = d->vcpu[vcpuid]) == NULL) && (cmd != VCPUOP_initialise) )
  11.151 +    if ( (v = d->vcpu[vcpuid]) == NULL )
  11.152          return -ENOENT;
  11.153  
  11.154      switch ( cmd )
  11.155 @@ -433,7 +405,9 @@ long do_vcpu_op(int cmd, int vcpuid, voi
  11.156          }
  11.157  
  11.158          LOCK_BIGLOCK(d);
  11.159 -        rc = (d->vcpu[vcpuid] == NULL) ? boot_vcpu(d, vcpuid, ctxt) : -EEXIST;
  11.160 +        rc = -EEXIST;
  11.161 +        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
  11.162 +            rc = boot_vcpu(d, vcpuid, ctxt);
  11.163          UNLOCK_BIGLOCK(d);
  11.164  
  11.165          xfree(ctxt);
    12.1 --- a/xen/common/sched_sedf.c	Wed Oct 12 16:15:02 2005 +0100
    12.2 +++ b/xen/common/sched_sedf.c	Wed Oct 12 16:34:49 2005 +0100
    12.3 @@ -1122,10 +1122,10 @@ static inline int should_switch(struct v
    12.4  void sedf_wake(struct vcpu *d) {
    12.5      s_time_t              now = NOW();
    12.6      struct sedf_vcpu_info* inf = EDOM_INFO(d);
    12.7 - 
    12.8 +
    12.9      PRINT(3, "sedf_wake was called, domain-id %i.%i\n",d->domain->domain_id,
   12.10            d->vcpu_id);
   12.11 - 
   12.12 +
   12.13      if (unlikely(is_idle_task(d->domain)))
   12.14          return;
   12.15     
    13.1 --- a/xen/common/schedule.c	Wed Oct 12 16:15:02 2005 +0100
    13.2 +++ b/xen/common/schedule.c	Wed Oct 12 16:34:49 2005 +0100
    13.3 @@ -80,69 +80,59 @@ static struct scheduler ops;
    13.4  /* Per-CPU periodic timer sends an event to the currently-executing domain. */
    13.5  static struct ac_timer t_timer[NR_CPUS]; 
    13.6  
    13.7 -void free_domain_struct(struct domain *d)
    13.8 +void free_domain(struct domain *d)
    13.9  {
   13.10      int i;
   13.11  
   13.12      SCHED_OP(free_task, d);
   13.13 -    /* vcpu 0 has to be the last one destructed. */
   13.14 -    for (i = MAX_VIRT_CPUS-1; i >= 0; i--)
   13.15 -        if ( d->vcpu[i] )
   13.16 -            arch_free_vcpu_struct(d->vcpu[i]);
   13.17 +
   13.18 +    for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- )
   13.19 +        if ( d->vcpu[i] != NULL )
   13.20 +            free_vcpu_struct(d->vcpu[i]);
   13.21  
   13.22      xfree(d);
   13.23  }
   13.24  
   13.25 -struct vcpu *alloc_vcpu_struct(
   13.26 -    struct domain *d, unsigned long vcpu)
   13.27 +struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id)
   13.28  {
   13.29 -    struct vcpu *v, *vc;
   13.30 +    struct vcpu *v;
   13.31  
   13.32 -    ASSERT( d->vcpu[vcpu] == NULL );
   13.33 +    BUG_ON(d->vcpu[vcpu_id] != NULL);
   13.34  
   13.35 -    if ( (v = arch_alloc_vcpu_struct()) == NULL )
   13.36 +    if ( (v = alloc_vcpu_struct(d, vcpu_id)) == NULL )
   13.37          return NULL;
   13.38  
   13.39 -    memset(v, 0, sizeof(*v));
   13.40 +    v->domain = d;
   13.41 +    v->vcpu_id = vcpu_id;
   13.42 +    atomic_set(&v->pausecnt, 0);
   13.43 +    v->cpumap = CPUMAP_RUNANYWHERE;
   13.44  
   13.45 -    d->vcpu[vcpu] = v;
   13.46 -    v->domain = d;
   13.47 -    v->vcpu_id = vcpu;
   13.48 +    d->vcpu[vcpu_id] = v;
   13.49  
   13.50      if ( SCHED_OP(alloc_task, v) < 0 )
   13.51 -        goto out;
   13.52 -
   13.53 -    if ( vcpu != 0 )
   13.54      {
   13.55 -        v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id];
   13.56 -
   13.57 -        for_each_vcpu( d, vc )
   13.58 -        {
   13.59 -            if ( (vc->next_in_list == NULL) ||
   13.60 -                 (vc->next_in_list->vcpu_id > vcpu) )
   13.61 -                break;
   13.62 -        }
   13.63 -        v->next_in_list  = vc->next_in_list;
   13.64 -        vc->next_in_list = v;
   13.65 -
   13.66 -        if (test_bit(_VCPUF_cpu_pinned, &vc->vcpu_flags)) {
   13.67 -            v->processor = (vc->processor + 1) % num_online_cpus();
   13.68 -            set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags);
   13.69 -        } else {
   13.70 -            v->processor = (vc->processor + 1) % num_online_cpus();
   13.71 -        }
   13.72 +        d->vcpu[vcpu_id] = NULL;
   13.73 +        free_vcpu_struct(v);
   13.74 +        return NULL;
   13.75      }
   13.76  
   13.77 -    return v;
   13.78 +    if ( vcpu_id == 0 )
   13.79 +        return v;
   13.80 +
   13.81 +    v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id];
   13.82 +
   13.83 +    d->vcpu[v->vcpu_id-1]->next_in_list = v;
   13.84  
   13.85 - out:
   13.86 -    d->vcpu[vcpu] = NULL;
   13.87 -    arch_free_vcpu_struct(v);
   13.88 +    v->processor = (d->vcpu[0]->processor + 1) % num_online_cpus();
   13.89 +    if ( test_bit(_VCPUF_cpu_pinned, &d->vcpu[0]->vcpu_flags) )
   13.90 +        set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags);
   13.91  
   13.92 -    return NULL;
   13.93 +    set_bit(_VCPUF_down, &v->vcpu_flags);
   13.94 +
   13.95 +    return v;
   13.96  }
   13.97  
   13.98 -struct domain *alloc_domain_struct(void)
   13.99 +struct domain *alloc_domain(void)
  13.100  {
  13.101      struct domain *d;
  13.102  
  13.103 @@ -151,7 +141,7 @@ struct domain *alloc_domain_struct(void)
  13.104      
  13.105      memset(d, 0, sizeof(*d));
  13.106  
  13.107 -    if ( alloc_vcpu_struct(d, 0) == NULL )
  13.108 +    if ( alloc_vcpu(d, 0) == NULL )
  13.109          goto out;
  13.110  
  13.111      return d;
  13.112 @@ -177,11 +167,6 @@ void sched_add_domain(struct vcpu *v)
  13.113          schedule_data[v->processor].idle = v;
  13.114          set_bit(_VCPUF_running, &v->vcpu_flags);
  13.115      }
  13.116 -    else
  13.117 -    {
  13.118 -        /* Must be unpaused by control software to start execution. */
  13.119 -        set_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
  13.120 -    }
  13.121  
  13.122      SCHED_OP(add_task, v);
  13.123      TRACE_2D(TRC_SCHED_DOM_ADD, d->domain_id, v->vcpu_id);
    14.1 --- a/xen/include/public/dom0_ops.h	Wed Oct 12 16:15:02 2005 +0100
    14.2 +++ b/xen/include/public/dom0_ops.h	Wed Oct 12 16:34:49 2005 +0100
    14.3 @@ -387,6 +387,13 @@ typedef struct {
    14.4      } *memory_map;
    14.5  } dom0_physical_memory_map_t;
    14.6  
    14.7 +#define DOM0_MAX_VCPUS 41
    14.8 +typedef struct {
    14.9 +    domid_t domain;             /* domain to be affected */
   14.10 +    unsigned int max;           /* maximum number of vcpus */
   14.11 +} dom0_max_vcpus_t;
   14.12 +
   14.13 +
   14.14  typedef struct {
   14.15      uint32_t cmd;
   14.16      uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
   14.17 @@ -422,6 +429,7 @@ typedef struct {
   14.18          dom0_getdomaininfolist_t getdomaininfolist;
   14.19          dom0_platform_quirk_t    platform_quirk;
   14.20          dom0_physical_memory_map_t physical_memory_map;
   14.21 +        dom0_max_vcpus_t         max_vcpus;
   14.22      } u;
   14.23  } dom0_op_t;
   14.24  
    15.1 --- a/xen/include/xen/domain.h	Wed Oct 12 16:15:02 2005 +0100
    15.2 +++ b/xen/include/xen/domain.h	Wed Oct 12 16:34:49 2005 +0100
    15.3 @@ -2,18 +2,19 @@
    15.4  #ifndef __XEN_DOMAIN_H__
    15.5  #define __XEN_DOMAIN_H__
    15.6  
    15.7 +extern int boot_vcpu(
    15.8 +    struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt);
    15.9 +
   15.10  /*
   15.11   * Arch-specifics.
   15.12   */
   15.13  
   15.14 -struct vcpu *arch_alloc_vcpu_struct(void);
   15.15 +struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id);
   15.16  
   15.17 -extern void arch_free_vcpu_struct(struct vcpu *v);
   15.18 +extern void free_vcpu_struct(struct vcpu *v);
   15.19  
   15.20  extern void arch_do_createdomain(struct vcpu *v);
   15.21  
   15.22 -extern void arch_do_boot_vcpu(struct vcpu *v);
   15.23 -
   15.24  extern int  arch_set_info_guest(
   15.25      struct vcpu *v, struct vcpu_guest_context *c);
   15.26  
    16.1 --- a/xen/include/xen/sched.h	Wed Oct 12 16:15:02 2005 +0100
    16.2 +++ b/xen/include/xen/sched.h	Wed Oct 12 16:34:49 2005 +0100
    16.3 @@ -61,7 +61,8 @@ struct vcpu
    16.4      vcpu_info_t     *vcpu_info;
    16.5  
    16.6      struct domain   *domain;
    16.7 -    struct vcpu *next_in_list;
    16.8 +
    16.9 +    struct vcpu     *next_in_list;
   16.10  
   16.11      struct ac_timer  timer;         /* one-shot timer for timeout values */
   16.12      unsigned long    sleep_tick;    /* tick at which this vcpu started sleep */
   16.13 @@ -166,11 +167,10 @@ extern struct vcpu *idle_task[NR_CPUS];
   16.14  #define IDLE_DOMAIN_ID   (0x7FFFU)
   16.15  #define is_idle_task(_d) (test_bit(_DOMF_idle_domain, &(_d)->domain_flags))
   16.16  
   16.17 -struct vcpu *alloc_vcpu_struct(struct domain *d,
   16.18 -                                             unsigned long vcpu);
   16.19 +struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id);
   16.20  
   16.21 -void free_domain_struct(struct domain *d);
   16.22 -struct domain *alloc_domain_struct();
   16.23 +struct domain *alloc_domain(void);
   16.24 +void free_domain(struct domain *d);
   16.25  
   16.26  #define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */
   16.27  #define put_domain(_d) \
   16.28 @@ -327,13 +327,15 @@ unsigned long __hypercall_create_continu
   16.29  extern struct domain *domain_hash[DOMAIN_HASH_SIZE];
   16.30  extern struct domain *domain_list;
   16.31  
   16.32 -#define for_each_domain(_d) \
   16.33 - for ( (_d) = domain_list; (_d) != NULL; (_d) = (_d)->next_in_list )
   16.34 +#define for_each_domain(_d)                     \
   16.35 + for ( (_d) = domain_list;                      \
   16.36 +       (_d) != NULL;                            \
   16.37 +       (_d) = (_d)->next_in_list )
   16.38  
   16.39 -#define for_each_vcpu(_d,_ed) \
   16.40 - for ( (_ed) = (_d)->vcpu[0]; \
   16.41 -       (_ed) != NULL;                \
   16.42 -       (_ed) = (_ed)->next_in_list )
   16.43 +#define for_each_vcpu(_d,_v)                    \
   16.44 + for ( (_v) = (_d)->vcpu[0];                    \
   16.45 +       (_v) != NULL;                            \
   16.46 +       (_v) = (_v)->next_in_list )
   16.47  
   16.48  /*
   16.49   * Per-VCPU flags (vcpu_flags).
   16.50 @@ -345,57 +347,55 @@ extern struct domain *domain_list;
   16.51  #define _VCPUF_fpu_dirtied     1
   16.52  #define VCPUF_fpu_dirtied      (1UL<<_VCPUF_fpu_dirtied)
   16.53   /* Domain is blocked waiting for an event. */
   16.54 -#define _VCPUF_blocked         3
   16.55 +#define _VCPUF_blocked         2
   16.56  #define VCPUF_blocked          (1UL<<_VCPUF_blocked)
   16.57 - /* Domain is paused by controller software. */
   16.58 -#define _VCPUF_ctrl_pause      4
   16.59 -#define VCPUF_ctrl_pause       (1UL<<_VCPUF_ctrl_pause)
   16.60   /* Currently running on a CPU? */
   16.61 -#define _VCPUF_running         5
   16.62 +#define _VCPUF_running         3
   16.63  #define VCPUF_running          (1UL<<_VCPUF_running)
   16.64   /* Disables auto-migration between CPUs. */
   16.65 -#define _VCPUF_cpu_pinned      6
   16.66 +#define _VCPUF_cpu_pinned      4
   16.67  #define VCPUF_cpu_pinned       (1UL<<_VCPUF_cpu_pinned)
   16.68   /* Domain migrated between CPUs. */
   16.69 -#define _VCPUF_cpu_migrated    7
   16.70 +#define _VCPUF_cpu_migrated    5
   16.71  #define VCPUF_cpu_migrated     (1UL<<_VCPUF_cpu_migrated)
   16.72   /* Initialization completed. */
   16.73 -#define _VCPUF_initialised     8
   16.74 +#define _VCPUF_initialised     6
   16.75  #define VCPUF_initialised      (1UL<<_VCPUF_initialised)
   16.76   /* VCPU is not-runnable */
   16.77 -#define _VCPUF_down            9
   16.78 +#define _VCPUF_down            7
   16.79  #define VCPUF_down             (1UL<<_VCPUF_down)
   16.80  
   16.81  /*
   16.82   * Per-domain flags (domain_flags).
   16.83   */
   16.84 - /* Has the guest OS been fully built yet? */
   16.85 -#define _DOMF_constructed      0
   16.86 -#define DOMF_constructed       (1UL<<_DOMF_constructed)
   16.87   /* Is this one of the per-CPU idle domains? */
   16.88 -#define _DOMF_idle_domain      1
   16.89 +#define _DOMF_idle_domain      0
   16.90  #define DOMF_idle_domain       (1UL<<_DOMF_idle_domain)
   16.91   /* Is this domain privileged? */
   16.92 -#define _DOMF_privileged       2
   16.93 +#define _DOMF_privileged       1
   16.94  #define DOMF_privileged        (1UL<<_DOMF_privileged)
   16.95   /* May this domain do IO to physical devices? */
   16.96 -#define _DOMF_physdev_access   3
   16.97 +#define _DOMF_physdev_access   2
   16.98  #define DOMF_physdev_access    (1UL<<_DOMF_physdev_access)
   16.99   /* Guest shut itself down for some reason. */
  16.100 -#define _DOMF_shutdown         4
  16.101 +#define _DOMF_shutdown         3
  16.102  #define DOMF_shutdown          (1UL<<_DOMF_shutdown)
  16.103   /* Guest is in process of shutting itself down (becomes DOMF_shutdown). */
  16.104 -#define _DOMF_shuttingdown     5
  16.105 +#define _DOMF_shuttingdown     4
  16.106  #define DOMF_shuttingdown      (1UL<<_DOMF_shuttingdown)
  16.107   /* Death rattle. */
  16.108 -#define _DOMF_dying            6
  16.109 +#define _DOMF_dying            5
  16.110  #define DOMF_dying             (1UL<<_DOMF_dying)
  16.111 + /* Domain is paused by controller software. */
  16.112 +#define _DOMF_ctrl_pause       6
  16.113 +#define DOMF_ctrl_pause        (1UL<<_DOMF_ctrl_pause)
  16.114  
  16.115  static inline int domain_runnable(struct vcpu *v)
  16.116  {
  16.117      return ( (atomic_read(&v->pausecnt) == 0) &&
  16.118 -             !(v->vcpu_flags & (VCPUF_blocked|VCPUF_ctrl_pause|VCPUF_down)) &&
  16.119 -             !(v->domain->domain_flags & (DOMF_shutdown|DOMF_shuttingdown)) );
  16.120 +             !(v->vcpu_flags & (VCPUF_blocked|VCPUF_down)) &&
  16.121 +             !(v->domain->domain_flags &
  16.122 +               (DOMF_shutdown|DOMF_shuttingdown|DOMF_ctrl_pause)) );
  16.123  }
  16.124  
  16.125  void vcpu_pause(struct vcpu *v);