@@ -94,7 +94,7 @@ void local_flush_tlb_all(void)
9494
9595 local_irq_save (flags );
9696 /* Save old context and create impossible VPN2 value */
97- old_ctx = read_c0_entryhi () & ASID_MASK ;
97+ old_ctx = read_c0_entryhi ();
9898 write_c0_entrylo0 (0 );
9999 write_c0_entrylo1 (0 );
100100
@@ -144,17 +144,17 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
144144 unsigned long end )
145145{
146146 struct mm_struct * mm = vma -> vm_mm ;
147- unsigned long flags ;
148- int cpu ;
147+ int cpu = smp_processor_id ();
149148
150- local_irq_save (flags );
151- cpu = smp_processor_id ();
152149 if (cpu_context (cpu , mm ) != 0 ) {
150+ unsigned long flags ;
153151 int size ;
152+
154153 size = (end - start + (PAGE_SIZE - 1 )) >> PAGE_SHIFT ;
155154 size = (size + 1 ) >> 1 ;
155+ local_irq_save (flags );
156156 if (size <= (current_cpu_data .tlbsize /2 )) {
157- int oldpid = read_c0_entryhi () & ASID_MASK ;
157+ int oldpid = read_c0_entryhi ();
158158 int newpid = cpu_asid (cpu , mm );
159159
160160 start &= (PAGE_MASK << 1 );
@@ -169,17 +169,17 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
169169 idx = read_c0_index ();
170170 write_c0_entrylo0 (0 );
171171 write_c0_entrylo1 (0 );
172- write_c0_entryhi (UNIQUE_ENTRYHI (idx ));
173172 if (idx < 0 )
174173 continue ;
174+ write_c0_entryhi (UNIQUE_ENTRYHI (idx ));
175175 tlb_write_indexed ();
176176 }
177177 write_c0_entryhi (oldpid );
178178 } else {
179179 drop_mmu_context (mm , cpu );
180180 }
181+ local_irq_restore (flags );
181182 }
182- local_irq_restore (flags );
183183}
184184
185185void local_flush_tlb_kernel_range (unsigned long start , unsigned long end )
@@ -189,7 +189,6 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
189189
190190 size = (end - start + (PAGE_SIZE - 1 )) >> PAGE_SHIFT ;
191191 size = (size + 1 ) >> 1 ;
192-
193192 local_irq_save (flags );
194193 if (size <= (current_cpu_data .tlbsize /2 )) {
195194 int pid = read_c0_entryhi ();
@@ -207,9 +206,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
207206 idx = read_c0_index ();
208207 write_c0_entrylo0 (0 );
209208 write_c0_entrylo1 (0 );
210- write_c0_entryhi (UNIQUE_ENTRYHI (idx ));
211209 if (idx < 0 )
212210 continue ;
211+ write_c0_entryhi (UNIQUE_ENTRYHI (idx ));
213212 tlb_write_indexed ();
214213 }
215214 write_c0_entryhi (pid );
@@ -221,15 +220,16 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
221220
222221void local_flush_tlb_page (struct vm_area_struct * vma , unsigned long page )
223222{
224- unsigned long flags ;
225223 int cpu = smp_processor_id ();
226224
227- local_irq_save (flags );
228225 if (cpu_context (cpu , vma -> vm_mm ) != 0 ) {
226+ unsigned long flags ;
229227 int oldpid , newpid , idx ;
228+
230229 newpid = cpu_asid (cpu , vma -> vm_mm );
231230 page &= (PAGE_MASK << 1 );
232- oldpid = read_c0_entryhi () & ASID_MASK ;
231+ local_irq_save (flags );
232+ oldpid = read_c0_entryhi ();
233233 write_c0_entryhi (page | newpid );
234234 tlb_probe ();
235235 idx = read_c0_index ();
@@ -240,10 +240,11 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
240240 /* Make sure all entries differ. */
241241 write_c0_entryhi (UNIQUE_ENTRYHI (idx ));
242242 tlb_write_indexed ();
243+
243244 finish :
244245 write_c0_entryhi (oldpid );
246+ local_irq_restore (flags );
245247 }
246- local_irq_restore (flags );
247248}
248249
249250/*
@@ -255,18 +256,17 @@ void local_flush_tlb_one(unsigned long page)
255256 unsigned long flags ;
256257 int oldpid , idx ;
257258
258- page &= (PAGE_MASK << 1 );
259- oldpid = read_c0_entryhi () & ASID_MASK ;
260-
261259 local_irq_save (flags );
260+ oldpid = read_c0_entryhi ();
261+ page &= (PAGE_MASK << 1 );
262262 write_c0_entryhi (page );
263263 tlb_probe ();
264264 idx = read_c0_index ();
265+ write_c0_entrylo0 (0 );
266+ write_c0_entrylo1 (0 );
265267 if (idx >= 0 ) {
266268 /* Make sure all entries differ. */
267269 write_c0_entryhi (UNIQUE_ENTRYHI (idx ));
268- write_c0_entrylo0 (0 );
269- write_c0_entrylo1 (0 );
270270 tlb_write_indexed ();
271271 }
272272
@@ -297,6 +297,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
297297{
298298 unsigned long flags ;
299299 pgd_t * pgdp ;
300+ pud_t * pudp ;
300301 pmd_t * pmdp ;
301302 pte_t * ptep ;
302303 int idx , pid ;
@@ -311,19 +312,26 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
311312
312313 pid = read_c0_entryhi () & ASID_MASK ;
313314 address &= (PAGE_MASK << 1 );
314- write_c0_entryhi (address | ( pid ) );
315+ write_c0_entryhi (address | pid );
315316 pgdp = pgd_offset (vma -> vm_mm , address );
316317 tlb_probe ();
317- pmdp = pmd_offset (pgdp , address );
318+ pudp = pud_offset (pgdp , address );
319+ pmdp = pmd_offset (pudp , address );
318320 idx = read_c0_index ();
319321 ptep = pte_offset_map (pmdp , address );
322+
323+ #if defined(CONFIG_64BIT_PHYS_ADDR ) && defined(CONFIG_CPU_MIPS32 )
324+ write_c0_entrylo0 (ptep -> pte_high );
325+ ptep ++ ;
326+ write_c0_entrylo1 (ptep -> pte_high );
327+ #else
320328 write_c0_entrylo0 (pte_val (* ptep ++ ) >> 6 );
321329 write_c0_entrylo1 (pte_val (* ptep ) >> 6 );
322- if (idx < 0 ) {
330+ #endif
331+ if (idx < 0 )
323332 tlb_write_random ();
324- } else {
333+ else
325334 tlb_write_indexed ();
326- }
327335 local_irq_restore (flags );
328336}
329337
@@ -336,7 +344,8 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
336344 unsigned long old_ctx ;
337345
338346 local_irq_save (flags );
339- old_ctx = read_c0_entryhi () & 0xff ;
347+ /* Save old context and create impossible VPN2 value */
348+ old_ctx = read_c0_entryhi ();
340349 old_pagemask = read_c0_pagemask ();
341350 wired = read_c0_wired ();
342351 write_c0_wired (wired + 1 );
0 commit comments