X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fmm%2Ffault.c;h=7a280f9da5e460243b29cfc6e499cf81881e98fd;hb=973b9821248435d0a15f0310bc913366a60e338b;hp=e31abd874386e37290f68226bde56b8858a4a71e;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index e31abd874..7a280f9da 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -51,11 +51,6 @@ unsigned long pte_misses; /* updated by do_page_fault() */ unsigned long pte_errors; /* updated by do_page_fault() */ unsigned int probingmem; -extern void die_if_kernel(char *, struct pt_regs *, long); -void bad_page_fault(struct pt_regs *, unsigned long, int sig); -void do_page_fault(struct pt_regs *, unsigned long, unsigned long); -extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep); - /* * Check whether the instruction at regs->nip is a store using * an update addressing form which will update r1. @@ -97,8 +92,8 @@ static int store_updates_sp(struct pt_regs *regs) * the error_code parameter is ESR for a data fault, 0 for an instruction * fault. */ -void do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) +int do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) { struct vm_area_struct * vma; struct mm_struct *mm = current->mm; @@ -124,21 +119,20 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_fault_handler && TRAP(regs) == 0x300) { debugger_fault_handler(regs); - return; + return 0; } #if !defined(CONFIG_4xx) if (error_code & 0x00400000) { /* DABR match */ if (debugger_dabr_match(regs)) - return; + return 0; } #endif /* !CONFIG_4xx */ #endif /* CONFIG_XMON || CONFIG_KGDB */ - if (in_atomic() || mm == NULL) { - bad_page_fault(regs, address, SIGSEGV); - return; - } + if (in_atomic() || mm == NULL) + return SIGSEGV; + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -227,15 +221,14 @@ good_area: struct page *page = pte_page(*ptep); if (! test_bit(PG_arch_1, &page->flags)) { - unsigned long phys = page_to_pfn(page) << PAGE_SHIFT; - __flush_dcache_icache_phys(phys); + flush_dcache_icache_page(page); set_bit(PG_arch_1, &page->flags); } pte_update(ptep, 0, _PAGE_HWEXEC); _tlbie(address); pte_unmap(ptep); up_read(&mm->mmap_sem); - return; + return 0; } if (ptep != NULL) pte_unmap(ptep); @@ -277,7 +270,7 @@ good_area: * -- Cort */ pte_misses++; - return; + return 0; bad_area: up_read(&mm->mmap_sem); @@ -290,11 +283,10 @@ bad_area: info.si_code = code; info.si_addr = (void *) address; force_sig_info(SIGSEGV, &info, current); - return; + return 0; } - bad_page_fault(regs, address, SIGSEGV); - return; + return SIGSEGV; /* * We ran out of memory, or some other thing happened to us that made @@ -310,8 +302,7 @@ out_of_memory: printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); - bad_page_fault(regs, address, SIGKILL); - return; + return SIGKILL; do_sigbus: up_read(&mm->mmap_sem); @@ -321,18 +312,18 @@ do_sigbus: info.si_addr = (void *)address; force_sig_info (SIGBUS, &info, current); if (!user_mode(regs)) - bad_page_fault(regs, address, SIGBUS); + return SIGBUS; + return 0; } /* * bad_page_fault is called when we have a bad access from the kernel. - * It is called from do_page_fault above and from some of the procedures - * in traps.c. + * It is called from the DSI and ISI handlers in head.S and from some + * of the procedures in traps.c. */ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) { - extern void die(const char *,struct pt_regs *,long); const struct exception_table_entry *entry; /* Are we prepared to handle this fault? */ @@ -359,7 +350,6 @@ pte_t *va_to_pte(unsigned long address) pgd_t *dir; pmd_t *pmd; pte_t *pte; - struct mm_struct *mm; if (address < TASK_SIZE) return NULL;