diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/xc/lib/xc_domain.c | 1 | ||||
-rw-r--r-- | tools/xc/lib/xc_linux_build.c | 25 | ||||
-rw-r--r-- | tools/xc/lib/xc_linux_restore.c | 175 | ||||
-rw-r--r-- | tools/xc/lib/xc_linux_save.c | 143 | ||||
-rw-r--r-- | tools/xc/lib/xc_netbsd_build.c | 26 |
5 files changed, 216 insertions, 154 deletions
diff --git a/tools/xc/lib/xc_domain.c b/tools/xc/lib/xc_domain.c index ec28f2686b..1d77bfc016 100644 --- a/tools/xc/lib/xc_domain.c +++ b/tools/xc/lib/xc_domain.c @@ -84,6 +84,7 @@ int xc_domain_getinfo(int xc_handle, { op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)next_domid; + op.u.getdomaininfo.ctxt = NULL; // no exec context info, thanks. if ( do_dom0_op(xc_handle, &op) < 0 ) break; info->domid = (u64)op.u.getdomaininfo.domain; diff --git a/tools/xc/lib/xc_linux_build.c b/tools/xc/lib/xc_linux_build.c index 7f81c924ad..42696666a8 100644 --- a/tools/xc/lib/xc_linux_build.c +++ b/tools/xc/lib/xc_linux_build.c @@ -26,6 +26,7 @@ static long get_tot_pages(int xc_handle, u64 domid) dom0_op_t op; op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; + op.u.getdomaininfo.ctxt = NULL; return (do_dom0_op(xc_handle, &op) < 0) ? -1 : op.u.getdomaininfo.tot_pages; } @@ -70,7 +71,7 @@ static int setup_guestos(int xc_handle, gzFile initrd_gfd, unsigned long initrd_len, unsigned long nr_pages, unsigned long *pvsi, unsigned long *pvke, - dom0_builddomain_t *builddomain, + full_execution_context_t *ctxt, const char *cmdline, unsigned long shared_info_frame, unsigned int control_evtchn) @@ -163,8 +164,6 @@ static int setup_guestos(int xc_handle, v_start, v_end); printf(" ENTRY ADDRESS: %08lx\n", vkern_entry); - memset(builddomain, 0, sizeof(*builddomain)); - if ( (pm_handle = init_pfn_mapper((domid_t)dom)) < 0 ) goto error_out; @@ -205,7 +204,7 @@ static int setup_guestos(int xc_handle, /* First allocate page for page dir. */ ppt_alloc = (vpt_start - v_start) >> PAGE_SHIFT; l2tab = page_array[ppt_alloc++] << PAGE_SHIFT; - builddomain->ctxt.pt_base = l2tab; + ctxt->pt_base = l2tab; /* Initialise the page tables. */ if ( (vl2tab = map_pfn_writeable(pm_handle, l2tab >> PAGE_SHIFT)) == NULL ) @@ -388,7 +387,7 @@ int xc_linux_build(int xc_handle, int initrd_fd = -1; gzFile initrd_gfd = NULL; int rc, i; - full_execution_context_t *ctxt; + full_execution_context_t st_ctxt, *ctxt = &st_ctxt; unsigned long nr_pages; char *image = NULL; unsigned long image_size, initrd_size=0; @@ -420,8 +419,15 @@ int xc_linux_build(int xc_handle, } } + if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ) + { + PERROR("Unable to mlock ctxt"); + return 1; + } + op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; + op.u.getdomaininfo.ctxt = ctxt; if ( (do_dom0_op(xc_handle, &op) < 0) || ((u64)op.u.getdomaininfo.domain != domid) ) { @@ -429,7 +435,7 @@ int xc_linux_build(int xc_handle, goto error_out; } if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) || - (op.u.getdomaininfo.ctxt.pt_base != 0) ) + (ctxt->pt_base != 0) ) { ERROR("Domain is already constructed"); goto error_out; @@ -438,7 +444,7 @@ int xc_linux_build(int xc_handle, if ( setup_guestos(xc_handle, domid, image, image_size, initrd_gfd, initrd_size, nr_pages, &vstartinfo_start, &vkern_entry, - &launch_op.u.builddomain, cmdline, + ctxt, cmdline, op.u.getdomaininfo.shared_info_frame, control_evtchn) < 0 ) { @@ -453,8 +459,6 @@ int xc_linux_build(int xc_handle, if ( image != NULL ) free(image); - ctxt = &launch_op.u.builddomain.ctxt; - ctxt->flags = 0; /* @@ -507,8 +511,11 @@ int xc_linux_build(int xc_handle, ctxt->failsafe_callback_cs = FLAT_GUESTOS_CS; ctxt->failsafe_callback_eip = 0; + memset( &launch_op, 0, sizeof(launch_op) ); + launch_op.u.builddomain.domain = (domid_t)domid; launch_op.u.builddomain.num_vifs = 1; + launch_op.u.builddomain.ctxt = ctxt; launch_op.cmd = DOM0_BUILDDOMAIN; rc = do_dom0_op(xc_handle, &launch_op); diff --git a/tools/xc/lib/xc_linux_restore.c b/tools/xc/lib/xc_linux_restore.c index 893cd0cef4..00acc5a687 100644 --- a/tools/xc/lib/xc_linux_restore.c +++ b/tools/xc/lib/xc_linux_restore.c @@ -58,8 +58,8 @@ int xc_linux_restore(int xc_handle, u64 *pdomid) { dom0_op_t op; - int rc = 1, i, j; - unsigned long mfn, pfn; + int rc = 1, i, j, n, k; + unsigned long mfn, pfn, xpfn; unsigned int prev_pc, this_pc; /* Number of page frames in use by this Linux session. */ @@ -114,6 +114,14 @@ int xc_linux_restore(int xc_handle, return 1; } + if ( mlock(&ctxt, sizeof(ctxt) ) ) + { + /* needed for when we do the build dom0 op, + but might as well do early */ + PERROR("Unable to mlock ctxt"); + return 1; + } + /* Start writing out the saved-domain record. */ if ( !checked_read(gfd, signature, 16) || (memcmp(signature, "LinuxGuestRecord", 16) != 0) ) @@ -159,12 +167,6 @@ int xc_linux_restore(int xc_handle, goto out; } - if ( !checked_read(gfd, pfn_type, 4 * nr_pfns) ) - { - ERROR("Error when reading from state file"); - goto out; - } - /* Set the domain's name to that from the restore file */ if ( xc_domain_setname( xc_handle, dom, name ) ) { @@ -184,6 +186,7 @@ int xc_linux_restore(int xc_handle, /* Get the domain's shared-info frame. */ op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)dom; + op.u.getdomaininfo.ctxt = NULL; if ( do_dom0_op(xc_handle, &op) < 0 ) { ERROR("Could not get information on new domain"); @@ -219,73 +222,119 @@ int xc_linux_restore(int xc_handle, * We uncanonicalise page tables as we go. */ prev_pc = 0; - for ( i = 0; i < nr_pfns; i++ ) + + n=0; + while(1) { - this_pc = (i * 100) / nr_pfns; + int j; + unsigned long region_pfn_type[1024]; + + this_pc = (n * 100) / nr_pfns; if ( (this_pc - prev_pc) >= 5 ) { verbose_printf("\b\b\b\b%3d%%", this_pc); prev_pc = this_pc; } - mfn = pfn_to_mfn_table[i]; - - ppage = map_pfn_writeable(pm_handle, mfn); - - if ( !checked_read(gfd, ppage, PAGE_SIZE) ) + if ( !checked_read(gfd, &j, sizeof(int)) ) { ERROR("Error when reading from state file"); goto out; } - if ( pfn_type[i] == L1TAB ) - { - for ( j = 0; j < 1024; j++ ) - { - if ( ppage[j] & _PAGE_PRESENT ) - { - if ( (pfn = ppage[j] >> PAGE_SHIFT) >= nr_pfns ) - { - ERROR("Frame number in type %d page table is out of range. i=%d j=%d pfn=%d nr_pfns=%d",pfn_type[i],i,j,pfn,nr_pfns); - goto out; - } - if ( (pfn_type[pfn] != NONE) && (ppage[j] & _PAGE_RW) ) - { - ERROR("Write access requested for a restricted frame"); - goto out; - } - ppage[j] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PAT); - ppage[j] |= pfn_to_mfn_table[pfn] << PAGE_SHIFT; - } - } - } - else if ( pfn_type[i] == L2TAB ) + printf("batch=%d\n",j); + + if(j==0) break; // our work here is done + + if ( !checked_read(gfd, region_pfn_type, j*sizeof(unsigned long)) ) { - for ( j = 0; j < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); j++ ) - { - if ( ppage[j] & _PAGE_PRESENT ) - { - if ( (pfn = ppage[j] >> PAGE_SHIFT) >= nr_pfns ) - { - ERROR("Frame number in page table is out of range"); - goto out; - } - if ( pfn_type[pfn] != L1TAB ) - { - ERROR("Page table mistyping"); - goto out; - } - ppage[j] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PSE); - ppage[j] |= pfn_to_mfn_table[pfn] << PAGE_SHIFT; - } - } + ERROR("Error when reading from state file"); + goto out; } - unmap_pfn(pm_handle, ppage); + for(i=0;i<j;i++) + { + pfn = region_pfn_type[i] & ~PGT_type_mask; + +//if(pfn_type[i])printf("^pfn=%d %08lx\n",pfn,pfn_type[i]); + + if (pfn>nr_pfns) + { + ERROR("pfn out of range"); + goto out; + } + + region_pfn_type[i] &= PGT_type_mask; + + pfn_type[pfn] = region_pfn_type[i]; + + mfn = pfn_to_mfn_table[pfn]; + +if(region_pfn_type[i])printf("i=%d pfn=%d mfn=%d type=%lx\n",i,pfn,mfn,region_pfn_type[i]); + + ppage = map_pfn_writeable(pm_handle, mfn); + + if ( !checked_read(gfd, ppage, PAGE_SIZE) ) + { + ERROR("Error when reading from state file"); + goto out; + } + + if ( region_pfn_type[i] == L1TAB ) + { + for ( k = 0; k < 1024; k++ ) + { + if ( ppage[k] & _PAGE_PRESENT ) + { + if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns ) + { + ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i],i,k,xpfn,nr_pfns); + goto out; + } +#if 0 + if ( (region_pfn_type[xpfn] != NONE) && (ppage[k] & _PAGE_RW) ) + { + ERROR("Write access requested for a restricted frame"); + goto out; + } +#endif + ppage[k] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PAT); + ppage[k] |= pfn_to_mfn_table[xpfn] << PAGE_SHIFT; + } + } + } + else if ( region_pfn_type[i] == L2TAB ) + { + for ( k = 0; k < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); k++ ) + { + if ( ppage[k] & _PAGE_PRESENT ) + { + if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns ) + { + ERROR("Frame number in page table is out of range"); + goto out; + } +#if 0 + if ( region_pfn_type[pfn] != L1TAB ) + { + ERROR("Page table mistyping"); + goto out; + } +#endif + ppage[k] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PSE); + ppage[k] |= pfn_to_mfn_table[xpfn] << PAGE_SHIFT; + } + } + } + + unmap_pfn(pm_handle, ppage); + + if ( add_mmu_update(xc_handle, mmu, + (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, pfn) ) + goto out; + + } - if ( add_mmu_update(xc_handle, mmu, - (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i) ) - goto out; } /* @@ -352,7 +401,9 @@ int xc_linux_restore(int xc_handle, pfn = ctxt.pt_base >> PAGE_SHIFT; if ( (pfn >= nr_pfns) || (pfn_type[pfn] != L2TAB) ) { - ERROR("PT base is bad"); + printf("PT base is bad. pfn=%d nr=%d type=%08lx %08lx\n", + pfn, nr_pfns, pfn_type[pfn], L2TAB); + ERROR("PT base is bad."); goto out; } ctxt.pt_base = pfn_to_mfn_table[pfn] << PAGE_SHIFT; @@ -406,11 +457,11 @@ int xc_linux_restore(int xc_handle, ERROR("Bad LDT base or size"); goto out; } - + op.cmd = DOM0_BUILDDOMAIN; op.u.builddomain.domain = (domid_t)dom; op.u.builddomain.num_vifs = 1; - memcpy(&op.u.builddomain.ctxt, &ctxt, sizeof(ctxt)); + op.u.builddomain.ctxt = &ctxt; rc = do_dom0_op(xc_handle, &op); out: diff --git a/tools/xc/lib/xc_linux_save.c b/tools/xc/lib/xc_linux_save.c index fb6fbd6f57..88ed9e15d7 100644 --- a/tools/xc/lib/xc_linux_save.c +++ b/tools/xc/lib/xc_linux_save.c @@ -10,7 +10,7 @@ #include <asm-xen/suspend.h> #include <zlib.h> -#define BATCH_SIZE 512 /* 1024 pages (4MB) at a time */ +#define BATCH_SIZE 1024 /* 1024 pages (4MB) at a time */ /* This may allow us to create a 'quiet' command-line option, if necessary. */ #define verbose_printf(_f, _a...) \ @@ -122,11 +122,18 @@ int xc_linux_save(int xc_handle, return 1; } + if ( mlock(&ctxt, sizeof(ctxt) ) ) + { + PERROR("Unable to mlock ctxt"); + return 1; + } + /* Ensure that the domain exists, and that it is stopped. */ for ( ; ; ) { op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; + op.u.getdomaininfo.ctxt = &ctxt; if ( (do_dom0_op(xc_handle, &op) < 0) || ((u64)op.u.getdomaininfo.domain != domid) ) { @@ -134,7 +141,6 @@ int xc_linux_save(int xc_handle, goto out; } - memcpy(&ctxt, &op.u.getdomaininfo.ctxt, sizeof(ctxt)); memcpy(name, op.u.getdomaininfo.name, sizeof(name)); shared_info_frame = op.u.getdomaininfo.shared_info_frame; @@ -223,7 +229,7 @@ int xc_linux_save(int xc_handle, /* We want zeroed memory so use calloc rather than malloc. */ - pfn_type = calloc(1, 4 * srec.nr_pfns); + pfn_type = calloc(BATCH_SIZE, sizeof(unsigned long)); if ( (pfn_type == NULL) ) { @@ -231,6 +237,11 @@ int xc_linux_save(int xc_handle, goto out; } + if ( mlock( pfn_type, BATCH_SIZE * sizeof(unsigned long) ) ) + { + ERROR("Unable to mlock"); + goto out; + } /* Track the mfn_to_pfn table down from the domains PT */ @@ -238,26 +249,22 @@ int xc_linux_save(int xc_handle, unsigned long *pgd; unsigned long mfn_to_pfn_table_start_mfn; - pgd = mfn_mapper_map_single(xc_handle, domid, + pgd = mfn_mapper_map_single(xc_handle, domid, PAGE_SIZE, PROT_READ, ctxt.pt_base>>PAGE_SHIFT); -/* - printf("pt mfn=%d pfn=%d type=%08x pte=%08x\n",ctxt.pt_base>>PAGE_SHIFT, - mfn_to_pfn_table[ctxt.pt_base>>PAGE_SHIFT], - pfn_type[mfn_to_pfn_table[ctxt.pt_base>>PAGE_SHIFT]], - pgd[HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT] ); -*/ - mfn_to_pfn_table_start_mfn = pgd[HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT]>>PAGE_SHIFT; - - live_mfn_to_pfn_table = - mfn_mapper_map_single(xc_handle, ~0ULL, - PAGE_SIZE*1024, PROT_READ, - mfn_to_pfn_table_start_mfn ); + + mfn_to_pfn_table_start_mfn = + pgd[HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT]>>PAGE_SHIFT; + + live_mfn_to_pfn_table = + mfn_mapper_map_single(xc_handle, ~0ULL, + PAGE_SIZE*1024, PROT_READ, + mfn_to_pfn_table_start_mfn ); } /* - * Quick sanity check. + * Quick belt and braces sanity check. */ for ( i = 0; i < srec.nr_pfns; i++ ) @@ -270,50 +277,6 @@ int xc_linux_save(int xc_handle, } -/* test new pfn_type stuff */ - { - int n, i, j; - - if ( mlock( pfn_type, srec.nr_pfns * sizeof(unsigned long) ) ) - { - ERROR("Unable to mlock"); - goto out; - } - for ( n = 0; n < srec.nr_pfns; ) - { - - for( j = 0, i = n; j < BATCH_SIZE && i < srec.nr_pfns ; j++, i++ ) - { - pfn_type[i] = live_pfn_to_mfn_table[i]; - } - - if ( get_pfn_type_batch(xc_handle, domid, j, &pfn_type[n]) ) - { - ERROR("get_pfn_type_batch failed"); - goto out; - } - - for( j = 0, i = n; j < BATCH_SIZE && i < srec.nr_pfns ; j++, i++ ) - { - - pfn_type[i] >>= 29; - - if(pfn_type[i] == 7) - { - ERROR("bogus page"); - goto out; - } - -/* if(pfn_type[i]) - printf("i=%d type=%d\n",i,pfn_type[i]); */ - } - - n+=j; - } - } - - - /* Canonicalise the suspend-record frame number. */ if ( !translate_mfn_to_pfn(&ctxt.cpu_ctxt.esi) ) { @@ -366,8 +329,7 @@ int xc_linux_save(int xc_handle, !checked_write(gfd, &srec.nr_pfns, sizeof(unsigned long)) || !checked_write(gfd, &ctxt, sizeof(ctxt)) || !checked_write(gfd, live_shinfo, PAGE_SIZE) || - !checked_write(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) || - !checked_write(gfd, pfn_type, 4 * srec.nr_pfns) ) + !checked_write(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) ) { ERROR("Error when writing to state file"); goto out; @@ -394,6 +356,11 @@ int xc_linux_save(int xc_handle, prev_pc = this_pc; } + for( j = 0, i = n; j < BATCH_SIZE && i < srec.nr_pfns ; j++, i++ ) + { + pfn_type[j] = live_pfn_to_mfn_table[i]; + } + for( j = 0, i = n; j < BATCH_SIZE && i < srec.nr_pfns ; j++, i++ ) { @@ -411,32 +378,54 @@ int xc_linux_save(int xc_handle, goto out; } -#if 0 - typer_handle = get_type_init( xc_handle, BATCH_SIZE ) - + if ( get_pfn_type_batch(xc_handle, domid, j, pfn_type) ) + { + ERROR("get_pfn_type_batch failed"); + goto out; + } + for( j = 0, i = n; j < BATCH_SIZE && i < srec.nr_pfns ; j++, i++ ) { - /* queue up ownership and type checks for all pages in batch */ + if((pfn_type[j]>>29) == 7) + { + ERROR("bogus page"); + goto out; + } - get_type_queue_entry( typer_handle, domain, - pfn_to_mfn_frame_list[i] ); + /* canonicalise mfn->pfn */ + pfn_type[j] = (pfn_type[j] & PGT_type_mask) | + live_mfn_to_pfn_table[pfn_type[j]&~PGT_type_mask]; + +/* if(pfn_type[j]>>29) + printf("i=%d type=%d\n",i,pfn_type[i]); */ } - region_type = get_type; -#endif + if ( !checked_write(gfd, &j, sizeof(int) ) ) + { + ERROR("Error when writing to state file"); + goto out; + } + + if ( !checked_write(gfd, pfn_type, sizeof(unsigned long)*j ) ) + { + ERROR("Error when writing to state file"); + goto out; + } + for( j = 0, i = n; j < BATCH_SIZE && i < srec.nr_pfns ; j++, i++ ) { /* write out pages in batch */ - if ( (pfn_type[i] == L1TAB) || (pfn_type[i] == L2TAB) ) + if ( ((pfn_type[j] & PGT_type_mask) == L1TAB) || + ((pfn_type[j] & PGT_type_mask) == L2TAB) ) { memcpy(page, region_base + (PAGE_SIZE*j), PAGE_SIZE); for ( k = 0; - k < ((pfn_type[i] == L2TAB) ? + k < (((pfn_type[j] & PGT_type_mask) == L2TAB) ? (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT) : 1024); k++ ) { @@ -478,6 +467,14 @@ int xc_linux_save(int xc_handle, /* Success! */ rc = 0; + /* Zero terminate */ + if ( !checked_write(gfd, &rc, sizeof(int)) ) + { + ERROR("Error when writing to state file"); + goto out; + } + + out: /* Restart the domain if we had to stop it to save its state. */ if ( we_stopped_it ) diff --git a/tools/xc/lib/xc_netbsd_build.c b/tools/xc/lib/xc_netbsd_build.c index 8793a512f2..7c67d57d71 100644 --- a/tools/xc/lib/xc_netbsd_build.c +++ b/tools/xc/lib/xc_netbsd_build.c @@ -27,6 +27,7 @@ static long get_tot_pages(int xc_handle, u64 domid) dom0_op_t op; op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; + op.u.getdomaininfo.ctxt = NULL; return (do_dom0_op(xc_handle, &op) < 0) ? -1 : op.u.getdomaininfo.tot_pages; } @@ -59,7 +60,7 @@ static int setup_guestos(int xc_handle, unsigned long tot_pages, unsigned long *virt_startinfo_addr, unsigned long *virt_load_addr, - dom0_builddomain_t *builddomain, + full_execution_context_t *ctxt, const char *cmdline, unsigned long shared_info_frame, unsigned int control_evtchn) @@ -78,8 +79,6 @@ static int setup_guestos(int xc_handle, mmu_t *mmu = NULL; int pm_handle, i; - memset(builddomain, 0, sizeof(*builddomain)); - if ( (pm_handle = init_pfn_mapper((domid_t)dom)) < 0 ) goto error_out; @@ -119,7 +118,7 @@ static int setup_guestos(int xc_handle, */ l2tab = page_array[alloc_index] << PAGE_SHIFT; alloc_index--; - builddomain->ctxt.pt_base = l2tab; + ctxt->pt_base = l2tab; if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL ) goto error_out; @@ -221,7 +220,7 @@ int xc_netbsd_build(int xc_handle, int kernel_fd = -1; gzFile kernel_gfd = NULL; int rc, i; - full_execution_context_t *ctxt; + full_execution_context_t st_ctxt, *ctxt = &st_ctxt; unsigned long virt_startinfo_addr; if ( (tot_pages = get_tot_pages(xc_handle, domid)) < 0 ) @@ -244,8 +243,15 @@ int xc_netbsd_build(int xc_handle, return 1; } + if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ) + { + PERROR("Unable to mlock ctxt"); + return 1; + } + op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; + op.u.getdomaininfo.ctxt = ctxt; if ( (do_dom0_op(xc_handle, &op) < 0) || ((u64)op.u.getdomaininfo.domain != domid) ) { @@ -253,7 +259,7 @@ int xc_netbsd_build(int xc_handle, goto error_out; } if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) || - (op.u.getdomaininfo.ctxt.pt_base != 0) ) + (op.u.getdomaininfo.ctxt->pt_base != 0) ) { ERROR("Domain is already constructed"); goto error_out; @@ -261,7 +267,7 @@ int xc_netbsd_build(int xc_handle, if ( setup_guestos(xc_handle, domid, kernel_gfd, tot_pages, &virt_startinfo_addr, - &load_addr, &launch_op.u.builddomain, cmdline, + &load_addr, &st_ctxt, cmdline, op.u.getdomaininfo.shared_info_frame, control_evtchn) < 0 ) { @@ -274,8 +280,6 @@ int xc_netbsd_build(int xc_handle, if( kernel_gfd ) gzclose(kernel_gfd); - ctxt = &launch_op.u.builddomain.ctxt; - ctxt->flags = 0; /* @@ -328,9 +332,11 @@ int xc_netbsd_build(int xc_handle, ctxt->failsafe_callback_cs = FLAT_GUESTOS_CS; ctxt->failsafe_callback_eip = 0; + memset( &launch_op, 0, sizeof(launch_op) ); + launch_op.u.builddomain.domain = (domid_t)domid; launch_op.u.builddomain.num_vifs = 1; - + launch_op.u.builddomain.ctxt = ctxt; launch_op.cmd = DOM0_BUILDDOMAIN; rc = do_dom0_op(xc_handle, &launch_op); |