]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ARM: btc: avoid invalidating the branch target cache on kernel TLB maintanence
authorRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 5 Jul 2011 08:01:13 +0000 (09:01 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 19 Jul 2011 10:44:06 +0000 (11:44 +0100)
Kernel space needs very little in the way of BTC maintanence as most
mappings which are created and destroyed are non-executable, and so
could never enter the instruction stream.

The case which does warrant BTC maintanence is when a module is loaded.
This creates a new executable mapping, but at that point the pages have
not been initialized with code and data, so at that point they contain
unpredictable information.  Invalidating the BTC at this stage serves
little useful purpose.

Before we execute module code, we call flush_icache_range(), which deals
with the BTC maintanence requirements.  This ensures that we have a BTC
maintanence operation before we execute code via the newly created
mapping.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/tlbflush.h
arch/arm/mm/tlb-fa.S
arch/arm/mm/tlb-v6.S
arch/arm/mm/tlb-v7.S

index d2005de383b8c105cf85368a5a7539bdaae0410b..8077145698ffff09f802644021ae9980b8b226a2 100644 (file)
 #define TLB_V6_D_ASID  (1 << 17)
 #define TLB_V6_I_ASID  (1 << 18)
 
-#define TLB_BTB                (1 << 28)
-
 /* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */
 #define TLB_V7_UIS_PAGE        (1 << 19)
 #define TLB_V7_UIS_FULL (1 << 20)
 #define TLB_V7_UIS_ASID (1 << 21)
 
-/* Inner Shareable BTB operation (ARMv7 MP extensions) */
-#define TLB_V7_IS_BTB  (1 << 22)
-
+#define TLB_BARRIER    (1 << 28)
 #define TLB_L2CLEAN_FR (1 << 29)               /* Feroceon */
 #define TLB_DCLEAN     (1 << 30)
 #define TLB_WB         (1 << 31)
@@ -58,7 +54,7 @@
  *       v4wb  - ARMv4 with write buffer without I TLB flush entry instruction
  *       v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
  *       fr    - Feroceon (v4wbi with non-outer-cacheable page table walks)
- *       fa    - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB))
+ *       fa    - Faraday (v4 with write buffer with UTLB)
  *       v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
  *       v7wbi - identical to v6wbi
  */
@@ -99,7 +95,7 @@
 # define v4_always_flags       (-1UL)
 #endif
 
-#define fa_tlb_flags   (TLB_WB | TLB_BTB | TLB_DCLEAN | \
+#define fa_tlb_flags   (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
                         TLB_V4_U_FULL | TLB_V4_U_PAGE)
 
 #ifdef CONFIG_CPU_TLB_FA
 # define v4wb_always_flags     (-1UL)
 #endif
 
-#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
                         TLB_V6_I_FULL | TLB_V6_D_FULL | \
                         TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
                         TLB_V6_I_ASID | TLB_V6_D_ASID)
 # define v6wbi_always_flags    (-1UL)
 #endif
 
-#define v7wbi_tlb_flags_smp    (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
+#define v7wbi_tlb_flags_smp    (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
                         TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
-#define v7wbi_tlb_flags_up     (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+#define v7wbi_tlb_flags_up     (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
                         TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
 
 #ifdef CONFIG_CPU_TLB_V7
@@ -341,15 +337,7 @@ static inline void local_flush_tlb_all(void)
        if (tlb_flag(TLB_V7_UIS_FULL))
                asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
 
-       if (tlb_flag(TLB_BTB)) {
-               /* flush the branch target cache */
-               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
-               dsb();
-               isb();
-       }
-       if (tlb_flag(TLB_V7_IS_BTB)) {
-               /* flush the branch target cache */
-               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+       if (tlb_flag(TLB_BARRIER)) {
                dsb();
                isb();
        }
@@ -389,17 +377,8 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
                asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc");
 #endif
 
-       if (tlb_flag(TLB_BTB)) {
-               /* flush the branch target cache */
-               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
-               dsb();
-       }
-       if (tlb_flag(TLB_V7_IS_BTB)) {
-               /* flush the branch target cache */
-               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+       if (tlb_flag(TLB_BARRIER))
                dsb();
-               isb();
-       }
 }
 
 static inline void
@@ -439,17 +418,8 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
                asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc");
 #endif
 
