From c92968dd1de5fe187f2b10753ca620b7e78cfc16 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 1 Feb 2021 18:29:27 +0100 Subject: [PATCH] ANDROID: arm64: mm: ensure that memstart_addr and physvirt_offset remain in sync In arm64_memblock_init(), physvirt_offset is defined in terms of PHYS_OFFSET, which is simply an alias for memstart_addr wrapped in a VM_BUG() check. Unfortunately, the assignment of physvirt_offset takes place before the point where the placement of DRAM in the linear region is randomized on KASLR kernels, which causes memstart_addr to be modified. This leads to a disparity between the two quantities. So defer the assignment of physvirt_offset and vmemmap to the point where memstart_addr has assumed its final value. Bug: 161946584 Signed-off-by: Ard Biesheuvel Cc: Will Deacon Signed-off-by: Greg Kroah-Hartman Change-Id: Ie0e70d825fbd23691a7f5719652b924aaeea29c6 --- arch/arm64/mm/init.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 45c00a54909c..5a2bb0764b68 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -321,20 +321,6 @@ void __init arm64_memblock_init(void) memstart_addr = round_down(memblock_start_of_DRAM(), ARM64_MEMSTART_ALIGN); - physvirt_offset = PHYS_OFFSET - PAGE_OFFSET; - - vmemmap = ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)); - - /* - * If we are running with a 52-bit kernel VA config on a system that - * does not support it, we have to offset our vmemmap and physvirt_offset - * s.t. we avoid the 52-bit portion of the direct linear map - */ - if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) { - vmemmap += (_PAGE_OFFSET(48) - _PAGE_OFFSET(52)) >> PAGE_SHIFT; - physvirt_offset = PHYS_OFFSET - _PAGE_OFFSET(48); - } - /* * Remove the memory that we will not be able to cover with the * linear mapping. Take care not to clip the kernel which may be @@ -405,6 +391,20 @@ void __init arm64_memblock_init(void) } } + physvirt_offset = PHYS_OFFSET - PAGE_OFFSET; + + vmemmap = ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)); + + /* + * If we are running with a 52-bit kernel VA config on a system that + * does not support it, we have to offset our vmemmap and physvirt_offset + * s.t. we avoid the 52-bit portion of the direct linear map + */ + if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) { + vmemmap += (_PAGE_OFFSET(48) - _PAGE_OFFSET(52)) >> PAGE_SHIFT; + physvirt_offset = PHYS_OFFSET - _PAGE_OFFSET(48); + } + /* * Register the kernel text, kernel data, initrd, and initial * pagetables with memblock.