mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
[LINUX] Kexec: Ensure that pages allocated for kexec have MFNs which are within
the required limits. Previously we were lucky since most dom0 pages would be low enough but now Xen is more aggressive in giving out higher MFNs when it can. Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
This commit is contained in:
1 parent
d04477b602
commit
a84c4f75e5
1 file changed
+20
-3
@@ -330,13 +330,27 @@ static int kimage_is_destination_range(struct kimage *image,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order)
|
||||
static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order, unsigned long limit)
|
||||
{
|
||||
struct page *pages;
|
||||
|
||||
pages = alloc_pages(gfp_mask, order);
|
||||
if (pages) {
|
||||
unsigned int count, i;
|
||||
#ifdef CONFIG_XEN
|
||||
int address_bits;
|
||||
|
||||
if (limit == ~0UL)
|
||||
address_bits = BITS_PER_LONG;
|
||||
else
|
||||
address_bits = long_log2(limit);
|
||||
|
||||
if (xen_create_contiguous_region((unsigned long)page_address(pages),
|
||||
order, address_bits) < 0) {
|
||||
__free_pages(pages, order);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
pages->mapping = NULL;
|
||||
set_page_private(pages, order);
|
||||
count = 1 << order;
|
||||
@@ -355,6 +369,9 @@ static void kimage_free_pages(struct page *page)
|
||||
count = 1 << order;
|
||||
for (i = 0; i < count; i++)
|
||||
ClearPageReserved(page + i);
|
||||
#ifdef CONFIG_XEN
|
||||
xen_destroy_contiguous_region((unsigned long)page_address(page), order);
|
||||
#endif
|
||||
__free_pages(page, order);
|
||||
}
|
||||
|
||||
@@ -400,7 +417,7 @@ static struct page *kimage_alloc_normal_control_pages(struct kimage *image,
|
||||
do {
|
||||
unsigned long pfn, epfn, addr, eaddr;
|
||||
|
||||
pages = kimage_alloc_pages(GFP_KERNEL, order);
|
||||
pages = kimage_alloc_pages(GFP_KERNEL, order, KEXEC_CONTROL_MEMORY_LIMIT);
|
||||
if (!pages)
|
||||
break;
|
||||
pfn = kexec_page_to_pfn(pages);
|
||||
@@ -709,7 +726,7 @@ static struct page *kimage_alloc_page(struct kimage *image,
|
||||
kimage_entry_t *old;
|
||||
|
||||
/* Allocate a page, if we run out of memory give up */
|
||||
page = kimage_alloc_pages(gfp_mask, 0);
|
||||
page = kimage_alloc_pages(gfp_mask, 0, KEXEC_SOURCE_MEMORY_LIMIT);
|
||||
if (!page)
|
||||
return NULL;
|
||||
/* If the page cannot be used file it away */
|
||||
|
||||