aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_64/mm.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-21 10:48:01 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-21 10:48:01 +0000
commitdea3f61b59084b48e48515d999d6d908e32341aa (patch)
treea76b946e413657b6391b30ebdc9834196df183c8 /xen/arch/x86/x86_64/mm.c
parent8e73d3d71c9904a0de911f955b431c25fd63e2d1 (diff)
downloadxen-dea3f61b59084b48e48515d999d6d908e32341aa.tar.gz
xen-dea3f61b59084b48e48515d999d6d908e32341aa.tar.bz2
xen-dea3f61b59084b48e48515d999d6d908e32341aa.zip
Check m2p/compat m2p table for new added memory.
As we allocate m2p/compat m2p/frametable page tables from new added memory, we want to make sure the new range can hold up the new page tables, this is because m2p/frametable need be aligned and cover more than the new-added range. Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
Diffstat (limited to 'xen/arch/x86/x86_64/mm.c')
-rw-r--r--xen/arch/x86/x86_64/mm.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
index a6954c743e..dfa12ad171 100644
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -1332,6 +1332,8 @@ int transfer_pages_to_heap(struct mem_hotadd_info *info)
int mem_hotadd_check(unsigned long spfn, unsigned long epfn)
{
+ unsigned long s, e, length;
+
if ( (spfn >= epfn) || (spfn < max_page) )
return 0;
@@ -1341,7 +1343,31 @@ int mem_hotadd_check(unsigned long spfn, unsigned long epfn)
if ( (spfn | epfn) & pfn_hole_mask )
return 0;
- /* TBD: Need make sure cover to m2p/ft page table */
+ /* Caculate at most required m2p/compat m2p/frametable pages */
+ s = (spfn & ~((1UL << (L2_PAGETABLE_SHIFT - 3)) - 1));
+ e = (epfn + (1UL << (L2_PAGETABLE_SHIFT - 3)) - 1) &
+ ~((1UL << (L2_PAGETABLE_SHIFT - 3)) - 1);
+
+ length = (e - s) * sizeof(unsigned long);
+
+ s = (spfn & ~((1UL << (L2_PAGETABLE_SHIFT - 2)) - 1));
+ e = (epfn + (1UL << (L2_PAGETABLE_SHIFT - 2)) - 1) &
+ ~((1UL << (L2_PAGETABLE_SHIFT - 2)) - 1);
+
+ e = min_t(unsigned long, e,
+ (RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START) >> 2);
+
+ if ( e > s )
+ length += (e -s) * sizeof(unsigned int);
+
+ s = pfn_to_pdx(spfn) & ~(PDX_GROUP_COUNT - 1);
+ e = ( pfn_to_pdx(epfn) + (PDX_GROUP_COUNT - 1) ) & ~(PDX_GROUP_COUNT - 1);
+
+ length += (e - s) * sizeof(struct page_info);
+
+ if ((length >> PAGE_SHIFT) > (epfn - spfn))
+ return 0;
+
return 1;
}