aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r--arch/sparc/mm/fault_32.c122
-rw-r--r--arch/sparc/mm/fault_64.c71
-rw-r--r--arch/sparc/mm/hugetlbpage.c1
-rw-r--r--arch/sparc/mm/init_32.c1
-rw-r--r--arch/sparc/mm/init_64.c7
-rw-r--r--arch/sparc/mm/nosun4c.c2
-rw-r--r--arch/sparc/mm/srmmu.c17
-rw-r--r--arch/sparc/mm/sun4c.c24
-rw-r--r--arch/sparc/mm/tsb.c1
9 files changed, 147 insertions, 99 deletions
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index b99f81c4906f..bd8601601afa 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -18,6 +18,7 @@
18#include <linux/signal.h> 18#include <linux/signal.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/smp.h> 20#include <linux/smp.h>
21#include <linux/perf_event.h>
21#include <linux/interrupt.h> 22#include <linux/interrupt.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/kdebug.h> 24#include <linux/kdebug.h>
@@ -34,6 +35,8 @@
34 35
35extern int prom_node_root; 36extern int prom_node_root;
36 37
38int show_unhandled_signals = 1;
39
37/* At boot time we determine these two values necessary for setting 40/* At boot time we determine these two values necessary for setting
38 * up the segment maps and page table entries (pte's). 41 * up the segment maps and page table entries (pte's).
39 */ 42 */
@@ -148,6 +151,45 @@ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
148 return 0; 151 return 0;
149} 152}
150 153
154static inline void
155show_signal_msg(struct pt_regs *regs, int sig, int code,
156 unsigned long address, struct task_struct *tsk)
157{
158 if (!unhandled_signal(tsk, sig))
159 return;
160
161 if (!printk_ratelimit())
162 return;
163
164 printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x",
165 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
166 tsk->comm, task_pid_nr(tsk), address,
167 (void *)regs->pc, (void *)regs->u_regs[UREG_I7],
168 (void *)regs->u_regs[UREG_FP], code);
169
170 print_vma_addr(KERN_CONT " in ", regs->pc);
171
172 printk(KERN_CONT "\n");
173}
174
175static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs,
176 unsigned long addr)
177{
178 siginfo_t info;
179
180 info.si_signo = sig;
181 info.si_code = code;
182 info.si_errno = 0;
183 info.si_addr = (void __user *) addr;
184 info.si_trapno = 0;
185
186 if (unlikely(show_unhandled_signals))
187 show_signal_msg(regs, sig, info.si_code,
188 addr, current);
189
190 force_sig_info (sig, &info, current);
191}
192
151extern unsigned long safe_compute_effective_address(struct pt_regs *, 193extern unsigned long safe_compute_effective_address(struct pt_regs *,
152 unsigned int); 194 unsigned int);
153 195
@@ -167,6 +209,14 @@ static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
167 return safe_compute_effective_address(regs, insn); 209 return safe_compute_effective_address(regs, insn);
168} 210}
169 211
212static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
213 int text_fault)
214{
215 unsigned long addr = compute_si_addr(regs, text_fault);
216
217 __do_fault_siginfo(code, sig, regs, addr);
218}
219
170asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, 220asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
171 unsigned long address) 221 unsigned long address)
172{ 222{
@@ -175,9 +225,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
175 struct mm_struct *mm = tsk->mm; 225 struct mm_struct *mm = tsk->mm;
176 unsigned int fixup; 226 unsigned int fixup;
177 unsigned long g2; 227 unsigned long g2;
178 siginfo_t info;
179 int from_user = !(regs->psr & PSR_PS); 228 int from_user = !(regs->psr & PSR_PS);
180 int fault; 229 int fault, code;
181 230
182 if(text_fault) 231 if(text_fault)
183 address = regs->pc; 232 address = regs->pc;
@@ -194,7 +243,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
194 if (!ARCH_SUN4C && address >= TASK_SIZE) 243 if (!ARCH_SUN4C && address >= TASK_SIZE)
195 goto vmalloc_fault; 244 goto vmalloc_fault;
196 245
197 info.si_code = SEGV_MAPERR; 246 code = SEGV_MAPERR;
198 247
199 /* 248 /*
200 * If we're in an interrupt or have no user 249 * If we're in an interrupt or have no user
@@ -203,6 +252,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
203 if (in_atomic() || !mm) 252 if (in_atomic() || !mm)
204 goto no_context; 253 goto no_context;
205 254
255 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
256
206 down_read(&mm->mmap_sem); 257 down_read(&mm->mmap_sem);
207 258
208 /* 259 /*
@@ -226,7 +277,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
226 * we can handle it.. 277 * we can handle it..
227 */ 278 */
228good_area: 279good_area:
229 info.si_code = SEGV_ACCERR; 280 code = SEGV_ACCERR;
230 if(write) { 281 if(write) {
231 if(!(vma->vm_flags & VM_WRITE)) 282 if(!(vma->vm_flags & VM_WRITE))
232 goto bad_area; 283 goto bad_area;
@@ -249,10 +300,15 @@ good_area:
249 goto do_sigbus; 300 goto do_sigbus;
250 BUG(); 301 BUG();
251 } 302 }
252 if (fault & VM_FAULT_MAJOR) 303 if (fault & VM_FAULT_MAJOR) {
253 current->maj_flt++; 304 current->maj_flt++;
254 else 305 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
306 regs, address);
307 } else {
255 current->min_flt++; 308 current->min_flt++;
309 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
310 regs, address);
311 }
256 up_read(&mm->mmap_sem); 312 up_read(&mm->mmap_sem);
257 return; 313 return;
258 314
@@ -265,18 +321,8 @@ bad_area:
265 321
266bad_area_nosemaphore: 322bad_area_nosemaphore:
267 /* User mode accesses just cause a SIGSEGV */ 323 /* User mode accesses just cause a SIGSEGV */
268 if(from_user) { 324 if (from_user) {
269#if 0 325 do_fault_siginfo(code, SIGSEGV, regs, text_fault);
270 printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n",
271 tsk->comm, tsk->pid, address, regs->pc);
272#endif
273 info.si_signo = SIGSEGV;
274 info.si_errno = 0;
275 /* info.si_code set above to make clear whether
276 this was a SEGV_MAPERR or SEGV_ACCERR fault. */
277 info.si_addr = (void __user *)compute_si_addr(regs, text_fault);
278 info.si_trapno = 0;
279 force_sig_info (SIGSEGV, &info, tsk);
280 return; 326 return;
281 } 327 }
282 328
@@ -327,12 +373,7 @@ out_of_memory:
327 373
328do_sigbus: 374do_sigbus:
329 up_read(&mm->mmap_sem); 375 up_read(&mm->mmap_sem);
330 info.si_signo = SIGBUS; 376 do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, text_fault);
331 info.si_errno = 0;
332 info.si_code = BUS_ADRERR;
333 info.si_addr = (void __user *) compute_si_addr(regs, text_fault);
334 info.si_trapno = 0;
335 force_sig_info (SIGBUS, &info, tsk);
336 if (!from_user) 377 if (!from_user)
337 goto no_context; 378 goto no_context;
338 379
@@ -370,7 +411,7 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
370 unsigned long address) 411 unsigned long address)
371{ 412{
372 extern void sun4c_update_mmu_cache(struct vm_area_struct *, 413 extern void sun4c_update_mmu_cache(struct vm_area_struct *,
373 unsigned long,pte_t); 414 unsigned long,pte_t *);
374 extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long); 415 extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long);
375 struct task_struct *tsk = current; 416 struct task_struct *tsk = current;
376 struct mm_struct *mm = tsk->mm; 417 struct mm_struct *mm = tsk->mm;
@@ -447,7 +488,7 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
447 * on the CPU and doing a shrink_mmap() on this vma. 488 * on the CPU and doing a shrink_mmap() on this vma.
448 */ 489 */
449 sun4c_update_mmu_cache (find_vma(current->mm, address), address, 490 sun4c_update_mmu_cache (find_vma(current->mm, address), address,
450 *ptep); 491 ptep);
451 else 492 else
452 do_sparc_fault(regs, text_fault, write, address); 493 do_sparc_fault(regs, text_fault, write, address);
453} 494}
@@ -458,14 +499,10 @@ static void force_user_fault(unsigned long address, int write)
458 struct vm_area_struct *vma; 499 struct vm_area_struct *vma;
459 struct task_struct *tsk = current; 500 struct task_struct *tsk = current;
460 struct mm_struct *mm = tsk->mm; 501 struct mm_struct *mm = tsk->mm;
461 siginfo_t info; 502 int code;
462 503
463 info.si_code = SEGV_MAPERR; 504 code = SEGV_MAPERR;
464 505
465#if 0
466 printk("wf<pid=%d,wr=%d,addr=%08lx>\n",
467 tsk->pid, write, address);
468#endif
469 down_read(&mm->mmap_sem); 506 down_read(&mm->mmap_sem);
470 vma = find_vma(mm, address); 507 vma = find_vma(mm, address);
471 if(!vma) 508 if(!vma)
@@ -477,7 +514,7 @@ static void force_user_fault(unsigned long address, int write)
477 if(expand_stack(vma, address)) 514 if(expand_stack(vma, address))
478 goto bad_area; 515 goto bad_area;
479good_area: 516good_area:
480 info.si_code = SEGV_ACCERR; 517 code = SEGV_ACCERR;
481 if(write) { 518 if(write) {
482 if(!(vma->vm_flags & VM_WRITE)) 519 if(!(vma->vm_flags & VM_WRITE))
483 goto bad_area; 520 goto bad_area;
@@ -494,27 +531,12 @@ good_area:
494 return; 531 return;
495bad_area: 532bad_area:
496 up_read(&mm->mmap_sem); 533 up_read(&mm->mmap_sem);
497#if 0 534 __do_fault_siginfo(code, SIGSEGV, tsk->thread.kregs, address);
498 printk("Window whee %s [%d]: segfaults at %08lx\n",
499 tsk->comm, tsk->pid, address);
500#endif
501 info.si_signo = SIGSEGV;
502 info.si_errno = 0;
503 /* info.si_code set above to make clear whether
504 this was a SEGV_MAPERR or SEGV_ACCERR fault. */
505 info.si_addr = (void __user *) address;
506 info.si_trapno = 0;
507 force_sig_info (SIGSEGV, &info, tsk);
508 return; 535 return;
509 536
510do_sigbus: 537do_sigbus:
511 up_read(&mm->mmap_sem); 538 up_read(&mm->mmap_sem);
512 info.si_signo = SIGBUS; 539 __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address);
513 info.si_errno = 0;
514 info.si_code = BUS_ADRERR;
515 info.si_addr = (void __user *) address;
516 info.si_trapno = 0;
517 force_sig_info (SIGBUS, &info, tsk);
518} 540}
519 541
520void window_overflow_fault(void) 542void window_overflow_fault(void)
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 43b0da96a4fb..f92ce56a8b22 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -16,6 +16,7 @@
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/perf_event.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
20#include <linux/kprobes.h> 21#include <linux/kprobes.h>
21#include <linux/kdebug.h> 22#include <linux/kdebug.h>
@@ -31,13 +32,14 @@
31#include <asm/sections.h> 32#include <asm/sections.h>
32#include <asm/mmu_context.h> 33#include <asm/mmu_context.h>
33 34
34#ifdef CONFIG_KPROBES 35int show_unhandled_signals = 1;
35static inline int notify_page_fault(struct pt_regs *regs) 36
37static inline __kprobes int notify_page_fault(struct pt_regs *regs)
36{ 38{
37 int ret = 0; 39 int ret = 0;
38 40
39 /* kprobe_running() needs smp_processor_id() */ 41 /* kprobe_running() needs smp_processor_id() */
40 if (!user_mode(regs)) { 42 if (kprobes_built_in() && !user_mode(regs)) {
41 preempt_disable(); 43 preempt_disable();
42 if (kprobe_running() && kprobe_fault_handler(regs, 0)) 44 if (kprobe_running() && kprobe_fault_handler(regs, 0))
43 ret = 1; 45 ret = 1;
@@ -45,12 +47,6 @@ static inline int notify_page_fault(struct pt_regs *regs)
45 } 47 }
46 return ret; 48 return ret;
47} 49}
48#else
49static inline int notify_page_fault(struct pt_regs *regs)
50{
51 return 0;
52}
53#endif
54 50
55static void __kprobes unhandled_fault(unsigned long address, 51static void __kprobes unhandled_fault(unsigned long address,
56 struct task_struct *tsk, 52 struct task_struct *tsk,
@@ -73,7 +69,7 @@ static void __kprobes unhandled_fault(unsigned long address,
73 die_if_kernel("Oops", regs); 69 die_if_kernel("Oops", regs);
74} 70}
75 71
76static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr) 72static void __kprobes bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
77{ 73{
78 printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", 74 printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
79 regs->tpc); 75 regs->tpc);
@@ -134,22 +130,48 @@ outret:
134 return insn; 130 return insn;
135} 131}
136 132
133static inline void
134show_signal_msg(struct pt_regs *regs, int sig, int code,
135 unsigned long address, struct task_struct *tsk)
136{
137 if (!unhandled_signal(tsk, sig))
138 return;
139
140 if (!printk_ratelimit())
141 return;
142
143 printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x",
144 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
145 tsk->comm, task_pid_nr(tsk), address,
146 (void *)regs->tpc, (void *)regs->u_regs[UREG_I7],
147 (void *)regs->u_regs[UREG_FP], code);
148
149 print_vma_addr(KERN_CONT " in ", regs->tpc);
150
151 printk(KERN_CONT "\n");
152}
153
137extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); 154extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int);
138 155
139static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, 156static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
140 unsigned int insn, int fault_code) 157 unsigned int insn, int fault_code)
141{ 158{
159 unsigned long addr;
142 siginfo_t info; 160 siginfo_t info;
143 161
144 info.si_code = code; 162 info.si_code = code;
145 info.si_signo = sig; 163 info.si_signo = sig;
146 info.si_errno = 0; 164 info.si_errno = 0;
147 if (fault_code & FAULT_CODE_ITLB) 165 if (fault_code & FAULT_CODE_ITLB)
148 info.si_addr = (void __user *) regs->tpc; 166 addr = regs->tpc;
149 else 167 else
150 info.si_addr = (void __user *) 168 addr = compute_effective_address(regs, insn, 0);
151 compute_effective_address(regs, insn, 0); 169 info.si_addr = (void __user *) addr;
152 info.si_trapno = 0; 170 info.si_trapno = 0;
171
172 if (unlikely(show_unhandled_signals))
173 show_signal_msg(regs, sig, code, addr, current);
174
153 force_sig_info(sig, &info, current); 175 force_sig_info(sig, &info, current);
154} 176}
155 177
@@ -170,8 +192,9 @@ static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn)
170 return insn; 192 return insn;
171} 193}
172 194
173static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, 195static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code,
174 unsigned int insn, unsigned long address) 196 int fault_code, unsigned int insn,
197 unsigned long address)
175{ 198{
176 unsigned char asi = ASI_P; 199 unsigned char asi = ASI_P;
177 200
@@ -225,7 +248,7 @@ cannot_handle:
225 unhandled_fault (address, current, regs); 248 unhandled_fault (address, current, regs);
226} 249}
227 250
228static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs) 251static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs)
229{ 252{
230 static int times; 253 static int times;
231 254
@@ -237,8 +260,8 @@ static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs)
237 show_regs(regs); 260 show_regs(regs);
238} 261}
239 262
240static void noinline bogus_32bit_fault_address(struct pt_regs *regs, 263static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
241 unsigned long addr) 264 unsigned long addr)
242{ 265{
243 static int times; 266 static int times;
244 267
@@ -302,6 +325,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
302 if (in_atomic() || !mm) 325 if (in_atomic() || !mm)
303 goto intr_or_no_mm; 326 goto intr_or_no_mm;
304 327
328 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
329
305 if (!down_read_trylock(&mm->mmap_sem)) { 330 if (!down_read_trylock(&mm->mmap_sem)) {
306 if ((regs->tstate & TSTATE_PRIV) && 331 if ((regs->tstate & TSTATE_PRIV) &&
307 !search_exception_tables(regs->tpc)) { 332 !search_exception_tables(regs->tpc)) {
@@ -406,11 +431,15 @@ good_area:
406 goto do_sigbus; 431 goto do_sigbus;
407 BUG(); 432 BUG();
408 } 433 }
409 if (fault & VM_FAULT_MAJOR) 434 if (fault & VM_FAULT_MAJOR) {
410 current->maj_flt++; 435 current->maj_flt++;
411 else 436 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
437 regs, address);
438 } else {
412 current->min_flt++; 439 current->min_flt++;
413 440 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
441 regs, address);
442 }
414 up_read(&mm->mmap_sem); 443 up_read(&mm->mmap_sem);
415 444
416 mm_rss = get_mm_rss(mm); 445 mm_rss = get_mm_rss(mm);
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index f27d10369e0c..5fdddf134caa 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -10,7 +10,6 @@
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/hugetlb.h> 11#include <linux/hugetlb.h>
12#include <linux/pagemap.h> 12#include <linux/pagemap.h>
13#include <linux/slab.h>
14#include <linux/sysctl.h> 13#include <linux/sysctl.h>
15 14
16#include <asm/mman.h> 15#include <asm/mman.h>
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index dc7c3b17a15f..6d0e02c4fe09 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -24,6 +24,7 @@
24#include <linux/bootmem.h> 24#include <linux/bootmem.h>
25#include <linux/pagemap.h> 25#include <linux/pagemap.h>
26#include <linux/poison.h> 26#include <linux/poison.h>
27#include <linux/gfp.h>
27 28
28#include <asm/sections.h> 29#include <asm/sections.h>
29#include <asm/system.h> 30#include <asm/system.h>
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 1886d37d411b..b2831dc3c121 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -13,7 +13,6 @@
13#include <linux/bootmem.h> 13#include <linux/bootmem.h>
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/hugetlb.h> 15#include <linux/hugetlb.h>
16#include <linux/slab.h>
17#include <linux/initrd.h> 16#include <linux/initrd.h>
18#include <linux/swap.h> 17#include <linux/swap.h>
19#include <linux/pagemap.h> 18#include <linux/pagemap.h>
@@ -26,6 +25,7 @@
26#include <linux/percpu.h> 25#include <linux/percpu.h>
27#include <linux/lmb.h> 26#include <linux/lmb.h>
28#include <linux/mmzone.h> 27#include <linux/mmzone.h>
28#include <linux/gfp.h>
29 29
30#include <asm/head.h> 30#include <asm/head.h>
31#include <asm/system.h> 31#include <asm/system.h>
@@ -289,12 +289,13 @@ static void flush_dcache(unsigned long pfn)
289 } 289 }
290} 290}
291 291
292void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) 292void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
293{ 293{
294 struct mm_struct *mm; 294 struct mm_struct *mm;
295 struct tsb *tsb; 295 struct tsb *tsb;
296 unsigned long tag, flags; 296 unsigned long tag, flags;
297 unsigned long tsb_index, tsb_hash_shift; 297 unsigned long tsb_index, tsb_hash_shift;
298 pte_t pte = *ptep;
298 299
299 if (tlb_type != hypervisor) { 300 if (tlb_type != hypervisor) {
300 unsigned long pfn = pte_pfn(pte); 301 unsigned long pfn = pte_pfn(pte);
@@ -2116,7 +2117,7 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
2116 "node=%d entry=%lu/%lu\n", start, block, nr, 2117 "node=%d entry=%lu/%lu\n", start, block, nr,
2117 node, 2118 node,
2118 addr >> VMEMMAP_CHUNK_SHIFT, 2119 addr >> VMEMMAP_CHUNK_SHIFT,
2119 VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT); 2120 VMEMMAP_SIZE);
2120 } 2121 }
2121 } 2122 }
2122 return 0; 2123 return 0;
diff --git a/arch/sparc/mm/nosun4c.c b/arch/sparc/mm/nosun4c.c
index 196263f895b7..4e62c27147c4 100644
--- a/arch/sparc/mm/nosun4c.c
+++ b/arch/sparc/mm/nosun4c.c
@@ -62,7 +62,7 @@ pte_t *sun4c_pte_offset_kernel(pmd_t *dir, unsigned long address)
62 return NULL; 62 return NULL;
63} 63}
64 64
65void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) 65void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
66{ 66{
67} 67}
68 68
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 509b1ffeba66..f5f75a58e0b3 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/slab.h>
14#include <linux/vmalloc.h> 13#include <linux/vmalloc.h>
15#include <linux/pagemap.h> 14#include <linux/pagemap.h>
16#include <linux/init.h> 15#include <linux/init.h>
@@ -20,6 +19,7 @@
20#include <linux/seq_file.h> 19#include <linux/seq_file.h>
21#include <linux/kdebug.h> 20#include <linux/kdebug.h>
22#include <linux/log2.h> 21#include <linux/log2.h>
22#include <linux/gfp.h>
23 23
24#include <asm/bitext.h> 24#include <asm/bitext.h>
25#include <asm/page.h> 25#include <asm/page.h>
@@ -694,7 +694,7 @@ extern void tsunami_setup_blockops(void);
694 * The following code is a deadwood that may be necessary when 694 * The following code is a deadwood that may be necessary when
695 * we start to make precise page flushes again. --zaitcev 695 * we start to make precise page flushes again. --zaitcev
696 */ 696 */
697static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) 697static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t *ptep)
698{ 698{
699#if 0 699#if 0
700 static unsigned long last; 700 static unsigned long last;
@@ -703,10 +703,10 @@ static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long ad
703 703
704 if (address == last) { 704 if (address == last) {
705 val = srmmu_hwprobe(address); 705 val = srmmu_hwprobe(address);
706 if (val != 0 && pte_val(pte) != val) { 706 if (val != 0 && pte_val(*ptep) != val) {
707 printk("swift_update_mmu_cache: " 707 printk("swift_update_mmu_cache: "
708 "addr %lx put %08x probed %08x from %p\n", 708 "addr %lx put %08x probed %08x from %p\n",
709 address, pte_val(pte), val, 709 address, pte_val(*ptep), val,
710 __builtin_return_address(0)); 710 __builtin_return_address(0));
711 srmmu_flush_whole_tlb(); 711 srmmu_flush_whole_tlb();
712 } 712 }
@@ -1990,7 +1990,7 @@ void __init poke_leonsparc(void)
1990void __init init_leon(void) 1990void __init init_leon(void)
1991{ 1991{
1992 1992
1993 srmmu_name = "Leon"; 1993 srmmu_name = "LEON";
1994 1994
1995 BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all, 1995 BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all,
1996 BTFIXUPCALL_NORM); 1996 BTFIXUPCALL_NORM);
@@ -2037,8 +2037,6 @@ static void __init get_srmmu_type(void)
2037 2037
2038 /* First, check for sparc-leon. */ 2038 /* First, check for sparc-leon. */
2039 if (sparc_cpu_model == sparc_leon) { 2039 if (sparc_cpu_model == sparc_leon) {
2040 psr_typ = 0xf; /* hardcoded ids for older models/simulators */
2041 psr_vers = 2;
2042 init_leon(); 2040 init_leon();
2043 return; 2041 return;
2044 } 2042 }
@@ -2301,7 +2299,8 @@ void __init ld_mmu_srmmu(void)
2301 BTFIXUPSET_CALL(flush_cache_mm, smp_flush_cache_mm, BTFIXUPCALL_NORM); 2299 BTFIXUPSET_CALL(flush_cache_mm, smp_flush_cache_mm, BTFIXUPCALL_NORM);
2302 BTFIXUPSET_CALL(flush_cache_range, smp_flush_cache_range, BTFIXUPCALL_NORM); 2300 BTFIXUPSET_CALL(flush_cache_range, smp_flush_cache_range, BTFIXUPCALL_NORM);
2303 BTFIXUPSET_CALL(flush_cache_page, smp_flush_cache_page, BTFIXUPCALL_NORM); 2301 BTFIXUPSET_CALL(flush_cache_page, smp_flush_cache_page, BTFIXUPCALL_NORM);
2304 if (sparc_cpu_model != sun4d) { 2302 if (sparc_cpu_model != sun4d &&
2303 sparc_cpu_model != sparc_leon) {
2305 BTFIXUPSET_CALL(flush_tlb_all, smp_flush_tlb_all, BTFIXUPCALL_NORM); 2304 BTFIXUPSET_CALL(flush_tlb_all, smp_flush_tlb_all, BTFIXUPCALL_NORM);
2306 BTFIXUPSET_CALL(flush_tlb_mm, smp_flush_tlb_mm, BTFIXUPCALL_NORM); 2305 BTFIXUPSET_CALL(flush_tlb_mm, smp_flush_tlb_mm, BTFIXUPCALL_NORM);
2307 BTFIXUPSET_CALL(flush_tlb_range, smp_flush_tlb_range, BTFIXUPCALL_NORM); 2306 BTFIXUPSET_CALL(flush_tlb_range, smp_flush_tlb_range, BTFIXUPCALL_NORM);
@@ -2330,6 +2329,8 @@ void __init ld_mmu_srmmu(void)
2330#ifdef CONFIG_SMP 2329#ifdef CONFIG_SMP
2331 if (sparc_cpu_model == sun4d) 2330 if (sparc_cpu_model == sun4d)
2332 sun4d_init_smp(); 2331 sun4d_init_smp();
2332 else if (sparc_cpu_model == sparc_leon)
2333 leon_init_smp();
2333 else 2334 else
2334 sun4m_init_smp(); 2335 sun4m_init_smp();
2335#endif 2336#endif
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 2ffacd67c424..cf38846753dd 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -12,11 +12,13 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/mm.h> 13#include <linux/mm.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h>
15#include <linux/bootmem.h> 16#include <linux/bootmem.h>
16#include <linux/highmem.h> 17#include <linux/highmem.h>
17#include <linux/fs.h> 18#include <linux/fs.h>
18#include <linux/seq_file.h> 19#include <linux/seq_file.h>
19#include <linux/scatterlist.h> 20#include <linux/scatterlist.h>
21#include <linux/bitmap.h>
20 22
21#include <asm/sections.h> 23#include <asm/sections.h>
22#include <asm/page.h> 24#include <asm/page.h>
@@ -1021,20 +1023,12 @@ static char *sun4c_lockarea(char *vaddr, unsigned long size)
1021 npages = (((unsigned long)vaddr & ~PAGE_MASK) + 1023 npages = (((unsigned long)vaddr & ~PAGE_MASK) +
1022 size + (PAGE_SIZE-1)) >> PAGE_SHIFT; 1024 size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
1023 1025
1024 scan = 0;
1025 local_irq_save(flags); 1026 local_irq_save(flags);
1026 for (;;) { 1027 base = bitmap_find_next_zero_area(sun4c_iobuffer_map, iobuffer_map_size,
1027 scan = find_next_zero_bit(sun4c_iobuffer_map, 1028 0, npages, 0);
1028 iobuffer_map_size, scan); 1029 if (base >= iobuffer_map_size)
1029 if ((base = scan) + npages > iobuffer_map_size) goto abend; 1030 goto abend;
1030 for (;;) {
1031 if (scan >= base + npages) goto found;
1032 if (test_bit(scan, sun4c_iobuffer_map)) break;
1033 scan++;
1034 }
1035 }
1036 1031
1037found:
1038 high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start; 1032 high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start;
1039 high = SUN4C_REAL_PGDIR_ALIGN(high); 1033 high = SUN4C_REAL_PGDIR_ALIGN(high);
1040 while (high > sun4c_iobuffer_high) { 1034 while (high > sun4c_iobuffer_high) {
@@ -1894,7 +1888,7 @@ static void sun4c_check_pgt_cache(int low, int high)
1894/* An experiment, turn off by default for now... -DaveM */ 1888/* An experiment, turn off by default for now... -DaveM */
1895#define SUN4C_PRELOAD_PSEG 1889#define SUN4C_PRELOAD_PSEG
1896 1890
1897void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) 1891void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
1898{ 1892{
1899 unsigned long flags; 1893 unsigned long flags;
1900 int pseg; 1894 int pseg;
@@ -1936,7 +1930,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
1936 start += PAGE_SIZE; 1930 start += PAGE_SIZE;
1937 } 1931 }
1938#ifndef SUN4C_PRELOAD_PSEG 1932#ifndef SUN4C_PRELOAD_PSEG
1939 sun4c_put_pte(address, pte_val(pte)); 1933 sun4c_put_pte(address, pte_val(*ptep));
1940#endif 1934#endif
1941 local_irq_restore(flags); 1935 local_irq_restore(flags);
1942 return; 1936 return;
@@ -1947,7 +1941,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
1947 add_lru(entry); 1941 add_lru(entry);
1948 } 1942 }
1949 1943
1950 sun4c_put_pte(address, pte_val(pte)); 1944 sun4c_put_pte(address, pte_val(*ptep));
1951 local_irq_restore(flags); 1945 local_irq_restore(flags);
1952} 1946}
1953 1947
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
index 36a0813f9517..101d7c82870b 100644
--- a/arch/sparc/mm/tsb.c
+++ b/arch/sparc/mm/tsb.c
@@ -5,6 +5,7 @@
5 5
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/preempt.h> 7#include <linux/preempt.h>
8#include <linux/slab.h>
8#include <asm/system.h> 9#include <asm/system.h>
9#include <asm/page.h> 10#include <asm/page.h>
10#include <asm/tlbflush.h> 11#include <asm/tlbflush.h>