arm64: mm: Introduce VA_BITS_MIN
authorSteve Capper <steve.capper@arm.com>
Wed, 7 Aug 2019 15:55:17 +0000 (16:55 +0100)
committerWill Deacon <will@kernel.org>
Fri, 9 Aug 2019 10:17:16 +0000 (11:17 +0100)
In order to support 52-bit kernel addresses detectable at boot time, the
kernel needs to know the most conservative VA_BITS possible should it
need to fall back to this quantity due to lack of hardware support.

A new compile time constant VA_BITS_MIN is introduced in this patch and
it is employed in the KASAN end address, KASLR, and EFI stub.

For Arm, if 52-bit VA support is unavailable the fallback is to 48-bits.

In other words: VA_BITS_MIN = min (48, VA_BITS)

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Steve Capper <steve.capper@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/efi.h
arch/arm64/include/asm/memory.h
arch/arm64/include/asm/processor.h
arch/arm64/kernel/head.S
arch/arm64/kernel/kaslr.c
arch/arm64/mm/kasan_init.c

index 76a14470258693743eb29a09028751e0f710a2c3..b54d3a86c44446735bfbfe4e49ab217460fc5b27 100644 (file)
@@ -79,7 +79,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
 
 /*
  * On arm64, we have to ensure that the initrd ends up in the linear region,
- * which is a 1 GB aligned region of size '1UL << (VA_BITS - 1)' that is
+ * which is a 1 GB aligned region of size '1UL << (VA_BITS_MIN - 1)' that is
  * guaranteed to cover the kernel Image.
  *
  * Since the EFI stub is part of the kernel Image, we can relax the
@@ -90,7 +90,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
 static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
                                                    unsigned long image_addr)
 {
-       return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS - 1));
+       return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
 }
 
 #define efi_call_early(f, ...)         sys_table_arg->boottime->f(__VA_ARGS__)
index 968659c90f5c01770727e39e4cdfe1ae8381ba47..79e75e45d5604aab6c19451b8a42a8b52d1da777 100644 (file)
 #define PCI_IO_END             (VMEMMAP_START - SZ_2M)
 #define PCI_IO_START           (PCI_IO_END - PCI_IO_SIZE)
 #define FIXADDR_TOP            (PCI_IO_START - SZ_2M)
+#if VA_BITS > 48
+#define VA_BITS_MIN            (48)
+#else
+#define VA_BITS_MIN            (VA_BITS)
+#endif
+#define _VA_START(va)          (UL(0xffffffffffffffff) - \
+                               (UL(1) << ((va) - 1)) + 1)
 
 #define KERNEL_START      _text
 #define KERNEL_END        _end
@@ -74,7 +81,7 @@
 #define KASAN_THREAD_SHIFT     1
 #else
 #define KASAN_THREAD_SHIFT     0
-#define KASAN_SHADOW_END       (VA_START)
+#define KASAN_SHADOW_END       (_VA_START(VA_BITS_MIN))
 #endif
 
 #define MIN_THREAD_SHIFT       (14 + KASAN_THREAD_SHIFT)
index 844e2964b0f5e5b0aad4b866283f24e26f794afe..0e1f2770192a83d200d6e702b434b98a4f1cae3b 100644 (file)
@@ -42,7 +42,7 @@
  * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
  */
 
-#define DEFAULT_MAP_WINDOW_64  (UL(1) << VA_BITS)
+#define DEFAULT_MAP_WINDOW_64  (UL(1) << VA_BITS_MIN)
 #define TASK_SIZE_64           (UL(1) << vabits_user)
 
 #ifdef CONFIG_COMPAT
index 2cdacd1c141b97295192e9685ffca9ef32765939..ac58c69993ec407a522824523004ffdac33a80e2 100644 (file)
@@ -314,7 +314,7 @@ __create_page_tables:
        mov     x5, #52
        cbnz    x6, 1f
 #endif
-       mov     x5, #VA_BITS
+       mov     x5, #VA_BITS_MIN
 1:
        adr_l   x6, vabits_user
        str     x5, [x6]
index 708051655ad9c597138419af816583c9f5ed2299..5a59f7567f9c8b50a02039ca2cad8eeb83d6aeca 100644 (file)
@@ -116,15 +116,15 @@ u64 __init kaslr_early_init(u64 dt_phys)
        /*
         * OK, so we are proceeding with KASLR enabled. Calculate a suitable
         * kernel image offset from the seed. Let's place the kernel in the
-        * middle half of the VMALLOC area (VA_BITS - 2), and stay clear of
+        * middle half of the VMALLOC area (VA_BITS_MIN - 2), and stay clear of
         * the lower and upper quarters to avoid colliding with other
         * allocations.
         * Even if we could randomize at page granularity for 16k and 64k pages,
         * let's always round to 2 MB so we don't interfere with the ability to
         * map using contiguous PTEs
         */
-       mask = ((1UL << (VA_BITS - 2)) - 1) & ~(SZ_2M - 1);
-       offset = BIT(VA_BITS - 3) + (seed & mask);
+       mask = ((1UL << (VA_BITS_MIN - 2)) - 1) & ~(SZ_2M - 1);
+       offset = BIT(VA_BITS_MIN - 3) + (seed & mask);
 
        /* use the top 16 bits to randomize the linear region */
        memstart_offset_seed = seed >> 48;
index 05edfe9b02e4dbb8399e4f2ff73c937eb9d73e89..72522227147413c2cdeccec0f8f3deaca88fd866 100644 (file)
@@ -156,7 +156,8 @@ asmlinkage void __init kasan_early_init(void)
 {
        BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=
                KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT)));
-       BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
+       BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), PGDIR_SIZE));
+       BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), PGDIR_SIZE));
        BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
        kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
                           true);