1e3e26b538c26ab22ceb949e6728e39484971955
[glsdk/meta-ti-glsdk.git] / recipes-bsp / linux / linux-omap / linus / 0003-ARM-get-rid-of-kmap_high_l1_vipt.patch
1 From 39af22a79232373764904576f31572f1db76af10 Mon Sep 17 00:00:00 2001
2 From: Nicolas Pitre <nicolas.pitre@linaro.org>
3 Date: Wed, 15 Dec 2010 15:14:45 -0500
4 Subject: [PATCH 03/66] ARM: get rid of kmap_high_l1_vipt()
6 Since commit 3e4d3af501 "mm: stack based kmap_atomic()", it is no longer
7 necessary to carry an ad hoc version of kmap_atomic() added in commit
8 7e5a69e83b "ARM: 6007/1: fix highmem with VIPT cache and DMA" to cope
9 with reentrancy.
11 In fact, it is now actively wrong to rely on fixed kmap type indices
12 (namely KM_L1_CACHE) as kmap_atomic() totally ignores them now and a
13 concurrent instance of it may reuse any slot for any purpose.
15 Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
16 ---
17 arch/arm/include/asm/highmem.h | 3 -
18 arch/arm/mm/dma-mapping.c | 7 ++-
19 arch/arm/mm/flush.c | 7 ++-
20 arch/arm/mm/highmem.c | 87 ----------------------------------------
21 4 files changed, 8 insertions(+), 96 deletions(-)
23 diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
24 index 1fc684e..7080e2c 100644
25 --- a/arch/arm/include/asm/highmem.h
26 +++ b/arch/arm/include/asm/highmem.h
27 @@ -25,9 +25,6 @@ extern void *kmap_high(struct page *page);
28 extern void *kmap_high_get(struct page *page);
29 extern void kunmap_high(struct page *page);
31 -extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
32 -extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
33 -
34 /*
35 * The following functions are already defined by <linux/highmem.h>
36 * when CONFIG_HIGHMEM is not set.
37 diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
38 index ac6a361..809f1bf 100644
39 --- a/arch/arm/mm/dma-mapping.c
40 +++ b/arch/arm/mm/dma-mapping.c
41 @@ -17,6 +17,7 @@
42 #include <linux/init.h>
43 #include <linux/device.h>
44 #include <linux/dma-mapping.h>
45 +#include <linux/highmem.h>
47 #include <asm/memory.h>
48 #include <asm/highmem.h>
49 @@ -480,10 +481,10 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
50 op(vaddr, len, dir);
51 kunmap_high(page);
52 } else if (cache_is_vipt()) {
53 - pte_t saved_pte;
54 - vaddr = kmap_high_l1_vipt(page, &saved_pte);
55 + /* unmapped pages might still be cached */
56 + vaddr = kmap_atomic(page);
57 op(vaddr + offset, len, dir);
58 - kunmap_high_l1_vipt(page, saved_pte);
59 + kunmap_atomic(vaddr);
60 }
61 } else {
62 vaddr = page_address(page) + offset;
63 diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
64 index 391ffae..c29f283 100644
65 --- a/arch/arm/mm/flush.c
66 +++ b/arch/arm/mm/flush.c
67 @@ -10,6 +10,7 @@
68 #include <linux/module.h>
69 #include <linux/mm.h>
70 #include <linux/pagemap.h>
71 +#include <linux/highmem.h>
73 #include <asm/cacheflush.h>
74 #include <asm/cachetype.h>
75 @@ -180,10 +181,10 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
76 __cpuc_flush_dcache_area(addr, PAGE_SIZE);
77 kunmap_high(page);
78 } else if (cache_is_vipt()) {
79 - pte_t saved_pte;
80 - addr = kmap_high_l1_vipt(page, &saved_pte);
81 + /* unmapped pages might still be cached */
82 + addr = kmap_atomic(page);
83 __cpuc_flush_dcache_area(addr, PAGE_SIZE);
84 - kunmap_high_l1_vipt(page, saved_pte);
85 + kunmap_atomic(addr);
86 }
87 }
89 diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
90 index c435fd9..807c057 100644
91 --- a/arch/arm/mm/highmem.c
92 +++ b/arch/arm/mm/highmem.c
93 @@ -140,90 +140,3 @@ struct page *kmap_atomic_to_page(const void *ptr)
94 pte = TOP_PTE(vaddr);
95 return pte_page(*pte);
96 }
97 -
98 -#ifdef CONFIG_CPU_CACHE_VIPT
99 -
100 -#include <linux/percpu.h>
101 -
102 -/*
103 - * The VIVT cache of a highmem page is always flushed before the page
104 - * is unmapped. Hence unmapped highmem pages need no cache maintenance
105 - * in that case.
106 - *
107 - * However unmapped pages may still be cached with a VIPT cache, and
108 - * it is not possible to perform cache maintenance on them using physical
109 - * addresses unfortunately. So we have no choice but to set up a temporary
110 - * virtual mapping for that purpose.
111 - *
112 - * Yet this VIPT cache maintenance may be triggered from DMA support
113 - * functions which are possibly called from interrupt context. As we don't
114 - * want to keep interrupt disabled all the time when such maintenance is
115 - * taking place, we therefore allow for some reentrancy by preserving and
116 - * restoring the previous fixmap entry before the interrupted context is
117 - * resumed. If the reentrancy depth is 0 then there is no need to restore
118 - * the previous fixmap, and leaving the current one in place allow it to
119 - * be reused the next time without a TLB flush (common with DMA).
120 - */
121 -
122 -static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
123 -
124 -void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
125 -{
126 - unsigned int idx, cpu;
127 - int *depth;
128 - unsigned long vaddr, flags;
129 - pte_t pte, *ptep;
130 -
131 - if (!in_interrupt())
132 - preempt_disable();
133 -
134 - cpu = smp_processor_id();
135 - depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
136 -
137 - idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
138 - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
139 - ptep = TOP_PTE(vaddr);
140 - pte = mk_pte(page, kmap_prot);
141 -
142 - raw_local_irq_save(flags);
143 - (*depth)++;
144 - if (pte_val(*ptep) == pte_val(pte)) {
145 - *saved_pte = pte;
146 - } else {
147 - *saved_pte = *ptep;
148 - set_pte_ext(ptep, pte, 0);
149 - local_flush_tlb_kernel_page(vaddr);
150 - }
151 - raw_local_irq_restore(flags);
152 -
153 - return (void *)vaddr;
154 -}
155 -
156 -void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
157 -{
158 - unsigned int idx, cpu = smp_processor_id();
159 - int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
160 - unsigned long vaddr, flags;
161 - pte_t pte, *ptep;
162 -
163 - idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
164 - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
165 - ptep = TOP_PTE(vaddr);
166 - pte = mk_pte(page, kmap_prot);
167 -
168 - BUG_ON(pte_val(*ptep) != pte_val(pte));
169 - BUG_ON(*depth <= 0);
170 -
171 - raw_local_irq_save(flags);
172 - (*depth)--;
173 - if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
174 - set_pte_ext(ptep, saved_pte, 0);
175 - local_flush_tlb_kernel_page(vaddr);
176 - }
177 - raw_local_irq_restore(flags);
178 -
179 - if (!in_interrupt())
180 - preempt_enable();
181 -}
182 -
183 -#endif /* CONFIG_CPU_CACHE_VIPT */
184 --
185 1.6.6.1