root/arch/alpha/mm/fault.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_page_fault

   1 /*
   2  *  linux/arch/alpha/mm/fault.c
   3  *
   4  *  Copyright (C) 1995  Linus Torvalds
   5  */
   6 
   7 #include <linux/config.h>
   8 #include <linux/signal.h>
   9 #include <linux/sched.h>
  10 #include <linux/head.h>
  11 #include <linux/kernel.h>
  12 #include <linux/errno.h>
  13 #include <linux/string.h>
  14 #include <linux/types.h>
  15 #include <linux/ptrace.h>
  16 #include <linux/mman.h>
  17 #include <linux/mm.h>
  18 
  19 #include <asm/system.h>
  20 #include <asm/segment.h>
  21 #include <asm/pgtable.h>
  22 
  23 extern void die_if_kernel(char *,struct pt_regs *,long);
  24 
  25 /*
  26  * This routine handles page faults.  It determines the address,
  27  * and the problem, and then passes it off to one of the appropriate
  28  * routines.
  29  *
  30  * mmcsr:
  31  *      0 = translation not valid (= do_no_page())
  32  *      1 = access violation (= user tries to access kernel pages)
  33  *      2 = fault-on-read
  34  *      3 = fault-on-execute
  35  *      4 = fault-on-write
  36  *
  37  * cause:
  38  *      -1 = instruction fetch
  39  *      0 = load
  40  *      1 = store
  41  */
  42 asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
     /* [previous][next][first][last][top][bottom][index][help] */
  43         long cause, struct pt_regs * regs)
  44 {
  45         struct vm_area_struct * vma;
  46 
  47         if (mmcsr == 1)
  48                 goto bad_area;
  49         vma = find_vma(current, address);
  50         if (!vma)
  51                 goto bad_area;
  52         if (vma->vm_start <= address)
  53                 goto good_area;
  54         if (!(vma->vm_flags & VM_GROWSDOWN))
  55                 goto bad_area;
  56         if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
  57                 goto bad_area;
  58         vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
  59         vma->vm_start = (address & PAGE_MASK);
  60 /*
  61  * Ok, we have a good vm_area for this memory access, so
  62  * we can handle it..
  63  */
  64 good_area:
  65         if (cause < 0) {
  66                 if (!(vma->vm_flags & VM_EXEC))
  67                         goto bad_area;
  68         } else if (!cause) {
  69                 if (!(vma->vm_flags & VM_READ))
  70                         goto bad_area;
  71         } else {
  72                 if (!(vma->vm_flags & VM_WRITE))
  73                         goto bad_area;
  74         }
  75 
  76         if (mmcsr) {
  77                 do_wp_page(vma, address, cause > 0);
  78                 return;
  79         }
  80         do_no_page(vma, address, cause > 0);
  81         return;
  82 
  83 /*
  84  * Something tried to access memory that isn't in our memory map..
  85  * Fix it, but check if it's kernel or user first..
  86  */
  87 bad_area:
  88         if (user_mode(regs)) {
  89                 send_sig(SIGSEGV, current, 1);
  90                 return;
  91         }
  92 /*
  93  * Oops. The kernel tried to access some bad page. We'll have to
  94  * terminate things with extreme prejudice.
  95  */
  96         printk(KERN_ALERT "Unable to handle kernel paging request at virtual address %08lx\n",address);
  97         die_if_kernel("Oops", regs, cause);
  98         do_exit(SIGKILL);
  99 }

/* [previous][next][first][last][top][bottom][index][help] */