aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-04-25 04:42:42 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-04-25 04:42:42 -0400
commita126f7c41d80322b42ae0383ed3dcb17ee0296fc (patch)
tree67f3605e72e01f7ec0b15af22d9d7b6ef8598b55 /arch/arm/mm
parent0098fc39e6d575f940487f09f303787efbc7a373 (diff)
parenta7eb7c6f9a657a01a8359edae31bbeacd18b072c (diff)
Merge branch 'mcpm' of git://git.linaro.org/people/nico/linux into devel-stable
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/context.c29
-rw-r--r--arch/arm/mm/dma-mapping.c5
-rw-r--r--arch/arm/mm/idmap.c1
-rw-r--r--arch/arm/mm/proc-v7-3level.S2
4 files changed, 23 insertions, 14 deletions
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 7a0511191f6b..a5a4b2bc42ba 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -152,9 +152,9 @@ static int is_reserved_asid(u64 asid)
152 return 0; 152 return 0;
153} 153}
154 154
155static void new_context(struct mm_struct *mm, unsigned int cpu) 155static u64 new_context(struct mm_struct *mm, unsigned int cpu)
156{ 156{
157 u64 asid = mm->context.id; 157 u64 asid = atomic64_read(&mm->context.id);
158 u64 generation = atomic64_read(&asid_generation); 158 u64 generation = atomic64_read(&asid_generation);
159 159
160 if (asid != 0 && is_reserved_asid(asid)) { 160 if (asid != 0 && is_reserved_asid(asid)) {
@@ -181,13 +181,14 @@ static void new_context(struct mm_struct *mm, unsigned int cpu)
181 cpumask_clear(mm_cpumask(mm)); 181 cpumask_clear(mm_cpumask(mm));
182 } 182 }
183 183
184 mm->context.id = asid; 184 return asid;
185} 185}
186 186
187void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) 187void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
188{ 188{
189 unsigned long flags; 189 unsigned long flags;
190 unsigned int cpu = smp_processor_id(); 190 unsigned int cpu = smp_processor_id();
191 u64 asid;
191 192
192 if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq)) 193 if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
193 __check_vmalloc_seq(mm); 194 __check_vmalloc_seq(mm);
@@ -198,20 +199,26 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
198 */ 199 */
199 cpu_set_reserved_ttbr0(); 200 cpu_set_reserved_ttbr0();
200 201
201 if (!((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS) 202 asid = atomic64_read(&mm->context.id);
202 && atomic64_xchg(&per_cpu(active_asids, cpu), mm->context.id)) 203 if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)
204 && atomic64_xchg(&per_cpu(active_asids, cpu), asid))
203 goto switch_mm_fastpath; 205 goto switch_mm_fastpath;
204 206
205 raw_spin_lock_irqsave(&cpu_asid_lock, flags); 207 raw_spin_lock_irqsave(&cpu_asid_lock, flags);
206 /* Check that our ASID belongs to the current generation. */ 208 /* Check that our ASID belongs to the current generation. */
207 if ((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS) 209 asid = atomic64_read(&mm->context.id);
208 new_context(mm, cpu); 210 if ((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) {
209 211 asid = new_context(mm, cpu);
210 atomic64_set(&per_cpu(active_asids, cpu), mm->context.id); 212 atomic64_set(&mm->context.id, asid);
211 cpumask_set_cpu(cpu, mm_cpumask(mm)); 213 }
212 214
213 if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) 215 if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) {
216 local_flush_bp_all();
214 local_flush_tlb_all(); 217 local_flush_tlb_all();
218 }
219
220 atomic64_set(&per_cpu(active_asids, cpu), asid);
221 cpumask_set_cpu(cpu, mm_cpumask(mm));
215 raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); 222 raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
216 223
217switch_mm_fastpath: 224switch_mm_fastpath:
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c7e3759f16d3..e9db6b4bf65a 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -342,6 +342,7 @@ static int __init atomic_pool_init(void)
342{ 342{
343 struct dma_pool *pool = &atomic_pool; 343 struct dma_pool *pool = &atomic_pool;
344 pgprot_t prot = pgprot_dmacoherent(pgprot_kernel); 344 pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
345 gfp_t gfp = GFP_KERNEL | GFP_DMA;
345 unsigned long nr_pages = pool->size >> PAGE_SHIFT; 346 unsigned long nr_pages = pool->size >> PAGE_SHIFT;
346 unsigned long *bitmap; 347 unsigned long *bitmap;
347 struct page *page; 348 struct page *page;
@@ -361,8 +362,8 @@ static int __init atomic_pool_init(void)
361 ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page, 362 ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page,
362 atomic_pool_init); 363 atomic_pool_init);
363 else 364 else
364 ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot, 365 ptr = __alloc_remap_buffer(NULL, pool->size, gfp, prot, &page,
365 &page, atomic_pool_init); 366 atomic_pool_init);
366 if (ptr) { 367 if (ptr) {
367 int i; 368 int i;
368 369
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 2dffc010cc41..5ee505c937d1 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -141,6 +141,7 @@ void setup_mm_for_reboot(void)
141{ 141{
142 /* Switch to the identity mapping. */ 142 /* Switch to the identity mapping. */
143 cpu_switch_mm(idmap_pgd, &init_mm); 143 cpu_switch_mm(idmap_pgd, &init_mm);
144 local_flush_bp_all();
144 145
145#ifdef CONFIG_CPU_HAS_ASID 146#ifdef CONFIG_CPU_HAS_ASID
146 /* 147 /*
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 50bf1dafc9ea..6ffd78c0f9ab 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -48,7 +48,7 @@
48ENTRY(cpu_v7_switch_mm) 48ENTRY(cpu_v7_switch_mm)
49#ifdef CONFIG_MMU 49#ifdef CONFIG_MMU
50 mmid r1, r1 @ get mm->context.id 50 mmid r1, r1 @ get mm->context.id
51 and r3, r1, #0xff 51 asid r3, r1
52 mov r3, r3, lsl #(48 - 32) @ ASID 52 mov r3, r3, lsl #(48 - 32) @ ASID
53 mcrr p15, 0, r0, r3, c2 @ set TTB 0 53 mcrr p15, 0, r0, r3, c2 @ set TTB 0
54 isb 54 isb