aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xc/lib/xc_linux_build.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/xc/lib/xc_linux_build.c')
-rw-r--r--tools/xc/lib/xc_linux_build.c86
1 files changed, 34 insertions, 52 deletions
diff --git a/tools/xc/lib/xc_linux_build.c b/tools/xc/lib/xc_linux_build.c
index 2ea7d00096..6c6c1c9449 100644
--- a/tools/xc/lib/xc_linux_build.c
+++ b/tools/xc/lib/xc_linux_build.c
@@ -87,7 +87,7 @@ static int copy_to_domain_page(int pm_handle,
unsigned long dst_pfn,
void *src_page)
{
- void *vaddr = map_pfn(pm_handle, dst_pfn);
+ void *vaddr = map_pfn_writeable(pm_handle, dst_pfn);
if ( vaddr == NULL )
return -1;
memcpy(vaddr, src_page, PAGE_SIZE);
@@ -106,13 +106,13 @@ static int setup_guestos(int xc_handle,
const char *cmdline,
unsigned long shared_info_frame)
{
- l1_pgentry_t *vl1tab;
- l2_pgentry_t *vl2tab;
+ 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, l2e, l1e=0;
- unsigned long l1tab = 0;
+ 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;
@@ -126,7 +126,7 @@ static int setup_guestos(int xc_handle,
if ( (pm_handle = init_pfn_mapper()) < 0 )
goto error_out;
- pgt_updates = malloc((tot_pages + 1024) * 3 * sizeof(mmu_update_t));
+ 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) )
@@ -210,60 +210,31 @@ static int setup_guestos(int xc_handle,
alloc_index--;
builddomain->ctxt.pt_base = l2tab;
- /*
- * 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++;
-
/* Initialise the page tables. */
- if ( (vl2tab = map_pfn(pm_handle, l2tab >> PAGE_SHIFT)) == NULL )
+ if ( (vl2tab = map_pfn_writeable(pm_handle, l2tab >> PAGE_SHIFT)) == NULL )
goto error_out;
memset(vl2tab, 0, PAGE_SIZE);
- unmap_pfn(pm_handle, vl2tab);
- l2e = l2tab + (l2_table_offset(virt_load_addr)*sizeof(l2_pgentry_t));
+ vl2e = &vl2tab[l2_table_offset(virt_load_addr)];
for ( count = 0; count < tot_pages; count++ )
{
- if ( (l1e & (PAGE_SIZE-1)) == 0 )
+ if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
{
- l1tab = page_array[alloc_index] << PAGE_SHIFT;
- if ( (vl1tab = map_pfn(pm_handle, l1tab >> PAGE_SHIFT)) == NULL )
+ l1tab = page_array[alloc_index--] << PAGE_SHIFT;
+ if ( vl1tab != NULL )
+ unmap_pfn(pm_handle, vl1tab);
+ if ( (vl1tab = map_pfn_writeable(pm_handle,
+ l1tab >> PAGE_SHIFT)) == NULL )
goto error_out;
memset(vl1tab, 0, PAGE_SIZE);
- unmap_pfn(pm_handle, vl1tab);
- alloc_index--;
-
- l1e = l1tab + (l1_table_offset(virt_load_addr+(count<<PAGE_SHIFT))*
- sizeof(l1_pgentry_t));
-
- /* Make appropriate entry in the page directory. */
- pgt_updates->ptr = l2e;
- pgt_updates->val = l1tab | L2_PROT;
- pgt_updates++;
- num_pgt_updates++;
- l2e += sizeof(l2_pgentry_t);
+ vl1e = &vl1tab[l1_table_offset(virt_load_addr +
+ (count<<PAGE_SHIFT))];
+ *vl2e++ = l1tab | L2_PROT;
}
- if ( count < pt_start )
- {
- pgt_updates->ptr = l1e;
- pgt_updates->val = (page_array[count] << PAGE_SHIFT) | L1_PROT;
- pgt_updates++;
- num_pgt_updates++;
- l1e += sizeof(l1_pgentry_t);
- }
- else
- {
- pgt_updates->ptr = l1e;
- pgt_updates->val =
- ((page_array[count] << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW;
- pgt_updates++;
- num_pgt_updates++;
- l1e += sizeof(l1_pgentry_t);
- }
+ *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
+ if ( count >= pt_start )
+ *vl1e &= ~_PAGE_RW;
+ vl1e++;
pgt_updates->ptr =
(page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
@@ -271,11 +242,22 @@ static int setup_guestos(int xc_handle,
pgt_updates++;
num_pgt_updates++;
}
+ unmap_pfn(pm_handle, vl1tab);
+ unmap_pfn(pm_handle, vl2tab);
+
+ /*
+ * 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++;
*virt_startinfo_addr =
virt_load_addr + ((alloc_index-1) << PAGE_SHIFT);
- start_info = map_pfn(pm_handle, page_array[alloc_index-1]);
+ start_info = map_pfn_writeable(pm_handle, page_array[alloc_index-1]);
memset(start_info, 0, sizeof(*start_info));
start_info->pt_base = virt_load_addr + ((tot_pages-1) << PAGE_SHIFT);
start_info->mod_start = initrd_addr;
@@ -289,7 +271,7 @@ static int setup_guestos(int xc_handle,
unmap_pfn(pm_handle, start_info);
/* shared_info page starts its life empty. */
- shared_info = map_pfn(pm_handle, shared_info_frame);
+ shared_info = map_pfn_writeable(pm_handle, shared_info_frame);
memset(shared_info, 0, PAGE_SIZE);
unmap_pfn(pm_handle, shared_info);