aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xc
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-02-27 15:19:27 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-02-27 15:19:27 +0000
commit852c5cea72e07706be1e778f6cdd03c8026ee966 (patch)
tree51881b783de92fce1aad9620e4964c0a2aedb56b /tools/xc
parent66090e1c4bc9de311f804ffb6a7a3dd97c6aeb71 (diff)
downloadxen-852c5cea72e07706be1e778f6cdd03c8026ee966.tar.gz
xen-852c5cea72e07706be1e778f6cdd03c8026ee966.tar.bz2
xen-852c5cea72e07706be1e778f6cdd03c8026ee966.zip
bitkeeper revision 1.755 (403f5fffwYqT6Gw88yRJHe04lMgpjg)
Many files: Further cleanups to the Xen pagetable interface.
Diffstat (limited to 'tools/xc')
-rw-r--r--tools/xc/lib/xc_linux_build.c60
-rw-r--r--tools/xc/lib/xc_linux_restore.c71
-rw-r--r--tools/xc/lib/xc_netbsd_build.c60
-rw-r--r--tools/xc/lib/xc_private.c70
-rw-r--r--tools/xc/lib/xc_private.h14
5 files changed, 134 insertions, 141 deletions
diff --git a/tools/xc/lib/xc_linux_build.c b/tools/xc/lib/xc_linux_build.c
index 6c6c1c9449..32b1515557 100644
--- a/tools/xc/lib/xc_linux_build.c
+++ b/tools/xc/lib/xc_linux_build.c
@@ -43,27 +43,6 @@ static int get_pfn_list(int xc_handle,
return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
}
-static int send_pgupdates(int xc_handle, mmu_update_t *updates, int nr_updates)
-{
- int ret = -1;
- privcmd_hypercall_t hypercall;
-
- hypercall.op = __HYPERVISOR_mmu_update;
- hypercall.arg[0] = (unsigned long)updates;
- hypercall.arg[1] = (unsigned long)nr_updates;
-
- if ( mlock(updates, nr_updates * sizeof(*updates)) != 0 )
- goto out1;
-
- if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
- goto out2;
-
- ret = 0;
-
- out2: (void)munlock(updates, nr_updates * sizeof(*updates));
- out1: return ret;
-}
-
/* Read the kernel header, extracting the image size and load address. */
static int read_kernel_header(gzFile gfd, long dom_size,
unsigned long *load_addr)
@@ -109,16 +88,15 @@ static int setup_guestos(int xc_handle,
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
unsigned long *page_array = NULL;
- mmu_update_t *pgt_update_arr = NULL, *pgt_updates = NULL;
int alloc_index, num_pt_pages;
unsigned long l2tab;
unsigned long l1tab;
- unsigned long num_pgt_updates = 0;
unsigned long count, pt_start, i, j;
unsigned long initrd_addr = 0, initrd_len = 0;
start_info_t *start_info;
shared_info_t *shared_info;
unsigned long ksize;
+ mmu_t *mmu = NULL;
int pm_handle;
memset(builddomain, 0, sizeof(*builddomain));
@@ -126,10 +104,7 @@ static int setup_guestos(int xc_handle,
if ( (pm_handle = init_pfn_mapper()) < 0 )
goto error_out;
- pgt_updates = malloc((tot_pages + 1) * sizeof(mmu_update_t));
- page_array = malloc(tot_pages * sizeof(unsigned long));
- pgt_update_arr = pgt_updates;
- if ( (pgt_update_arr == NULL) || (page_array == NULL) )
+ if ( (page_array = malloc(tot_pages * sizeof(unsigned long))) == NULL )
{
PERROR("Could not allocate memory");
goto error_out;
@@ -210,6 +185,9 @@ static int setup_guestos(int xc_handle,
alloc_index--;
builddomain->ctxt.pt_base = l2tab;
+ if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
+ goto error_out;
+
/* Initialise the page tables. */
if ( (vl2tab = map_pfn_writeable(pm_handle, l2tab >> PAGE_SHIFT)) == NULL )
goto error_out;
@@ -236,11 +214,10 @@ static int setup_guestos(int xc_handle,
*vl1e &= ~_PAGE_RW;
vl1e++;
- pgt_updates->ptr =
- (page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
- pgt_updates->val = count;
- pgt_updates++;
- num_pgt_updates++;
+ if ( add_mmu_update(xc_handle, mmu,
+ (page_array[count] << PAGE_SHIFT) |
+ MMU_MACHPHYS_UPDATE, count) )
+ goto error_out;
}
unmap_pfn(pm_handle, vl1tab);
unmap_pfn(pm_handle, vl2tab);
@@ -249,10 +226,9 @@ static int setup_guestos(int xc_handle,
* Pin down l2tab addr as page dir page - causes hypervisor to provide
* correct protection for the page
*/
- pgt_updates->ptr = l2tab | MMU_EXTENDED_COMMAND;
- pgt_updates->val = MMUEXT_PIN_L2_TABLE;
- pgt_updates++;
- num_pgt_updates++;
+ if ( add_mmu_update(xc_handle, mmu,
+ l2tab | MMU_EXTENDED_COMMAND, MMUEXT_PIN_L2_TABLE) )
+ goto error_out;
*virt_startinfo_addr =
virt_load_addr + ((alloc_index-1) << PAGE_SHIFT);
@@ -267,7 +243,6 @@ static int setup_guestos(int xc_handle,
start_info->flags = 0;
strncpy(start_info->cmd_line, cmdline, MAX_CMD_LEN);
start_info->cmd_line[MAX_CMD_LEN-1] = '\0';
-
unmap_pfn(pm_handle, start_info);
/* shared_info page starts its life empty. */
@@ -276,20 +251,21 @@ static int setup_guestos(int xc_handle,
unmap_pfn(pm_handle, shared_info);
/* Send the page update requests down to the hypervisor. */
- if ( send_pgupdates(xc_handle, pgt_update_arr, num_pgt_updates) < 0 )
+ if ( finish_mmu_updates(xc_handle, mmu) )
goto error_out;
+ free(mmu);
+ (void)close_pfn_mapper(pm_handle);
free(page_array);
- free(pgt_update_arr);
return 0;
error_out:
+ if ( mmu != NULL )
+ free(mmu);
if ( pm_handle >= 0 )
(void)close_pfn_mapper(pm_handle);
- if ( page_array )
+ if ( page_array != NULL )
free(page_array);
- if ( pgt_update_arr )
- free(pgt_update_arr);
return -1;
}
diff --git a/tools/xc/lib/xc_linux_restore.c b/tools/xc/lib/xc_linux_restore.c
index 74e7641bed..3b00a81011 100644
--- a/tools/xc/lib/xc_linux_restore.c
+++ b/tools/xc/lib/xc_linux_restore.c
@@ -43,56 +43,6 @@ static int get_pfn_list(int xc_handle,
return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
}
-#define MAX_MMU_UPDATES 1024
-
-static int flush_mmu_updates(int xc_handle,
- mmu_update_t *mmu_updates,
- int *mmu_update_idx)
-{
- int err = 0;
- privcmd_hypercall_t hypercall;
-
- if ( *mmu_update_idx == 0 )
- return 0;
-
- hypercall.op = __HYPERVISOR_mmu_update;
- hypercall.arg[0] = (unsigned long)mmu_updates;
- hypercall.arg[1] = (unsigned long)*mmu_update_idx;
-
- if ( mlock(mmu_updates, sizeof(mmu_updates)) != 0 )
- {
- PERROR("Could not lock pagetable update array");
- err = 1;
- goto out;
- }
-
- if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
- {
- ERROR("Failure when submitting mmu updates");
- err = 1;
- }
-
- *mmu_update_idx = 0;
-
- (void)munlock(mmu_updates, sizeof(mmu_updates));
-
- out:
- return err;
-}
-
-static int add_mmu_update(int xc_handle,
- mmu_update_t *mmu_updates,
- int *mmu_update_idx,
- unsigned long ptr,
- unsigned long val)
-{
- mmu_updates[*mmu_update_idx].ptr = ptr;
- mmu_updates[*mmu_update_idx].val = val;
- if ( ++*mmu_update_idx == MAX_MMU_UPDATES )
- return flush_mmu_updates(xc_handle, mmu_updates, mmu_update_idx);
- return 0;
-}
-
static int checked_read(gzFile fd, void *buf, size_t count)
{
int rc;
@@ -147,8 +97,7 @@ int xc_linux_restore(int xc_handle,
int fd;
gzFile gfd;
- mmu_update_t mmu_updates[MAX_MMU_UPDATES];
- int mmu_update_idx = 0;
+ mmu_t *mmu = NULL;
int pm_handle = -1;
@@ -252,6 +201,12 @@ int xc_linux_restore(int xc_handle,
goto out;
}
+ if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
+ {
+ ERROR("Could not initialise for MMU updates");
+ goto out;
+ }
+
verbose_printf("Reloading memory pages: 0%%");
/*
@@ -323,7 +278,7 @@ int xc_linux_restore(int xc_handle,
unmap_pfn(pm_handle, ppage);
- if ( add_mmu_update(xc_handle, mmu_updates, &mmu_update_idx,
+ if ( add_mmu_update(xc_handle, mmu,
(mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i) )
goto out;
}
@@ -336,7 +291,7 @@ int xc_linux_restore(int xc_handle,
{
if ( pfn_type[i] == L1TAB )
{
- if ( add_mmu_update(xc_handle, mmu_updates, &mmu_update_idx,
+ if ( add_mmu_update(xc_handle, mmu,
(pfn_to_mfn_table[i]<<PAGE_SHIFT) |
MMU_EXTENDED_COMMAND,
MMUEXT_PIN_L1_TABLE) )
@@ -344,7 +299,7 @@ int xc_linux_restore(int xc_handle,
}
else if ( pfn_type[i] == L2TAB )
{
- if ( add_mmu_update(xc_handle, mmu_updates, &mmu_update_idx,
+ if ( add_mmu_update(xc_handle, mmu,
(pfn_to_mfn_table[i]<<PAGE_SHIFT) |
MMU_EXTENDED_COMMAND,
MMUEXT_PIN_L2_TABLE) )
@@ -352,8 +307,7 @@ int xc_linux_restore(int xc_handle,
}
}
-
- if ( flush_mmu_updates(xc_handle, mmu_updates, &mmu_update_idx) )
+ if ( finish_mmu_updates(xc_handle, mmu) )
goto out;
verbose_printf("\b\b\b\b100%%\nMemory reloaded.\n");
@@ -455,6 +409,9 @@ int xc_linux_restore(int xc_handle,
rc = do_dom0_op(xc_handle, &op);
out:
+ if ( mmu != NULL )
+ free(mmu);
+
if ( rc != 0 )
{
if ( dom != 0 )
diff --git a/tools/xc/lib/xc_netbsd_build.c b/tools/xc/lib/xc_netbsd_build.c
index 23df4afb72..56fd35dbab 100644
--- a/tools/xc/lib/xc_netbsd_build.c
+++ b/tools/xc/lib/xc_netbsd_build.c
@@ -53,27 +53,6 @@ static int get_pfn_list(int xc_handle,
return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
}
-static int send_pgupdates(int xc_handle, mmu_update_t *updates, int nr_updates)
-{
- int ret = -1;
- privcmd_hypercall_t hypercall;
-
- hypercall.op = __HYPERVISOR_mmu_update;
- hypercall.arg[0] = (unsigned long)updates;
- hypercall.arg[1] = (unsigned long)nr_updates;
-
- if ( mlock(updates, nr_updates * sizeof(*updates)) != 0 )
- goto out1;
-
- if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
- goto out2;
-
- ret = 0;
-
- out2: (void)munlock(updates, nr_updates * sizeof(*updates));
- out1: return ret;
-}
-
static int setup_guestos(int xc_handle,
u64 dom,
gzFile kernel_gfd,
@@ -87,16 +66,15 @@ static int setup_guestos(int xc_handle,
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
unsigned long *page_array = NULL;
- mmu_update_t *pgt_update_arr = NULL, *pgt_updates = NULL;
int alloc_index, num_pt_pages;
unsigned long l2tab;
unsigned long l1tab;
- unsigned long num_pgt_updates = 0;
unsigned long count, pt_start;
unsigned long symtab_addr = 0, symtab_len = 0;
start_info_t *start_info;
shared_info_t *shared_info;
unsigned long ksize;
+ mmu_t *mmu = NULL;
int pm_handle;
memset(builddomain, 0, sizeof(*builddomain));
@@ -104,10 +82,7 @@ static int setup_guestos(int xc_handle,
if ( (pm_handle = init_pfn_mapper()) < 0 )
goto error_out;
- pgt_updates = malloc((tot_pages + 1) * sizeof(mmu_update_t));
- page_array = malloc(tot_pages * sizeof(unsigned long));
- pgt_update_arr = pgt_updates;
- if ( (pgt_update_arr == NULL) || (page_array == NULL) )
+ if ( (page_array = malloc(tot_pages * sizeof(unsigned long))) == NULL )
{
PERROR("Could not allocate memory");
goto error_out;
@@ -144,7 +119,10 @@ static int setup_guestos(int xc_handle,
l2tab = page_array[alloc_index] << PAGE_SHIFT;
alloc_index--;
builddomain->ctxt.pt_base = l2tab;
-
+
+ if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
+ goto error_out;
+
/* Initialise the page tables. */
if ( (vl2tab = map_pfn_writeable(pm_handle, l2tab >> PAGE_SHIFT)) == NULL )
goto error_out;
@@ -171,11 +149,10 @@ static int setup_guestos(int xc_handle,
*vl1e &= ~_PAGE_RW;
vl1e++;
- pgt_updates->ptr =
- (page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
- pgt_updates->val = count;
- pgt_updates++;
- num_pgt_updates++;
+ if ( add_mmu_update(xc_handle, mmu,
+ (page_array[count] << PAGE_SHIFT) |
+ MMU_MACHPHYS_UPDATE, count) )
+ goto error_out;
}
unmap_pfn(pm_handle, vl1tab);
unmap_pfn(pm_handle, vl2tab);
@@ -184,10 +161,9 @@ static int setup_guestos(int xc_handle,
* Pin down l2tab addr as page dir page - causes hypervisor to provide
* correct protection for the page
*/
- pgt_updates->ptr = l2tab | MMU_EXTENDED_COMMAND;
- pgt_updates->val = MMUEXT_PIN_L2_TABLE;
- pgt_updates++;
- num_pgt_updates++;
+ if ( add_mmu_update(xc_handle, mmu,
+ l2tab | MMU_EXTENDED_COMMAND, MMUEXT_PIN_L2_TABLE) )
+ goto error_out;
*virt_startinfo_addr =
*virt_load_addr + ((alloc_index-1) << PAGE_SHIFT);
@@ -202,7 +178,6 @@ static int setup_guestos(int xc_handle,
start_info->flags = 0;
strncpy(start_info->cmd_line, cmdline, MAX_CMD_LEN);
start_info->cmd_line[MAX_CMD_LEN-1] = '\0';
-
unmap_pfn(pm_handle, start_info);
/* shared_info page starts its life empty. */
@@ -211,20 +186,21 @@ static int setup_guestos(int xc_handle,
unmap_pfn(pm_handle, shared_info);
/* Send the page update requests down to the hypervisor. */
- if ( send_pgupdates(xc_handle, pgt_update_arr, num_pgt_updates) < 0 )
+ if ( finish_mmu_updates(xc_handle, mmu) )
goto error_out;
+ free(mmu);
+ (void)close_pfn_mapper(pm_handle);
free(page_array);
- free(pgt_update_arr);
return 0;
error_out:
+ if ( mmu != NULL )
+ free(mmu);
if ( pm_handle >= 0 )
(void)close_pfn_mapper(pm_handle);
if ( page_array == NULL )
free(page_array);
- if ( pgt_update_arr == NULL )
- free(pgt_update_arr);
return -1;
}
diff --git a/tools/xc/lib/xc_private.c b/tools/xc/lib/xc_private.c
index 4331cc943c..3b634148eb 100644
--- a/tools/xc/lib/xc_private.c
+++ b/tools/xc/lib/xc_private.c
@@ -38,3 +38,73 @@ void unmap_pfn(int pm_handle, void *vaddr)
{
(void)munmap(vaddr, PAGE_SIZE);
}
+
+#define FIRST_MMU_UPDATE 2
+
+static int flush_mmu_updates(int xc_handle, mmu_t *mmu)
+{
+ int err = 0;
+ privcmd_hypercall_t hypercall;
+
+ if ( mmu->idx == FIRST_MMU_UPDATE )
+ return 0;
+
+ /* The first two requests set the correct subject domain. */
+ mmu->updates[0].val = (unsigned long)(mmu->subject<<16) & ~0xFFFFUL;
+ mmu->updates[0].ptr = (unsigned long)(mmu->subject<< 0) & ~0xFFFFUL;
+ mmu->updates[1].val = (unsigned long)(mmu->subject>>16) & ~0xFFFFUL;
+ mmu->updates[1].ptr = (unsigned long)(mmu->subject>>32) & ~0xFFFFUL;
+ mmu->updates[0].ptr |= MMU_EXTENDED_COMMAND;
+ mmu->updates[0].val |= MMUEXT_SET_SUBJECTDOM_L;
+ mmu->updates[1].ptr |= MMU_EXTENDED_COMMAND;
+ mmu->updates[1].val |= MMUEXT_SET_SUBJECTDOM_H;
+
+ hypercall.op = __HYPERVISOR_mmu_update;
+ hypercall.arg[0] = (unsigned long)mmu->updates;
+ hypercall.arg[1] = (unsigned long)mmu->idx;
+
+ if ( mlock(mmu->updates, sizeof(mmu->updates)) != 0 )
+ {
+ PERROR("Could not lock pagetable update array");
+ err = 1;
+ goto out;
+ }
+
+ if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
+ {
+ ERROR("Failure when submitting mmu updates");
+ err = 1;
+ }
+
+ mmu->idx = FIRST_MMU_UPDATE;
+
+ (void)munlock(mmu->updates, sizeof(mmu->updates));
+
+ out:
+ return err;
+}
+
+mmu_t *init_mmu_updates(int xc_handle, domid_t dom)
+{
+ mmu_t *mmu = malloc(sizeof(mmu_t));
+ if ( mmu == NULL )
+ return mmu;
+ mmu->idx = FIRST_MMU_UPDATE;
+ mmu->subject = dom;
+ return mmu;
+}
+
+int add_mmu_update(int xc_handle, mmu_t *mmu,
+ unsigned long ptr, unsigned long val)
+{
+ mmu->updates[mmu->idx].ptr = ptr;
+ mmu->updates[mmu->idx].val = val;
+ if ( ++mmu->idx == MAX_MMU_UPDATES )
+ return flush_mmu_updates(xc_handle, mmu);
+ return 0;
+}
+
+int finish_mmu_updates(int xc_handle, mmu_t *mmu)
+{
+ return flush_mmu_updates(xc_handle, mmu);
+}
diff --git a/tools/xc/lib/xc_private.h b/tools/xc/lib/xc_private.h
index c08a2564ec..6499c58872 100644
--- a/tools/xc/lib/xc_private.h
+++ b/tools/xc/lib/xc_private.h
@@ -153,4 +153,18 @@ void *map_pfn_writeable(int pm_handle, unsigned long pfn);
void *map_pfn_readonly(int pm_handle, unsigned long pfn);
void unmap_pfn(int pm_handle, void *vaddr);
+/*
+ * MMU updates.
+ */
+#define MAX_MMU_UPDATES 1024
+typedef struct {
+ mmu_update_t updates[MAX_MMU_UPDATES];
+ int idx;
+ domid_t subject;
+} mmu_t;
+mmu_t *init_mmu_updates(int xc_handle, domid_t dom);
+int add_mmu_update(int xc_handle, mmu_t *mmu,
+ unsigned long ptr, unsigned long val);
+int finish_mmu_updates(int xc_handle, mmu_t *mmu);
+
#endif /* __XC_PRIVATE_H__ */