diff --git a/tools/ioemu/memory/misc_mem.cc b/tools/ioemu/memory/misc_mem.cc index 51be8cbfb3..a69591dc1d 100644 --- a/tools/ioemu/memory/misc_mem.cc +++ b/tools/ioemu/memory/misc_mem.cc @@ -174,20 +174,16 @@ BX_MEM_C::init_memory(int memsize) #define PAGE_SHIFT 12 #define PAGE_SIZE (1 << PAGE_SHIFT) -#define round_pgup(x) (((x) + PAGE_SIZE-1) & ~ (PAGE_SIZE-1)) - int npte_pages = 1 + (round_pgup(nr_pages * 4) / PAGE_SIZE); - - /* We don't map pte pages and the top 64k -- XXX: this could be a problem */ if ((vector = (Bit8u *) xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE, page_array, - nr_pages - npte_pages - 16)) == 0) { + nr_pages - 1)) == 0) { BX_ERROR(("Could not map guest physical")); return; } - BX_MEM_THIS dma_limit = (nr_pages - npte_pages - 16) << PAGE_SHIFT; + BX_MEM_THIS dma_limit = (nr_pages - 1) << PAGE_SHIFT; BX_INFO(("DMA limit: %lx", BX_MEM_THIS dma_limit)); shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, diff --git a/tools/libxc/xc.h b/tools/libxc/xc.h index ceb43214e5..81d7b2ed3f 100644 --- a/tools/libxc/xc.h +++ b/tools/libxc/xc.h @@ -211,6 +211,7 @@ xc_plan9_build (int xc_handle, struct mem_map; int xc_vmx_build(int xc_handle, u32 domid, + int memsize, const char *image_name, struct mem_map *memmap, const char *ramdisk_name, diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index 85de2a3f97..7623b2b448 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -47,7 +47,7 @@ loadelfsymtab( struct domain_setup_info *dsi); static int setup_guestos(int xc_handle, - u32 dom, + u32 dom, int memsize, char *image, unsigned long image_size, gzFile initrd_gfd, unsigned long initrd_len, unsigned long nr_pages, @@ -110,21 +110,23 @@ static int setup_guestos(int xc_handle, * read-only). We have a pair of simultaneous equations in two unknowns, * which we solve by exhaustive search. */ - nr_pt_pages = 1 + (nr_pages >> (PAGE_SHIFT - 2)); vboot_params_start = LINUX_BOOT_PARAMS_ADDR; vboot_params_end = vboot_params_start + PAGE_SIZE; vboot_gdt_start = vboot_params_end; vboot_gdt_end = vboot_gdt_start + PAGE_SIZE; - v_end = nr_pages << PAGE_SHIFT; - vpt_end = v_end - (16 << PAGE_SHIFT); /* leaving the top 64k untouched */ - vpt_start = vpt_end - (nr_pt_pages << PAGE_SHIFT); - vinitrd_end = vpt_start; + + v_end = memsize << 20; + vinitrd_end = v_end - PAGE_SIZE; /* leaving the top 4k untouched for IO requests page use */ vinitrd_start = vinitrd_end - initrd_len; vinitrd_start = vinitrd_start & (~(PAGE_SIZE - 1)); if(initrd_len == 0) vinitrd_start = vinitrd_end = 0; + nr_pt_pages = 1 + ((memsize + 3) >> 2); + vpt_start = v_end; + vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE); + printf("VIRTUAL MEMORY ARRANGEMENT:\n" " Boot_params: %08lx->%08lx\n" " boot_gdt: %08lx->%08lx\n" @@ -218,9 +220,6 @@ static int setup_guestos(int xc_handle, } *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT; - if ( (count >= ((vpt_start-dsi.v_start)>>PAGE_SHIFT)) && - (count < ((vpt_end -dsi.v_start)>>PAGE_SHIFT)) ) - *vl1e &= ~_PAGE_RW; vl1e++; } munmap(vl1tab, PAGE_SIZE); @@ -267,7 +266,7 @@ static int setup_guestos(int xc_handle, boot_paramsp->initrd_start = vinitrd_start; boot_paramsp->initrd_size = initrd_len; - i = (nr_pages >> (PAGE_SHIFT - 10)) - (1 << 10) - 4; + i = ((memsize - 1) << 10) - 4; boot_paramsp->alt_mem_k = i; /* alt_mem_k */ boot_paramsp->screen.overlap.ext_mem_k = i & 0xFFFF; /* ext_mem_k */ @@ -374,6 +373,7 @@ int vmx_identify(void) int xc_vmx_build(int xc_handle, u32 domid, + int memsize, const char *image_name, struct mem_map *mem_mapp, const char *ramdisk_name, @@ -445,7 +445,7 @@ int xc_vmx_build(int xc_handle, goto error_out; } - if ( setup_guestos(xc_handle, domid, image, image_size, + if ( setup_guestos(xc_handle, domid, memsize, image, image_size, initrd_gfd, initrd_size, nr_pages, ctxt, cmdline, op.u.getdomaininfo.shared_info_frame, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 6fb510111f..543a2cd380 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -405,15 +405,18 @@ static PyObject *pyxc_vmx_build(PyObject *self, PyObject *memmap; int control_evtchn, flags = 0; int numItems, i; + int memsize; struct mem_map mem_map; - static char *kwd_list[] = { "dom", "control_evtchn", + static char *kwd_list[] = { "dom", "control_evtchn", + "memsize", "image", "memmap", "ramdisk", "cmdline", "flags", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iisO!|ssi", kwd_list, + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisO!|ssi", kwd_list, &dom, &control_evtchn, + &memsize, &image, &PyList_Type, &memmap, &ramdisk, &cmdline, &flags) ) return NULL; @@ -467,7 +470,7 @@ static PyObject *pyxc_vmx_build(PyObject *self, mem_map.map[i-1].caching_attr = lf4; } - if ( xc_vmx_build(xc->xc_handle, dom, image, &mem_map, + if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, &mem_map, ramdisk, cmdline, control_evtchn, flags) != 0 ) return PyErr_SetFromErrno(xc_error); diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 16a6437763..22a0a8b282 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -320,6 +320,7 @@ class XendDomainInfo: self.restart_time = None self.console_port = None self.savedinfo = None + self.image_handler = None self.is_vmx = 0 self.vcpus = 1 @@ -455,6 +456,7 @@ class XendDomainInfo: except: raise VmError('invalid vcpus value') + self.find_image_handler() self.init_domain() self.configure_console() self.configure_backends() @@ -471,7 +473,7 @@ class XendDomainInfo: raise return deferred - def construct_image(self): + def find_image_handler(self): """Construct the boot image for the domain. @return vm @@ -482,10 +484,17 @@ class XendDomainInfo: image_name = sxp.name(image) if image_name is None: raise VmError('missing image name') + if image_name == "vmx": + self.is_vmx = 1 image_handler = get_image_handler(image_name) if image_handler is None: raise VmError('unknown image type: ' + image_name) - image_handler(self, image) + self.image_handler = image_handler + return self + + def construct_image(self): + image = sxp.child_value(self.config, 'image') + self.image_handler(self, image) return self def config_devices(self, name): @@ -730,7 +739,8 @@ class XendDomainInfo: except: raise VmError('invalid cpu') cpu_weight = self.cpu_weight - dom = xc.domain_create(dom= dom, mem_kb= memory * 1024, + memory = memory * 1024 + self.pgtable_size(memory) + dom = xc.domain_create(dom= dom, mem_kb= memory, cpu= cpu, cpu_weight= cpu_weight) if dom <= 0: raise VmError('Creating domain failed: name=%s memory=%d' @@ -757,6 +767,7 @@ class XendDomainInfo: err = buildfn(dom = dom, image = kernel, control_evtchn = 0, + memsize = self.memory, memmap = memmap, cmdline = cmdline, ramdisk = ramdisk, @@ -1084,6 +1095,18 @@ class XendDomainInfo: d.addErrback(dlist_err) return d + def pgtable_size(self, memory): + """Return the size of memory needed for 1:1 page tables for physical + mode. + + @param memory: size in MB + @return size in KB + """ + if self.is_vmx: + # Logic x86-32 specific. + # 1 page for the PGD + 1 pte page for 4MB of memory (rounded) + return (1 + ((memory + 3) >> 2)) * 4 + return 0 def vm_image_linux(vm, image): """Create a VM for a linux image. @@ -1159,7 +1182,6 @@ def vm_image_vmx(vm, image): from xen.util.memmap import memmap_parse memmap = memmap_parse(memmap) vm.create_domain("vmx", kernel, ramdisk, cmdline, memmap) - vm.is_vmx = 1 return vm def vm_dev_vif(vm, val, index, change=0):