debuggers.hg
changeset 22880:722f7b7678dc
tools/libxc, hvm: Fix 1G page allocation algorithm
Currently, cur_pages (which is used as index into page_array for
fetching gfns) is used to judge whether it is proper here to allocated
1G pages. However, cur_pages == page_array[cur_pages] only holds true
when it is below 4G. When it is above 4G, page_array[cur_pages] -
cur_pages = 256M.
As a result, when guest has 10G memory, 8 1G-pages are allocated. But
only 2 of them have their corresponding gfns 1G aligned. The other 6
are forced to split to 2M pages, as their starting gfns are 4G+256M,
5G+256M .................
Inside the patch, true gfns are used instead of cur_pages to fix this
issue.
Signed-off-by: Shan Haitao <haitao.shan@intel.com>
Acked-by: George Dunlap <george.dunlap@citrix.com>
Currently, cur_pages (which is used as index into page_array for
fetching gfns) is used to judge whether it is proper here to allocated
1G pages. However, cur_pages == page_array[cur_pages] only holds true
when it is below 4G. When it is above 4G, page_array[cur_pages] -
cur_pages = 256M.
As a result, when guest has 10G memory, 8 1G-pages are allocated. But
only 2 of them have their corresponding gfns 1G aligned. The other 6
are forced to split to 2M pages, as their starting gfns are 4G+256M,
5G+256M .................
Inside the patch, true gfns are used instead of cur_pages to fix this
issue.
Signed-off-by: Shan Haitao <haitao.shan@intel.com>
Acked-by: George Dunlap <george.dunlap@citrix.com>
author | Shan Haitao <haitao.shan@intel.com> |
---|---|
date | Fri Jan 28 11:08:49 2011 +0000 (2011-01-28) |
parents | f68570fb0032 |
children | 4fea7664a6fb |
files | tools/libxc/xc_hvm_build.c |
line diff
1.1 --- a/tools/libxc/xc_hvm_build.c Fri Jan 28 06:03:01 2011 +0000 1.2 +++ b/tools/libxc/xc_hvm_build.c Fri Jan 28 11:08:49 2011 +0000 1.3 @@ -137,7 +137,7 @@ static int setup_guest(xc_interface *xch 1.4 xen_pfn_t *page_array = NULL; 1.5 unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT); 1.6 unsigned long target_pages = (unsigned long)target << (20 - PAGE_SHIFT); 1.7 - unsigned long entry_eip, cur_pages; 1.8 + unsigned long entry_eip, cur_pages, cur_pfn; 1.9 void *hvm_info_page; 1.10 uint32_t *ident_pt; 1.11 struct elf_binary elf; 1.12 @@ -215,11 +215,13 @@ static int setup_guest(xc_interface *xch 1.13 1.14 if ( count > max_pages ) 1.15 count = max_pages; 1.16 - 1.17 + 1.18 + cur_pfn = page_array[cur_pages]; 1.19 + 1.20 /* Take care the corner cases of super page tails */ 1.21 - if ( ((cur_pages & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) && 1.22 - (count > (-cur_pages & (SUPERPAGE_1GB_NR_PFNS-1))) ) 1.23 - count = -cur_pages & (SUPERPAGE_1GB_NR_PFNS-1); 1.24 + if ( ((cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) && 1.25 + (count > (-cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1))) ) 1.26 + count = -cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1); 1.27 else if ( ((count & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) && 1.28 (count > SUPERPAGE_1GB_NR_PFNS) ) 1.29 count &= ~(SUPERPAGE_1GB_NR_PFNS - 1); 1.30 @@ -227,9 +229,9 @@ static int setup_guest(xc_interface *xch 1.31 /* Attemp to allocate 1GB super page. Because in each pass we only 1.32 * allocate at most 1GB, we don't have to clip super page boundaries. 1.33 */ 1.34 - if ( ((count | cur_pages) & (SUPERPAGE_1GB_NR_PFNS - 1)) == 0 && 1.35 + if ( ((count | cur_pfn) & (SUPERPAGE_1GB_NR_PFNS - 1)) == 0 && 1.36 /* Check if there exists MMIO hole in the 1GB memory range */ 1.37 - !check_mmio_hole(cur_pages << PAGE_SHIFT, 1.38 + !check_mmio_hole(cur_pfn << PAGE_SHIFT, 1.39 SUPERPAGE_1GB_NR_PFNS << PAGE_SHIFT) ) 1.40 { 1.41 long done; 1.42 @@ -260,15 +262,15 @@ static int setup_guest(xc_interface *xch 1.43 count = max_pages; 1.44 1.45 /* Clip partial superpage extents to superpage boundaries. */ 1.46 - if ( ((cur_pages & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) && 1.47 - (count > (-cur_pages & (SUPERPAGE_2MB_NR_PFNS-1))) ) 1.48 - count = -cur_pages & (SUPERPAGE_2MB_NR_PFNS-1); 1.49 + if ( ((cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) && 1.50 + (count > (-cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1))) ) 1.51 + count = -cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1); 1.52 else if ( ((count & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) && 1.53 (count > SUPERPAGE_2MB_NR_PFNS) ) 1.54 count &= ~(SUPERPAGE_2MB_NR_PFNS - 1); /* clip non-s.p. tail */ 1.55 1.56 /* Attempt to allocate superpage extents. */ 1.57 - if ( ((count | cur_pages) & (SUPERPAGE_2MB_NR_PFNS - 1)) == 0 ) 1.58 + if ( ((count | cur_pfn) & (SUPERPAGE_2MB_NR_PFNS - 1)) == 0 ) 1.59 { 1.60 long done; 1.61 unsigned long nr_extents = count >> SUPERPAGE_2MB_SHIFT;