move full execution context out-of-line from dom0_op_t.
further changes to save/restore.
{
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;
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;
}
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)
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;
/* 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 )
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;
}
}
+ 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) )
{
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;
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 )
{
if ( image != NULL )
free(image);
- ctxt = &launch_op.u.builddomain.ctxt;
-
ctxt->flags = 0;
/*
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);
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. */
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) )
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 ) )
{
/* 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");
* 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;
}
/*
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;
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:
#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...) \
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) )
{
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;
/* 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) )
{
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 */
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++ )
}
-/* 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) )
{
!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;
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++ )
{
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++ )
{
/* 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 )
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;
}
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)
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;
*/
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;
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 )
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) )
{
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;
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 )
{
if( kernel_gfd )
gzclose(kernel_gfd);
- ctxt = &launch_op.u.builddomain.ctxt;
-
ctxt->flags = 0;
/*
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);
long do_dom0_op(dom0_op_t *u_dom0_op)
{
long ret = 0;
- dom0_op_t *op;
+ dom0_op_t curop,*op=&curop;
if ( !IS_PRIV(current) )
return -EPERM;
- if ( (op = kmalloc(sizeof(*op), GFP_KERNEL)) == NULL )
- return -ENOMEM;
-
if ( copy_from_user(op, u_dom0_op, sizeof(*op)) )
{
- ret = -EFAULT;
- goto out;
+ return -EFAULT;
}
if ( op->interface_version != DOM0_INTERFACE_VERSION )
{
- ret = -EACCES;
- goto out;
+ return -EACCES;
}
switch ( op->cmd )
for_each_domain ( p )
{
if ( p->domain >= op->u.getdomaininfo.domain )
- break;
+ break;
}
if ( p == NULL )
{
ret = -ESRCH;
+ goto gdi_out;
}
else
{
+printk("AAAA %p\n",op->u.getdomaininfo.ctxt);
op->u.getdomaininfo.domain = p->domain;
strcpy (op->u.getdomaininfo.name, p->name);
op->u.getdomaininfo.processor = p->processor;
op->u.getdomaininfo.cpu_time = p->cpu_time;
op->u.getdomaininfo.shared_info_frame =
__pa(p->shared_info) >> PAGE_SHIFT;
- if ( p->state == TASK_STOPPED )
+
+ if ( p->state == TASK_STOPPED && op->u.getdomaininfo.ctxt )
{
+ full_execution_context_t *c=NULL;
+
+ if ( (c = kmalloc(sizeof(*c), GFP_KERNEL)) == NULL )
+ {
+ ret= -ENOMEM;
+ goto gdi_out;
+ }
+
rmb(); /* Ensure that we see saved register state. */
- op->u.getdomaininfo.ctxt.flags = 0;
- memcpy(&op->u.getdomaininfo.ctxt.cpu_ctxt,
+ c->flags = 0;
+ memcpy(&c->cpu_ctxt,
&p->shared_info->execution_context,
sizeof(p->shared_info->execution_context));
if ( test_bit(PF_DONEFPUINIT, &p->flags) )
- op->u.getdomaininfo.ctxt.flags |= ECF_I387_VALID;
- memcpy(&op->u.getdomaininfo.ctxt.fpu_ctxt,
+ c->flags |= ECF_I387_VALID;
+ memcpy(&c->fpu_ctxt,
&p->thread.i387,
sizeof(p->thread.i387));
- memcpy(&op->u.getdomaininfo.ctxt.trap_ctxt,
+ memcpy(&c->trap_ctxt,
p->thread.traps,
sizeof(p->thread.traps));
#ifdef ARCH_HAS_FAST_TRAP
if ( (p->thread.fast_trap_desc.a == 0) &&
(p->thread.fast_trap_desc.b == 0) )
- op->u.getdomaininfo.ctxt.fast_trap_idx = 0;
+ c->fast_trap_idx = 0;
else
- op->u.getdomaininfo.ctxt.fast_trap_idx =
+ c->fast_trap_idx =
p->thread.fast_trap_idx;
#endif
- op->u.getdomaininfo.ctxt.ldt_base = p->mm.ldt_base;
- op->u.getdomaininfo.ctxt.ldt_ents = p->mm.ldt_ents;
- op->u.getdomaininfo.ctxt.gdt_ents = 0;
+ c->ldt_base = p->mm.ldt_base;
+ c->ldt_ents = p->mm.ldt_ents;
+ c->gdt_ents = 0;
if ( GET_GDT_ADDRESS(p) == GDT_VIRT_START )
{
for ( i = 0; i < 16; i++ )
- op->u.getdomaininfo.ctxt.gdt_frames[i] =
+ c->gdt_frames[i] =
l1_pgentry_to_pagenr(p->mm.perdomain_pt[i]);
- op->u.getdomaininfo.ctxt.gdt_ents =
+ c->gdt_ents =
(GET_GDT_ENTRIES(p) + 1) >> 3;
}
- op->u.getdomaininfo.ctxt.guestos_ss = p->thread.guestos_ss;
- op->u.getdomaininfo.ctxt.guestos_esp = p->thread.guestos_sp;
- op->u.getdomaininfo.ctxt.pt_base =
+ c->guestos_ss = p->thread.guestos_ss;
+ c->guestos_esp = p->thread.guestos_sp;
+ c->pt_base =
pagetable_val(p->mm.pagetable);
- memcpy(op->u.getdomaininfo.ctxt.debugreg,
+ memcpy(c->debugreg,
p->thread.debugreg,
sizeof(p->thread.debugreg));
- op->u.getdomaininfo.ctxt.event_callback_cs =
+ c->event_callback_cs =
p->event_selector;
- op->u.getdomaininfo.ctxt.event_callback_eip =
+ c->event_callback_eip =
p->event_address;
- op->u.getdomaininfo.ctxt.failsafe_callback_cs =
+ c->failsafe_callback_cs =
p->failsafe_selector;
- op->u.getdomaininfo.ctxt.failsafe_callback_eip =
+ c->failsafe_callback_eip =
p->failsafe_address;
+
+ if( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
+ {
+printk("URGHT %p\n",op->u.getdomaininfo.ctxt);
+ ret = -EINVAL;
+ }
+
+ if (c) kfree(c);
}
}
+
+ if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+ ret = -EINVAL;
+
+ gdi_out:
read_unlock_irqrestore(&tasklist_lock, flags);
- copy_to_user(u_dom0_op, op, sizeof(*op));
+
}
break;
}
- out:
- kfree(op);
return ret;
}
int final_setup_guestos(struct task_struct *p, dom0_builddomain_t *builddomain)
{
unsigned long phys_basetab;
- int i;
+ int i, rc = 0;
+ full_execution_context_t *c;
+
+ if ( (c = kmalloc(sizeof(*c), GFP_KERNEL)) == NULL )
+ return -ENOMEM;
if ( test_bit(PF_CONSTRUCTED, &p->flags) )
- return -EINVAL;
+ {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if ( copy_from_user(c, builddomain->ctxt, sizeof(*c)) )
+ {
+ rc = -EFAULT;
+ goto out;
+ }
clear_bit(PF_DONEFPUINIT, &p->flags);
- if ( builddomain->ctxt.flags & ECF_I387_VALID )
+ if ( c->flags & ECF_I387_VALID )
set_bit(PF_DONEFPUINIT, &p->flags);
memcpy(&p->shared_info->execution_context,
- &builddomain->ctxt.cpu_ctxt,
+ &c->cpu_ctxt,
sizeof(p->shared_info->execution_context));
memcpy(&p->thread.i387,
- &builddomain->ctxt.fpu_ctxt,
+ &c->fpu_ctxt,
sizeof(p->thread.i387));
memcpy(p->thread.traps,
- &builddomain->ctxt.trap_ctxt,
+ &c->trap_ctxt,
sizeof(p->thread.traps));
#ifdef ARCH_HAS_FAST_TRAP
SET_DEFAULT_FAST_TRAP(&p->thread);
- (void)set_fast_trap(p, builddomain->ctxt.fast_trap_idx);
+ (void)set_fast_trap(p, c->fast_trap_idx);
#endif
- p->mm.ldt_base = builddomain->ctxt.ldt_base;
- p->mm.ldt_ents = builddomain->ctxt.ldt_ents;
+ p->mm.ldt_base = c->ldt_base;
+ p->mm.ldt_ents = c->ldt_ents;
SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES);
SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS);
- if ( builddomain->ctxt.gdt_ents != 0 )
+ if ( c->gdt_ents != 0 )
(void)set_gdt(p,
- builddomain->ctxt.gdt_frames,
- builddomain->ctxt.gdt_ents);
- p->thread.guestos_ss = builddomain->ctxt.guestos_ss;
- p->thread.guestos_sp = builddomain->ctxt.guestos_esp;
+ c->gdt_frames,
+ c->gdt_ents);
+ p->thread.guestos_ss = c->guestos_ss;
+ p->thread.guestos_sp = c->guestos_esp;
for ( i = 0; i < 8; i++ )
- (void)set_debugreg(p, i, builddomain->ctxt.debugreg[i]);
- p->event_selector = builddomain->ctxt.event_callback_cs;
- p->event_address = builddomain->ctxt.event_callback_eip;
- p->failsafe_selector = builddomain->ctxt.failsafe_callback_cs;
- p->failsafe_address = builddomain->ctxt.failsafe_callback_eip;
+ (void)set_debugreg(p, i, c->debugreg[i]);
+ p->event_selector = c->event_callback_cs;
+ p->event_address = c->event_callback_eip;
+ p->failsafe_selector = c->failsafe_callback_cs;
+ p->failsafe_address = c->failsafe_callback_eip;
- phys_basetab = builddomain->ctxt.pt_base;
+ phys_basetab = c->pt_base;
p->mm.pagetable = mk_pagetable(phys_basetab);
get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], p,
PGT_base_page_table);
(void)create_net_vif(p->domain);
set_bit(PF_CONSTRUCTED, &p->flags);
+
+out:
+ if (c) kfree(c);
- return 0;
+ return rc;
}
static inline int is_loadable_phdr(Elf_Phdr *phdr)
{
/* IN variables. */
domid_t domain;
+ full_execution_context_t *ctxt;
/* OUT variables. */
char name[MAX_DOMAIN_NAME];
int processor;
unsigned int tot_pages, max_pages;
long long cpu_time;
unsigned long shared_info_frame; /* MFN of shared_info struct */
- full_execution_context_t ctxt;
} dom0_getdomaininfo_t;
#define DOM0_BUILDDOMAIN 13
/* IN variables. */
domid_t domain;
unsigned int num_vifs;
- full_execution_context_t ctxt;
+ /* IN/OUT parameters */
+ full_execution_context_t *ctxt;
} dom0_builddomain_t;
#define DOM0_IOPL 14
domid_t domain; /* To which domain does the frame belong? */
/* OUT variables. */
/* Is the page PINNED to a type? */
- enum { NONE, L1TAB, L2TAB, L3TAB, L4TAB } type;
+ enum { NONE, L1TAB=(1<<29), L2TAB=(2<<29), L3TAB=(3<<29), L4TAB=(4<<29) } type;
+#define PGT_type_mask (7<<29)
} dom0_getpageframeinfo_t;