arm64: mm: move vmemmap region right below the linear region
This moves the vmemmap region right below PAGE_OFFSET, aka the start of the linear region, and redefines its size to be a power of two. Due to the placement of PAGE_OFFSET in the middle of the address space, whose size is a power of two as well, this guarantees that virt to page conversions and vice versa can be implemented efficiently, by masking and shifting rather than ordinary arithmetic. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
Родитель
e44308e62e
Коммит
3e1907d5bf
|
@ -39,6 +39,21 @@
|
||||||
*/
|
*/
|
||||||
#define PCI_IO_SIZE SZ_16M
|
#define PCI_IO_SIZE SZ_16M
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log2 of the upper bound of the size of a struct page. Used for sizing
|
||||||
|
* the vmemmap region only, does not affect actual memory footprint.
|
||||||
|
* We don't use sizeof(struct page) directly since taking its size here
|
||||||
|
* requires its definition to be available at this point in the inclusion
|
||||||
|
* chain, and it may not be a power of 2 in the first place.
|
||||||
|
*/
|
||||||
|
#define STRUCT_PAGE_MAX_SHIFT 6
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VMEMMAP_SIZE - allows the whole linear region to be covered by
|
||||||
|
* a struct page array
|
||||||
|
*/
|
||||||
|
#define VMEMMAP_SIZE (UL(1) << (VA_BITS - PAGE_SHIFT - 1 + STRUCT_PAGE_MAX_SHIFT))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PAGE_OFFSET - the virtual address of the start of the kernel image (top
|
* PAGE_OFFSET - the virtual address of the start of the kernel image (top
|
||||||
* (VA_BITS - 1))
|
* (VA_BITS - 1))
|
||||||
|
@ -54,7 +69,8 @@
|
||||||
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
|
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
|
||||||
#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE)
|
#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE)
|
||||||
#define MODULES_VSIZE (SZ_128M)
|
#define MODULES_VSIZE (SZ_128M)
|
||||||
#define PCI_IO_END (PAGE_OFFSET - SZ_2M)
|
#define VMEMMAP_START (PAGE_OFFSET - VMEMMAP_SIZE)
|
||||||
|
#define PCI_IO_END (VMEMMAP_START - SZ_2M)
|
||||||
#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
|
#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
|
||||||
#define FIXADDR_TOP (PCI_IO_START - SZ_2M)
|
#define FIXADDR_TOP (PCI_IO_START - SZ_2M)
|
||||||
#define TASK_SIZE_64 (UL(1) << VA_BITS)
|
#define TASK_SIZE_64 (UL(1) << VA_BITS)
|
||||||
|
|
|
@ -24,20 +24,15 @@
|
||||||
#include <asm/pgtable-prot.h>
|
#include <asm/pgtable-prot.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VMALLOC and SPARSEMEM_VMEMMAP ranges.
|
* VMALLOC range.
|
||||||
*
|
*
|
||||||
* VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array
|
|
||||||
* (rounded up to PUD_SIZE).
|
|
||||||
* VMALLOC_START: beginning of the kernel vmalloc space
|
* VMALLOC_START: beginning of the kernel vmalloc space
|
||||||
* VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
|
* VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space
|
||||||
* fixed mappings and modules
|
* and fixed mappings
|
||||||
*/
|
*/
|
||||||
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT - 1)) * sizeof(struct page), PUD_SIZE)
|
|
||||||
|
|
||||||
#define VMALLOC_START (MODULES_END)
|
#define VMALLOC_START (MODULES_END)
|
||||||
#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
|
#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
|
||||||
|
|
||||||
#define VMEMMAP_START (VMALLOC_END + SZ_64K)
|
|
||||||
#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
|
#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
|
||||||
|
|
||||||
#define FIRST_USER_ADDRESS 0UL
|
#define FIRST_USER_ADDRESS 0UL
|
||||||
|
|
|
@ -37,14 +37,14 @@ enum address_markers_idx {
|
||||||
MODULES_END_NR,
|
MODULES_END_NR,
|
||||||
VMALLOC_START_NR,
|
VMALLOC_START_NR,
|
||||||
VMALLOC_END_NR,
|
VMALLOC_END_NR,
|
||||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
|
||||||
VMEMMAP_START_NR,
|
|
||||||
VMEMMAP_END_NR,
|
|
||||||
#endif
|
|
||||||
FIXADDR_START_NR,
|
FIXADDR_START_NR,
|
||||||
FIXADDR_END_NR,
|
FIXADDR_END_NR,
|
||||||
PCI_START_NR,
|
PCI_START_NR,
|
||||||
PCI_END_NR,
|
PCI_END_NR,
|
||||||
|
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||||
|
VMEMMAP_START_NR,
|
||||||
|
VMEMMAP_END_NR,
|
||||||
|
#endif
|
||||||
KERNEL_SPACE_NR,
|
KERNEL_SPACE_NR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,14 +53,14 @@ static struct addr_marker address_markers[] = {
|
||||||
{ MODULES_END, "Modules end" },
|
{ MODULES_END, "Modules end" },
|
||||||
{ VMALLOC_START, "vmalloc() Area" },
|
{ VMALLOC_START, "vmalloc() Area" },
|
||||||
{ VMALLOC_END, "vmalloc() End" },
|
{ VMALLOC_END, "vmalloc() End" },
|
||||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
|
||||||
{ 0, "vmemmap start" },
|
|
||||||
{ 0, "vmemmap end" },
|
|
||||||
#endif
|
|
||||||
{ FIXADDR_START, "Fixmap start" },
|
{ FIXADDR_START, "Fixmap start" },
|
||||||
{ FIXADDR_TOP, "Fixmap end" },
|
{ FIXADDR_TOP, "Fixmap end" },
|
||||||
{ PCI_IO_START, "PCI I/O start" },
|
{ PCI_IO_START, "PCI I/O start" },
|
||||||
{ PCI_IO_END, "PCI I/O end" },
|
{ PCI_IO_END, "PCI I/O end" },
|
||||||
|
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||||
|
{ 0, "vmemmap start" },
|
||||||
|
{ 0, "vmemmap end" },
|
||||||
|
#endif
|
||||||
{ PAGE_OFFSET, "Linear Mapping" },
|
{ PAGE_OFFSET, "Linear Mapping" },
|
||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
|
@ -412,6 +412,10 @@ void __init mem_init(void)
|
||||||
MLK_ROUNDUP(__start_rodata, _etext),
|
MLK_ROUNDUP(__start_rodata, _etext),
|
||||||
MLK_ROUNDUP(__init_begin, __init_end),
|
MLK_ROUNDUP(__init_begin, __init_end),
|
||||||
MLK_ROUNDUP(_sdata, _edata));
|
MLK_ROUNDUP(_sdata, _edata));
|
||||||
|
pr_cont(" fixed : 0x%16lx - 0x%16lx (%6ld KB)\n",
|
||||||
|
MLK(FIXADDR_START, FIXADDR_TOP));
|
||||||
|
pr_cont(" PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n",
|
||||||
|
MLM(PCI_IO_START, PCI_IO_END));
|
||||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||||
pr_cont(" vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n"
|
pr_cont(" vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n"
|
||||||
" 0x%16lx - 0x%16lx (%6ld MB actual)\n",
|
" 0x%16lx - 0x%16lx (%6ld MB actual)\n",
|
||||||
|
@ -420,10 +424,6 @@ void __init mem_init(void)
|
||||||
MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()),
|
MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()),
|
||||||
(unsigned long)virt_to_page(high_memory)));
|
(unsigned long)virt_to_page(high_memory)));
|
||||||
#endif
|
#endif
|
||||||
pr_cont(" fixed : 0x%16lx - 0x%16lx (%6ld KB)\n",
|
|
||||||
MLK(FIXADDR_START, FIXADDR_TOP));
|
|
||||||
pr_cont(" PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n",
|
|
||||||
MLM(PCI_IO_START, PCI_IO_END));
|
|
||||||
pr_cont(" memory : 0x%16lx - 0x%16lx (%6ld MB)\n",
|
pr_cont(" memory : 0x%16lx - 0x%16lx (%6ld MB)\n",
|
||||||
MLM(__phys_to_virt(memblock_start_of_DRAM()),
|
MLM(__phys_to_virt(memblock_start_of_DRAM()),
|
||||||
(unsigned long)high_memory));
|
(unsigned long)high_memory));
|
||||||
|
@ -440,6 +440,12 @@ void __init mem_init(void)
|
||||||
BUILD_BUG_ON(TASK_SIZE_32 > TASK_SIZE_64);
|
BUILD_BUG_ON(TASK_SIZE_32 > TASK_SIZE_64);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure we chose the upper bound of sizeof(struct page)
|
||||||
|
* correctly.
|
||||||
|
*/
|
||||||
|
BUILD_BUG_ON(sizeof(struct page) > (1 << STRUCT_PAGE_MAX_SHIFT));
|
||||||
|
|
||||||
if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
|
if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
|
||||||
extern int sysctl_overcommit_memory;
|
extern int sysctl_overcommit_memory;
|
||||||
/*
|
/*
|
||||||
|
|
Загрузка…
Ссылка в новой задаче