From bb86bf28aec6d0a207ae09f38a43e94133d4d6db Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 25 Apr 2009 11:25:34 +0200 Subject: MIPS: Fix highmem. Commit 351336929ccf222ae38ff0cb7a8dd5fd5c6236a0 (kernel.org) rsp. b3594a089f1c17ff919f8f78505c3f20e1f6f8ce (linux-mips.org): > From: Chris Dearman > Date: Wed, 19 Sep 2007 00:58:24 +0100 > Subject: [PATCH] [MIPS] Allow setting of the cache attribute at run time. > > Slightly tacky, but there is a precedent in the sparc archirecture code. introduces the variable _page_cachable_default, which defaults to zero and. is used to create the prototype PTE for __kmap_atomic in arch/mips/mm/init.c:kmap_init before initialization in arch/mips/mm/c-r4k.c:coherency_setup, so the default value of 0 will be used as the CCA of kmap atomic pages which on many processors is not a defined CCA value and may result in writes to kmap_atomic pages getting corrupted. Debugged by Jon Fraser (jfraser@broadcom.com). Signed-off-by: Ralf Baechle --- arch/mips/mm/highmem.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'arch/mips/mm/highmem.c') diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 4481656d106..2b1309b2580 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -1,7 +1,12 @@ #include #include +#include #include +static pte_t *kmap_pte; + +unsigned long highstart_pfn, highend_pfn; + void *__kmap(struct page *page) { void *addr; @@ -14,6 +19,7 @@ void *__kmap(struct page *page) return addr; } +EXPORT_SYMBOL(__kmap); void __kunmap(struct page *page) { @@ -22,6 +28,7 @@ void __kunmap(struct page *page) return; kunmap_high(page); } +EXPORT_SYMBOL(__kunmap); /* * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because @@ -48,11 +55,12 @@ void *__kmap_atomic(struct page *page, enum km_type type) #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(!pte_none(*(kmap_pte - idx))); #endif - set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL)); local_flush_tlb_one((unsigned long)vaddr); return (void*) vaddr; } +EXPORT_SYMBOL(__kmap_atomic); void __kunmap_atomic(void *kvaddr, enum km_type type) { @@ -77,6 +85,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) pagefault_enable(); } +EXPORT_SYMBOL(__kunmap_atomic); /* * This is the same as kmap_atomic() but can map memory that doesn't @@ -92,7 +101,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); + set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL)); flush_tlb_one(vaddr); return (void*) vaddr; @@ -111,7 +120,11 @@ struct page *__kmap_atomic_to_page(void *ptr) return pte_page(*pte); } -EXPORT_SYMBOL(__kmap); -EXPORT_SYMBOL(__kunmap); -EXPORT_SYMBOL(__kmap_atomic); -EXPORT_SYMBOL(__kunmap_atomic); +void __init kmap_init(void) +{ + unsigned long kmap_vstart; + + /* cache the first kmap pte */ + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); + kmap_pte = kmap_get_fixmap_pte(kmap_vstart); +} -- cgit v1.2.3