| From 6d0f581d1768d3eaba15776e7dd1fdfec10cfe36 Mon Sep 17 00:00:00 2001 |
| From: Max Filippov <jcmvbkbc@gmail.com> |
| Date: Fri, 28 Jul 2017 17:42:59 -0700 |
| Subject: xtensa: fix cache aliasing handling code for WT cache |
| |
| From: Max Filippov <jcmvbkbc@gmail.com> |
| |
| commit 6d0f581d1768d3eaba15776e7dd1fdfec10cfe36 upstream. |
| |
| Currently building kernel for xtensa core with aliasing WT cache fails |
| with the following messages: |
| |
| mm/memory.c:2152: undefined reference to `flush_dcache_page' |
| mm/memory.c:2332: undefined reference to `local_flush_cache_page' |
| mm/memory.c:1919: undefined reference to `local_flush_cache_range' |
| mm/memory.c:4179: undefined reference to `copy_to_user_page' |
| mm/memory.c:4183: undefined reference to `copy_from_user_page' |
| |
| This happens because implementation of these functions is only compiled |
| when data cache is WB, which looks wrong: even when data cache doesn't |
| need flushing it still needs invalidation. The functions like |
| __flush_[invalidate_]dcache_* are correctly defined for both WB and WT |
| caches (and even if they weren't that'd still be ok, just slower). |
| |
| Fix this by providing the same implementation of the above functions for |
| both WB and WT cache. |
| |
| Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/xtensa/mm/cache.c | 10 +++------- |
| 1 file changed, 3 insertions(+), 7 deletions(-) |
| |
| --- a/arch/xtensa/mm/cache.c |
| +++ b/arch/xtensa/mm/cache.c |
| @@ -120,10 +120,6 @@ void copy_user_highpage(struct page *dst |
| preempt_enable(); |
| } |
| |
| -#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */ |
| - |
| -#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
| - |
| /* |
| * Any time the kernel writes to a user page cache page, or it is about to |
| * read from a page cache page this routine is called. |
| @@ -208,7 +204,7 @@ void local_flush_cache_page(struct vm_ar |
| __invalidate_icache_page_alias(virt, phys); |
| } |
| |
| -#endif |
| +#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */ |
| |
| void |
| update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) |
| @@ -225,7 +221,7 @@ update_mmu_cache(struct vm_area_struct * |
| |
| flush_tlb_page(vma, addr); |
| |
| -#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
| +#if (DCACHE_WAY_SIZE > PAGE_SIZE) |
| |
| if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { |
| unsigned long phys = page_to_phys(page); |
| @@ -256,7 +252,7 @@ update_mmu_cache(struct vm_area_struct * |
| * flush_dcache_page() on the page. |
| */ |
| |
| -#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
| +#if (DCACHE_WAY_SIZE > PAGE_SIZE) |
| |
| void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
| unsigned long vaddr, void *dst, const void *src, |