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)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 29 Feb 2016 18:31:03 +0000 (18:31 +0000)
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>
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 3b897b9f88071fefd6a1c4659c63fdd5dec34334..22c6758b01aa690b5027b1ed378a9c0c33bdec86 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
@@ -181,7 +181,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);