| From 57737c49dd72c96cfbcd4f66559f3ffc399aeb4f Mon Sep 17 00:00:00 2001 |
| From: Helge Deller <deller@gmx.de> |
| Date: Fri, 31 Jan 2014 21:33:17 +0100 |
| Subject: parisc: fix cache-flushing |
| |
| From: Helge Deller <deller@gmx.de> |
| |
| commit 57737c49dd72c96cfbcd4f66559f3ffc399aeb4f upstream. |
| |
| This commit: |
| f8dae00684d678afa13041ef170cecfd1297ed40: parisc: Ensure full cache coherency for kmap/kunmap |
| caused negative caching side-effects, e.g. hanging processes with expect and |
| too many inequivalent alias messages from flush_dcache_page() on Debian 5 systems. |
| |
| This patch now partly reverts it and has been in production use on our debian buildd |
| makeservers since a week without any major problems. |
| |
| Signed-off-by: Helge Deller <deller@gmx.de> |
| Signed-off-by: John David Anglin <dave.anglin@bell.net> |
| Signed-off-by: Helge Deller <deller@gmx.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/parisc/include/asm/cacheflush.h | 2 -- |
| arch/parisc/include/asm/page.h | 3 ++- |
| arch/parisc/kernel/cache.c | 14 ++++++++++++++ |
| 3 files changed, 16 insertions(+), 3 deletions(-) |
| |
| --- a/arch/parisc/include/asm/cacheflush.h |
| +++ b/arch/parisc/include/asm/cacheflush.h |
| @@ -132,7 +132,6 @@ void mark_rodata_ro(void); |
| static inline void *kmap(struct page *page) |
| { |
| might_sleep(); |
| - flush_dcache_page(page); |
| return page_address(page); |
| } |
| |
| @@ -144,7 +143,6 @@ static inline void kunmap(struct page *p |
| static inline void *kmap_atomic(struct page *page) |
| { |
| pagefault_disable(); |
| - flush_dcache_page(page); |
| return page_address(page); |
| } |
| |
| --- a/arch/parisc/include/asm/page.h |
| +++ b/arch/parisc/include/asm/page.h |
| @@ -29,7 +29,8 @@ struct page; |
| void clear_page_asm(void *page); |
| void copy_page_asm(void *to, void *from); |
| #define clear_user_page(vto, vaddr, page) clear_page_asm(vto) |
| -#define copy_user_page(vto, vfrom, vaddr, page) copy_page_asm(vto, vfrom) |
| +void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, |
| + struct page *pg); |
| |
| /* #define CONFIG_PARISC_TMPALIAS */ |
| |
| --- a/arch/parisc/kernel/cache.c |
| +++ b/arch/parisc/kernel/cache.c |
| @@ -388,6 +388,20 @@ void flush_kernel_dcache_page_addr(void |
| } |
| EXPORT_SYMBOL(flush_kernel_dcache_page_addr); |
| |
| +void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, |
| + struct page *pg) |
| +{ |
| + /* Copy using kernel mapping. No coherency is needed (all in |
| + kunmap) for the `to' page. However, the `from' page needs to |
| + be flushed through a mapping equivalent to the user mapping |
| + before it can be accessed through the kernel mapping. */ |
| + preempt_disable(); |
| + flush_dcache_page_asm(__pa(vfrom), vaddr); |
| + preempt_enable(); |
| + copy_page_asm(vto, vfrom); |
| +} |
| +EXPORT_SYMBOL(copy_user_page); |
| + |
| void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) |
| { |
| unsigned long flags; |