extern unsigned long dom_fw_setup(struct domain *, char *, int);
/* this belongs in include/asm, but there doesn't seem to be a suitable place */
-void free_perdomain_pt(struct domain *d)
+void arch_domain_destroy(struct domain *d)
{
- printf("free_perdomain_pt: not implemented\n");
+ printf("arch_domain_destroy: not implemented\n");
//free_page((unsigned long)d->mm.perdomain_pt);
+ free_xenheap_page(d->shared_info);
}
static void default_idle(void)
memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
}
-int arch_do_createdomain(struct vcpu *v)
+int arch_domain_create(struct domain *d)
{
- struct domain *d = v->domain;
struct thread_info *ti = alloc_thread_info(v);
/* Clear thread_info to clear some important fields, like preempt_count */
printk("Can't allocate pgd for domain %d\n",d->domain_id);
return -ENOMEM;
}
- printf ("arch_do_create_domain: domain=%p\n", d);
+ printf ("arch_domain_create: domain=%p\n", d);
return 0;
}
printk("About to call scheduler_init()\n");
scheduler_init();
idle_vcpu[0] = (struct vcpu*) ia64_r13;
- idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
+ idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
BUG_ON(idle_domain == NULL);
late_setup_arch(&cmdline);
/* Create initial domain 0. */
-printk("About to call do_createdomain()\n");
- dom0 = do_createdomain(0, 0);
+printk("About to call domain_create()\n");
+ dom0 = domain_create(0, 0);
#ifdef CLONE_DOMAIN0
{
int i;
for (i = 0; i < CLONE_DOMAIN0; i++) {
- clones[i] = do_createdomain(i+1, 0);
+ clones[i] = domain_create(i+1, 0);
if ( clones[i] == NULL )
panic("Error creating domain0 clone %d\n",i);
}
v->arch.flags = TF_kernel_mode;
if ( is_idle_domain(d) )
+ {
percpu_ctxt[vcpu_id].curr_vcpu = v;
-
- if ( (v->vcpu_id = vcpu_id) != 0 )
+ v->arch.schedule_tail = continue_idle_domain;
+ }
+ else
{
- v->arch.schedule_tail = d->vcpu[0]->arch.schedule_tail;
- v->arch.perdomain_ptes =
- d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
+ v->arch.schedule_tail = continue_nonidle_domain;
}
+ v->arch.perdomain_ptes =
+ d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
+
+ v->arch.guest_vtable = __linear_l2_table;
+ v->arch.shadow_vtable = __shadow_linear_l2_table;
+#if defined(__x86_64__)
+ v->arch.guest_vl3table = __linear_l3_table;
+ v->arch.guest_vl4table = __linear_l4_table;
+#endif
+
return v;
}
void free_vcpu_struct(struct vcpu *v)
{
- BUG_ON(v->next_in_list != NULL);
- if ( v->vcpu_id != 0 )
- v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL;
xfree(v);
}
-void free_perdomain_pt(struct domain *d)
-{
- free_xenheap_pages(
- d->arch.mm_perdomain_pt,
- get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
-
-#ifdef __x86_64__
- free_xenheap_page(d->arch.mm_perdomain_l2);
- free_xenheap_page(d->arch.mm_perdomain_l3);
-#endif
-}
-
-int arch_do_createdomain(struct vcpu *v)
+int arch_domain_create(struct domain *d)
{
- struct domain *d = v->domain;
l1_pgentry_t gdt_l1e;
int vcpuid, pdpt_order, rc;
#ifdef __x86_64__
d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order);
if ( d->arch.mm_perdomain_pt == NULL )
goto fail_nomem;
-
memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order);
- v->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
/*
* Map Xen segments into every VCPU's GDT, irrespective of whether every
d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
- v->arch.guest_vtable = __linear_l2_table;
- v->arch.shadow_vtable = __shadow_linear_l2_table;
-
#if defined(__i386__)
mapcache_init(d);
#else /* __x86_64__ */
- v->arch.guest_vl3table = __linear_l3_table;
- v->arch.guest_vl4table = __linear_l4_table;
-
d->arch.mm_perdomain_l2 = alloc_xenheap_page();
d->arch.mm_perdomain_l3 = alloc_xenheap_page();
if ( (d->arch.mm_perdomain_l2 == NULL) ||
goto fail_nomem;
memset(d->shared_info, 0, PAGE_SIZE);
- v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
}
- v->arch.schedule_tail = is_idle_domain(d) ?
- continue_idle_domain : continue_nonidle_domain;
-
return 0;
fail_nomem:
return -ENOMEM;
}
+void arch_domain_destroy(struct domain *d)
+{
+ free_xenheap_pages(
+ d->arch.mm_perdomain_pt,
+ get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
+
+#ifdef __x86_64__
+ free_xenheap_page(d->arch.mm_perdomain_l2);
+ free_xenheap_page(d->arch.mm_perdomain_l3);
+#endif
+
+ free_xenheap_page(d->shared_info);
+}
+
/* This is called by arch_final_setup_guest and do_boot_vcpu */
int arch_set_info_guest(
struct vcpu *v, struct vcpu_guest_context *c)
scheduler_init();
- idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
+ idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
BUG_ON(idle_domain == NULL);
set_current(idle_domain->vcpu[0]);
acm_init(&initrdidx, mbi, initial_images_start);
/* Create initial domain 0. */
- dom0 = do_createdomain(0, 0);
+ dom0 = domain_create(0, 0);
if ( dom0 == NULL )
panic("Error creating domain 0\n");
pro = i;
ret = -ENOMEM;
- if ( (d = do_createdomain(dom, pro)) == NULL )
+ if ( (d = domain_create(dom, pro)) == NULL )
break;
memcpy(d->handle, op->u.createdomain.handle,
struct domain *dom0;
-struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
+struct domain *domain_create(domid_t dom_id, unsigned int cpu)
{
struct domain *d, **pd;
struct vcpu *v;
INIT_LIST_HEAD(&d->page_list);
INIT_LIST_HEAD(&d->xenpage_list);
+ rangeset_domain_initialise(d);
+
if ( !is_idle_domain(d) )
+ {
set_bit(_DOMF_ctrl_pause, &d->domain_flags);
+ if ( evtchn_init(d) != 0 )
+ goto fail1;
+ if ( grant_table_create(d) != 0 )
+ goto fail2;
+ }
- if ( !is_idle_domain(d) &&
- ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
- goto fail1;
-
- if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
- goto fail2;
+ if ( arch_domain_create(d) != 0 )
+ goto fail3;
- rangeset_domain_initialise(d);
+ 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) ||
- (arch_do_createdomain(v) != 0) )
- goto fail3;
+ if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
+ goto fail5;
if ( !is_idle_domain(d) )
{
return d;
+ fail5:
+ free_vcpu(v);
+ fail4:
+ arch_domain_destroy(d);
fail3:
- rangeset_domain_destroy(d);
+ if ( !is_idle_domain(d) )
+ grant_table_destroy(d);
fail2:
- grant_table_destroy(d);
+ if ( !is_idle_domain(d) )
+ evtchn_destroy(d);
fail1:
- evtchn_destroy(d);
+ rangeset_domain_destroy(d);
free_domain(d);
return NULL;
}
/* Release resources belonging to task @p. */
-void domain_destruct(struct domain *d)
+void domain_destroy(struct domain *d)
{
struct domain **pd;
atomic_t old, new;
BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
- /* May be already destructed, or get_domain() can race us. */
+ /* May be already destroyed, or get_domain() can race us. */
_atomic_set(old, 0);
- _atomic_set(new, DOMAIN_DESTRUCTED);
+ _atomic_set(new, DOMAIN_DESTROYED);
old = atomic_compareandswap(old, new, &d->refcnt);
if ( _atomic_read(old) != 0 )
return;
evtchn_destroy(d);
grant_table_destroy(d);
- free_perdomain_pt(d);
- free_xenheap_page(d->shared_info);
+ arch_domain_destroy(d);
free_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];
v->cpu_affinity = is_idle_domain(d) ?
cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
if ( vcpu_id != 0 )
{
- v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
d->vcpu[v->vcpu_id-1]->next_in_list = v;
- set_bit(_VCPUF_down, &v->vcpu_flags);
+ if ( !is_idle_domain(d) )
+ set_bit(_VCPUF_down, &v->vcpu_flags);
}
return v;
}
+void free_vcpu(struct vcpu *v)
+{
+ /* NB. Rest of destruction is done in free_domain(). */
+ sched_rem_domain(v);
+}
+
struct domain *alloc_domain(void)
{
struct domain *d;
#include <asm/vmx_platform.h>
#include <xen/list.h>
-extern int arch_do_createdomain(struct vcpu *);
-
extern void domain_relinquish_resources(struct domain *);
struct arch_domain {
extern void free_vcpu_struct(struct vcpu *v);
-extern int arch_do_createdomain(struct vcpu *v);
+extern int arch_domain_create(struct domain *d);
+
+extern void arch_domain_destroy(struct domain *d);
extern int arch_set_info_guest(
struct vcpu *v, struct vcpu_guest_context *c);
-extern void free_perdomain_pt(struct domain *d);
-
extern void domain_relinquish_resources(struct domain *d);
extern void dump_pageframe_info(struct domain *d);
struct vcpu *alloc_vcpu(
struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
+void free_vcpu(struct vcpu *v);
struct domain *alloc_domain(void);
void free_domain(struct domain *d);
-#define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */
+#define DOMAIN_DESTROYED (1<<31) /* assumes atomic_t is >= 32 bits */
#define put_domain(_d) \
- if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destruct(_d)
+ if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destroy(_d)
/*
* Use this when you don't have an existing reference to @d. It returns
- * FALSE if @d is being destructed.
+ * FALSE if @d is being destroyed.
*/
static always_inline int get_domain(struct domain *d)
{
do
{
old = seen;
- if ( unlikely(_atomic_read(old) & DOMAIN_DESTRUCTED) )
+ if ( unlikely(_atomic_read(old) & DOMAIN_DESTROYED) )
return 0;
_atomic_set(new, _atomic_read(old) + 1);
seen = atomic_compareandswap(old, new, &d->refcnt);
/*
* Use this when you already have, or are borrowing, a reference to @d.
- * In this case we know that @d cannot be destructed under our feet.
+ * In this case we know that @d cannot be destroyed under our feet.
*/
static inline void get_knownalive_domain(struct domain *d)
{
atomic_inc(&d->refcnt);
- ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTRUCTED));
+ ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
}
-extern struct domain *do_createdomain(
+extern struct domain *domain_create(
domid_t dom_id, unsigned int cpu);
extern int construct_dom0(
struct domain *d,
extern int set_info_guest(struct domain *d, dom0_setvcpucontext_t *);
struct domain *find_domain_by_id(domid_t dom);
-extern void domain_destruct(struct domain *d);
+extern void domain_destroy(struct domain *d);
extern void domain_kill(struct domain *d);
extern void domain_shutdown(struct domain *d, u8 reason);
extern void domain_pause_for_debugger(void);