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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [alpha/] [mm/] [fault.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 *  linux/arch/alpha/mm/fault.c
3
 *
4
 *  Copyright (C) 1995  Linus Torvalds
5
 */
6
 
7
#include <linux/signal.h>
8
#include <linux/sched.h>
9
#include <linux/head.h>
10
#include <linux/kernel.h>
11
#include <linux/errno.h>
12
#include <linux/string.h>
13
#include <linux/types.h>
14
#include <linux/ptrace.h>
15
#include <linux/mman.h>
16
#include <linux/mm.h>
17
 
18
#include <asm/system.h>
19
#include <asm/segment.h>
20
#include <asm/pgtable.h>
21
#include <asm/mmu_context.h>
22
 
23
unsigned long asn_cache = ASN_FIRST_VERSION;
24
 
25
#ifndef BROKEN_ASN
26
/*
27
 * Select a new ASN and reload the context. This is
28
 * not inlined as this expands to a pretty large
29
 * function.
30
 */
31
void get_new_asn_and_reload(struct task_struct *tsk, struct mm_struct *mm)
32
{
33
        get_new_mmu_context(tsk, mm, asn_cache);
34
        reload_context(tsk);
35
}
36
#endif
37
 
38
extern void die_if_kernel(char *,struct pt_regs *,long);
39
 
40
/*
41
 * This routine handles page faults.  It determines the address,
42
 * and the problem, and then passes it off to handle_mm_fault().
43
 *
44
 * mmcsr:
45
 *      0 = translation not valid
46
 *      1 = access violation
47
 *      2 = fault-on-read
48
 *      3 = fault-on-execute
49
 *      4 = fault-on-write
50
 *
51
 * cause:
52
 *      -1 = instruction fetch
53
 *      0 = load
54
 *      1 = store
55
 */
56
asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long cause,
57
        unsigned long a3, unsigned long a4, unsigned long a5,
58
        struct pt_regs regs)
59
{
60
        struct vm_area_struct * vma;
61
        struct task_struct *tsk = current;
62
        struct mm_struct *mm = tsk->mm;
63
 
64
        down(&mm->mmap_sem);
65
        vma = find_vma(mm, address);
66
        if (!vma)
67
                goto bad_area;
68
        if (vma->vm_start <= address)
69
                goto good_area;
70
        if (!(vma->vm_flags & VM_GROWSDOWN))
71
                goto bad_area;
72
        if (expand_stack(vma, address))
73
                goto bad_area;
74
/*
75
 * Ok, we have a good vm_area for this memory access, so
76
 * we can handle it..
77
 */
78
good_area:
79
        if (cause < 0) {
80
                if (!(vma->vm_flags & VM_EXEC))
81
                        goto bad_area;
82
        } else if (!cause) {
83
                /* Allow reads even for write-only mappings */
84
                if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
85
                        goto bad_area;
86
        } else {
87
                if (!(vma->vm_flags & VM_WRITE))
88
                        goto bad_area;
89
        }
90
        handle_mm_fault(vma, address, cause > 0);
91
        up(&mm->mmap_sem);
92
        return;
93
 
94
/*
95
 * Something tried to access memory that isn't in our memory map..
96
 * Fix it, but check if it's kernel or user first..
97
 */
98
bad_area:
99
        up(&mm->mmap_sem);
100
        if (user_mode(&regs)) {
101
                printk("%s: memory violation at pc=%08lx rp=%08lx (bad address = %08lx)\n",
102
                        tsk->comm, regs.pc, regs.r26, address);
103
                die_if_kernel("oops", &regs, cause);
104
                force_sig(SIGSEGV, tsk);
105
                return;
106
        }
107
/*
108
 * Oops. The kernel tried to access some bad page. We'll have to
109
 * terminate things with extreme prejudice.
110
 */
111
        printk(KERN_ALERT
112
               "Unable to handle kernel paging request at virtual address %016lx\n", address);
113
        die_if_kernel("Oops", &regs, cause);
114
        do_exit(SIGKILL);
115
}

powered by: WebSVN 2.1.0

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