aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-09-23 16:21:52 +0200
committerJan Beulich <jbeulich@suse.com>2013-09-23 16:21:52 +0200
commitf9db6b06dd235976e4cbf69625bd53391cc9f094 (patch)
tree7ccd280f283e1ce3c99a30c86c736354ec3b3951
parent8a10907615c42b71f1dde01bc190d339e9db051b (diff)
downloadxen-f9db6b06dd235976e4cbf69625bd53391cc9f094.tar.gz
xen-f9db6b06dd235976e4cbf69625bd53391cc9f094.tar.bz2
xen-f9db6b06dd235976e4cbf69625bd53391cc9f094.zip
x86: fix memory cut-off when using PFN compression
For one setup_max_pdx(), when invoked a second time (after SRAT got parsed), needs to start from the original max_page value again (using the already adjusted one from the first invocation would not allow the cut-off boundary to be moved up). Second, _if_ we need to cut off some part of memory, we must not allow this to also propagate into the NUMA accounting. Otherwise cutoff_node() results in nodes_cover_memory() to find some parts of memory apparently not having a PXM association, causing all SRAT info to be ignored. The only possibly problematic consumer of node_spanned_pages (the meaning of which gets altered here in that it now also includes memory Xen can't actively make use of) is XEN_SYSCTL_numainfo: At a first glance the potentially larger reported memory size shouldn't confuse tool stacks. And finally we must not put our boot time modules at addresses which (at that time) can't be guaranteed to be accessible later. This applies to both the EFI boot loader and the module relocation code. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org> Acked-by: Dario Faggioli <dario.faggioli@citrix.com> master commit: 8efce9d69998a3d3c720ac7dbdb9b7e240369957 master date: 2013-09-12 09:52:53 +0200
-rw-r--r--xen/arch/x86/efi/boot.c3
-rw-r--r--xen/arch/x86/setup.c19
2 files changed, 13 insertions, 9 deletions
diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c
index 055ac13ce6..66a6fdba21 100644
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -459,7 +459,8 @@ static bool_t __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
what = what ?: L"Seek";
else
{
- file->addr = (EFI_PHYSICAL_ADDRESS)1 << (32 + PAGE_SHIFT);
+ file->addr = min(1UL << (32 + PAGE_SHIFT),
+ HYPERVISOR_VIRT_END - DIRECTMAP_VIRT_START);
ret = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
PFN_UP(size), &file->addr);
}
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index a70d31bbbb..0b92874596 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -377,9 +377,9 @@ static uint64_t __init consider_modules(
return e;
}
-static void __init setup_max_pdx(void)
+static void __init setup_max_pdx(unsigned long top_page)
{
- max_pdx = pfn_to_pdx(max_page - 1) + 1;
+ max_pdx = pfn_to_pdx(top_page - 1) + 1;
if ( max_pdx > (DIRECTMAP_SIZE >> PAGE_SHIFT) )
max_pdx = DIRECTMAP_SIZE >> PAGE_SHIFT;
@@ -547,7 +547,7 @@ void __init __start_xen(unsigned long mbi_p)
unsigned int initrdidx;
multiboot_info_t *mbi = __va(mbi_p);
module_t *mod = (module_t *)__va(mbi->mods_addr);
- unsigned long nr_pages, modules_headroom, *module_map;
+ unsigned long nr_pages, raw_max_page, modules_headroom, *module_map;
int i, j, e820_warn = 0, bytes = 0;
bool_t acpi_boot_table_init_done = 0;
struct ns16550_defaults ns16550 = {
@@ -751,7 +751,7 @@ void __init __start_xen(unsigned long mbi_p)
}
/* Sanitise the raw E820 map to produce a final clean version. */
- max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
+ max_page = raw_max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
/* Create a temporary copy of the E820 map. */
memcpy(&boot_e820, &e820, sizeof(e820));
@@ -820,7 +820,10 @@ void __init __start_xen(unsigned long mbi_p)
(end - s) >> PAGE_SHIFT, PAGE_HYPERVISOR);
}
- e = min_t(uint64_t, e, 1ULL << (PAGE_SHIFT + 32));
+ if ( e > min(HYPERVISOR_VIRT_END - DIRECTMAP_VIRT_START,
+ 1UL << (PAGE_SHIFT + 32)) )
+ e = min(HYPERVISOR_VIRT_END - DIRECTMAP_VIRT_START,
+ 1UL << (PAGE_SHIFT + 32));
#define reloc_size ((__pa(&_end) + mask) & ~mask)
/* Is the region suitable for relocating Xen? */
if ( !xen_phys_start && e <= limit )
@@ -969,7 +972,7 @@ void __init __start_xen(unsigned long mbi_p)
/* Late kexec reservation (dynamic start address). */
kexec_reserve_area(&boot_e820);
- setup_max_pdx();
+ setup_max_pdx(raw_max_page);
if ( highmem_start )
xenheap_max_mfn(PFN_DOWN(highmem_start));
@@ -995,7 +998,7 @@ void __init __start_xen(unsigned long mbi_p)
{
acpi_boot_table_init_done = 1;
srat_parse_regions(s);
- setup_max_pdx();
+ setup_max_pdx(raw_max_page);
}
if ( pfn_to_pdx((e - 1) >> PAGE_SHIFT) >= max_pdx )
@@ -1133,7 +1136,7 @@ void __init __start_xen(unsigned long mbi_p)
acpi_numa_init();
- numa_initmem_init(0, max_page);
+ numa_initmem_init(0, raw_max_page);
end_boot_allocator();
system_state = SYS_STATE_boot;