diff options
| -rw-r--r-- | arch/arm/mm/context.c | 7 | ||||
| -rw-r--r-- | include/asm-arm/cacheflush.h | 15 |
2 files changed, 22 insertions, 0 deletions
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 9da43a0fdcdf..c9e9a5586267 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c | |||
| @@ -47,6 +47,13 @@ void __new_context(struct mm_struct *mm) | |||
| 47 | : "r" (0)); | 47 | : "r" (0)); |
| 48 | isb(); | 48 | isb(); |
| 49 | flush_tlb_all(); | 49 | flush_tlb_all(); |
| 50 | if (icache_is_vivt_asid_tagged()) { | ||
| 51 | asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" | ||
| 52 | "mcr p15, 0, %0, c7, c5, 6 @ flush BTAC/BTB\n" | ||
| 53 | : | ||
| 54 | : "r" (0)); | ||
| 55 | dsb(); | ||
| 56 | } | ||
| 50 | } | 57 | } |
| 51 | 58 | ||
| 52 | mm->context.id = asid; | 59 | mm->context.id = asid; |
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 6832ef96bc16..d1294a46c70c 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h | |||
| @@ -438,6 +438,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma, | |||
| 438 | #define __cacheid_vipt(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val)) | 438 | #define __cacheid_vipt(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val)) |
| 439 | #define __cacheid_vipt_nonaliasing(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val)) | 439 | #define __cacheid_vipt_nonaliasing(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val)) |
| 440 | #define __cacheid_vipt_aliasing(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val)) | 440 | #define __cacheid_vipt_aliasing(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val)) |
| 441 | #define __cacheid_vivt_asid_tagged_instr(val) (__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0) | ||
| 441 | 442 | ||
| 442 | #if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) | 443 | #if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) |
| 443 | 444 | ||
| @@ -445,6 +446,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma, | |||
| 445 | #define cache_is_vipt() 0 | 446 | #define cache_is_vipt() 0 |
| 446 | #define cache_is_vipt_nonaliasing() 0 | 447 | #define cache_is_vipt_nonaliasing() 0 |
| 447 | #define cache_is_vipt_aliasing() 0 | 448 | #define cache_is_vipt_aliasing() 0 |
| 449 | #define icache_is_vivt_asid_tagged() 0 | ||
| 448 | 450 | ||
| 449 | #elif defined(CONFIG_CPU_CACHE_VIPT) | 451 | #elif defined(CONFIG_CPU_CACHE_VIPT) |
| 450 | 452 | ||
| @@ -462,6 +464,12 @@ static inline void flush_anon_page(struct vm_area_struct *vma, | |||
| 462 | __cacheid_vipt_aliasing(__val); \ | 464 | __cacheid_vipt_aliasing(__val); \ |
| 463 | }) | 465 | }) |
| 464 | 466 | ||
| 467 | #define icache_is_vivt_asid_tagged() \ | ||
| 468 | ({ \ | ||
| 469 | unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ | ||
| 470 | __cacheid_vivt_asid_tagged_instr(__val); \ | ||
| 471 | }) | ||
| 472 | |||
| 465 | #else | 473 | #else |
| 466 | 474 | ||
| 467 | #define cache_is_vivt() \ | 475 | #define cache_is_vivt() \ |
| @@ -490,6 +498,13 @@ static inline void flush_anon_page(struct vm_area_struct *vma, | |||
| 490 | __cacheid_vipt_aliasing(__val); \ | 498 | __cacheid_vipt_aliasing(__val); \ |
| 491 | }) | 499 | }) |
| 492 | 500 | ||
| 501 | #define icache_is_vivt_asid_tagged() \ | ||
| 502 | ({ \ | ||
| 503 | unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ | ||
| 504 | __cacheid_present(__val) && \ | ||
| 505 | __cacheid_vivt_asid_tagged_instr(__val); \ | ||
| 506 | }) | ||
| 507 | |||
| 493 | #endif | 508 | #endif |
| 494 | 509 | ||
| 495 | #endif | 510 | #endif |
