OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [ppc64/] [mm/] [fault.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  arch/ppc/mm/fault.c
3
 *
4
 *  PowerPC version
5
 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6
 *
7
 *  Derived from "arch/i386/mm/fault.c"
8
 *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
9
 *
10
 *  Modified by Cort Dougan and Paul Mackerras.
11
 *
12
 *  Modified for PPC64 by Dave Engebretsen (engebret@ibm.com)
13
 *
14
 *  This program is free software; you can redistribute it and/or
15
 *  modify it under the terms of the GNU General Public License
16
 *  as published by the Free Software Foundation; either version
17
 *  2 of the License, or (at your option) any later version.
18
 */
19
 
20
#include <linux/config.h>
21
#include <linux/signal.h>
22
#include <linux/sched.h>
23
#include <linux/kernel.h>
24
#include <linux/errno.h>
25
#include <linux/string.h>
26
#include <linux/types.h>
27
#include <linux/ptrace.h>
28
#include <linux/mman.h>
29
#include <linux/mm.h>
30
#include <linux/interrupt.h>
31
 
32
#include <asm/page.h>
33
#include <asm/pgtable.h>
34
#include <asm/mmu.h>
35
#include <asm/mmu_context.h>
36
#include <asm/system.h>
37
#include <asm/uaccess.h>
38
 
39
#include <asm/ppcdebug.h>
40
 
41
#if defined(CONFIG_KDB)
42
#include <linux/kdb.h>
43
#endif
44
 
45
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
46
extern void (*debugger)(struct pt_regs *);
47
extern void (*debugger_fault_handler)(struct pt_regs *);
48
extern int (*debugger_dabr_match)(struct pt_regs *);
49
int debugger_kernel_faults = 1;
50
#endif
51
 
52
extern void die_if_kernel(char *, struct pt_regs *, long);
53
void bad_page_fault(struct pt_regs *, unsigned long);
54
void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
55
 
56
#ifdef CONFIG_PPCDBG
57
extern unsigned long get_srr0(void);
58
extern unsigned long get_srr1(void);
59
#endif
60
 
61
/*
62
 * Check whether the instruction at regs->nip is a store using
63
 * an update addressing form which will update r1.
64
 */
65
static int store_updates_sp(struct pt_regs *regs)
66
{
67
        unsigned int inst;
68
 
69
        if (get_user(inst, (unsigned int *)regs->nip))
70
                return 0;
71
        /* check for 1 in the rA field */
72
        if (((inst >> 16) & 0x1f) != 1)
73
                return 0;
74
        /* check major opcode */
75
        switch (inst >> 26) {
76
        case 37:        /* stwu */
77
        case 39:        /* stbu */
78
        case 45:        /* sthu */
79
        case 53:        /* stfsu */
80
        case 55:        /* stfdu */
81
                return 1;
82
        case 62:        /* std or stdu */
83
                return (inst & 3) == 1;
84
        case 31:
85
                /* check minor opcode */
86
                switch ((inst >> 1) & 0x3ff) {
87
                case 181:       /* stdux */
88
                case 183:       /* stwux */
89
                case 247:       /* stbux */
90
                case 439:       /* sthux */
91
                case 695:       /* stfsux */
92
                case 759:       /* stfdux */
93
                        return 1;
94
                }
95
        }
96
        return 0;
97
}
98
 
99
/*
100
 * The error_code parameter is
101
 *  - DSISR for a non-SLB data access fault,
102
 *  - SRR1 & 0x08000000 for a non-SLB instruction access fault
103
 *  - 0 any SLB fault.
104
 */
105
void do_page_fault(struct pt_regs *regs, unsigned long address,
106
                   unsigned long error_code)
107
{
108
        struct vm_area_struct * vma, * prev_vma;
109
        struct mm_struct *mm = current->mm;
110
        siginfo_t info;
111
        unsigned long code = SEGV_MAPERR;
112
        unsigned long is_write = error_code & 0x02000000;
113
        unsigned long mm_fault_return;
114
 
115
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
116
        if (debugger_fault_handler && (regs->trap == 0x300 ||
117
                                       regs->trap == 0x380)) {
118
                debugger_fault_handler(regs);
119
                return;
120
        }
121
#endif /* CONFIG_XMON || CONFIG_KGDB */
122
 
123
        /* On a kernel SLB miss we can only check for a valid exception entry */
124
        if (!user_mode(regs) && (regs->trap == 0x380)) {
125
                bad_page_fault(regs, address);
126
                return;
127
        }
128
 
129
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
130
        if (error_code & 0x00400000) {
131
                /* DABR match */
132
                if (debugger_dabr_match(regs))
133
                        return;
134
        }
135
#endif /* CONFIG_XMON || CONFIG_KGDB || CONFIG_KDB */
136
 
137
        if (in_interrupt() || mm == NULL) {
138
                bad_page_fault(regs, address);
139
                return;
140
        }
141
        down_read(&mm->mmap_sem);
142
        vma = find_vma(mm, address);
143
        PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma = 0x%16.16lx\n", vma);
144
        if (!vma) {
145
                PPCDBG(PPCDBG_MM, "\tdo_page_fault: !vma\n");
146
                goto bad_area;
147
        }
148
        PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_start = 0x%16.16lx, vma->vm_flags = 0x%16.16lx\n", vma->vm_start, vma->vm_flags);
149
        if (vma->vm_start <= address) {
150
                goto good_area;
151
        }
152
        if (!(vma->vm_flags & VM_GROWSDOWN)) {
153
                PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_flags = %lx, %lx\n", vma->vm_flags, VM_GROWSDOWN);
154
                goto bad_area;
155
        }
156
 
157
        /*
158
         * N.B. The POWER/Open ABI allows programs to access up to
159
         * 288 bytes below the stack pointer.
160
         * The kernel signal delivery code writes up to about 1.5kB
161
         * below the stack pointer (r1) before decrementing it.
162
         * The exec code can write slightly over 640kB to the stack
163
         * before setting the user r1.  Thus we allow the stack to
164
         * expand to 1MB without further checks.
165
         */
166
        if (address + 0x100000 < vma->vm_end) {
167
                /* get user regs even if this fault is in kernel mode */
168
                struct pt_regs *uregs = current->thread.regs;
169
                if (uregs == NULL)
170
                        goto bad_area;
171
 
172
                /*
173
                 * A user-mode access to an address a long way below
174
                 * the stack pointer is only valid if the instruction
175
                 * is one which would update the stack pointer to the
176
                 * address accessed if the instruction completed,
177
                 * i.e. either stwu rs,n(r1) or stwux rs,r1,rb
178
                 * (or the byte, halfword, float or double forms).
179
                 *
180
                 * If we don't check this then any write to the area
181
                 * between the last mapped region and the stack will
182
                 * expand the stack rather than segfaulting.
183
                 */
184
                if (address + 2048 < uregs->gpr[1]
185
                    && (!user_mode(regs) || !store_updates_sp(regs)))
186
                        goto bad_area;
187
        }
188
 
189
        if (expand_stack(vma, address)) {
190
                PPCDBG(PPCDBG_MM, "\tdo_page_fault: expand_stack\n");
191
                goto bad_area;
192
        }
193
 
194
good_area:
195
        code = SEGV_ACCERR;
196
 
197
        /* a write */
198
        if (is_write) {
199
                if (!(vma->vm_flags & VM_WRITE))
200
                        goto bad_area;
201
        /* a read */
202
        } else {
203
                /* protection fault */
204
                if (error_code & 0x08000000)
205
                        goto bad_area;
206
                if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
207
                        goto bad_area;
208
        }
209
 
210
 survive:
211
        /*
212
         * If for any reason at all we couldn't handle the fault,
213
         * make sure we exit gracefully rather than endlessly redo
214
         * the fault.
215
         */
216
        PPCDBG(PPCDBG_MM, "\tdo_page_fault: calling handle_mm_fault\n");
217
        mm_fault_return = handle_mm_fault(mm, vma, address, is_write);
218
        PPCDBG(PPCDBG_MM, "\tdo_page_fault: handle_mm_fault = 0x%lx\n",
219
               mm_fault_return);
220
        switch(mm_fault_return) {
221
        case 1:
222
                current->min_flt++;
223
                break;
224
        case 2:
225
                current->maj_flt++;
226
                break;
227
        case 0:
228
                goto do_sigbus;
229
        default:
230
                goto out_of_memory;
231
        }
232
 
233
        up_read(&mm->mmap_sem);
234
        return;
235
 
236
bad_area:
237
        up_read(&mm->mmap_sem);
238
 
239
        /* User mode accesses cause a SIGSEGV */
240
        if (user_mode(regs)) {
241
                info.si_signo = SIGSEGV;
242
                info.si_errno = 0;
243
                info.si_code = code;
244
                info.si_addr = (void *) address;
245
                PPCDBG(PPCDBG_SIGNAL, "Bad addr in user: 0x%lx\n", address);
246
#ifdef CONFIG_XMON
247
                ifppcdebug(PPCDBG_SIGNALXMON)
248
                    PPCDBG_ENTER_DEBUGGER_REGS(regs);
249
#endif
250
 
251
                force_sig_info(SIGSEGV, &info, current);
252
                return;
253
        }
254
 
255
        bad_page_fault(regs, address);
256
        return;
257
 
258
/*
259
 * We ran out of memory, or some other thing happened to us that made
260
 * us unable to handle the page fault gracefully.
261
 */
262
out_of_memory:
263
        up_read(&mm->mmap_sem);
264
        if (current->pid == 1) {
265
                yield();
266
                down_read(&mm->mmap_sem);
267
                goto survive;
268
        }
269
        printk("VM: killing process %s\n", current->comm);
270
        if (user_mode(regs))
271
                do_exit(SIGKILL);
272
        bad_page_fault(regs, address);
273
        return;
274
 
275
do_sigbus:
276
        up_read(&mm->mmap_sem);
277
        info.si_signo = SIGBUS;
278
        info.si_errno = 0;
279
        info.si_code = BUS_ADRERR;
280
        info.si_addr = (void *)address;
281
        force_sig_info (SIGBUS, &info, current);
282
        if (!user_mode(regs))
283
                bad_page_fault(regs, address);
284
}
285
 
286
/*
287
 * bad_page_fault is called when we have a bad access from the kernel.
288
 * It is called from do_page_fault above and from some of the procedures
289
 * in traps.c.
290
 */
291
void
292
bad_page_fault(struct pt_regs *regs, unsigned long address)
293
{
294
        unsigned long fixup;
295
 
296
        /* Are we prepared to handle this fault?  */
297
        if ((fixup = search_exception_table(regs->nip)) != 0) {
298
                regs->nip = fixup;
299
                return;
300
        }
301
 
302
        /* kernel has accessed a bad area */
303
        show_regs(regs);
304
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
305
        if (debugger_kernel_faults)
306
                debugger(regs);
307
#endif
308
        print_backtrace( (unsigned long *)regs->gpr[1] );
309
        panic("kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d",
310
              regs->nip,regs->link,address,current->comm,current->pid);
311
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.