[FOSS_TLK]platform: tegra: add XN bits to identity mappings
Chris Johnson [Tue, 3 Feb 2015 03:05:27 +0000 (19:05 -0800)]
The identity mappings need to be careful to avoid speculative
instruction fetch, which can trigger MC errors in carved out
regions and in certain regions mapped to AHB accesses.

Adding XN bits to these Device-nGnRnE mappings prevent these
speculative reads.

Bug 200039988

Change-Id: I9869bb7cffba05a6b155eeeb7548c43cf690c4a6
Reviewed-on: http://git-master/r/715784
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Tested-by: Varun Wadekar <vwadekar@nvidia.com>

arch/arm/arm/start.S
arch/arm/include/arch/arm/mmu_ldesc_macros.h

index 3f9e342..48b0a81 100644 (file)
@@ -111,9 +111,15 @@ reset:
         */
        ldr     r0, =tt
        sub     r0, r0, r6              // second level phys
+       mov     r10, r0
        mmu_desc_create_null_entry r0, r1
        mmu_desc_create_ident_mapping r0, r1, r2, r3
 
+       mov     r0, r10
+       mov     r1, r5
+       mov     r2, r4
+       mmu_desc_setup_carveout_ident r0, r1, r2, r3, r11
+
 #if defined(WITH_MONITOR_BIN)
        /*
         * With a separate monitor binary, phys base with this VMEMBASE isn't
index c9e1561..13db945 100644 (file)
 #include <config.h>
 #include <arch/arm/mmu_ldesc.h>
 
-#define MMU_PTE_L2_BLOCK_MMIO_FLAGS    \
+#define MMU_PTE_L2_BLOCK_MMIO_LOWER    \
        (MMU_MEMORY_SET_ATTR_IDX(MMU_MEMORY_STRONGLY_ORDERED) | \
         MMU_MEMORY_ACCESS_FLAG |       \
         MMU_MEMORY_AP_P_RW_U_NA | 0x1)
 
+/* no execute for bits for EL1/EL0 */
+#define MMU_PTE_L2_BLOCK_MMIO_UXN      (1 << 54)
+#define MMU_PTE_L2_BLOCK_MMIO_PXN      (1 << 53)
+
+#define MMU_PTE_L2_BLOCK_MMIO_UPPER    \
+       (MMU_PTE_L2_BLOCK_MMIO_UXN | MMU_PTE_L2_BLOCK_MMIO_PXN)
+
 #define MMU_PTE_L2_BLOCK_KERN_FLAGS    \
        (MMU_MEMORY_SET_ATTR_IDX(MMU_MEMORY_WB_OUTER_NO_ALLOC_INNER_ALLOC) | \
         MMU_MEMORY_ACCESS_FLAG |       \
 .endm
 
 /* create identity 2MB entries for MMIO */
-.macro mmu_desc_create_ident_mapping, pt, pte, idx, zero
+.macro mmu_desc_create_ident_mapping, pt, pte, idx, upper
        /* create second level identity entries */
-       mov32   \pte, MMU_PTE_L2_BLOCK_MMIO_FLAGS
+       mov32   \pte, MMU_PTE_L2_BLOCK_MMIO_LOWER
        mov     \idx, #1
-       mov     \zero, #0
+       mov     \upper, #(MMU_PTE_L2_BLOCK_MMIO_UPPER >> 32)
 1:
        add     \pte, \pte, #(1 << MMU_L2_BLOCK_SHIFT)
-       stmia   \pt!, {\pte, \zero}     @ write PTE and upper 0
+       stmia   \pt!, {\pte, \upper}    @ write PTE and upper 0
        add     \idx, #1
        cmp     \idx, #0x800            @ # of 2MB mappings in 32bit VA
        blt     1b
 .endm
 
+/* create identity 2MB entries for TZ carveout */
+.macro mmu_desc_setup_carveout_ident, pt, addr, len, pte, tmp
+       /* create second level identity entries */
+       mov32   \pte, MMU_PTE_L2_BLOCK_MMIO_LOWER
+       lsr     \addr, #MMU_L2_BLOCK_SHIFT
+       mov     \tmp, \addr
+       lsl     \addr, #MMU_L2_BLOCK_SHIFT
+       orr     \pte, \addr
+       add     \pt, \tmp, lsl #3
+
+       /* roundup length to L2 blocks */
+       mov32   \tmp, ((1 << MMU_L2_BLOCK_SHIFT) - 1)
+       add     \tmp, \len, \tmp
+       lsr     \len, \tmp, #MMU_L2_BLOCK_SHIFT         @ L2 block count
+       mov     \tmp, #0
+1:
+       stmia   \pt!, {\pte, \tmp}    @ write PTE and upper 0
+       add     \pte, \pte, #(1 << MMU_L2_BLOCK_SHIFT)
+       subs    \len, \len, #0x1
+       bne     1b
+.endm
+
 /* map phys carveout with L3 entries */
 .macro mmu_desc_map_phys_l3, virt, phys, len, pt, l2, tmp, tmp2, zero
        /* setup L2 entries */