summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Rapoport <mike.rapoport@gmail.com>2019-08-30 14:27:56 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-10-07 18:57:14 +0200
commit297904ea60a3c3f6a8d0037ba1fc2f3f9517f7a0 (patch)
treef9224fe5173fd37ad1931c674dd4f21d1eecad37
parent9a87ab2b4d60efed6690a731e14d6836bf92682d (diff)
downloadlinux-stable-297904ea60a3c3f6a8d0037ba1fc2f3f9517f7a0.tar.gz
linux-stable-297904ea60a3c3f6a8d0037ba1fc2f3f9517f7a0.tar.bz2
linux-stable-297904ea60a3c3f6a8d0037ba1fc2f3f9517f7a0.zip
ARM: 8903/1: ensure that usable memory in bank 0 starts from a PMD-aligned address
[ Upstream commit 00d2ec1e6bd82c0538e6dd3e4a4040de93ba4fef ] The calculation of memblock_limit in adjust_lowmem_bounds() assumes that bank 0 starts from a PMD-aligned address. However, the beginning of the first bank may be NOMAP memory and the start of usable memory will be not aligned to PMD boundary. In such case the memblock_limit will be set to the end of the NOMAP region, which will prevent any memblock allocations. Mark the region between the end of the NOMAP area and the next PMD-aligned address as NOMAP as well, so that the usable memory will start at PMD-aligned address. Signed-off-by: Mike Rapoport <rppt@linux.ibm.com> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--arch/arm/mm/mmu.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e46a6a446cdd..70e560cf8ca0 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1175,6 +1175,22 @@ void __init adjust_lowmem_bounds(void)
*/
vmalloc_limit = (u64)(uintptr_t)vmalloc_min - PAGE_OFFSET + PHYS_OFFSET;
+ /*
+ * The first usable region must be PMD aligned. Mark its start
+ * as MEMBLOCK_NOMAP if it isn't
+ */
+ for_each_memblock(memory, reg) {
+ if (!memblock_is_nomap(reg)) {
+ if (!IS_ALIGNED(reg->base, PMD_SIZE)) {
+ phys_addr_t len;
+
+ len = round_up(reg->base, PMD_SIZE) - reg->base;
+ memblock_mark_nomap(reg->base, len);
+ }
+ break;
+ }
+ }
+
for_each_memblock(memory, reg) {
phys_addr_t block_start = reg->base;
phys_addr_t block_end = reg->base + reg->size;