arm64: mm: treat memstart_addr as a signed quantity
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Fri, 26 Feb 2016 16:57:14 +0000 (17:57 +0100)
committerAlex Shi <alex.shi@linaro.org>
Thu, 12 May 2016 00:41:36 +0000 (08:41 +0800)
Commit c031a4213c11 ("arm64: kaslr: randomize the linear region")
implements randomization of the linear region, by subtracting a random
multiple of PUD_SIZE from memstart_addr. This causes the virtual mapping
of system RAM to move upwards in the linear region, and at the same time
causes memstart_addr to assume a value which may be negative if the offset
of system RAM in the physical space is smaller than its offset relative to
PAGE_OFFSET in the virtual space.

Since memstart_addr is effectively an offset now, redefine its type as s64
so that expressions involving shifting or division preserve its sign.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
(cherry picked from commit 020d044f66874eba058ce8264fc550f3eca67879)
Signed-off-by: Alex Shi <alex.shi@linaro.org>
arch/arm64/include/asm/memory.h
arch/arm64/mm/init.c

index 5f8667a99e41133384b980c89db37c77cc19abae..12f8a00fb3f1767a645a04358dcaca08fd4f6b43 100644 (file)
 #include <linux/bitops.h>
 #include <linux/mmdebug.h>
 
-extern phys_addr_t             memstart_addr;
+extern s64                     memstart_addr;
 /* PHYS_OFFSET - the physical address of the start of memory. */
 #define PHYS_OFFSET            ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; })
 
index 19ccdb73c680cc40b428312ff5910ca5644dbd60..9db46dfb6afb987c8ee59324fdc28d4e62f4ca61 100644 (file)
@@ -54,7 +54,7 @@
  * executes, which assigns it its actual value. So use a default value
  * that cannot be mistaken for a real physical address.
  */
-phys_addr_t memstart_addr __read_mostly = ~0ULL;
+s64 memstart_addr __read_mostly = -1;
 phys_addr_t arm64_dma_phys_limit __read_mostly;
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -188,7 +188,7 @@ void __init arm64_memblock_init(void)
         * linear mapping. Take care not to clip the kernel which may be
         * high in memory.
         */
-       memblock_remove(max(memstart_addr + linear_region_size, __pa(_end)),
+       memblock_remove(max_t(u64, memstart_addr + linear_region_size, __pa(_end)),
                        ULLONG_MAX);
        if (memblock_end_of_DRAM() > linear_region_size)
                memblock_remove(0, memblock_end_of_DRAM() - linear_region_size);