aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/highmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/highmem.c')
-rw-r--r--arch/arm/mm/highmem.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index e05e8ad26ba5..45aeaaca9052 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -18,6 +18,21 @@
18#include <asm/tlbflush.h> 18#include <asm/tlbflush.h>
19#include "mm.h" 19#include "mm.h"
20 20
21pte_t *fixmap_page_table;
22
23static inline void set_fixmap_pte(int idx, pte_t pte)
24{
25 unsigned long vaddr = __fix_to_virt(idx);
26 set_pte_ext(fixmap_page_table + idx, pte, 0);
27 local_flush_tlb_kernel_page(vaddr);
28}
29
30static inline pte_t get_fixmap_pte(unsigned long vaddr)
31{
32 unsigned long idx = __virt_to_fix(vaddr);
33 return *(fixmap_page_table + idx);
34}
35
21void *kmap(struct page *page) 36void *kmap(struct page *page)
22{ 37{
23 might_sleep(); 38 might_sleep();
@@ -69,14 +84,14 @@ void *kmap_atomic(struct page *page)
69 * With debugging enabled, kunmap_atomic forces that entry to 0. 84 * With debugging enabled, kunmap_atomic forces that entry to 0.
70 * Make sure it was indeed properly unmapped. 85 * Make sure it was indeed properly unmapped.
71 */ 86 */
72 BUG_ON(!pte_none(get_top_pte(vaddr))); 87 BUG_ON(!pte_none(*(fixmap_page_table + idx)));
73#endif 88#endif
74 /* 89 /*
75 * When debugging is off, kunmap_atomic leaves the previous mapping 90 * When debugging is off, kunmap_atomic leaves the previous mapping
76 * in place, so the contained TLB flush ensures the TLB is updated 91 * in place, so the contained TLB flush ensures the TLB is updated
77 * with the new mapping. 92 * with the new mapping.
78 */ 93 */
79 set_top_pte(vaddr, mk_pte(page, kmap_prot)); 94 set_fixmap_pte(idx, mk_pte(page, kmap_prot));
80 95
81 return (void *)vaddr; 96 return (void *)vaddr;
82} 97}
@@ -95,7 +110,7 @@ void __kunmap_atomic(void *kvaddr)
95 __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); 110 __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
96#ifdef CONFIG_DEBUG_HIGHMEM 111#ifdef CONFIG_DEBUG_HIGHMEM
97 BUG_ON(vaddr != __fix_to_virt(idx)); 112 BUG_ON(vaddr != __fix_to_virt(idx));
98 set_top_pte(vaddr, __pte(0)); 113 set_fixmap_pte(idx, __pte(0));
99#else 114#else
100 (void) idx; /* to kill a warning */ 115 (void) idx; /* to kill a warning */
101#endif 116#endif
@@ -119,9 +134,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
119 idx = type + KM_TYPE_NR * smp_processor_id(); 134 idx = type + KM_TYPE_NR * smp_processor_id();
120 vaddr = __fix_to_virt(idx); 135 vaddr = __fix_to_virt(idx);
121#ifdef CONFIG_DEBUG_HIGHMEM 136#ifdef CONFIG_DEBUG_HIGHMEM
122 BUG_ON(!pte_none(get_top_pte(vaddr))); 137 BUG_ON(!pte_none(*(fixmap_page_table + idx)));
123#endif 138#endif
124 set_top_pte(vaddr, pfn_pte(pfn, kmap_prot)); 139 set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
125 140
126 return (void *)vaddr; 141 return (void *)vaddr;
127} 142}
@@ -133,5 +148,5 @@ struct page *kmap_atomic_to_page(const void *ptr)
133 if (vaddr < FIXADDR_START) 148 if (vaddr < FIXADDR_START)
134 return virt_to_page(ptr); 149 return virt_to_page(ptr);
135 150
136 return pte_page(get_top_pte(vaddr)); 151 return pte_page(get_fixmap_pte(vaddr));
137} 152}