From 20f4d3cb9b94ce3fec9a6135b9ad075b82b24f41 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 23 Aug 2006 09:00:04 -0700 Subject: [PARISC] parisc specific kmap API implementation for pa8800 This patch fixes the pa8800 at a gross level (there are still other subtle incoherency issues which can still cause crashes and HPMCs). What it does is try to force eject inequivalent aliases before they become visible to the L2 cache (which is where we get the incoherence problems). A new function (parisc_requires_coherency) is introduced in asm/processor.h to identify the pa8x00 processors (8800 and 8900) which have the issue. Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'arch/parisc/kernel/cache.c') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index bc7c4a4e26a1..7e8d697aef36 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -91,7 +91,8 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) flush_kernel_dcache_page(page); clear_bit(PG_dcache_dirty, &page->flags); - } + } else if (parisc_requires_coherency()) + flush_kernel_dcache_page(page); } void @@ -370,3 +371,45 @@ void parisc_setup_cache_timing(void) printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus()); } + +extern void purge_kernel_dcache_page(unsigned long); +extern void clear_user_page_asm(void *page, unsigned long vaddr); + +void +clear_user_page(void *page, unsigned long vaddr, struct page *pg) +{ + purge_kernel_dcache_page((unsigned long)page); + purge_tlb_start(); + pdtlb_kernel(page); + purge_tlb_end(); + clear_user_page_asm(page, vaddr); +} + +void flush_kernel_dcache_page_addr(void *addr) +{ + flush_kernel_dcache_page_asm(addr); + purge_tlb_start(); + pdtlb_kernel(addr); + purge_tlb_end(); +} +EXPORT_SYMBOL(flush_kernel_dcache_page_addr); + +void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, + struct page *pg) +{ + /* no coherency needed (all in kmap/kunmap) */ + copy_user_page_asm(vto, vfrom); + if (!parisc_requires_coherency()) + flush_kernel_dcache_page_asm(vto); +} +EXPORT_SYMBOL(copy_user_page); + +#ifdef CONFIG_PA8X00 + +void kunmap_parisc(void *addr) +{ + if (parisc_requires_coherency()) + flush_kernel_dcache_page_addr(addr); +} +EXPORT_SYMBOL(kunmap_parisc); +#endif -- cgit v1.2.3 From d207ac0f7c9736782bfa51cff2109b74d26c3622 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 19 Sep 2006 19:32:42 -0600 Subject: [PARISC] Fix CONFIG_DEBUG_SPINLOCK Joel Soete points out that we refer to pa_tlb_lock but only define it if CONFIG_SMP which breaks a uniprocessor build with CONFIG_DEBUG_SPINLOCK enabled. No module refers to pa_tlb_lock, so we can delete the export. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/parisc/kernel/cache.c') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 7e8d697aef36..e91c2be7236a 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -35,15 +35,12 @@ int icache_stride __read_mostly; EXPORT_SYMBOL(dcache_stride); -#if defined(CONFIG_SMP) /* On some machines (e.g. ones with the Merced bus), there can be * only a single PxTLB broadcast at a time; this must be guaranteed * by software. We put a spinlock around all TLB flushes to * ensure this. */ DEFINE_SPINLOCK(pa_tlb_lock); -EXPORT_SYMBOL(pa_tlb_lock); -#endif struct pdc_cache_info cache_info __read_mostly; #ifndef CONFIG_PA20 -- cgit v1.2.3 From 8d0b7d1055bedca784b143b0af9b37bd971b7cd2 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 20 Sep 2006 21:44:09 -0600 Subject: [PARISC] Export clear_user_page to modules Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/parisc/kernel/cache.c') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index e91c2be7236a..0be51e92a2fc 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -372,8 +372,7 @@ void parisc_setup_cache_timing(void) extern void purge_kernel_dcache_page(unsigned long); extern void clear_user_page_asm(void *page, unsigned long vaddr); -void -clear_user_page(void *page, unsigned long vaddr, struct page *pg) +void clear_user_page(void *page, unsigned long vaddr, struct page *pg) { purge_kernel_dcache_page((unsigned long)page); purge_tlb_start(); @@ -381,6 +380,7 @@ clear_user_page(void *page, unsigned long vaddr, struct page *pg) purge_tlb_end(); clear_user_page_asm(page, vaddr); } +EXPORT_SYMBOL(clear_user_page); void flush_kernel_dcache_page_addr(void *addr) { -- cgit v1.2.3