linux/arch/sh/mm/fault_32.c
<<
>>
Prefs
   1/*
   2 * Page fault handler for SH with an MMU.
   3 *
   4 *  Copyright (C) 1999  Niibe Yutaka
   5 *  Copyright (C) 2003 - 2007  Paul Mundt
   6 *
   7 *  Based on linux/arch/i386/mm/fault.c:
   8 *   Copyright (C) 1995  Linus Torvalds
   9 *
  10 * This file is subject to the terms and conditions of the GNU General Public
  11 * License.  See the file "COPYING" in the main directory of this archive
  12 * for more details.
  13 */
  14#include <linux/kernel.h>
  15#include <linux/mm.h>
  16#include <linux/hardirq.h>
  17#include <linux/kprobes.h>
  18#include <asm/io_trapped.h>
  19#include <asm/system.h>
  20#include <asm/mmu_context.h>
  21#include <asm/tlbflush.h>
  22#include <asm/kgdb.h>
  23
  24/*
  25 * This routine handles page faults.  It determines the address,
  26 * and the problem, and then passes it off to one of the appropriate
  27 * routines.
  28 */
  29asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
  30                                        unsigned long writeaccess,
  31                                        unsigned long address)
  32{
  33        struct task_struct *tsk;
  34        struct mm_struct *mm;
  35        struct vm_area_struct * vma;
  36        int si_code;
  37        int fault;
  38        siginfo_t info;
  39
  40#ifdef CONFIG_SH_KGDB
  41        if (kgdb_nofault && kgdb_bus_err_hook)
  42                kgdb_bus_err_hook();
  43#endif
  44
  45        tsk = current;
  46        si_code = SEGV_MAPERR;
  47
  48        if (unlikely(address >= TASK_SIZE)) {
  49                /*
  50                 * Synchronize this task's top level page-table
  51                 * with the 'reference' page table.
  52                 *
  53                 * Do _not_ use "tsk" here. We might be inside
  54                 * an interrupt in the middle of a task switch..
  55                 */
  56                int offset = pgd_index(address);
  57                pgd_t *pgd, *pgd_k;
  58                pud_t *pud, *pud_k;
  59                pmd_t *pmd, *pmd_k;
  60
  61                pgd = get_TTB() + offset;
  62                pgd_k = swapper_pg_dir + offset;
  63
  64                /* This will never happen with the folded page table. */
  65                if (!pgd_present(*pgd)) {
  66                        if (!pgd_present(*pgd_k))
  67                                goto bad_area_nosemaphore;
  68                        set_pgd(pgd, *pgd_k);
  69                        return;
  70                }
  71
  72                pud = pud_offset(pgd, address);
  73                pud_k = pud_offset(pgd_k, address);
  74                if (pud_present(*pud) || !pud_present(*pud_k))
  75                        goto bad_area_nosemaphore;
  76                set_pud(pud, *pud_k);
  77
  78                pmd = pmd_offset(pud, address);
  79                pmd_k = pmd_offset(pud_k, address);
  80                if (pmd_present(*pmd) || !pmd_present(*pmd_k))
  81                        goto bad_area_nosemaphore;
  82                set_pmd(pmd, *pmd_k);
  83
  84                return;
  85        }
  86
  87        /* Only enable interrupts if they were on before the fault */
  88        if ((regs->sr & SR_IMASK) != SR_IMASK) {
  89                trace_hardirqs_on();
  90                local_irq_enable();
  91        }
  92
  93        mm = tsk->mm;
  94
  95        /*
  96         * If we're in an interrupt or have no user
  97         * context, we must not take the fault..
  98         */
  99        if (in_atomic() || !mm)
 100                goto no_context;
 101
 102        down_read(&mm->mmap_sem);
 103
 104        vma = find_vma(mm, address);
 105        if (!vma)
 106                goto bad_area;
 107        if (vma->vm_start <= address)
 108                goto good_area;
 109        if (!(vma->vm_flags & VM_GROWSDOWN))
 110                goto bad_area;
 111        if (expand_stack(vma, address))
 112                goto bad_area;
 113/*
 114 * Ok, we have a good vm_area for this memory access, so
 115 * we can handle it..
 116 */
 117good_area:
 118        si_code = SEGV_ACCERR;
 119        if (writeaccess) {
 120                if (!(vma->vm_flags & VM_WRITE))
 121                        goto bad_area;
 122        } else {
 123                if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
 124                        goto bad_area;
 125        }
 126
 127        /*
 128         * If for any reason at all we couldn't handle the fault,
 129         * make sure we exit gracefully rather than endlessly redo
 130         * the fault.
 131         */
 132survive:
 133        fault = handle_mm_fault(mm, vma, address, writeaccess);
 134        if (unlikely(fault & VM_FAULT_ERROR)) {
 135                if (fault & VM_FAULT_OOM)
 136                        goto out_of_memory;
 137                else if (fault & VM_FAULT_SIGBUS)
 138                        goto do_sigbus;
 139                BUG();
 140        }
 141        if (fault & VM_FAULT_MAJOR)
 142                tsk->maj_flt++;
 143        else
 144                tsk->min_flt++;
 145
 146        up_read(&mm->mmap_sem);
 147        return;
 148
 149/*
 150 * Something tried to access memory that isn't in our memory map..
 151 * Fix it, but check if it's kernel or user first..
 152 */
 153bad_area:
 154        up_read(&mm->mmap_sem);
 155
 156bad_area_nosemaphore:
 157        if (user_mode(regs)) {
 158                info.si_signo = SIGSEGV;
 159                info.si_errno = 0;
 160                info.si_code = si_code;
 161                info.si_addr = (void *) address;
 162                force_sig_info(SIGSEGV, &info, tsk);
 163                return;
 164        }
 165
 166no_context:
 167        /* Are we prepared to handle this kernel fault?  */
 168        if (fixup_exception(regs))
 169                return;
 170
 171        if (handle_trapped_io(regs, address))
 172                return;
 173/*
 174 * Oops. The kernel tried to access some bad page. We'll have to
 175 * terminate things with extreme prejudice.
 176 *
 177 */
 178
 179        bust_spinlocks(1);
 180
 181        if (oops_may_print()) {
 182                unsigned long page;
 183
 184                if (address < PAGE_SIZE)
 185                        printk(KERN_ALERT "Unable to handle kernel NULL "
 186                                          "pointer dereference");
 187                else
 188                        printk(KERN_ALERT "Unable to handle kernel paging "
 189                                          "request");
 190                printk(" at virtual address %08lx\n", address);
 191                printk(KERN_ALERT "pc = %08lx\n", regs->pc);
 192                page = (unsigned long)get_TTB();
 193                if (page) {
 194                        page = ((__typeof__(page) *)page)[address >> PGDIR_SHIFT];
 195                        printk(KERN_ALERT "*pde = %08lx\n", page);
 196                        if (page & _PAGE_PRESENT) {
 197                                page &= PAGE_MASK;
 198                                address &= 0x003ff000;
 199                                page = ((__typeof__(page) *)
 200                                                __va(page))[address >>
 201                                                            PAGE_SHIFT];
 202                                printk(KERN_ALERT "*pte = %08lx\n", page);
 203                        }
 204                }
 205        }
 206
 207        die("Oops", regs, writeaccess);
 208        bust_spinlocks(0);
 209        do_exit(SIGKILL);
 210
 211/*
 212 * We ran out of memory, or some other thing happened to us that made
 213 * us unable to handle the page fault gracefully.
 214 */
 215out_of_memory:
 216        up_read(&mm->mmap_sem);
 217        if (is_global_init(current)) {
 218                yield();
 219                down_read(&mm->mmap_sem);
 220                goto survive;
 221        }
 222        printk("VM: killing process %s\n", tsk->comm);
 223        if (user_mode(regs))
 224                do_group_exit(SIGKILL);
 225        goto no_context;
 226
 227do_sigbus:
 228        up_read(&mm->mmap_sem);
 229
 230        /*
 231         * Send a sigbus, regardless of whether we were in kernel
 232         * or user mode.
 233         */
 234        info.si_signo = SIGBUS;
 235        info.si_errno = 0;
 236        info.si_code = BUS_ADRERR;
 237        info.si_addr = (void *)address;
 238        force_sig_info(SIGBUS, &info, tsk);
 239
 240        /* Kernel mode? Handle exceptions or die */
 241        if (!user_mode(regs))
 242                goto no_context;
 243}
 244
 245#ifdef CONFIG_SH_STORE_QUEUES
 246/*
 247 * This is a special case for the SH-4 store queues, as pages for this
 248 * space still need to be faulted in before it's possible to flush the
 249 * store queue cache for writeout to the remapped region.
 250 */
 251#define P3_ADDR_MAX             (P4SEG_STORE_QUE + 0x04000000)
 252#else
 253#define P3_ADDR_MAX             P4SEG
 254#endif
 255
 256/*
 257 * Called with interrupts disabled.
 258 */
 259asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
 260                                         unsigned long writeaccess,
 261                                         unsigned long address)
 262{
 263        pgd_t *pgd;
 264        pud_t *pud;
 265        pmd_t *pmd;
 266        pte_t *pte;
 267        pte_t entry;
 268
 269#ifdef CONFIG_SH_KGDB
 270        if (kgdb_nofault && kgdb_bus_err_hook)
 271                kgdb_bus_err_hook();
 272#endif
 273
 274        /*
 275         * We don't take page faults for P1, P2, and parts of P4, these
 276         * are always mapped, whether it be due to legacy behaviour in
 277         * 29-bit mode, or due to PMB configuration in 32-bit mode.
 278         */
 279        if (address >= P3SEG && address < P3_ADDR_MAX) {
 280                pgd = pgd_offset_k(address);
 281        } else {
 282                if (unlikely(address >= TASK_SIZE || !current->mm))
 283                        return 1;
 284
 285                pgd = pgd_offset(current->mm, address);
 286        }
 287
 288        pud = pud_offset(pgd, address);
 289        if (pud_none_or_clear_bad(pud))
 290                return 1;
 291        pmd = pmd_offset(pud, address);
 292        if (pmd_none_or_clear_bad(pmd))
 293                return 1;
 294
 295        pte = pte_offset_kernel(pmd, address);
 296        entry = *pte;
 297        if (unlikely(pte_none(entry) || pte_not_present(entry)))
 298                return 1;
 299        if (unlikely(writeaccess && !pte_write(entry)))
 300                return 1;
 301
 302        if (writeaccess)
 303                entry = pte_mkdirty(entry);
 304        entry = pte_mkyoung(entry);
 305
 306#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SMP)
 307        /*
 308         * ITLB is not affected by "ldtlb" instruction.
 309         * So, we need to flush the entry by ourselves.
 310         */
 311        local_flush_tlb_one(get_asid(), address & PAGE_MASK);
 312#endif
 313
 314        set_pte(pte, entry);
 315        update_mmu_cache(NULL, address, entry);
 316
 317        return 0;
 318}
 319
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.