arm64: Re-order reserved_ttbr0 in linker script
authorSteve Capper <steve.capper@arm.com>
Thu, 11 Jan 2018 10:11:57 +0000 (10:11 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Sun, 14 Jan 2018 18:49:51 +0000 (18:49 +0000)
Currently one resolves the location of the reserved_ttbr0 for PAN by
taking a positive offset from swapper_pg_dir. In a future patch we wish
to extend the swapper s.t. its size is determined at link time rather
than comile time, rendering SWAPPER_DIR_SIZE unsuitable for such a low
level calculation.

In this patch we re-arrange the order of the linker script s.t. instead
one computes reserved_ttbr0 by subtracting RESERVED_TTBR0_SIZE from
swapper_pg_dir.

Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Steve Capper <steve.capper@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/asm-uaccess.h
arch/arm64/include/asm/uaccess.h
arch/arm64/kernel/vmlinux.lds.S

index f4f234b6155e9bc560c660dd9e3ebb74f36ab22a..8719ce122a38e3083c41305519f1ca369fd36215 100644 (file)
  */
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
        .macro  __uaccess_ttbr0_disable, tmp1
-       mrs     \tmp1, ttbr1_el1                // swapper_pg_dir
-       add     \tmp1, \tmp1, #SWAPPER_DIR_SIZE // reserved_ttbr0 at the end of swapper_pg_dir
-       msr     ttbr0_el1, \tmp1                // set reserved TTBR0_EL1
+       mrs     \tmp1, ttbr1_el1                        // swapper_pg_dir
+       sub     \tmp1, \tmp1, #RESERVED_TTBR0_SIZE      // reserved_ttbr0 just before swapper_pg_dir
+       msr     ttbr0_el1, \tmp1                        // set reserved TTBR0_EL1
        isb
-       sub     \tmp1, \tmp1, #SWAPPER_DIR_SIZE
+       add     \tmp1, \tmp1, #RESERVED_TTBR0_SIZE
        bic     \tmp1, \tmp1, #TTBR_ASID_MASK
        msr     ttbr1_el1, \tmp1                // set reserved ASID
        isb
index 3821fab01d7d59085bc1d377e71aa268303baf76..01ade20d5456810656dcc72fb535d7dad033d140 100644 (file)
@@ -108,8 +108,8 @@ static inline void __uaccess_ttbr0_disable(void)
        unsigned long ttbr;
 
        ttbr = read_sysreg(ttbr1_el1);
-       /* reserved_ttbr0 placed at the end of swapper_pg_dir */
-       write_sysreg(ttbr + SWAPPER_DIR_SIZE, ttbr0_el1);
+       /* reserved_ttbr0 placed before swapper_pg_dir */
+       write_sysreg(ttbr - RESERVED_TTBR0_SIZE, ttbr0_el1);
        isb();
        /* Set reserved ASID */
        ttbr &= ~TTBR_ASID_MASK;
index ddfd3c0942f7acf27d3bb0396ebbd3ba87303296..8e567de8f369f75ab37f412946a2fc89a5547cdd 100644 (file)
@@ -218,13 +218,12 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);
        idmap_pg_dir = .;
        . += IDMAP_DIR_SIZE;
-       swapper_pg_dir = .;
-       . += SWAPPER_DIR_SIZE;
-
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
        reserved_ttbr0 = .;
        . += RESERVED_TTBR0_SIZE;
 #endif
+       swapper_pg_dir = .;
+       . += SWAPPER_DIR_SIZE;
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
        tramp_pg_dir = .;