arm64: Add support for 48-bit VA space with 64KB page configuration

This patch allows support for 3 levels of page tables with 64KB page
configuration allowing 48-bit VA space. The pgd is no longer a full
PAGE_SIZE (PTRS_PER_PGD is 64) and (swapper|idmap)_pg_dir are not fully
populated (pgd_alloc falls back to kzalloc).

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Jungseok Lee <jungseoklee85@gmail.com>
This commit is contained in:
Catalin Marinas 2014-07-21 15:54:50 +01:00
parent 7078db4621
commit 383c279911
4 changed files with 22 additions and 9 deletions

View File

@ -45,6 +45,14 @@ Start End Size Use
fffffc0000000000 ffffffffffffffff 4TB kernel fffffc0000000000 ffffffffffffffff 4TB kernel
AArch64 Linux memory layout with 64KB pages + 3 levels:
Start End Size Use
-----------------------------------------------------------------------
0000000000000000 0000ffffffffffff 256TB user
ffff000000000000 ffffffffffffffff 256TB kernel
For details of the virtual kernel memory layout please see the kernel For details of the virtual kernel memory layout please see the kernel
booting log. booting log.

View File

@ -210,6 +210,7 @@ config ARM64_VA_BITS
config ARM64_PGTABLE_LEVELS config ARM64_PGTABLE_LEVELS
int int
default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42 default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39 default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
default 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48 default 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48

View File

@ -34,17 +34,19 @@
/* /*
* The idmap and swapper page tables need some space reserved in the kernel * The idmap and swapper page tables need some space reserved in the kernel
* image. Both require pgd, pud (4 levels only) and pmd tables to (section) * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
* map the kernel. The swapper also maps the FDT (see __create_page_tables for * map the kernel. With the 64K page configuration, swapper and idmap need to
* more information). * map to pte level. The swapper also maps the FDT (see __create_page_tables
* for more information).
*/ */
#if CONFIG_ARM64_PGTABLE_LEVELS == 4 #ifdef CONFIG_ARM64_64K_PAGES
#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE) #define SWAPPER_PGTABLE_LEVELS (CONFIG_ARM64_PGTABLE_LEVELS)
#define IDMAP_DIR_SIZE (3 * PAGE_SIZE)
#else #else
#define SWAPPER_DIR_SIZE (2 * PAGE_SIZE) #define SWAPPER_PGTABLE_LEVELS (CONFIG_ARM64_PGTABLE_LEVELS - 1)
#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
#endif #endif
#define SWAPPER_DIR_SIZE (SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
#define IDMAP_DIR_SIZE (SWAPPER_DIR_SIZE)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/pgtable-types.h> #include <asm/pgtable-types.h>

View File

@ -55,9 +55,11 @@
#ifdef CONFIG_ARM64_64K_PAGES #ifdef CONFIG_ARM64_64K_PAGES
#define BLOCK_SHIFT PAGE_SHIFT #define BLOCK_SHIFT PAGE_SHIFT
#define BLOCK_SIZE PAGE_SIZE #define BLOCK_SIZE PAGE_SIZE
#define TABLE_SHIFT PMD_SHIFT
#else #else
#define BLOCK_SHIFT SECTION_SHIFT #define BLOCK_SHIFT SECTION_SHIFT
#define BLOCK_SIZE SECTION_SIZE #define BLOCK_SIZE SECTION_SIZE
#define TABLE_SHIFT PUD_SHIFT
#endif #endif
#define KERNEL_START KERNEL_RAM_VADDR #define KERNEL_START KERNEL_RAM_VADDR
@ -505,8 +507,8 @@ ENDPROC(__calc_phys_offset)
*/ */
.macro create_pgd_entry, tbl, virt, tmp1, tmp2 .macro create_pgd_entry, tbl, virt, tmp1, tmp2
create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2 create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
#if CONFIG_ARM64_PGTABLE_LEVELS == 4 #if SWAPPER_PGTABLE_LEVELS == 3
create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2 create_table_entry \tbl, \virt, TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
#endif #endif
.endm .endm