Skip to content

Commit dfd55ad

Browse files
Ard Biesheuvelwildea01
authored andcommitted
arm64: vmemmap: use virtual projection of linear region
Commit dd006da ("arm64: mm: increase VA range of identity map") made some changes to the memory mapping code to allow physical memory to reside at an offset that exceeds the size of the virtual mapping. However, since the size of the vmemmap area is proportional to the size of the VA area, but it is populated relative to the physical space, we may end up with the struct page array being mapped outside of the vmemmap region. For instance, on my Seattle A0 box, I can see the following output in the dmesg log. vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000 ( 8 GB maximum) 0xffffffbfc0000000 - 0xffffffbfd0000000 ( 256 MB actual) We can fix this by deciding that the vmemmap region is not a projection of the physical space, but of the virtual space above PAGE_OFFSET, i.e., the linear region. This way, we are guaranteed that the vmemmap region is of sufficient size, and we can even reduce the size by half. Cc: <stable@vger.kernel.org> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
1 parent 81f70ba commit dfd55ad

File tree

2 files changed

+6
-5
lines changed

2 files changed

+6
-5
lines changed

arch/arm64/include/asm/pgtable.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@
3434
/*
3535
* VMALLOC and SPARSEMEM_VMEMMAP ranges.
3636
*
37-
* VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
37+
* VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array
3838
* (rounded up to PUD_SIZE).
3939
* VMALLOC_START: beginning of the kernel VA space
4040
* VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
4141
* fixed mappings and modules
4242
*/
43-
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
43+
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT - 1)) * sizeof(struct page), PUD_SIZE)
4444

4545
#ifndef CONFIG_KASAN
4646
#define VMALLOC_START (VA_START)
@@ -51,7 +51,8 @@
5151

5252
#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
5353

54-
#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K))
54+
#define VMEMMAP_START (VMALLOC_END + SZ_64K)
55+
#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
5556

5657
#define FIRST_USER_ADDRESS 0UL
5758

arch/arm64/mm/init.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ void __init mem_init(void)
319319
#endif
320320
MLG(VMALLOC_START, VMALLOC_END),
321321
#ifdef CONFIG_SPARSEMEM_VMEMMAP
322-
MLG((unsigned long)vmemmap,
323-
(unsigned long)vmemmap + VMEMMAP_SIZE),
322+
MLG(VMEMMAP_START,
323+
VMEMMAP_START + VMEMMAP_SIZE),
324324
MLM((unsigned long)virt_to_page(PAGE_OFFSET),
325325
(unsigned long)virt_to_page(high_memory)),
326326
#endif

0 commit comments

Comments
 (0)