debuggers.hg
changeset 20943:217f6aa87716
mem hotplug: Fix an incorrect sanity check in memory add
Current, memory hot-add will fail if the new added memory is bigger
than current max_pages. This is really a stupid checking, considering
user may hot-add the biggest address riser card firstly.
This patch fix this issue. It check if all new added memory is
unpopulated, if yes, then it is ok.
Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
Current, memory hot-add will fail if the new added memory is bigger
than current max_pages. This is really a stupid checking, considering
user may hot-add the biggest address riser card firstly.
This patch fix this issue. It check if all new added memory is
unpopulated, if yes, then it is ok.
Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Thu Feb 04 13:09:30 2010 +0000 (2010-02-04) |
parents | ece60564af6f |
children | 8c1889297084 |
files | xen/arch/x86/x86_64/mm.c |
line diff
1.1 --- a/xen/arch/x86/x86_64/mm.c Thu Feb 04 09:09:13 2010 +0000 1.2 +++ b/xen/arch/x86/x86_64/mm.c Thu Feb 04 13:09:30 2010 +0000 1.3 @@ -1332,9 +1332,12 @@ int transfer_pages_to_heap(struct mem_ho 1.4 1.5 int mem_hotadd_check(unsigned long spfn, unsigned long epfn) 1.6 { 1.7 - unsigned long s, e, length; 1.8 + unsigned long s, e, length, sidx, eidx; 1.9 1.10 - if ( (spfn >= epfn) || (spfn < max_page) ) 1.11 + if ( (spfn >= epfn) ) 1.12 + return 0; 1.13 + 1.14 + if (pfn_to_pdx(epfn) > (FRAMETABLE_SIZE / sizeof(*frame_table))) 1.15 return 0; 1.16 1.17 if ( (spfn | epfn) & ((1UL << PAGETABLE_ORDER) - 1) ) 1.18 @@ -1343,6 +1346,20 @@ int mem_hotadd_check(unsigned long spfn, 1.19 if ( (spfn | epfn) & pfn_hole_mask ) 1.20 return 0; 1.21 1.22 + /* Make sure the new range is not present now */ 1.23 + sidx = ((pfn_to_pdx(spfn) + PDX_GROUP_COUNT - 1) & ~(PDX_GROUP_COUNT - 1)) 1.24 + / PDX_GROUP_COUNT; 1.25 + eidx = (pfn_to_pdx(epfn - 1) & ~(PDX_GROUP_COUNT - 1)) / PDX_GROUP_COUNT; 1.26 + if (sidx >= eidx) 1.27 + return 0; 1.28 + 1.29 + s = find_next_zero_bit(pdx_group_valid, eidx, sidx); 1.30 + if ( s > eidx ) 1.31 + return 0; 1.32 + e = find_next_bit(pdx_group_valid, eidx, s); 1.33 + if ( e < eidx ) 1.34 + return 0; 1.35 + 1.36 /* Caculate at most required m2p/compat m2p/frametable pages */ 1.37 s = (spfn & ~((1UL << (L2_PAGETABLE_SHIFT - 3)) - 1)); 1.38 e = (epfn + (1UL << (L2_PAGETABLE_SHIFT - 3)) - 1) & 1.39 @@ -1433,8 +1450,11 @@ int memory_add(unsigned long spfn, unsig 1.40 goto destroy_frametable; 1.41 1.42 /* Set max_page as setup_m2p_table will use it*/ 1.43 - max_page = epfn; 1.44 - max_pdx = pfn_to_pdx(max_page - 1) + 1; 1.45 + if (max_page < epfn) 1.46 + { 1.47 + max_page = epfn; 1.48 + max_pdx = pfn_to_pdx(max_page - 1) + 1; 1.49 + } 1.50 total_pages += epfn - spfn; 1.51 1.52 set_pdx_range(spfn, epfn); 1.53 @@ -1443,7 +1463,7 @@ int memory_add(unsigned long spfn, unsig 1.54 if ( ret ) 1.55 goto destroy_m2p; 1.56 1.57 - for ( i = old_max; i < epfn; i++ ) 1.58 + for ( i = spfn; i < epfn; i++ ) 1.59 if ( iommu_map_page(dom0, i, i) ) 1.60 break; 1.61