# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Node ID 8036118ac7265006f683c2ae20b92d722909d0e6 # Parent 25483d9b55d4307d125f4135b609a6387f247ba8 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 Signed-off-by: Alex Williamson diff -r 25483d9b55d4 -r 8036118ac726 xen/arch/ia64/xen/dom_fw.c --- a/xen/arch/ia64/xen/dom_fw.c Wed May 31 16:07:47 2006 -0600 +++ b/xen/arch/ia64/xen/dom_fw.c Fri Jun 02 15:26:40 2006 +0900 @@ -3,6 +3,9 @@ * Copyright (C) 2004 Hewlett-Packard Co. * Dan Magenheimer (dan.magenheimer@xxxxxx) * + * Copyright (c) 2006 Isaku Yamahata + * VA Linux Systems Japan K.K. + * dom0 vp model support */ #include @@ -782,6 +785,13 @@ efi_mdt_cmp(const void *a, const void *b return 1; if (x->phys_addr < y->phys_addr) return -1; + + // num_pages == 0 is allowed. + if (x->num_pages > y->num_pages) + return 1; + if (x->num_pages < y->num_pages) + return -1; + return 0; } @@ -1011,11 +1021,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 @@ -1048,6 +1063,50 @@ 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); + + // find gap and fill it with conventional memory + num_mds = i; + for (j = 0; j < num_mds; j++) { + unsigned long end; + unsigned long next_start; + + md = &efi_memmap[j]; + end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); + + next_start = maxmem; + if (j + 1 < num_mds) { + efi_memory_desc_t* next_md = &efi_memmap[j + 1]; + next_start = next_md->phys_addr; + BUG_ON(end > next_start); + if (end == next_md->phys_addr) + continue; + } + + // clip the range and align to PAGE_SIZE + // Avoid "legacy" low memory addresses and the + // HYPERCALL patch area. + if (end < HYPERCALL_END) + end = HYPERCALL_END; + if (next_start > maxmem) + next_start = maxmem; + end = PAGE_ALIGN(end); + next_start = next_start & PAGE_MASK; + if (end >= next_start) + continue; + + MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, + end, next_start, 0); + if (next_start >= maxmem) + break; + } +#endif } else { #ifndef CONFIG_XEN_IA64_DOM0_VP @@ -1078,11 +1137,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 25483d9b55d4 -r 8036118ac726 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Wed May 31 16:07:47 2006 -0600 +++ b/xen/arch/ia64/xen/domain.c Fri Jun 02 15:26:40 2006 +0900 @@ -1845,14 +1845,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();