-       if (tlb_flag(TLB_BTB)) {
-               /* flush the branch target cache */
-               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
-               dsb();
-       }
-       if (tlb_flag(TLB_V7_IS_BTB)) {
-               /* flush the branch target cache */
-               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+       if (tlb_flag(TLB_BARRIER))
                dsb();
-               isb();
-       }
 }
 
 static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -482,15 +452,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
        if (tlb_flag(TLB_V7_UIS_PAGE))
                asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc");
 
-       if (tlb_flag(TLB_BTB)) {
-               /* flush the branch target cache */
-               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
-               dsb();
-               isb();
-       }
-       if (tlb_flag(TLB_V7_IS_BTB)) {
-               /* flush the branch target cache */
-               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+       if (tlb_flag(TLB_BARRIER)) {
                dsb();
                isb();
        }
index 9694f1f6f4854a7261853f5d6329684f9dd98ba4..d887a31faaae7d1d93fa6265add0b84c7184e2f3 100644 (file)
@@ -46,7 +46,6 @@ ENTRY(fa_flush_user_tlb_range)
        add     r0, r0, #PAGE_SZ
        cmp     r0, r1
        blo     1b
-       mcr     p15, 0, r3, c7, c5, 6           @ invalidate BTB
        mcr     p15, 0, r3, c7, c10, 4          @ data write barrier
        mov     pc, lr
 
@@ -60,9 +59,8 @@ ENTRY(fa_flush_kern_tlb_range)
        add     r0, r0, #PAGE_SZ
        cmp     r0, r1
        blo     1b
-       mcr     p15, 0, r3, c7, c5, 6           @ invalidate BTB
        mcr     p15, 0, r3, c7, c10, 4          @ data write barrier
-       mcr     p15, 0, r3, c7, c5, 4           @ prefetch flush
+       mcr     p15, 0, r3, c7, c5, 4           @ prefetch flush (isb)
        mov     pc, lr
 
        __INITDATA
index 73d7d89b04c48a93c13d3f1e204853065fbcdc7c..ffe06a69a6e558d905628d235bd255362ae099ec 100644 (file)
@@ -54,7 +54,6 @@ ENTRY(v6wbi_flush_user_tlb_range)
        add     r0, r0, #PAGE_SZ
        cmp     r0, r1
        blo     1b
-       mcr     p15, 0, ip, c7, c5, 6           @ flush BTAC/BTB
        mcr     p15, 0, ip, c7, c10, 4          @ data synchronization barrier
        mov     pc, lr
 
@@ -83,9 +82,8 @@ ENTRY(v6wbi_flush_kern_tlb_range)
        add     r0, r0, #PAGE_SZ
        cmp     r0, r1
        blo     1b
-       mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
        mcr     p15, 0, r2, c7, c10, 4          @ data synchronization barrier
-       mcr     p15, 0, r2, c7, c5, 4           @ prefetch flush
+       mcr     p15, 0, r2, c7, c5, 4           @ prefetch flush (isb)
        mov     pc, lr
 
        __INIT
index 53cd5b45467318e7fae97127bcdead01e3f4e8eb..86bb7166450830a272a2c79fddbf11d181468ac3 100644 (file)
@@ -48,9 +48,6 @@ ENTRY(v7wbi_flush_user_tlb_range)
        add     r0, r0, #PAGE_SZ
        cmp     r0, r1
        blo     1b
-       mov     ip, #0
-       ALT_SMP(mcr     p15, 0, ip, c7, c1, 6)  @ flush BTAC/BTB Inner Shareable
-       ALT_UP(mcr      p15, 0, ip, c7, c5, 6)  @ flush BTAC/BTB
        dsb
        mov     pc, lr
 ENDPROC(v7wbi_flush_user_tlb_range)
@@ -75,9 +72,6 @@ ENTRY(v7wbi_flush_kern_tlb_range)
        add     r0, r0, #PAGE_SZ
        cmp     r0, r1
        blo     1b
-       mov     r2, #0
-       ALT_SMP(mcr     p15, 0, r2, c7, c1, 6)  @ flush BTAC/BTB Inner Shareable
-       ALT_UP(mcr      p15, 0, r2, c7, c5, 6)  @ flush BTAC/BTB
        dsb
        isb
        mov     pc, lr