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>
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;