~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/sh/mm/fault_32.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
#include <linux/hardirq.h>
17
17
#include <linux/kprobes.h>
18
18
#include <linux/perf_event.h>
19
 
#include <trace/fault.h>
20
19
#include <asm/io_trapped.h>
21
20
#include <asm/system.h>
22
21
#include <asm/mmu_context.h>
23
22
#include <asm/tlbflush.h>
24
23
 
25
 
DEFINE_TRACE(page_fault_entry);
26
 
DEFINE_TRACE(page_fault_exit);
27
 
DEFINE_TRACE(page_fault_nosem_entry);
28
 
DEFINE_TRACE(page_fault_nosem_exit);
29
 
 
30
24
static inline int notify_page_fault(struct pt_regs *regs, int trap)
31
25
{
32
26
        int ret = 0;
206
200
         * make sure we exit gracefully rather than endlessly redo
207
201
         * the fault.
208
202
         */
209
 
        trace_page_fault_entry(regs,
210
 
                ({
211
 
                        unsigned long trapnr;
212
 
                        asm volatile("stc       r2_bank,%0": "=r" (trapnr));
213
 
                        trapnr;
214
 
                }) >> 5, mm, vma, address, writeaccess);
215
203
        fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0);
216
 
        trace_page_fault_exit(fault);
217
204
        if (unlikely(fault & VM_FAULT_ERROR)) {
218
205
                if (fault & VM_FAULT_OOM)
219
206
                        goto out_of_memory;
243
230
 
244
231
bad_area_nosemaphore:
245
232
        if (user_mode(regs)) {
246
 
                trace_page_fault_nosem_entry(regs,
247
 
                ({
248
 
                        unsigned long trapnr;
249
 
                        asm volatile("stc       r2_bank,%0": "=r" (trapnr));
250
 
                        trapnr;
251
 
                }) >> 5, address);
252
233
                info.si_signo = SIGSEGV;
253
234
                info.si_errno = 0;
254
235
                info.si_code = si_code;
255
236
                info.si_addr = (void *) address;
256
237
                force_sig_info(SIGSEGV, &info, tsk);
257
 
                trace_page_fault_nosem_exit();
258
238
                return;
259
239
        }
260
240
 
344
324
        pmd_t *pmd;
345
325
        pte_t *pte;
346
326
        pte_t entry;
347
 
        int ret;
348
 
        int irqvec;
349
 
 
350
 
        irqvec = lookup_exception_vector();
351
 
        trace_page_fault_nosem_entry(regs, irqvec, address);
352
327
 
353
328
        /*
354
329
         * We don't take page faults for P1, P2, and parts of P4, these
358
333
        if (address >= P3SEG && address < P3_ADDR_MAX) {
359
334
                pgd = pgd_offset_k(address);
360
335
        } else {
361
 
                if (unlikely(address >= TASK_SIZE || !current->mm)) {
362
 
                        ret = 1;
363
 
                        goto out;
364
 
                }
 
336
                if (unlikely(address >= TASK_SIZE || !current->mm))
 
337
                        return 1;
365
338
 
366
339
                pgd = pgd_offset(current->mm, address);
367
340
        }
368
341
 
369
342
        pud = pud_offset(pgd, address);
370
 
        if (pud_none_or_clear_bad(pud)) {
371
 
                ret = 1;
372
 
                goto out;
373
 
        }
 
343
        if (pud_none_or_clear_bad(pud))
 
344
                return 1;
374
345
        pmd = pmd_offset(pud, address);
375
 
        if (pmd_none_or_clear_bad(pmd)) {
376
 
                ret = 1;
377
 
                goto out;
378
 
        }
 
346
        if (pmd_none_or_clear_bad(pmd))
 
347
                return 1;
379
348
        pte = pte_offset_kernel(pmd, address);
380
349
        entry = *pte;
381
 
        if (unlikely(pte_none(entry) || pte_not_present(entry))) {
382
 
                ret = 1;
383
 
                goto out;
384
 
        }
385
 
        if (unlikely(writeaccess && !pte_write(entry))) {
386
 
                ret = 1;
387
 
                goto out;
388
 
        }
 
350
        if (unlikely(pte_none(entry) || pte_not_present(entry)))
 
351
                return 1;
 
352
        if (unlikely(writeaccess && !pte_write(entry)))
 
353
                return 1;
389
354
 
390
355
        if (writeaccess)
391
356
                entry = pte_mkdirty(entry);
405
370
 
406
371
        update_mmu_cache(NULL, address, pte);
407
372
 
408
 
        ret = 0;
409
 
out:
410
 
        trace_page_fault_nosem_exit();
411
 
        return ret;
 
373
        return 0;
412
374
}