aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-08-19 15:39:07 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-08-19 15:39:07 +0000
commite23d7726d5aebf24e119fcd33b3438ed64c74a4b (patch)
tree1ccd638b7211fe7033578a0880869dde06b4b7c0
parent8e9f7aa2977967bce51c83adf16e48ad6f378dfc (diff)
downloadxen-e23d7726d5aebf24e119fcd33b3438ed64c74a4b.tar.gz
xen-e23d7726d5aebf24e119fcd33b3438ed64c74a4b.tar.bz2
xen-e23d7726d5aebf24e119fcd33b3438ed64c74a4b.zip
bitkeeper revision 1.1159.44.1 (4124c99bzYQ86nF2sa6s-nSiOfibyQ)
Clean up mapping of I/O memory and Xen-heap memory. We define two 'dummy domains' for this purpose which can be specified to MMUEXT_SET_FOREIGNDOM.
-rw-r--r--linux-2.4.26-xen-sparse/arch/xen/mm/ioremap.c15
-rw-r--r--linux-2.4.26-xen-sparse/drivers/char/mem.c3
-rw-r--r--linux-2.6.7-xen-sparse/arch/xen/i386/mm/ioremap.c15
-rw-r--r--linux-2.6.7-xen-sparse/drivers/char/mem.c3
-rw-r--r--linux-2.6.7-xen-sparse/drivers/xen/privcmd/privcmd.c15
-rw-r--r--tools/libxc/xc.h2
-rw-r--r--tools/libxc/xc_linux_save.c2
-rw-r--r--xen/arch/x86/memory.c81
-rw-r--r--xen/arch/x86/setup.c3
-rw-r--r--xen/common/dom0_ops.c9
-rw-r--r--xen/common/domain.c17
-rw-r--r--xen/common/kernel.c3
-rw-r--r--xen/common/memory.c19
-rw-r--r--xen/common/page_alloc.c2
-rw-r--r--xen/include/asm-x86/mm.h2
-rw-r--r--xen/include/hypervisor-ifs/hypervisor-if.h33
-rw-r--r--xen/include/xen/sched.h15
17 files changed, 152 insertions, 87 deletions
diff --git a/linux-2.4.26-xen-sparse/arch/xen/mm/ioremap.c b/linux-2.4.26-xen-sparse/arch/xen/mm/ioremap.c
index 9cd34cd925..34c95c84b5 100644
--- a/linux-2.4.26-xen-sparse/arch/xen/mm/ioremap.c
+++ b/linux-2.4.26-xen-sparse/arch/xen/mm/ioremap.c
@@ -115,17 +115,10 @@ int direct_remap_area_pages(struct mm_struct *mm,
#define MAX_DIRECTMAP_MMU_QUEUE 130
mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
- if ( domid != 0 )
- {
- u[0].ptr = MMU_EXTENDED_COMMAND;
- u[0].val = MMUEXT_SET_FOREIGNDOM;
- u[0].val |= (unsigned long)domid << 16;
- v = w = &u[1];
- }
- else
- {
- v = w = &u[0];
- }
+ u[0].ptr = MMU_EXTENDED_COMMAND;
+ u[0].val = MMUEXT_SET_FOREIGNDOM;
+ u[0].val |= (unsigned long)domid << 16;
+ v = w = &u[1];
start_address = address;
diff --git a/linux-2.4.26-xen-sparse/drivers/char/mem.c b/linux-2.4.26-xen-sparse/drivers/char/mem.c
index 5635b269aa..f0d8502190 100644
--- a/linux-2.4.26-xen-sparse/drivers/char/mem.c
+++ b/linux-2.4.26-xen-sparse/drivers/char/mem.c
@@ -237,6 +237,9 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
if (!(start_info.flags & SIF_PRIVILEGED))
return -ENXIO;
+ if (file->private_data == NULL)
+ file->private_data = (void *)(unsigned long)DOMID_IO;
+
/* DONTCOPY is essential for Xen as copy_page_range is broken. */
vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6.7-xen-sparse/arch/xen/i386/mm/ioremap.c
index e6d1e95cb4..3fb6ea9aa0 100644
--- a/linux-2.6.7-xen-sparse/arch/xen/i386/mm/ioremap.c
+++ b/linux-2.6.7-xen-sparse/arch/xen/i386/mm/ioremap.c
@@ -415,17 +415,10 @@ int direct_remap_area_pages(struct mm_struct *mm,
#define MAX_DIRECTMAP_MMU_QUEUE 130
mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
- if ( domid != 0 )
- {
- u[0].ptr = MMU_EXTENDED_COMMAND;
- u[0].val = MMUEXT_SET_FOREIGNDOM;
- u[0].val |= (unsigned long)domid << 16;
- v = w = &u[1];
- }
- else
- {
- v = w = &u[0];
- }
+ u[0].ptr = MMU_EXTENDED_COMMAND;
+ u[0].val = MMUEXT_SET_FOREIGNDOM;
+ u[0].val |= (unsigned long)domid << 16;
+ v = w = &u[1];
start_address = address;
diff --git a/linux-2.6.7-xen-sparse/drivers/char/mem.c b/linux-2.6.7-xen-sparse/drivers/char/mem.c
index ceea2b5ffd..ed3df13f65 100644
--- a/linux-2.6.7-xen-sparse/drivers/char/mem.c
+++ b/linux-2.6.7-xen-sparse/drivers/char/mem.c
@@ -247,6 +247,9 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
if (!(start_info.flags & SIF_PRIVILEGED))
return -ENXIO;
+ if (file->private_data == NULL)
+ file->private_data = (void *)(unsigned long)DOMID_IO;
+
/* DONTCOPY is essential for Xen as copy_page_range is broken. */
vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
diff --git a/linux-2.6.7-xen-sparse/drivers/xen/privcmd/privcmd.c b/linux-2.6.7-xen-sparse/drivers/xen/privcmd/privcmd.c
index aa7a1d9a01..c57bdf6b23 100644
--- a/linux-2.6.7-xen-sparse/drivers/xen/privcmd/privcmd.c
+++ b/linux-2.6.7-xen-sparse/drivers/xen/privcmd/privcmd.c
@@ -138,17 +138,10 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
if ( (m.addr + (m.num<<PAGE_SHIFT)) > vma->vm_end )
{ ret = -EFAULT; goto batch_err; }
- if ( m.dom != 0 )
- {
- u[0].ptr = MMU_EXTENDED_COMMAND;
- u[0].val = MMUEXT_SET_FOREIGNDOM;
- u[0].val |= (unsigned long)m.dom << 16;
- v = w = &u[1];
- }
- else
- {
- v = w = &u[0];
- }
+ u[0].ptr = MMU_EXTENDED_COMMAND;
+ u[0].val = MMUEXT_SET_FOREIGNDOM;
+ u[0].val |= (unsigned long)m.dom << 16;
+ v = w = &u[1];
p = m.arr;
addr = m.addr;
diff --git a/tools/libxc/xc.h b/tools/libxc/xc.h
index 974ac975f2..8b54ed0207 100644
--- a/tools/libxc/xc.h
+++ b/tools/libxc/xc.h
@@ -154,6 +154,8 @@ int xc_rrobin_global_set(int xc_handle, u64 slice);
int xc_rrobin_global_get(int xc_handle, u64 *slice);
#define DOMID_SELF (0x7FF0U)
+#define DOMID_IO (0x7FF1U)
+#define DOMID_XEN (0x7FF2U)
typedef struct {
#define EVTCHNSTAT_closed 0 /* Chennel is not in use. */
diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c
index 5a47b30f56..def9f7516d 100644
--- a/tools/libxc/xc_linux_save.c
+++ b/tools/libxc/xc_linux_save.c
@@ -423,7 +423,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
mfn_to_pfn_table_start_mfn = xc_get_m2p_start_mfn( xc_handle );
live_mfn_to_pfn_table =
- mfn_mapper_map_single(xc_handle, 0x7FFFU,
+ mfn_mapper_map_single(xc_handle, DOMID_XEN,
PAGE_SIZE*1024, PROT_READ,
mfn_to_pfn_table_start_mfn );
diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c
index cb0cf2f19a..5152e39648 100644
--- a/xen/arch/x86/memory.c
+++ b/xen/arch/x86/memory.c
@@ -137,14 +137,49 @@ static struct {
*/
#define FOREIGNDOM (percpu_info[smp_processor_id()].foreign ? : current)
-void ptwr_init_backpointers(void);
+/* Private domain structs for DOMID_XEN and DOMID_IO. */
+static struct domain *dom_xen, *dom_io;
void arch_init_memory(void)
{
+ static void ptwr_init_backpointers(void);
+ unsigned long mfn;
+
memset(percpu_info, 0, sizeof(percpu_info));
vm_assist_info[VMASST_TYPE_writeable_pagetables].enable =
ptwr_init_backpointers;
+
+ /* Initialise to a magic of 0x55555555 so easier to spot bugs later. */
+ memset(machine_to_phys_mapping, 0x55, 4<<20);
+
+ /*
+ * Initialise our DOMID_XEN domain.
+ * Any Xen-heap pages that we will allow to be mapped will have
+ * their domain field set to dom_xen.
+ */
+ dom_xen = alloc_domain_struct();
+ atomic_set(&dom_xen->refcnt, 1);
+ dom_xen->domain = DOMID_XEN;
+
+ /*
+ * Initialise our DOMID_IO domain.
+ * This domain owns no pages but is considered a special case when
+ * mapping I/O pages, as the mappings occur at the priv of the caller.
+ */
+ dom_io = alloc_domain_struct();
+ atomic_set(&dom_io->refcnt, 1);
+ dom_io->domain = DOMID_IO;
+
+ /* M2P table is mappable read-only by privileged domains. */
+ for ( mfn = virt_to_phys(&machine_to_phys_mapping[0<<20])>>PAGE_SHIFT;
+ mfn < virt_to_phys(&machine_to_phys_mapping[1<<20])>>PAGE_SHIFT;
+ mfn++ )
+ {
+ frame_table[mfn].u.inuse.count_info = 1 | PGC_allocated;
+ frame_table[mfn].u.inuse.type_info = 1 | PGT_gdt_page; /* non-RW */
+ frame_table[mfn].u.inuse.domain = dom_xen;
+ }
}
static void __invalidate_shadow_ldt(struct domain *d)
@@ -178,7 +213,7 @@ static inline void invalidate_shadow_ldt(struct domain *d)
}
-int alloc_segdesc_page(struct pfn_info *page)
+static int alloc_segdesc_page(struct pfn_info *page)
{
unsigned long *descs = map_domain_mem((page-frame_table) << PAGE_SHIFT);
int i;
@@ -345,11 +380,15 @@ get_page_from_l1e(
if ( unlikely(!pfn_is_ram(pfn)) )
{
- if ( IS_PRIV(current) )
+ /* Revert to caller privileges if FD == DOMID_IO. */
+ if ( d == dom_io )
+ d = current;
+
+ if ( IS_PRIV(d) )
return 1;
- if ( IS_CAPABLE_PHYSDEV(current) )
- return domain_iomem_in_pfn(current, pfn);
+ if ( IS_CAPABLE_PHYSDEV(d) )
+ return domain_iomem_in_pfn(d, pfn);
MEM_LOG("Non-privileged attempt to map I/O space %08lx", pfn);
return 0;
@@ -827,9 +866,16 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
if ( !IS_PRIV(d) )
{
- MEM_LOG("Dom %u has no privilege to set subject domain",
- d->domain);
- okay = 0;
+ switch ( domid )
+ {
+ case DOMID_IO:
+ get_knownalive_domain(e = dom_io);
+ break;
+ default:
+ MEM_LOG("Dom %u cannot set foreign dom\n", d->domain);
+ okay = 0;
+ break;
+ }
}
else
{
@@ -839,8 +885,19 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
percpu_info[cpu].foreign = e = find_domain_by_id(domid);
if ( e == NULL )
{
- MEM_LOG("Unknown domain '%u'", domid);
- okay = 0;
+ switch ( domid )
+ {
+ case DOMID_XEN:
+ get_knownalive_domain(e = dom_xen);
+ break;
+ case DOMID_IO:
+ get_knownalive_domain(e = dom_io);
+ break;
+ default:
+ MEM_LOG("Unknown domain '%u'", domid);
+ okay = 0;
+ break;
+ }
}
}
break;
@@ -926,7 +983,7 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
* the lock so they'll spin waiting for us.
*/
if ( unlikely(e->tot_pages++ == 0) )
- get_domain(e);
+ get_knownalive_domain(e);
list_add_tail(&page->list, &e->page_list);
reassign_fail:
@@ -1493,7 +1550,7 @@ int ptwr_do_page_fault(unsigned long addr)
return 0;
}
-void ptwr_init_backpointers(void)
+static void ptwr_init_backpointers(void)
{
struct pfn_info *page;
unsigned long pde;
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index e629930ab6..3d18ebd4ee 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -16,6 +16,7 @@
#include <asm/domain_page.h>
#include <asm/pdb.h>
+extern void arch_init_memory(void);
extern void init_IRQ(void);
extern void trap_init(void);
extern void time_init(void);
@@ -360,6 +361,8 @@ void __init start_of_day(void)
time_init(); /* installs software handler for HZ clock. */
init_apic_mappings(); /* make APICs addressable in our pagetables. */
+ arch_init_memory();
+
#ifndef CONFIG_SMP
APIC_init_uniprocessor();
#else
diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
index 6c8abcb8f8..1f1e911b73 100644
--- a/xen/common/dom0_ops.c
+++ b/xen/common/dom0_ops.c
@@ -25,13 +25,14 @@
extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int);
extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op);
-extern void arch_getdomaininfo_ctxt(struct domain *, full_execution_context_t *);
+extern void arch_getdomaininfo_ctxt(
+ struct domain *, full_execution_context_t *);
static inline int is_free_domid(domid_t dom)
{
struct domain *d;
- if ( dom >= DOMID_SELF )
+ if ( dom >= DOMID_FIRST_RESERVED )
return 0;
if ( (d = find_domain_by_id(dom)) == NULL )
@@ -66,7 +67,7 @@ static int allocate_domid(domid_t *pdom)
}
/* Couldn't find a free domain id in 0..topdom, try higher. */
- for ( dom = topdom; dom < DOMID_SELF; dom++ )
+ for ( dom = topdom; dom < DOMID_FIRST_RESERVED; dom++ )
{
if ( is_free_domid(dom) )
{
@@ -167,7 +168,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
domid_t dom;
dom = op->u.createdomain.domain;
- if ( (dom > 0) && (dom < DOMID_SELF) )
+ if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
{
ret = -EINVAL;
if ( !is_free_domid(dom) )
diff --git a/xen/common/domain.c b/xen/common/domain.c
index cac4c2edf0..4ca9f58135 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -39,11 +39,18 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
d->domain = dom_id;
d->processor = cpu;
d->create_time = NOW();
- /* Initialise the sleep_lock */
spin_lock_init(&d->sleep_lock);
memcpy(&d->thread, &idle0_task.thread, sizeof(d->thread));
+ spin_lock_init(&d->page_alloc_lock);
+ INIT_LIST_HEAD(&d->page_list);
+ d->max_pages = d->tot_pages = 0;
+
+ /* Per-domain PCI-device list. */
+ spin_lock_init(&d->pcidev_lock);
+ INIT_LIST_HEAD(&d->pcidev_list);
+
if ( d->domain != IDLE_DOMAIN_ID )
{
if ( init_event_channels(d) != 0 )
@@ -59,16 +66,8 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
d->addr_limit = USER_DS;
- spin_lock_init(&d->page_alloc_lock);
- INIT_LIST_HEAD(&d->page_list);
- d->max_pages = d->tot_pages = 0;
-
arch_do_createdomain(d);
- /* Per-domain PCI-device list. */
- spin_lock_init(&d->pcidev_lock);
- INIT_LIST_HEAD(&d->pcidev_list);
-
sched_add_domain(d);
write_lock_irqsave(&tasklist_lock, flags);
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index d4cd43ae9d..707cede7f1 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -304,9 +304,6 @@ void cmain(multiboot_info_t *mbi)
start_of_day();
- /* Add CPU0 idle task to the task hash list */
- task_hash[TASK_HASH(IDLE_DOMAIN_ID)] = &idle0_task;
-
/* Create initial domain 0. */
new_dom = do_createdomain(0, 0);
if ( new_dom == NULL )
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 8e513b55e3..2dfdd10e07 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -37,14 +37,8 @@ struct pfn_info *frame_table;
unsigned long frame_table_size;
unsigned long max_page;
-extern void arch_init_memory(void);
-
void __init init_frametable(void *frametable_vstart, unsigned long nr_pages)
{
- unsigned long mfn;
-
- arch_init_memory();
-
max_page = nr_pages;
frame_table_size = nr_pages * sizeof(struct pfn_info);
frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK;
@@ -54,17 +48,4 @@ void __init init_frametable(void *frametable_vstart, unsigned long nr_pages)
panic("Not enough memory for frame table - reduce Xen heap size?\n");
memset(frame_table, 0, frame_table_size);
-
- /* Initialise to a magic of 0x55555555 so easier to spot bugs later. */
- memset(machine_to_phys_mapping, 0x55, 4<<20);
-
- /* Pin the ownership of the MP table so that DOM0 can map it later. */
- for ( mfn = virt_to_phys(&machine_to_phys_mapping[0<<20])>>PAGE_SHIFT;
- mfn < virt_to_phys(&machine_to_phys_mapping[1<<20])>>PAGE_SHIFT;
- mfn++ )
- {
- frame_table[mfn].u.inuse.count_info = 1 | PGC_allocated;
- frame_table[mfn].u.inuse.type_info = 1 | PGT_gdt_page; /* non-RW */
- frame_table[mfn].u.inuse.domain = &idle0_task;
- }
}
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index b3b056fd68..323ecd244e 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -393,7 +393,7 @@ struct pfn_info *alloc_domheap_pages(struct domain *d, int order)
}
if ( unlikely(d->tot_pages == 0) )
- get_domain(d);
+ get_knownalive_domain(d);
d->tot_pages += 1 << order;
diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
index c0143352e0..a2fc40e0b3 100644
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -108,7 +108,7 @@ struct pfn_info
/* _dom holds an allocation reference */ \
(_pfn)->u.inuse.count_info = PGC_allocated | 1; \
if ( unlikely((_dom)->xenheap_pages++ == 0) ) \
- get_domain(_dom); \
+ get_knownalive_domain(_dom); \
spin_unlock(&(_dom)->page_alloc_lock); \
} while ( 0 )
diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h
index 1c28062c5b..efcaeb8abb 100644
--- a/xen/include/hypervisor-ifs/hypervisor-if.h
+++ b/xen/include/hypervisor-ifs/hypervisor-if.h
@@ -87,8 +87,10 @@
* ptr[1:0] == MMU_NORMAL_PT_UPDATE:
* Updates an entry in a page table. If updating an L1 table, and the new
* table entry is valid/present, the mapped frame must belong to the FD, if
- * an FD has been specified. If attempting to map an I/O page, then the FD
- * is ignored, but the calling domain must have sufficient privilege.
+ * an FD has been specified. If attempting to map an I/O page then the
+ * caller assumes the privilege of the FD.
+ * FD == DOMID_IO: Permit /only/ I/O mappings, at the priv level of the caller.
+ * FD == DOMID_XEN: Map restricted areas of Xen's heap space.
* ptr[:2] -- Machine address of the page-table entry to modify.
* val -- Value to write.
*
@@ -121,6 +123,7 @@
* val[7:0] == MMUEXT_SET_FOREIGNDOM:
* val[31:15] -- Domain to set as the Foreign Domain (FD).
* (NB. DOMID_SELF is not recognised)
+ * If FD != DOMID_IO then the caller must be privileged.
*
* val[7:0] == MMUEXT_REASSIGN_PAGE:
* ptr[:2] -- A machine address within the page to be reassigned to the FD.
@@ -186,9 +189,31 @@
#ifndef __ASSEMBLY__
typedef u16 domid_t;
+
+/* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */
+#define DOMID_FIRST_RESERVED (0x7FF0U)
+
/* DOMID_SELF is used in certain contexts to refer to oneself. */
-#define DOMID_SELF (0x7FF0U)
-/* NB. IDs >= 0x7FF1 are reserved for future use. */
+#define DOMID_SELF (0x7FF0U)
+
+/*
+ * DOMID_IO is used to restrict page-table updates to mapping I/O memory.
+ * Although no Foreign Domain need be specified to map I/O pages, DOMID_IO
+ * is useful to ensure that no mappings to the OS's own heap are accidentally
+ * installed. (e.g., in Linux this could cause havoc as reference counts
+ * aren't adjusted on the I/O-mapping code path).
+ * This only makes sense in MMUEXT_SET_FOREIGNDOM, but in that context can
+ * be specified by any calling domain.
+ */
+#define DOMID_IO (0x7FF1U)
+
+/*
+ * DOMID_XEN is used to allow privileged domains to map restricted parts of
+ * Xen's heap space (e.g., the machine_to_phys table).
+ * This only makes sense in MMUEXT_SET_FOREIGNDOM, and is only permitted if
+ * the caller is privileged.
+ */
+#define DOMID_XEN (0x7FF2U)
/*
* Send an array of these to HYPERVISOR_mmu_update().
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 06b6faf6cc..af74cf5380 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -164,11 +164,26 @@ struct domain *alloc_domain_struct();
#define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */
#define put_domain(_d) \
if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destruct(_d)
+
+/*
+ * Use this when you don't have an existing reference to @d. It returns
+ * FALSE if @d is being destructed.
+ */
static inline int get_domain(struct domain *d)
{
atomic_inc(&d->refcnt);
return !(atomic_read(&d->refcnt) & DOMAIN_DESTRUCTED);
}
+
+/*
+ * 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.
+ */
+static inline void get_knownalive_domain(struct domain *d)
+{
+ atomic_inc(&d->refcnt);
+ ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTRUCTED));
+}
extern struct domain *do_createdomain(
domid_t dom_id, unsigned int cpu);