aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/context.c')
-rw-r--r--arch/arm/mm/context.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index b0ee9ba3cfab..8bfae964b133 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -24,9 +24,7 @@ DEFINE_PER_CPU(struct mm_struct *, current_mm);
24 24
25/* 25/*
26 * We fork()ed a process, and we need a new context for the child 26 * We fork()ed a process, and we need a new context for the child
27 * to run in. We reserve version 0 for initial tasks so we will 27 * to run in.
28 * always allocate an ASID. The ASID 0 is reserved for the TTBR
29 * register changing sequence.
30 */ 28 */
31void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) 29void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
32{ 30{
@@ -36,8 +34,11 @@ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
36 34
37static void flush_context(void) 35static void flush_context(void)
38{ 36{
39 /* set the reserved ASID before flushing the TLB */ 37 u32 ttb;
40 asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (0)); 38 /* Copy TTBR1 into TTBR0 */
39 asm volatile("mrc p15, 0, %0, c2, c0, 1\n"
40 "mcr p15, 0, %0, c2, c0, 0"
41 : "=r" (ttb));
41 isb(); 42 isb();
42 local_flush_tlb_all(); 43 local_flush_tlb_all();
43 if (icache_is_vivt_asid_tagged()) { 44 if (icache_is_vivt_asid_tagged()) {
@@ -93,7 +94,7 @@ static void reset_context(void *info)
93 return; 94 return;
94 95
95 smp_rmb(); 96 smp_rmb();
96 asid = cpu_last_asid + cpu + 1; 97 asid = cpu_last_asid + cpu;
97 98
98 flush_context(); 99 flush_context();
99 set_mm_context(mm, asid); 100 set_mm_context(mm, asid);
@@ -143,13 +144,13 @@ void __new_context(struct mm_struct *mm)
143 * to start a new version and flush the TLB. 144 * to start a new version and flush the TLB.
144 */ 145 */
145 if (unlikely((asid & ~ASID_MASK) == 0)) { 146 if (unlikely((asid & ~ASID_MASK) == 0)) {
146 asid = cpu_last_asid + smp_processor_id() + 1; 147 asid = cpu_last_asid + smp_processor_id();
147 flush_context(); 148 flush_context();
148#ifdef CONFIG_SMP 149#ifdef CONFIG_SMP
149 smp_wmb(); 150 smp_wmb();
150 smp_call_function(reset_context, NULL, 1); 151 smp_call_function(reset_context, NULL, 1);
151#endif 152#endif
152 cpu_last_asid += NR_CPUS; 153 cpu_last_asid += NR_CPUS - 1;
153 } 154 }
154 155
155 set_mm_context(mm, asid); 156 set_mm_context(mm, asid);