WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [XEN] Separate domain creation from vcpu

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Separate domain creation from vcpu creation.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 05 Jul 2006 15:00:31 +0000
Delivery-date: Wed, 05 Jul 2006 08:02:40 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 462d6e4cb29a620685f7c382a2372edcc99e2e4a
# Parent  222b492cc0635e9f6ebf2a60da2b8398821e4c5f
[XEN] Separate domain creation from vcpu creation.
Creating a domain no longer creates vcpu0 -- that is now
done later.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/xensetup.c |   10 ++--
 xen/arch/x86/domain.c        |    2 
 xen/arch/x86/setup.c         |    9 ++-
 xen/arch/x86/traps.c         |    7 +--
 xen/common/dom0_ops.c        |  100 ++++++++++++++++++++++---------------------
 xen/common/domain.c          |   98 +++++++++++++++++++++++++-----------------
 xen/common/event_channel.c   |    7 ++-
 xen/common/sched_sedf.c      |    2 
 xen/drivers/char/console.c   |    2 
 xen/include/xen/sched.h      |   25 +++++++---
 10 files changed, 154 insertions(+), 108 deletions(-)

diff -r 222b492cc063 -r 462d6e4cb29a xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/arch/ia64/xen/xensetup.c      Wed Jul 05 14:27:27 2006 +0100
@@ -425,8 +425,9 @@ void start_kernel(void)
 
     scheduler_init();
     idle_vcpu[0] = (struct vcpu*) ia64_r13;
-    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
-    BUG_ON(idle_domain == NULL);
+    idle_domain = domain_create(IDLE_DOMAIN_ID);
+    if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
+        BUG();
 
     late_setup_arch(&cmdline);
     alloc_dom_xen_and_dom_io();
@@ -503,9 +504,8 @@ printk("num_online_cpus=%d, max_cpus=%d\
     }
 
     /* Create initial domain 0. */
-    dom0 = domain_create(0, 0);
-
-    if ( dom0 == NULL )
+    dom0 = domain_create(0);
+    if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
         panic("Error creating domain 0\n");
 
     set_bit(_DOMF_privileged, &dom0->domain_flags);
diff -r 222b492cc063 -r 462d6e4cb29a xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/arch/x86/domain.c     Wed Jul 05 14:27:27 2006 +0100
@@ -951,7 +951,7 @@ void domain_relinquish_resources(struct 
         }
     }
 
-    if ( hvm_guest(d->vcpu[0]) )
+    if ( d->vcpu[0] && hvm_guest(d->vcpu[0]) )
         hvm_relinquish_guest_resources(d);
 
     shadow_mode_disable(d);
