File: /usr/src/linux/arch/ppc/mm/fault.c

1     /*
2      * BK Id: SCCS/s.fault.c 1.13 06/28/01 15:50:17 paulus
3      */
4     /*
5      *  arch/ppc/mm/fault.c
6      *
7      *  PowerPC version 
8      *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
9      *
10      *  Derived from "arch/i386/mm/fault.c"
11      *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
12      *
13      *  Modified by Cort Dougan and Paul Mackerras.
14      *
15      *  This program is free software; you can redistribute it and/or
16      *  modify it under the terms of the GNU General Public License
17      *  as published by the Free Software Foundation; either version
18      *  2 of the License, or (at your option) any later version.
19      */
20     
21     #include <linux/config.h>
22     #include <linux/signal.h>
23     #include <linux/sched.h>
24     #include <linux/kernel.h>
25     #include <linux/errno.h>
26     #include <linux/string.h>
27     #include <linux/types.h>
28     #include <linux/ptrace.h>
29     #include <linux/mman.h>
30     #include <linux/mm.h>
31     #include <linux/interrupt.h>
32     
33     #include <asm/page.h>
34     #include <asm/pgtable.h>
35     #include <asm/mmu.h>
36     #include <asm/mmu_context.h>
37     #include <asm/system.h>
38     #include <asm/uaccess.h>
39     
40     #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
41     extern void (*debugger)(struct pt_regs *);
42     extern void (*debugger_fault_handler)(struct pt_regs *);
43     extern int (*debugger_dabr_match)(struct pt_regs *);
44     int debugger_kernel_faults = 1;
45     #endif
46     
47     unsigned long htab_reloads;	/* updated by hashtable.S:hash_page() */
48     unsigned long htab_evicts; 	/* updated by hashtable.S:hash_page() */
49     unsigned long htab_preloads;	/* updated by hashtable.S:add_hash_page() */
50     unsigned long pte_misses;	/* updated by do_page_fault() */
51     unsigned long pte_errors;	/* updated by do_page_fault() */
52     unsigned int probingmem;
53     
54     extern void die_if_kernel(char *, struct pt_regs *, long);
55     void bad_page_fault(struct pt_regs *, unsigned long, int sig);
56     void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
57     
58     /*
59      * For 600- and 800-family processors, the error_code parameter is DSISR
60      * for a data fault, SRR1 for an instruction fault. For 400-family processors
61      * the error_code parameter is ESR for a data fault, 0 for an instruction
62      * fault.
63      */
64     void do_page_fault(struct pt_regs *regs, unsigned long address,
65     		   unsigned long error_code)
66     {
67     	struct vm_area_struct * vma;
68     	struct mm_struct *mm = current->mm;
69     	siginfo_t info;
70     	int code = SEGV_MAPERR;
71     #if defined(CONFIG_4xx)
72     	int is_write = error_code & ESR_DST;
73     #else
74     	int is_write = 0;
75     
76     	/*
77     	 * Fortunately the bit assignments in SRR1 for an instruction
78     	 * fault and DSISR for a data fault are mostly the same for the
79     	 * bits we are interested in.  But there are some bits which
80     	 * indicate errors in DSISR but can validly be set in SRR1.
81     	 */
82     	if (regs->trap == 0x400)
83     		error_code &= 0x48200000;
84     	else
85     		is_write = error_code & 0x02000000;
86     #endif /* CONFIG_4xx */
87     
88     #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
89     	if (debugger_fault_handler && regs->trap == 0x300) {
90     		debugger_fault_handler(regs);
91     		return;
92     	}
93     #if !defined(CONFIG_4xx)
94     	if (error_code & 0x00400000) {
95     		/* DABR match */
96     		if (debugger_dabr_match(regs))
97     			return;
98     	}
99     #endif /* !CONFIG_4xx */
100     #endif /* CONFIG_XMON || CONFIG_KGDB */
101     
102     	if (in_interrupt() || mm == NULL) {
103     		bad_page_fault(regs, address, SIGSEGV);
104     		return;
105     	}
106     	down_read(&mm->mmap_sem);
107     	vma = find_vma(mm, address);
108     	if (!vma)
109     		goto bad_area;
110     	if (vma->vm_start <= address)
111     		goto good_area;
112     	if (!(vma->vm_flags & VM_GROWSDOWN))
113     		goto bad_area;
114     	if (expand_stack(vma, address))
115     		goto bad_area;
116     
117     good_area:
118     	code = SEGV_ACCERR;
119     #if defined(CONFIG_6xx)
120     	if (error_code & 0x95700000)
121     		/* an error such as lwarx to I/O controller space,
122     		   address matching DABR, eciwx, etc. */
123     		goto bad_area;
124     #endif /* CONFIG_6xx */
125     #if defined(CONFIG_8xx)
126             /* The MPC8xx seems to always set 0x80000000, which is
127              * "undefined".  Of those that can be set, this is the only
128              * one which seems bad.
129              */
130     	if (error_code & 0x10000000)
131                     /* Guarded storage error. */
132     		goto bad_area;
133     #endif /* CONFIG_8xx */
134     	
135     	/* a write */
136     	if (is_write) {
137     		if (!(vma->vm_flags & VM_WRITE))
138     			goto bad_area;
139     	/* a read */
140     	} else {
141     		/* protection fault */
142     		if (error_code & 0x08000000)
143     			goto bad_area;
144     		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
145     			goto bad_area;
146     	}
147     
148     	/*
149     	 * If for any reason at all we couldn't handle the fault,
150     	 * make sure we exit gracefully rather than endlessly redo
151     	 * the fault.
152     	 */
153             switch (handle_mm_fault(mm, vma, address, is_write)) {
154             case 1:
155                     current->min_flt++;
156                     break;
157             case 2:
158                     current->maj_flt++;
159                     break;
160             case 0:
161                     goto do_sigbus;
162             default:
163                     goto out_of_memory;
164     	}
165     
166     	up_read(&mm->mmap_sem);
167     	/*
168     	 * keep track of tlb+htab misses that are good addrs but
169     	 * just need pte's created via handle_mm_fault()
170     	 * -- Cort
171     	 */
172     	pte_misses++;
173     	return;
174     
175     bad_area:
176     	up_read(&mm->mmap_sem);
177     	pte_errors++;	
178     
179     	/* User mode accesses cause a SIGSEGV */
180     	if (user_mode(regs)) {
181     		info.si_signo = SIGSEGV;
182     		info.si_errno = 0;
183     		info.si_code = code;
184     		info.si_addr = (void *) address;
185     		force_sig_info(SIGSEGV, &info, current);
186     		return;
187     	}
188     
189     	bad_page_fault(regs, address, SIGSEGV);
190     	return;
191     
192     /*
193      * We ran out of memory, or some other thing happened to us that made
194      * us unable to handle the page fault gracefully.
195      */
196     out_of_memory:
197     	up_read(&mm->mmap_sem);
198     	printk("VM: killing process %s\n", current->comm);
199     	if (user_mode(regs))
200     		do_exit(SIGKILL);
201     	bad_page_fault(regs, address, SIGKILL);
202     	return;
203     
204     do_sigbus:
205     	up_read(&mm->mmap_sem);
206     	info.si_signo = SIGBUS;
207     	info.si_errno = 0;
208     	info.si_code = BUS_ADRERR;
209     	info.si_addr = (void *)address;
210     	force_sig_info (SIGBUS, &info, current);
211     	if (!user_mode(regs))
212     		bad_page_fault(regs, address, SIGBUS);
213     }
214     
215     /*
216      * bad_page_fault is called when we have a bad access from the kernel.
217      * It is called from do_page_fault above and from some of the procedures
218      * in traps.c.
219      */
220     void
221     bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
222     {
223     	extern void die(const char *,struct pt_regs *,long);
224     
225     	unsigned long fixup;
226     
227     	/* Are we prepared to handle this fault?  */
228     	if ((fixup = search_exception_table(regs->nip)) != 0) {
229     		regs->nip = fixup;
230     		return;
231     	}
232     
233     	/* kernel has accessed a bad area */
234     #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
235     	if (debugger_kernel_faults)
236     		debugger(regs);
237     #endif
238     	die("kernel access of bad area", regs, sig);
239     }
240     
241     #ifdef CONFIG_8xx
242     
243     /* The pgtable.h claims some functions generically exist, but I
244      * can't find them......
245      */
246     pte_t *va_to_pte(unsigned long address)
247     {
248     	pgd_t *dir;
249     	pmd_t *pmd;
250     	pte_t *pte;
251     	struct mm_struct *mm;
252     
253     	if (address < TASK_SIZE)
254     		mm = current->mm;
255     	else
256     		mm = &init_mm;
257     
258     	dir = pgd_offset(mm, address & PAGE_MASK);
259     	if (dir) {
260     		pmd = pmd_offset(dir, address & PAGE_MASK);
261     		if (pmd && pmd_present(*pmd)) {
262     			pte = pte_offset(pmd, address & PAGE_MASK);
263     			if (pte && pte_present(*pte)) {
264     				return(pte);
265     			}
266     		}
267     		else {
268     			return (0);
269     		}
270     	}
271     	else {
272     		return (0);
273     	}
274     	return (0);
275     }
276     
277     unsigned long va_to_phys(unsigned long address)
278     {
279     	pte_t *pte;
280     	
281     	pte = va_to_pte(address);
282     	if (pte)
283     		return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK)));
284     	return (0);
285     }
286     
287     void
288     print_8xx_pte(struct mm_struct *mm, unsigned long addr)
289     {
290             pgd_t * pgd;
291             pmd_t * pmd;
292             pte_t * pte;
293     
294             printk(" pte @ 0x%8lx: ", addr);
295             pgd = pgd_offset(mm, addr & PAGE_MASK);
296             if (pgd) {
297                     pmd = pmd_offset(pgd, addr & PAGE_MASK);
298                     if (pmd && pmd_present(*pmd)) {
299                             pte = pte_offset(pmd, addr & PAGE_MASK);
300                             if (pte) {
301                                     printk(" (0x%08lx)->(0x%08lx)->0x%08lx\n",
302                                             (long)pgd, (long)pte, (long)pte_val(*pte));
303     #define pp ((long)pte_val(*pte))				
304     				printk(" RPN: %05lx PP: %lx SPS: %lx SH: %lx "
305     				       "CI: %lx v: %lx\n",
306     				       pp>>12,    /* rpn */
307     				       (pp>>10)&3, /* pp */
308     				       (pp>>3)&1, /* small */
309     				       (pp>>2)&1, /* shared */
310     				       (pp>>1)&1, /* cache inhibit */
311     				       pp&1       /* valid */
312     				       );
313     #undef pp				
314                             }
315                             else {
316                                     printk("no pte\n");
317                             }
318                     }
319                     else {
320                             printk("no pmd\n");
321                     }
322             }
323             else {
324                     printk("no pgd\n");
325             }
326     }
327     
328     int
329     get_8xx_pte(struct mm_struct *mm, unsigned long addr)
330     {
331             pgd_t * pgd;
332             pmd_t * pmd;
333             pte_t * pte;
334             int     retval = 0;
335     
336             pgd = pgd_offset(mm, addr & PAGE_MASK);
337             if (pgd) {
338                     pmd = pmd_offset(pgd, addr & PAGE_MASK);
339                     if (pmd && pmd_present(*pmd)) {
340                             pte = pte_offset(pmd, addr & PAGE_MASK);
341                             if (pte) {
342                                             retval = (int)pte_val(*pte);
343                             }
344                     }
345             }
346             return(retval);
347     }
348     #endif /* CONFIG_8xx */
349     
350     #if 0
351     /*
352      * Misc debugging functions.  Please leave them here. -- Cort
353      */
354     void print_pte(struct _PTE p)
355     {
356     	printk(
357     "%08x %08x vsid: %06x h: %01x api: %02x rpn: %05x rcwimg: %d%d%d%d%d%d pp: %02x\n",
358     		*((unsigned long *)(&p)), *((long *)&p+1),
359     		p.vsid, p.h, p.api, p.rpn,
360     		p.r,p.c,p.w,p.i,p.m,p.g,p.pp);
361     }
362     
363     /*
364      * Search the hw hash table for a mapping to the given physical
365      * address. -- Cort
366      */
367     unsigned long htab_phys_to_va(unsigned long address)
368     {
369     	extern PTE *Hash, *Hash_end;
370     	PTE *ptr;
371     
372     	for ( ptr = Hash ; ptr < Hash_end ; ptr++ )
373     	{
374     		if ( ptr->rpn == (address>>12) )
375     			printk("phys %08lX -> va ???\n",
376     			       address);
377     	}
378     }
379     #endif
380