diff options
Diffstat (limited to 'tools/libxc/xc_linux_build.c')
-rw-r--r-- | tools/libxc/xc_linux_build.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 012d66ae93..660c30a3f1 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -48,17 +48,18 @@ static int probeimageformat(char *image, } static int setup_guest(int xc_handle, - u32 dom, - char *image, unsigned long image_size, - gzFile initrd_gfd, unsigned long initrd_len, - unsigned long nr_pages, - unsigned long *pvsi, unsigned long *pvke, - vcpu_guest_context_t *ctxt, - const char *cmdline, - unsigned long shared_info_frame, - unsigned int control_evtchn, - unsigned long flags, - unsigned int vcpus) + u32 dom, + char *image, unsigned long image_size, + gzFile initrd_gfd, unsigned long initrd_len, + unsigned long nr_pages, + unsigned long *pvsi, unsigned long *pvke, + unsigned long *pvss, vcpu_guest_context_t *ctxt, + const char *cmdline, + unsigned long shared_info_frame, + unsigned int control_evtchn, + unsigned long flags, + unsigned int vcpus, + unsigned int store_evtchn, unsigned long *store_mfn) { l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; l2_pgentry_t *vl2tab=NULL, *vl2e=NULL; @@ -91,6 +92,8 @@ static int setup_guest(int xc_handle, unsigned long vphysmap_end; unsigned long vstartinfo_start; unsigned long vstartinfo_end; + unsigned long vstoreinfo_start; + unsigned long vstoreinfo_end; unsigned long vstack_start; unsigned long vstack_end; unsigned long vpt_start; @@ -130,7 +133,10 @@ static int setup_guest(int xc_handle, vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE); vstartinfo_start = vpt_end; vstartinfo_end = vstartinfo_start + PAGE_SIZE; - vstack_start = vstartinfo_end; + /* Place store shared page after startinfo. */ + vstoreinfo_start = vstartinfo_end; + vstoreinfo_end = vstartinfo_end + PAGE_SIZE; + vstack_start = vstoreinfo_end; vstack_end = vstack_start + PAGE_SIZE; v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); if ( (v_end - vstack_end) < (512UL << 10) ) @@ -161,6 +167,7 @@ static int setup_guest(int xc_handle, " Phys-Mach map: %p->%p\n" " Page tables: %p->%p\n" " Start info: %p->%p\n" + " Store page: %p->%p\n" " Boot stack: %p->%p\n" " TOTAL: %p->%p\n", _p(dsi.v_kernstart), _p(dsi.v_kernend), @@ -168,6 +175,7 @@ static int setup_guest(int xc_handle, _p(vphysmap_start), _p(vphysmap_end), _p(vpt_start), _p(vpt_end), _p(vstartinfo_start), _p(vstartinfo_end), + _p(vstoreinfo_start), _p(vstoreinfo_end), _p(vstack_start), _p(vstack_end), _p(dsi.v_start), _p(v_end)); printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); @@ -377,6 +385,8 @@ static int setup_guest(int xc_handle, start_info->nr_pt_frames = nr_pt_pages; start_info->mfn_list = vphysmap_start; start_info->domain_controller_evtchn = control_evtchn; + start_info->store_page = vstoreinfo_start; + start_info->store_evtchn = store_evtchn; if ( initrd_len != 0 ) { start_info->mod_start = vinitrd_start; @@ -386,6 +396,9 @@ static int setup_guest(int xc_handle, start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0'; munmap(start_info, PAGE_SIZE); + /* Tell our caller where we told domain store page was. */ + *store_mfn = page_array[((vstoreinfo_start-dsi.v_start)>>PAGE_SHIFT)]; + /* shared_info page starts its life empty. */ shared_info = xc_map_foreign_range( xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame); @@ -407,6 +420,7 @@ static int setup_guest(int xc_handle, free(page_array); *pvsi = vstartinfo_start; + *pvss = vstack_start; *pvke = dsi.v_kernentry; return 0; @@ -426,7 +440,9 @@ int xc_linux_build(int xc_handle, const char *cmdline, unsigned int control_evtchn, unsigned long flags, - unsigned int vcpus) + unsigned int vcpus, + unsigned int store_evtchn, + unsigned long *store_mfn) { dom0_op_t launch_op, op; int initrd_fd = -1; @@ -436,7 +452,7 @@ int xc_linux_build(int xc_handle, unsigned long nr_pages; char *image = NULL; unsigned long image_size, initrd_size=0; - unsigned long vstartinfo_start, vkern_entry; + unsigned long vstartinfo_start, vkern_entry, vstack_start; if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 ) { @@ -493,11 +509,12 @@ int xc_linux_build(int xc_handle, } if ( setup_guest(xc_handle, domid, image, image_size, - initrd_gfd, initrd_size, nr_pages, - &vstartinfo_start, &vkern_entry, - ctxt, cmdline, - op.u.getdomaininfo.shared_info_frame, - control_evtchn, flags, vcpus) < 0 ) + initrd_gfd, initrd_size, nr_pages, + &vstartinfo_start, &vkern_entry, + &vstack_start, ctxt, cmdline, + op.u.getdomaininfo.shared_info_frame, + control_evtchn, flags, vcpus, + store_evtchn, store_mfn) < 0 ) { ERROR("Error constructing guest OS"); goto error_out; @@ -528,7 +545,7 @@ int xc_linux_build(int xc_handle, ctxt->user_regs.ss = FLAT_KERNEL_SS; ctxt->user_regs.cs = FLAT_KERNEL_CS; ctxt->user_regs.eip = vkern_entry; - ctxt->user_regs.esp = vstartinfo_start + 2*PAGE_SIZE; + ctxt->user_regs.esp = vstack_start + PAGE_SIZE; ctxt->user_regs.esi = vstartinfo_start; ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */ @@ -550,7 +567,7 @@ int xc_linux_build(int xc_handle, /* Ring 1 stack is the initial stack. */ ctxt->kernel_ss = FLAT_KERNEL_SS; - ctxt->kernel_sp = vstartinfo_start + 2*PAGE_SIZE; + ctxt->kernel_sp = vstack_start + PAGE_SIZE; /* No debugging. */ memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg)); |