# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Node ID e3e02e227b3e8d97537c38d5cdba9959bdd05d6a # Parent f6774d15d763fead75e6320e63fa1f14fabab26a check memory descriptor over lap in dom_fw_init() and assign page to dom0 precisely. PATCHNAME: assign_page_to_dom0_precisely Signed-off-by: Isaku Yamahata diff -r f6774d15d763 -r e3e02e227b3e xen/arch/ia64/xen/dom_fw.c --- a/xen/arch/ia64/xen/dom_fw.c Thu Jun 01 11:39:04 2006 +0900 +++ b/xen/arch/ia64/xen/dom_fw.c Thu Jun 01 11:39:06 2006 +0900 @@ -1017,11 +1017,16 @@ dom_fw_init (struct domain *d, const cha /* simulate 1MB free memory at physical address zero */ MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 0);//XXX +#else + int num_mds; + int j; #endif /* hypercall patches live here, masquerade as reserved PAL memory */ MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END, 0); + + +#ifndef CONFIG_XEN_IA64_DOM0_VP MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem-IA64_GRANULE_SIZE, 0);//XXX make sure this doesn't overlap on i/o, runtime area. -#ifndef CONFIG_XEN_IA64_DOM0_VP /* hack */ MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,last_start,last_end,1); #endif @@ -1054,6 +1059,52 @@ dom_fw_init (struct domain *d, const cha dom_fw_dom0_passthrough, &arg); } else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0); + +#ifdef CONFIG_XEN_IA64_DOM0_VP + // simple + // MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, + // HYPERCALL_END, maxmem, 0); + // is not good. Check overlap. + sort(efi_memmap, i, sizeof(efi_memory_desc_t), efi_mdt_cmp, NULL); + + num_mds = i; + for (j = 0; j < num_mds; j++) { + unsigned long start; + unsigned long end; + unsigned long next_start; + int k; + + md = &efi_memmap[j]; + start = md->phys_addr; + end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); + + if (maxmem < start) + break; + + // find gap + next_start = maxmem; + for (k = j + 1; k < num_mds; k++) { + efi_memory_desc_t* next_md = &efi_memmap[k]; + + if (end != next_md->phys_addr) { + next_start = next_md->phys_addr; + break; + } + end = next_md->phys_addr + + (next_md->num_pages << EFI_PAGE_SHIFT); + } + + if (next_start < HYPERCALL_END) + continue; + + if (end < HYPERCALL_END) + end = HYPERCALL_END; + if (next_start > maxmem) + next_start = maxmem; + MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, + end, next_start, 0); + } +#endif } else { #ifndef CONFIG_XEN_IA64_DOM0_VP @@ -1084,11 +1135,45 @@ dom_fw_init (struct domain *d, const cha bp->console_info.orig_y = 24; bp->fpswa = dom_pa((unsigned long) fpswa_inf); if (d == dom0) { + int j; + u64 addr; + // XXX CONFIG_XEN_IA64_DOM0_VP - // initrd_start address is hard coded in start_kernel() + // initrd_start address is hard coded in construct_dom0() bp->initrd_start = (dom0_start+dom0_size) - (PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024); bp->initrd_size = ia64_boot_param->initrd_size; + + // dom0 doesn't need build_physmap_table() + // see arch_set_info_guest() + // instead we allocate pages manually. + for (j = 0; j < i; j++) { + md = &efi_memmap[j]; + if (md->phys_addr > maxmem) + break; + + if (md->type == EFI_LOADER_DATA || + md->type == EFI_PAL_CODE || + md->type == EFI_CONVENTIONAL_MEMORY) { + unsigned long start = (md->phys_addr & PAGE_MASK); + unsigned long end = md->phys_addr + + (md->num_pages << EFI_PAGE_SHIFT); + + if (end == start) + end += PAGE_SIZE;// md->num_pages = 0 is allowed. + if (end > (max_page << PAGE_SHIFT)) + end = (max_page << PAGE_SHIFT); + + for (addr = start; addr < end; addr += PAGE_SIZE) { + assign_new_domain0_page(d, addr); + } + } + } + // work around for legacy device driver. + for (addr = 0; addr < 1 * MB; addr += PAGE_SIZE) { + assign_new_domain0_page(d, addr); + } + d->arch.physmap_built = 1; } else { bp->initrd_start = d->arch.initrd_start; diff -r f6774d15d763 -r e3e02e227b3e xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Thu Jun 01 11:39:04 2006 +0900 +++ b/xen/arch/ia64/xen/domain.c Thu Jun 01 11:39:06 2006 +0900 @@ -1882,14 +1882,6 @@ int construct_dom0(struct domain *d, new_thread(v, pkern_entry, 0, 0); physdev_init_dom0(d); - // dom0 doesn't need build_physmap_table() - // see arch_set_info_guest() - // instead we allocate pages manually. - for (i = 0; i < max_pages; i++) { - assign_new_domain0_page(d, i << PAGE_SHIFT); - } - d->arch.physmap_built = 1; - // FIXME: Hack for keyboard input //serial_input_init();