Commit f8dae00684d678afa13041ef170cecfd1297ed40

Authored by John David Anglin
Committed by Helge Deller
1 parent ceb3b0212d

parisc: Ensure full cache coherency for kmap/kunmap

Helge Deller noted a few weeks ago problems with the AIO support on
parisc. This change is the result of numerous iterations on how best to
deal with this problem.

The solution adopted here is to provide full cache coherency in a
uniform manner on all parisc systems. This involves calling
flush_dcache_page() on kmap operations and flush_kernel_dcache_page() on
kunmap operations. As a result, the copy_user_page() and
clear_user_page() functions can be removed and the overall code is
simpler.

The change ensures that both userspace and kernel aliases to a mapped
page are invalidated and flushed. This is necessary for the correct
operation of PA8800 and PA8900 based systems which do not support
inequivalent aliases.

With this change, I have observed no cache related issues on c8000 and
rp3440. It is now possible for example to do kernel builds with "-j64"
on four way systems.

On systems using XFS file systems, the patch recently posted by Mikulas
Patocka to "fix crash using XFS on loopback" is needed to avoid a hang
caused by an uninitialized lock passed to flush_dcache_page() in the
page struct.

Signed-off-by: John David Anglin <dave.anglin@bell.net>
Cc: stable@vger.kernel.org # v3.9+
Signed-off-by: Helge Deller <deller@gmx.de>

Showing 3 changed files with 6 additions and 46 deletions Side-by-side Diff

arch/parisc/include/asm/cacheflush.h
... ... @@ -125,42 +125,38 @@
125 125 void mark_rodata_ro(void);
126 126 #endif
127 127  
128   -#ifdef CONFIG_PA8X00
129   -/* Only pa8800, pa8900 needs this */
130   -
131 128 #include <asm/kmap_types.h>
132 129  
133 130 #define ARCH_HAS_KMAP
134 131  
135   -void kunmap_parisc(void *addr);
136   -
137 132 static inline void *kmap(struct page *page)
138 133 {
139 134 might_sleep();
  135 + flush_dcache_page(page);
140 136 return page_address(page);
141 137 }
142 138  
143 139 static inline void kunmap(struct page *page)
144 140 {
145   - kunmap_parisc(page_address(page));
  141 + flush_kernel_dcache_page_addr(page_address(page));
146 142 }
147 143  
148 144 static inline void *kmap_atomic(struct page *page)
149 145 {
150 146 pagefault_disable();
  147 + flush_dcache_page(page);
151 148 return page_address(page);
152 149 }
153 150  
154 151 static inline void __kunmap_atomic(void *addr)
155 152 {
156   - kunmap_parisc(addr);
  153 + flush_kernel_dcache_page_addr(addr);
157 154 pagefault_enable();
158 155 }
159 156  
160 157 #define kmap_atomic_prot(page, prot) kmap_atomic(page)
161 158 #define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn))
162 159 #define kmap_atomic_to_page(ptr) virt_to_page(ptr)
163   -#endif
164 160  
165 161 #endif /* _PARISC_CACHEFLUSH_H */
arch/parisc/include/asm/page.h
... ... @@ -28,9 +28,8 @@
28 28  
29 29 void clear_page_asm(void *page);
30 30 void copy_page_asm(void *to, void *from);
31   -void clear_user_page(void *vto, unsigned long vaddr, struct page *pg);
32   -void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
33   - struct page *pg);
  31 +#define clear_user_page(vto, vaddr, page) clear_page_asm(vto)
  32 +#define copy_user_page(vto, vfrom, vaddr, page) copy_page_asm(vto, vfrom)
34 33  
35 34 /* #define CONFIG_PARISC_TMPALIAS */
36 35  
arch/parisc/kernel/cache.c
... ... @@ -388,41 +388,6 @@
388 388 }
389 389 EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
390 390  
391   -void clear_user_page(void *vto, unsigned long vaddr, struct page *page)
392   -{
393   - clear_page_asm(vto);
394   - if (!parisc_requires_coherency())
395   - flush_kernel_dcache_page_asm(vto);
396   -}
397   -EXPORT_SYMBOL(clear_user_page);
398   -
399   -void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
400   - struct page *pg)
401   -{
402   - /* Copy using kernel mapping. No coherency is needed
403   - (all in kmap/kunmap) on machines that don't support
404   - non-equivalent aliasing. However, the `from' page
405   - needs to be flushed before it can be accessed through
406   - the kernel mapping. */
407   - preempt_disable();
408   - flush_dcache_page_asm(__pa(vfrom), vaddr);
409   - preempt_enable();
410   - copy_page_asm(vto, vfrom);
411   - if (!parisc_requires_coherency())
412   - flush_kernel_dcache_page_asm(vto);
413   -}
414   -EXPORT_SYMBOL(copy_user_page);
415   -
416   -#ifdef CONFIG_PA8X00
417   -
418   -void kunmap_parisc(void *addr)
419   -{
420   - if (parisc_requires_coherency())
421   - flush_kernel_dcache_page_addr(addr);
422   -}
423   -EXPORT_SYMBOL(kunmap_parisc);
424   -#endif
425   -
426 391 void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
427 392 {
428 393 unsigned long flags;