diff -r 222b492cc063 -r 462d6e4cb29a xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/arch/x86/setup.c      Wed Jul 05 14:27:27 2006 +0100
@@ -439,8 +439,9 @@ void __init __start_xen(multiboot_info_t
 
     scheduler_init();
 
-    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
-    BUG_ON(idle_domain == NULL);
+    idle_domain = domain_create(IDLE_DOMAIN_ID);
+    if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
+        BUG();
 
     set_current(idle_domain->vcpu[0]);
     this_cpu(curr_vcpu) = idle_domain->vcpu[0];
@@ -537,8 +538,8 @@ void __init __start_xen(multiboot_info_t
     acm_init(&initrdidx, mbi, initial_images_start);
 
     /* Create initial domain 0. */
-    dom0 = domain_create(0, 0);
-    if ( dom0 == NULL )
+    dom0 = domain_create(0);
+    if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
         panic("Error creating domain 0\n");
 
     set_bit(_DOMF_privileged, &dom0->domain_flags);
diff -r 222b492cc063 -r 462d6e4cb29a xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/arch/x86/traps.c      Wed Jul 05 14:27:27 2006 +0100
@@ -1397,13 +1397,14 @@ static void nmi_dom0_report(unsigned int
 static void nmi_dom0_report(unsigned int reason_idx)
 {
     struct domain *d;
-
-    if ( (d = dom0) == NULL )
+    struct vcpu   *v;
+
+    if ( ((d = dom0) == NULL) || ((v = d->vcpu[0]) == NULL) )
         return;
 
     set_bit(reason_idx, &d->shared_info->arch.nmi_reason);
 
-    if ( test_and_set_bit(_VCPUF_nmi_pending, &d->vcpu[0]->vcpu_flags) )
+    if ( test_and_set_bit(_VCPUF_nmi_pending, &v->vcpu_flags) )
         raise_softirq(NMI_SOFTIRQ); /* not safe to wake up a vcpu here */
 }
 
diff -r 222b492cc063 -r 462d6e4cb29a xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/common/dom0_ops.c     Wed Jul 05 14:27:27 2006 +0100
@@ -90,6 +90,44 @@ static void getdomaininfo(struct domain 
     memcpy(info->handle, d->handle, sizeof(xen_domain_handle_t));
 }
 
+static unsigned int default_vcpu0_location(void)
+{
+    struct domain *d;
+    struct vcpu   *v;
+    unsigned int   i, cpu, cnt[NR_CPUS] = { 0 };
+    cpumask_t      cpu_exclude_map;
+
+    /* Do an initial CPU placement. Pick the least-populated CPU. */
+    read_lock(&domlist_lock);
+    for_each_domain ( d )
+        for_each_vcpu ( d, v )
+        if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
+            cnt[v->processor]++;
+    read_unlock(&domlist_lock);
+
+    /*
+     * If we're on a HT system, we only auto-allocate to a non-primary HT. We 
+     * favour high numbered CPUs in the event of a tie.
+     */
+    cpu = first_cpu(cpu_sibling_map[0]);
+    if ( cpus_weight(cpu_sibling_map[0]) > 1 )
+        cpu = next_cpu(cpu, cpu_sibling_map[0]);
+    cpu_exclude_map = cpu_sibling_map[0];
+    for_each_online_cpu ( i )
+    {
+        if ( cpu_isset(i, cpu_exclude_map) )
+            continue;
+        if ( (i == first_cpu(cpu_sibling_map[i])) &&
+             (cpus_weight(cpu_sibling_map[i]) > 1) )
+            continue;
+        cpus_or(cpu_exclude_map, cpu_exclude_map, cpu_sibling_map[i]);
+        if ( cnt[i] <= cnt[cpu] )
+            cpu = i;
+    }
+
+    return cpu;
+}
+
 long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
 {
     long ret = 0;
@@ -150,7 +188,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
         if ( d != NULL )
         {
             ret = -EINVAL;
-            if ( (d != current->domain) && 
+            if ( (d != current->domain) && (d->vcpu[0] != NULL) &&
                  test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
             {
                 domain_unpause_by_systemcontroller(d);
@@ -164,11 +202,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
     case DOM0_CREATEDOMAIN:
     {
         struct domain *d;
-        unsigned int   pro;
         domid_t        dom;
-        struct vcpu   *v;
-        unsigned int   i, cnt[NR_CPUS] = { 0 };
-        cpumask_t      cpu_exclude_map;
         static domid_t rover = 0;
 
         /*
@@ -202,36 +236,8 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
             rover = dom;
         }
 
-        /* Do an initial CPU placement. Pick the least-populated CPU. */
-        read_lock(&domlist_lock);
-        for_each_domain ( d )
-            for_each_vcpu ( d, v )
-                if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
-                    cnt[v->processor]++;
-        read_unlock(&domlist_lock);
-        
-        /*
-         * If we're on a HT system, we only auto-allocate to a non-primary HT.
-         * We favour high numbered CPUs in the event of a tie.
-         */
-        pro = first_cpu(cpu_sibling_map[0]);
-        if ( cpus_weight(cpu_sibling_map[0]) > 1 )
-            pro = next_cpu(pro, cpu_sibling_map[0]);
-        cpu_exclude_map = cpu_sibling_map[0];
-        for_each_online_cpu ( i )
-        {
-            if ( cpu_isset(i, cpu_exclude_map) )
-                continue;
-            if ( (i == first_cpu(cpu_sibling_map[i])) &&
-                 (cpus_weight(cpu_sibling_map[i]) > 1) )
-                continue;
-            cpus_or(cpu_exclude_map, cpu_exclude_map, cpu_sibling_map[i]);
-            if ( cnt[i] <= cnt[pro] )
-                pro = i;
-        }
-
         ret = -ENOMEM;
-        if ( (d = domain_create(dom, pro)) == NULL )
+        if ( (d = domain_create(dom)) == NULL )
             break;
 
         memcpy(d->handle, op->u.createdomain.handle,
@@ -258,14 +264,8 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
         if ( (d = find_domain_by_id(op->u.max_vcpus.domain)) == NULL )
             break;
 
-        /*
-         * Can only create new VCPUs while the domain is not fully constructed
-         * (and hence not runnable). Xen needs auditing for races before
-         * removing this check.
-         */
-        ret = -EINVAL;
-        if ( test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
-            goto maxvcpu_out;
+        /* Needed, for example, to ensure writable p.t. state is synced. */
+        domain_pause(d);
 
         /* We cannot reduce maximum VCPUs. */
         ret = -EINVAL;
@@ -275,17 +275,21 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
         ret = -ENOMEM;
         for ( i = 0; i < max; i++ )
         {
-            if ( d->vcpu[i] == NULL )
-            {
-                cpu = (d->vcpu[i-1]->processor + 1) % num_online_cpus();
-                if ( alloc_vcpu(d, i, cpu) == NULL )
-                    goto maxvcpu_out;
-            }
+            if ( d->vcpu[i] != NULL )
+                continue;
+
+            cpu = (i == 0) ?
+                default_vcpu0_location() :
+                (d->vcpu[i-1]->processor + 1) % num_online_cpus();
+
+            if ( alloc_vcpu(d, i, cpu) == NULL )
+                goto maxvcpu_out;
         }
 
         ret = 0;
 
     maxvcpu_out:
+        domain_unpause(d);
         put_domain(d);
     }
     break;
diff -r 222b492cc063 -r 462d6e4cb29a xen/common/domain.c
--- a/xen/common/domain.c       Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/common/domain.c       Wed Jul 05 14:27:27 2006 +0100
@@ -46,6 +46,7 @@ struct domain *alloc_domain(domid_t domi
     atomic_set(&d->refcnt, 1);
     spin_lock_init(&d->big_lock);
     spin_lock_init(&d->page_alloc_lock);
+    spin_lock_init(&d->pause_lock);
     INIT_LIST_HEAD(&d->page_list);
     INIT_LIST_HEAD(&d->xenpage_list);
 
@@ -81,8 +82,8 @@ struct vcpu *alloc_vcpu(
     v->domain = d;
     v->vcpu_id = vcpu_id;
     v->processor = cpu_id;
-    atomic_set(&v->pausecnt, 0);
     v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
+    spin_lock_init(&v->pause_lock);
 
     v->cpu_affinity = is_idle_domain(d) ?
         cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
@@ -110,30 +111,22 @@ struct vcpu *alloc_idle_vcpu(unsigned in
 {
     struct domain *d;
     struct vcpu *v;
-    unsigned int vcpu_id;
-
-    if ((vcpu_id = cpu_id % MAX_VIRT_CPUS) == 0)
-    {
-        d = domain_create(IDLE_DOMAIN_ID, cpu_id);
-        BUG_ON(d == NULL);
-        v = d->vcpu[0];
-    }
-    else
-    {
-        d = idle_vcpu[cpu_id - vcpu_id]->domain;
-        BUG_ON(d == NULL);
-        v = alloc_vcpu(d, vcpu_id, cpu_id);
-    }
-
+    unsigned int vcpu_id = cpu_id % MAX_VIRT_CPUS;
+
+    d = (vcpu_id == 0) ?
+        domain_create(IDLE_DOMAIN_ID) :
+        idle_vcpu[cpu_id - vcpu_id]->domain;
+    BUG_ON(d == NULL);
+
+    v = alloc_vcpu(d, vcpu_id, cpu_id);
     idle_vcpu[cpu_id] = v;
 
     return v;
 }
 
-struct domain *domain_create(domid_t domid, unsigned int cpu)
+struct domain *domain_create(domid_t domid)
 {
     struct domain *d, **pd;
-    struct vcpu *v;
 
     if ( (d = alloc_domain(domid)) == NULL )
         return NULL;
@@ -152,13 +145,10 @@ struct domain *domain_create(domid_t dom
     if ( arch_domain_create(d) != 0 )
         goto fail3;
 
-    if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
-        goto fail4;
-
     d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
     d->irq_caps   = rangeset_new(d, "Interrupts", 0);
     if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
-        goto fail4; /* NB. alloc_vcpu() is undone in free_domain() */
+        goto fail4;
 
     if ( !is_idle_domain(d) )
     {
@@ -327,11 +317,12 @@ void domain_shutdown(struct domain *d, u
     d->shutdown_code = reason;
 
     /* Put every vcpu to sleep, but don't wait (avoids inter-vcpu deadlock). */
+    spin_lock(&d->pause_lock);
+    d->pause_count++;
+    set_bit(_DOMF_paused, &d->domain_flags);
+    spin_unlock(&d->pause_lock);
     for_each_vcpu ( d, v )
-    {
-        atomic_inc(&v->pausecnt);
         vcpu_sleep_nosync(v);
-    }
 
     get_knownalive_domain(d);
     domain_shuttingdown[smp_processor_id()] = d;
@@ -398,34 +389,65 @@ void domain_destroy(struct domain *d)
 
 void vcpu_pause(struct vcpu *v)
 {
-    BUG_ON(v == current);
-    atomic_inc(&v->pausecnt);
+    ASSERT(v != current);
+
+    spin_lock(&v->pause_lock);
+    if ( v->pause_count++ == 0 )
+        set_bit(_VCPUF_paused, &v->vcpu_flags);
+    spin_unlock(&v->pause_lock);
+
     vcpu_sleep_sync(v);
 }
 
+void vcpu_unpause(struct vcpu *v)
+{
+    int wake;
+
+    ASSERT(v != current);
+
+    spin_lock(&v->pause_lock);
+    wake = (--v->pause_count == 0);
+    if ( wake )
+        clear_bit(_VCPUF_paused, &v->vcpu_flags);
+    spin_unlock(&v->pause_lock);
+
+    if ( wake )
+        vcpu_wake(v);
+}
+
 void domain_pause(struct domain *d)
 {
     struct vcpu *v;
 
+    ASSERT(d != current->domain);
+
+    spin_lock(&d->pause_lock);
+    if ( d->pause_count++ == 0 )
+        set_bit(_DOMF_paused, &d->domain_flags);
+    spin_unlock(&d->pause_lock);
+
     for_each_vcpu( d, v )
-        vcpu_pause(v);
+        vcpu_sleep_sync(v);
 
     sync_pagetable_state(d);
 }
 
-void vcpu_unpause(struct vcpu *v)
-{
-    BUG_ON(v == current);
-    if ( atomic_dec_and_test(&v->pausecnt) )
-        vcpu_wake(v);
-}
-
 void domain_unpause(struct domain *d)
 {
     struct vcpu *v;
-
-    for_each_vcpu( d, v )
-        vcpu_unpause(v);
+    int wake;
+
+    ASSERT(d != current->domain);
+
+    spin_lock(&d->pause_lock);
+    wake = (--d->pause_count == 0);
+    if ( wake )
+        clear_bit(_DOMF_paused, &d->domain_flags);
+    spin_unlock(&d->pause_lock);
+
+    if ( wake )
+        for_each_vcpu( d, v )
+            vcpu_wake(v);
 }
 
 void domain_pause_by_systemcontroller(struct domain *d)
diff -r 222b492cc063 -r 462d6e4cb29a xen/common/event_channel.c
--- a/xen/common/event_channel.c        Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/common/event_channel.c        Wed Jul 05 14:27:27 2006 +0100
@@ -525,11 +525,16 @@ void send_guest_global_virq(struct domai
 void send_guest_global_virq(struct domain *d, int virq)
 {
     int port;
+    struct vcpu *v;
     struct evtchn *chn;
 
     ASSERT(virq_is_global(virq));
 
-    port = d->vcpu[0]->virq_to_evtchn[virq];
+    v = d->vcpu[0];
+    if ( unlikely(v == NULL) )
+        return;
+
+    port = v->virq_to_evtchn[virq];
     if ( unlikely(port == 0) )
         return;
 
diff -r 222b492cc063 -r 462d6e4cb29a xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/common/sched_sedf.c   Wed Jul 05 14:27:27 2006 +0100
@@ -1429,6 +1429,8 @@ static int sedf_adjdom(struct domain *p,
     }
     else if ( cmd->direction == SCHED_INFO_GET )
     {
+        if ( p->vcpu[0] == NULL )
+            return -EINVAL;
         cmd->u.sedf.period    = EDOM_INFO(p->vcpu[0])->period;
         cmd->u.sedf.slice     = EDOM_INFO(p->vcpu[0])->slice;
         cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status & EXTRA_AWARE;
diff -r 222b492cc063 -r 462d6e4cb29a xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/drivers/char/console.c        Wed Jul 05 14:27:27 2006 +0100
@@ -279,7 +279,7 @@ static void switch_serial_input(void)
 {
     static char *input_str[2] = { "DOM0", "Xen" };
     xen_rx = !xen_rx;
-    if ( SWITCH_CODE != 0 )
+    if ( (SWITCH_CODE != 0) && (dom0 != NULL) )
     {
         printk("*** Serial input -> %s "
                "(type 'CTRL-%c' three times to switch input to %s).\n",
diff -r 222b492cc063 -r 462d6e4cb29a xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Wed Jul 05 11:31:33 2006 +0100
+++ b/xen/include/xen/sched.h   Wed Jul 05 14:27:27 2006 +0100
@@ -78,9 +78,10 @@ struct vcpu
 
     unsigned long    vcpu_flags;
 
+    spinlock_t       pause_lock;
+    unsigned int     pause_count;
+
     u16              virq_to_evtchn[NR_VIRQS];
-
-    atomic_t         pausecnt;
 
     /* Bitmask of CPUs on which this VCPU may run. */
     cpumask_t        cpu_affinity;
@@ -141,6 +142,10 @@ struct domain
     struct rangeset *irq_caps;
 
     unsigned long    domain_flags;
+
+    spinlock_t       pause_lock;
+    unsigned int     pause_count;
+
     unsigned long    vm_assist;
 
     atomic_t         refcnt;
@@ -220,8 +225,7 @@ static inline void get_knownalive_domain
     ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
 }
 
-extern struct domain *domain_create(
-    domid_t domid, unsigned int cpu);
+extern struct domain *domain_create(domid_t domid);
 extern int construct_dom0(
     struct domain *d,
     unsigned long image_start, unsigned long image_len, 
@@ -368,6 +372,9 @@ extern struct domain *domain_list;
  /* VCPU is polling a set of event channels (SCHEDOP_poll). */
 #define _VCPUF_polling         10
 #define VCPUF_polling          (1UL<<_VCPUF_polling)
+ /* VCPU is paused by the hypervisor? */
+#define _VCPUF_paused          11
+#define VCPUF_paused           (1UL<<_VCPUF_paused)
 
 /*
  * Per-domain flags (domain_flags).
@@ -390,12 +397,16 @@ extern struct domain *domain_list;
  /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
 #define _DOMF_polling          5
 #define DOMF_polling           (1UL<<_DOMF_polling)
+ /* Domain is paused by the hypervisor? */
+#define _DOMF_paused           6
+#define DOMF_paused            (1UL<<_DOMF_paused)
 
 static inline int vcpu_runnable(struct vcpu *v)
 {
-    return ( (atomic_read(&v->pausecnt) == 0) &&
-             !(v->vcpu_flags & (VCPUF_blocked|VCPUF_down)) &&
-             !(v->domain->domain_flags & (DOMF_shutdown|DOMF_ctrl_pause)) );
+    return ( !(v->vcpu_flags &
+               (VCPUF_blocked|VCPUF_down|VCPUF_paused)) &&
+             !(v->domain->domain_flags &
+               (DOMF_shutdown|DOMF_ctrl_pause|DOMF_paused)) );
 }
 
 void vcpu_pause(struct vcpu *v);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [XEN] Separate domain creation from vcpu creation., Xen patchbot-unstable <=