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 <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Change-Id: Ie0e70d825fbd23691a7f5719652b924aaeea29c6
This commit is contained in:
Ard Biesheuvel 2021-02-01 18:29:27 +01:00 • committed by Greg Kroah-Hartman
commit c92968dd1d

View file

@ -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.