Commit 4348810a authored by Russell King's avatar Russell King

ARM: btc: avoid invalidating the branch target cache on kernel TLB maintanence

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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent eb96c925
...@@ -34,16 +34,12 @@ ...@@ -34,16 +34,12 @@
#define TLB_V6_D_ASID (1 << 17) #define TLB_V6_D_ASID (1 << 17)
#define TLB_V6_I_ASID (1 << 18) #define TLB_V6_I_ASID (1 << 18)
#define TLB_BTB (1 << 28)
/* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */ /* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */
#define TLB_V7_UIS_PAGE (1 << 19) #define TLB_V7_UIS_PAGE (1 << 19)
#define TLB_V7_UIS_FULL (1 << 20) #define TLB_V7_UIS_FULL (1 << 20)
#define TLB_V7_UIS_ASID (1 << 21) #define TLB_V7_UIS_ASID (1 << 21)
/* Inner Shareable BTB operation (ARMv7 MP extensions) */ #define TLB_BARRIER (1 << 28)
#define TLB_V7_IS_BTB (1 << 22)
#define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */
#define TLB_DCLEAN (1 << 30) #define TLB_DCLEAN (1 << 30)
#define TLB_WB (1 << 31) #define TLB_WB (1 << 31)
...@@ -58,7 +54,7 @@ ...@@ -58,7 +54,7 @@
* v4wb - ARMv4 with write buffer without I TLB flush entry instruction * v4wb - ARMv4 with write buffer without I TLB flush entry instruction
* v4wbi - ARMv4 with write buffer with 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) * 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 * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
* v7wbi - identical to v6wbi * v7wbi - identical to v6wbi
*/ */
...@@ -99,7 +95,7 @@ ...@@ -99,7 +95,7 @@
# define v4_always_flags (-1UL) # define v4_always_flags (-1UL)
#endif #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) TLB_V4_U_FULL | TLB_V4_U_PAGE)
#ifdef CONFIG_CPU_TLB_FA #ifdef CONFIG_CPU_TLB_FA
...@@ -166,7 +162,7 @@ ...@@ -166,7 +162,7 @@
# define v4wb_always_flags (-1UL) # define v4wb_always_flags (-1UL)
#endif #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_FULL | TLB_V6_D_FULL | \
TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
TLB_V6_I_ASID | TLB_V6_D_ASID) TLB_V6_I_ASID | TLB_V6_D_ASID)
...@@ -184,9 +180,9 @@ ...@@ -184,9 +180,9 @@
# define v6wbi_always_flags (-1UL) # define v6wbi_always_flags (-1UL)
#endif #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) 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) TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
#ifdef CONFIG_CPU_TLB_V7 #ifdef CONFIG_CPU_TLB_V7
...@@ -341,15 +337,7 @@ static inline void local_flush_tlb_all(void) ...@@ -341,15 +337,7 @@ static inline void local_flush_tlb_all(void)
if (tlb_flag(TLB_V7_UIS_FULL)) if (tlb_flag(TLB_V7_UIS_FULL))
asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
if (tlb_flag(TLB_BTB)) { if (tlb_flag(TLB_BARRIER)) {
/* 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");
dsb(); dsb();
isb(); isb();
} }
...@@ -389,17 +377,8 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) ...@@ -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"); asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc");
#endif #endif
if (tlb_flag(TLB_BTB)) { if (tlb_flag(TLB_BARRIER))
/* 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");
dsb(); dsb();
isb();
}
} }
static inline void static inline void
...@@ -439,17 +418,8 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) ...@@ -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"); asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc");
#endif #endif
if (tlb_flag(TLB_BTB)) { if (tlb_flag(TLB_BARRIER))
/* 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");
dsb(); dsb();
isb();
}
} }
static inline void local_flush_tlb_kernel_page(unsigned long kaddr) 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) ...@@ -482,15 +452,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
if (tlb_flag(TLB_V7_UIS_PAGE)) if (tlb_flag(TLB_V7_UIS_PAGE))
asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc"); asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc");
if (tlb_flag(TLB_BTB)) { if (tlb_flag(TLB_BARRIER)) {
/* 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");
dsb(); dsb();
isb(); isb();
} }
......
...@@ -46,7 +46,6 @@ ENTRY(fa_flush_user_tlb_range) ...@@ -46,7 +46,6 @@ ENTRY(fa_flush_user_tlb_range)
add r0, r0, #PAGE_SZ add r0, r0, #PAGE_SZ
cmp r0, r1 cmp r0, r1
blo 1b 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, c10, 4 @ data write barrier
mov pc, lr mov pc, lr
...@@ -60,9 +59,8 @@ ENTRY(fa_flush_kern_tlb_range) ...@@ -60,9 +59,8 @@ ENTRY(fa_flush_kern_tlb_range)
add r0, r0, #PAGE_SZ add r0, r0, #PAGE_SZ
cmp r0, r1 cmp r0, r1
blo 1b 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, 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 mov pc, lr
__INITDATA __INITDATA
......
...@@ -54,7 +54,6 @@ ENTRY(v6wbi_flush_user_tlb_range) ...@@ -54,7 +54,6 @@ ENTRY(v6wbi_flush_user_tlb_range)
add r0, r0, #PAGE_SZ add r0, r0, #PAGE_SZ
cmp r0, r1 cmp r0, r1
blo 1b blo 1b
mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB
mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier
mov pc, lr mov pc, lr
...@@ -83,9 +82,8 @@ ENTRY(v6wbi_flush_kern_tlb_range) ...@@ -83,9 +82,8 @@ ENTRY(v6wbi_flush_kern_tlb_range)
add r0, r0, #PAGE_SZ add r0, r0, #PAGE_SZ
cmp r0, r1 cmp r0, r1
blo 1b 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, 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 mov pc, lr
__INIT __INIT
......
...@@ -48,9 +48,6 @@ ENTRY(v7wbi_flush_user_tlb_range) ...@@ -48,9 +48,6 @@ ENTRY(v7wbi_flush_user_tlb_range)
add r0, r0, #PAGE_SZ add r0, r0, #PAGE_SZ
cmp r0, r1 cmp r0, r1
blo 1b 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 dsb
mov pc, lr mov pc, lr
ENDPROC(v7wbi_flush_user_tlb_range) ENDPROC(v7wbi_flush_user_tlb_range)
...@@ -75,9 +72,6 @@ ENTRY(v7wbi_flush_kern_tlb_range) ...@@ -75,9 +72,6 @@ ENTRY(v7wbi_flush_kern_tlb_range)
add r0, r0, #PAGE_SZ add r0, r0, #PAGE_SZ
cmp r0, r1 cmp r0, r1
blo 1b 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 dsb
isb isb
mov pc, lr mov pc, lr
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment