arm64: Add 16K page size support
authorSuzuki K. Poulose <suzuki.poulose@arm.com>
Mon, 19 Oct 2015 13:19:37 +0000 (14:19 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 19 Oct 2015 16:55:12 +0000 (17:55 +0100)
This patch turns on the 16K page support in the kernel. We
support 48bit VA (4 level page tables) and 47bit VA (3 level
page tables).

With 16K we can map 128 entries using contiguous bit hint
at level 3 to map 2M using single TLB entry.

TODO: 16K supports 32 contiguous entries at level 2 to get us
1G(which is not yet supported by the infrastructure). That should
be a separate patch altogether.

Cc: Will Deacon <will.deacon@arm.com>
Cc: Jeremy Linton <jeremy.linton@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Steve Capper <steve.capper@linaro.org>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/Kconfig
arch/arm64/include/asm/page.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/thread_info.h
arch/arm64/kvm/Kconfig
arch/arm64/mm/proc.S

index 13b51a0c4e7fbacfda062844ee1b600bde6da627..854166422c429d62cb5f18904ccf86cde33bddba 100644 (file)
@@ -173,7 +173,8 @@ config PGTABLE_LEVELS
        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 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48
+       default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
+       default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
 
 source "init/Kconfig"
 
@@ -363,6 +364,13 @@ config ARM64_4K_PAGES
        help
          This feature enables 4KB pages support.
 
+config ARM64_16K_PAGES
+       bool "16KB"
+       help
+         The system will use 16KB pages support. AArch32 emulation
+         requires applications compiled with 16K (or a multiple of 16K)
+         aligned segments.
+
 config ARM64_64K_PAGES
        bool "64KB"
        help
@@ -376,6 +384,7 @@ endchoice
 choice
        prompt "Virtual address space size"
        default ARM64_VA_BITS_39 if ARM64_4K_PAGES
+       default ARM64_VA_BITS_47 if ARM64_16K_PAGES
        default ARM64_VA_BITS_42 if ARM64_64K_PAGES
        help
          Allows choosing one of multiple possible virtual address
@@ -390,6 +399,10 @@ config ARM64_VA_BITS_42
        bool "42-bit"
        depends on ARM64_64K_PAGES
 
+config ARM64_VA_BITS_47
+       bool "47-bit"
+       depends on ARM64_16K_PAGES
+
 config ARM64_VA_BITS_48
        bool "48-bit"
 
@@ -399,6 +412,7 @@ config ARM64_VA_BITS
        int
        default 39 if ARM64_VA_BITS_39
        default 42 if ARM64_VA_BITS_42
+       default 47 if ARM64_VA_BITS_47
        default 48 if ARM64_VA_BITS_48
 
 config CPU_BIG_ENDIAN
@@ -466,7 +480,7 @@ config ARCH_WANT_GENERAL_HUGETLB
        def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-       def_bool y if ARM64_4K_PAGES
+       def_bool y if ARM64_4K_PAGES || ARM64_16K_PAGES
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
        def_bool y
@@ -503,7 +517,25 @@ config XEN
 config FORCE_MAX_ZONEORDER
        int
        default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
+       default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
        default "11"
+       help
+         The kernel memory allocator divides physically contiguous memory
+         blocks into "zones", where each zone is a power of two number of
+         pages.  This option selects the largest power of two that the kernel
+         keeps in the memory allocator.  If you need to allocate very large
+         blocks of physically contiguous memory, then you may need to
+         increase this value.
+
+         This config option is actually maximum order plus one. For example,
+         a value of 11 means that the largest free memory block is 2^10 pages.
+
+         We make sure that we can allocate upto a HugePage size for each configuration.
+         Hence we have :
+               MAX_ORDER = (PMD_SHIFT - PAGE_SHIFT) + 1 => PAGE_SHIFT - 2
+
+         However for 4K, we choose a higher default value, 11 as opposed to 10, giving us
+         4M allocations matching the default size used by generic code.
 
 menuconfig ARMV8_DEPRECATED
        bool "Emulate deprecated/obsolete ARMv8 instructions"
@@ -689,9 +721,9 @@ config COMPAT
          the user helper functions, VFP support and the ptrace interface are
          handled appropriately by the kernel.
 
-         If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you
-         will only be able to execute AArch32 binaries that were compiled with
-         64k aligned segments.
+         If you use a page size other than 4KB (i.e, 16KB or 64KB), please be aware
+         that you will only be able to execute AArch32 binaries that were compiled
+         with page size aligned segments.
 
          If you want to execute 32-bit userspace applications, say Y.
 
index da3235494ffdb05abde178818b35f01ed587df47..9b2f5a9d019df493fa6021ee3ca6b4779401d8c4 100644 (file)
@@ -24,6 +24,9 @@
 #ifdef CONFIG_ARM64_64K_PAGES
 #define PAGE_SHIFT             16
 #define CONT_SHIFT             5
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define PAGE_SHIFT             14
+#define CONT_SHIFT             7
 #else
 #define PAGE_SHIFT             12
 #define CONT_SHIFT             4
index d59cb231a6735e09bb32df473b820b9887ab6430..4b57e108053824763a18ece838366845c5967659 100644 (file)
@@ -59,6 +59,9 @@
 #if defined(CONFIG_ARM64_4K_PAGES)
 #define ID_AA64MMFR0_TGRAN_SHIFT       ID_AA64MMFR0_TGRAN4_SHIFT
 #define ID_AA64MMFR0_TGRAN_SUPPORTED   ID_AA64MMFR0_TGRAN4_SUPPORTED
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define ID_AA64MMFR0_TGRAN_SHIFT       ID_AA64MMFR0_TGRAN16_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED   ID_AA64MMFR0_TGRAN16_SUPPORTED
 #elif defined(CONFIG_ARM64_64K_PAGES)
 #define ID_AA64MMFR0_TGRAN_SHIFT       ID_AA64MMFR0_TGRAN64_SHIFT
 #define ID_AA64MMFR0_TGRAN_SUPPORTED   ID_AA64MMFR0_TGRAN64_SUPPORTED
index 5eac6a2300af9d9910feabd0b09e27584e2dac0c..90c7ff233735d7691bf3b34b7075dffd07dbf939 100644 (file)
@@ -25,6 +25,8 @@
 
 #ifdef CONFIG_ARM64_4K_PAGES
 #define THREAD_SIZE_ORDER      2
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define THREAD_SIZE_ORDER      0
 #endif
 
 #define THREAD_SIZE            16384
index 5c7e920e486132c5257255ff843d81a6616670b1..6a7d5cd772e6b73929fc33099d2c9193b1c0cb60 100644 (file)
@@ -19,6 +19,7 @@ if VIRTUALIZATION
 config KVM
        bool "Kernel-based Virtual Machine (KVM) support"
        depends on OF
+       depends on !ARM64_16K_PAGES
        select MMU_NOTIFIER
        select PREEMPT_NOTIFIERS
        select ANON_INODES
@@ -33,6 +34,8 @@ config KVM
        select HAVE_KVM_IRQFD
        ---help---
          Support hosting virtualized guest machines.
+         We don't support KVM with 16K page tables yet, due to the multiple
+         levels of fake page tables.
 
          If unsure, say N.
 
index 91cb2eaac256bfc03c963abeac6d25e022cba8aa..3a4b8b19978bb304c9913e51da9db9f072ff49ff 100644 (file)
@@ -30,7 +30,9 @@
 
 #ifdef CONFIG_ARM64_64K_PAGES
 #define TCR_TG_FLAGS   TCR_TG0_64K | TCR_TG1_64K
-#else
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define TCR_TG_FLAGS   TCR_TG0_16K | TCR_TG1_16K
+#else /* CONFIG_ARM64_4K_PAGES */
 #define TCR_TG_FLAGS   TCR_TG0_4K | TCR_TG1_4K
 #endif