[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v7 9/9] xen: retrieve reserved pages on populate_physmap
When a static domain populates memory through populate_physmap at runtime, it shall retrieve reserved pages from resv_page_list to make sure that guest RAM is still restricted in statically configured memory regions. This commit also introduces a new helper acquire_reserved_page to make it work. Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx> --- v7 changes: - remove the lock, since we add the page to rsv_page_list after it has been totally freed. --- v6 changes: - drop the lock before returning --- v5 changes: - extract common codes for assigning pages into a helper assign_domstatic_pages - refine commit message - remove stub function acquire_reserved_page - Alloc/free of memory can happen concurrently. So access to rsv_page_list needs to be protected with a spinlock --- v4 changes: - miss dropping __init in acquire_domstatic_pages - add the page back to the reserved list in case of error - remove redundant printk - refine log message and make it warn level --- v3 changes: - move is_domain_using_staticmem to the common header file - remove #ifdef CONFIG_STATIC_MEMORY-ary - remove meaningless page_to_mfn(page) in error log --- v2 changes: - introduce acquire_reserved_page to retrieve reserved pages from resv_page_list - forbid non-zero-order requests in populate_physmap - let is_domain_static return ((void)(d), false) on x86 --- xen/common/memory.c | 23 ++++++++++++++ xen/common/page_alloc.c | 68 ++++++++++++++++++++++++++++++----------- xen/include/xen/mm.h | 1 + 3 files changed, 75 insertions(+), 17 deletions(-) diff --git a/xen/common/memory.c b/xen/common/memory.c index f2d009843a..cb330ce877 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -245,6 +245,29 @@ static void populate_physmap(struct memop_args *a) mfn = _mfn(gpfn); } + else if ( is_domain_using_staticmem(d) ) + { + /* + * No easy way to guarantee the retrieved pages are contiguous, + * so forbid non-zero-order requests here. + */ + if ( a->extent_order != 0 ) + { + gdprintk(XENLOG_WARNING, + "Cannot allocate static order-%u pages for static %pd\n", + a->extent_order, d); + goto out; + } + + mfn = acquire_reserved_page(d, a->memflags); + if ( mfn_eq(mfn, INVALID_MFN) ) + { + gdprintk(XENLOG_WARNING, + "%pd: failed to retrieve a reserved page\n", + d); + goto out; + } + } else { page = alloc_domheap_pages(d, a->extent_order, a->memflags); diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index fee396a92d..74628889ea 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -2673,9 +2673,8 @@ void free_staticmem_pages(struct page_info *pg, unsigned long nr_mfns, spin_unlock(&heap_lock); } -static bool __init prepare_staticmem_pages(struct page_info *pg, - unsigned long nr_mfns, - unsigned int memflags) +static bool prepare_staticmem_pages(struct page_info *pg, unsigned long nr_mfns, + unsigned int memflags) { bool need_tlbflush = false; uint32_t tlbflush_timestamp = 0; @@ -2756,21 +2755,9 @@ static struct page_info * __init acquire_staticmem_pages(mfn_t smfn, return pg; } -/* - * Acquire nr_mfns contiguous pages, starting at #smfn, of static memory, - * then assign them to one specific domain #d. - */ -int __init acquire_domstatic_pages(struct domain *d, mfn_t smfn, - unsigned int nr_mfns, unsigned int memflags) +static int assign_domstatic_pages(struct domain *d, struct page_info *pg, + unsigned int nr_mfns, unsigned int memflags) { - struct page_info *pg; - - ASSERT_ALLOC_CONTEXT(); - - pg = acquire_staticmem_pages(smfn, nr_mfns, memflags); - if ( !pg ) - return -ENOENT; - if ( !d || (memflags & (MEMF_no_owner | MEMF_no_refcount)) ) { /* @@ -2789,6 +2776,53 @@ int __init acquire_domstatic_pages(struct domain *d, mfn_t smfn, return 0; } + +/* + * Acquire nr_mfns contiguous pages, starting at #smfn, of static memory, + * then assign them to one specific domain #d. + */ +int __init acquire_domstatic_pages(struct domain *d, mfn_t smfn, + unsigned int nr_mfns, unsigned int memflags) +{ + struct page_info *pg; + + ASSERT_ALLOC_CONTEXT(); + + pg = acquire_staticmem_pages(smfn, nr_mfns, memflags); + if ( !pg ) + return -ENOENT; + + if ( assign_domstatic_pages(d, pg, nr_mfns, memflags) ) + return -EINVAL; + + return 0; +} + +/* + * Acquire a page from reserved page list(resv_page_list), when populating + * memory for static domain on runtime. + */ +mfn_t acquire_reserved_page(struct domain *d, unsigned int memflags) +{ + struct page_info *page; + + /* Acquire a page from reserved page list(resv_page_list). */ + page = page_list_remove_head(&d->resv_page_list); + if ( unlikely(!page) ) + return INVALID_MFN; + + if ( !prepare_staticmem_pages(page, 1, memflags) ) + goto fail; + + if ( assign_domstatic_pages(d, page, 1, memflags) ) + goto fail; + + return page_to_mfn(page); + + fail: + page_list_add_tail(page, &d->resv_page_list); + return INVALID_MFN; +} #endif /* diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index 68a647ceae..e6803fd8a2 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -99,6 +99,7 @@ int acquire_domstatic_pages(struct domain *d, mfn_t smfn, unsigned int nr_mfns, #else #define put_static_pages(d, page, order) ((void)(d), (void)(page), (void)(order)) #endif +mfn_t acquire_reserved_page(struct domain *d, unsigned int memflags); /* Map machine page range in Xen virtual address space. */ int map_pages_to_xen( -- 2.25.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |