| From 9e25ebfe56ece7541cd10a20d715cbdd148a2e06 Mon Sep 17 00:00:00 2001 |
| From: Doug Berger <opendmb@gmail.com> |
| Date: Thu, 29 Jun 2017 18:41:36 +0100 |
| Subject: ARM: 8685/1: ensure memblock-limit is pmd-aligned |
| |
| From: Doug Berger <opendmb@gmail.com> |
| |
| commit 9e25ebfe56ece7541cd10a20d715cbdd148a2e06 upstream. |
| |
| The pmd containing memblock_limit is cleared by prepare_page_table() |
| which creates the opportunity for early_alloc() to allocate unmapped |
| memory if memblock_limit is not pmd aligned causing a boot-time hang. |
| |
| Commit 965278dcb8ab ("ARM: 8356/1: mm: handle non-pmd-aligned end of RAM") |
| attempted to resolve this problem, but there is a path through the |
| adjust_lowmem_bounds() routine where if all memory regions start and |
| end on pmd-aligned addresses the memblock_limit will be set to |
| arm_lowmem_limit. |
| |
| Since arm_lowmem_limit can be affected by the vmalloc early parameter, |
| the value of arm_lowmem_limit may not be pmd-aligned. This commit |
| corrects this oversight such that memblock_limit is always rounded |
| down to pmd-alignment. |
| |
| Fixes: 965278dcb8ab ("ARM: 8356/1: mm: handle non-pmd-aligned end of RAM") |
| Signed-off-by: Doug Berger <opendmb@gmail.com> |
| Suggested-by: Mark Rutland <mark.rutland@arm.com> |
| Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/arm/mm/mmu.c | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| --- a/arch/arm/mm/mmu.c |
| +++ b/arch/arm/mm/mmu.c |
| @@ -1142,15 +1142,15 @@ void __init sanity_check_meminfo(void) |
| |
| high_memory = __va(arm_lowmem_limit - 1) + 1; |
| |
| + if (!memblock_limit) |
| + memblock_limit = arm_lowmem_limit; |
| + |
| /* |
| * Round the memblock limit down to a pmd size. This |
| * helps to ensure that we will allocate memory from the |
| * last full pmd, which should be mapped. |
| */ |
| - if (memblock_limit) |
| - memblock_limit = round_down(memblock_limit, PMD_SIZE); |
| - if (!memblock_limit) |
| - memblock_limit = arm_lowmem_limit; |
| + memblock_limit = round_down(memblock_limit, PMD_SIZE); |
| |
| memblock_set_current_limit(memblock_limit); |
| } |