diff options
Diffstat (limited to 'arch/arm/mm/highmem.c')
| -rw-r--r-- | arch/arm/mm/highmem.c | 33 | 
1 files changed, 24 insertions, 9 deletions
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 21b9e1bf9b7..45aeaaca905 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -18,6 +18,21 @@  #include <asm/tlbflush.h>  #include "mm.h" +pte_t *fixmap_page_table; + +static inline void set_fixmap_pte(int idx, pte_t pte) +{ +	unsigned long vaddr = __fix_to_virt(idx); +	set_pte_ext(fixmap_page_table + idx, pte, 0); +	local_flush_tlb_kernel_page(vaddr); +} + +static inline pte_t get_fixmap_pte(unsigned long vaddr) +{ +	unsigned long idx = __virt_to_fix(vaddr); +	return *(fixmap_page_table + idx); +} +  void *kmap(struct page *page)  {  	might_sleep(); @@ -63,20 +78,20 @@ void *kmap_atomic(struct page *page)  	type = kmap_atomic_idx_push();  	idx = type + KM_TYPE_NR * smp_processor_id(); -	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +	vaddr = __fix_to_virt(idx);  #ifdef CONFIG_DEBUG_HIGHMEM  	/*  	 * With debugging enabled, kunmap_atomic forces that entry to 0.  	 * Make sure it was indeed properly unmapped.  	 */ -	BUG_ON(!pte_none(get_top_pte(vaddr))); +	BUG_ON(!pte_none(*(fixmap_page_table + idx)));  #endif  	/*  	 * When debugging is off, kunmap_atomic leaves the previous mapping  	 * in place, so the contained TLB flush ensures the TLB is updated  	 * with the new mapping.  	 */ -	set_top_pte(vaddr, mk_pte(page, kmap_prot)); +	set_fixmap_pte(idx, mk_pte(page, kmap_prot));  	return (void *)vaddr;  } @@ -94,8 +109,8 @@ void __kunmap_atomic(void *kvaddr)  		if (cache_is_vivt())  			__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);  #ifdef CONFIG_DEBUG_HIGHMEM -		BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); -		set_top_pte(vaddr, __pte(0)); +		BUG_ON(vaddr != __fix_to_virt(idx)); +		set_fixmap_pte(idx, __pte(0));  #else  		(void) idx;  /* to kill a warning */  #endif @@ -117,11 +132,11 @@ void *kmap_atomic_pfn(unsigned long pfn)  	type = kmap_atomic_idx_push();  	idx = type + KM_TYPE_NR * smp_processor_id(); -	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +	vaddr = __fix_to_virt(idx);  #ifdef CONFIG_DEBUG_HIGHMEM -	BUG_ON(!pte_none(get_top_pte(vaddr))); +	BUG_ON(!pte_none(*(fixmap_page_table + idx)));  #endif -	set_top_pte(vaddr, pfn_pte(pfn, kmap_prot)); +	set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));  	return (void *)vaddr;  } @@ -133,5 +148,5 @@ struct page *kmap_atomic_to_page(const void *ptr)  	if (vaddr < FIXADDR_START)  		return virt_to_page(ptr); -	return pte_page(get_top_pte(vaddr)); +	return pte_page(get_fixmap_pte(vaddr));  }  | 
