summaryrefslogtreecommitdiff
path: root/arch/arm64/mm/init.c
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2016-03-30 14:25:46 +0200
committerAmit Pundir <amit.pundir@linaro.org>2016-10-12 17:34:22 +0530
commit87b1b0b0bee129c09d5d68bcc28101f1d29a670b (patch)
tree3667b369d918274b907c75d7c5754fa172a1c644 /arch/arm64/mm/init.c
parent91ce39653a16205ce0676cac413690b8e8009f38 (diff)
UPSTREAM: arm64/mm: ensure memstart_addr remains sufficiently aligned
After choosing memstart_addr to be the highest multiple of ARM64_MEMSTART_ALIGN less than or equal to the first usable physical memory address, we clip the memblocks to the maximum size of the linear region. Since the kernel may be high up in memory, we take care not to clip the kernel itself, which means we have to clip some memory from the bottom if this occurs, to ensure that the distance between the first and the last usable physical memory address can be covered by the linear region. However, we fail to update memstart_addr if this clipping from the bottom occurs, which means that we may still end up with virtual addresses that wrap into the userland range. So increment memstart_addr as appropriate to prevent this from happening. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com> Change-Id: I72306207cc46a30b780f5e00b9ef23aa8409867e (cherry picked from commit 2958987f5da2ebcf6a237c5f154d7e3340e60945) Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Diffstat (limited to 'arch/arm64/mm/init.c')
-rw-r--r--arch/arm64/mm/init.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 05a1088377aa..678878077996 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -192,8 +192,12 @@ void __init arm64_memblock_init(void)
*/
memblock_remove(max_t(u64, memstart_addr + linear_region_size, __pa(_end)),
ULLONG_MAX);
- if (memblock_end_of_DRAM() > linear_region_size)
- memblock_remove(0, memblock_end_of_DRAM() - linear_region_size);
+ if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
+ /* ensure that memstart_addr remains sufficiently aligned */
+ memstart_addr = round_up(memblock_end_of_DRAM() - linear_region_size,
+ ARM64_MEMSTART_ALIGN);
+ memblock_remove(0, memstart_addr);
+ }
/*
* Apply the memory limit if it was set. Since the kernel may be loaded