diff options
-rw-r--r-- | arch/arm/mm/fault-armv.c | 4 | ||||
-rw-r--r-- | arch/arm/mm/flush.c | 2 | ||||
-rw-r--r-- | include/asm-arm/cacheflush.h | 7 | ||||
-rw-r--r-- | include/asm-arm/mmu_context.h | 5 |
4 files changed, 18 insertions, 0 deletions
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 44558d5f9313..fbfa26058442 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c | |||
@@ -144,13 +144,17 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) | |||
144 | page = pfn_to_page(pfn); | 144 | page = pfn_to_page(pfn); |
145 | mapping = page_mapping(page); | 145 | mapping = page_mapping(page); |
146 | if (mapping) { | 146 | if (mapping) { |
147 | #ifndef CONFIG_SMP | ||
147 | int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); | 148 | int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); |
148 | 149 | ||
149 | if (dirty) | 150 | if (dirty) |
150 | __flush_dcache_page(mapping, page); | 151 | __flush_dcache_page(mapping, page); |
152 | #endif | ||
151 | 153 | ||
152 | if (cache_is_vivt()) | 154 | if (cache_is_vivt()) |
153 | make_coherent(mapping, vma, addr, pfn); | 155 | make_coherent(mapping, vma, addr, pfn); |
156 | else if (vma->vm_flags & VM_EXEC) | ||
157 | __flush_icache_all(); | ||
154 | } | 158 | } |
155 | } | 159 | } |
156 | 160 | ||
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 9df507d36e0b..029ee65fda2b 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -199,6 +199,8 @@ void flush_dcache_page(struct page *page) | |||
199 | __flush_dcache_page(mapping, page); | 199 | __flush_dcache_page(mapping, page); |
200 | if (mapping && cache_is_vivt()) | 200 | if (mapping && cache_is_vivt()) |
201 | __flush_dcache_aliases(mapping, page); | 201 | __flush_dcache_aliases(mapping, page); |
202 | else if (mapping) | ||
203 | __flush_icache_all(); | ||
202 | } | 204 | } |
203 | } | 205 | } |
204 | EXPORT_SYMBOL(flush_dcache_page); | 206 | EXPORT_SYMBOL(flush_dcache_page); |
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 759a97b56eed..559fb4af1f62 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h | |||
@@ -410,6 +410,13 @@ extern void flush_dcache_page(struct page *); | |||
410 | 410 | ||
411 | extern void __flush_dcache_page(struct address_space *mapping, struct page *page); | 411 | extern void __flush_dcache_page(struct address_space *mapping, struct page *page); |
412 | 412 | ||
413 | static inline void __flush_icache_all(void) | ||
414 | { | ||
415 | asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" | ||
416 | : | ||
417 | : "r" (0)); | ||
418 | } | ||
419 | |||
413 | #define ARCH_HAS_FLUSH_ANON_PAGE | 420 | #define ARCH_HAS_FLUSH_ANON_PAGE |
414 | static inline void flush_anon_page(struct vm_area_struct *vma, | 421 | static inline void flush_anon_page(struct vm_area_struct *vma, |
415 | struct page *page, unsigned long vmaddr) | 422 | struct page *page, unsigned long vmaddr) |
diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h index 6913d02ca5d6..91b9dfdfed52 100644 --- a/include/asm-arm/mmu_context.h +++ b/include/asm-arm/mmu_context.h | |||
@@ -97,6 +97,11 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
97 | #ifdef CONFIG_MMU | 97 | #ifdef CONFIG_MMU |
98 | unsigned int cpu = smp_processor_id(); | 98 | unsigned int cpu = smp_processor_id(); |
99 | 99 | ||
100 | #ifdef CONFIG_SMP | ||
101 | /* check for possible thread migration */ | ||
102 | if (!cpus_empty(next->cpu_vm_mask) && !cpu_isset(cpu, next->cpu_vm_mask)) | ||
103 | __flush_icache_all(); | ||
104 | #endif | ||
100 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask) || prev != next) { | 105 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask) || prev != next) { |
101 | check_context(next); | 106 | check_context(next); |
102 | cpu_switch_mm(next->pgd, next); | 107 | cpu_switch_mm(next->pgd, next); |