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.
* 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;
#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)
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);
* -- Cort
*/
pte_misses++;
- return;
+ return 0;
bad_area:
up_read(&mm->mmap_sem);
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
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);
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? */
pgd_t *dir;
pmd_t *pmd;
pte_t *pte;
- struct mm_struct *mm;
if (address < TASK_SIZE)
return NULL;