⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fault-armo.c

📁 arm平台上的uclinux系统全部源代码
💻 C
字号:
/* *  linux/arch/arm/mm/fault.c * *  Copyright (C) 1995  Linus Torvalds *  Modifications for ARM processor (c) 1995, 1996 Russell King */#include <linux/signal.h>#include <linux/sched.h>#include <linux/head.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/types.h>#include <linux/ptrace.h>#include <linux/mman.h>#include <linux/mm.h>#include <asm/system.h>#include <asm/segment.h>#include <asm/pgtable.h>#define FAULT_CODE_FORCECOW	0x80#define FAULT_CODE_PREFETCH	0x04#define FAULT_CODE_WRITE	0x02#define FAULT_CODE_USER		0x01extern void die_if_kernel(char *, struct pt_regs *, long, int, int);static voidhandle_dataabort (unsigned long addr, int mode, struct pt_regs *regs){    struct task_struct *tsk = current;    struct mm_struct *mm = tsk->mm;    struct vm_area_struct *vma;    down(&mm->mmap_sem);    vma = find_vma (mm, addr);    if (!vma)	goto bad_area;    if (addr >= vma->vm_start)	goto good_area;    if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack (vma, addr))	goto bad_area;    /*     * Ok, we have a good vm_area for this memory access, so     * we can handle it..     */good_area:    if (mode & FAULT_CODE_WRITE) { /* write? */	if (!(vma->vm_flags & VM_WRITE))	    goto bad_area;    } else {	if (!(vma->vm_flags & (VM_READ|VM_EXEC)))	    goto bad_area;    }    /*     * Dirty hack for now...  Should solve the problem with ldm though!     */    handle_mm_fault (vma, addr, mode & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW));    up(&mm->mmap_sem);    return;    /*     * Something tried to access memory that isn't in our memory map..     * Fix it, but check if it's kernel or user first..     */bad_area:    up(&mm->mmap_sem);    if (mode & FAULT_CODE_USER) {	tsk->tss.error_code = mode;	tsk->tss.trap_no = 14;	printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",		tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);	force_sig(SIGSEGV, tsk);	return;    } else {	/*	 * Oops. The kernel tried to access some bad page. We'll have to	 * terminate things with extreme prejudice.	 */    	pgd_t *pgd;    	pmd_t *pmd;	if (addr < PAGE_SIZE)	    printk (KERN_ALERT "Unable to handle kernel NULL pointer dereference");	else	    printk (KERN_ALERT "Unable to handle kernel paging request");	printk (" at virtual address %08lx\n", addr);	printk (KERN_ALERT "current->tss.memmap = %08lX\n", tsk->tss.memmap);	pgd = pgd_offset (vma->vm_mm, addr);	printk (KERN_ALERT "*pgd = %08lx", pgd_val (*pgd));	if (!pgd_none (*pgd)) {	    pmd = pmd_offset (pgd, addr);	    printk (", *pmd = %08lx", pmd_val (*pmd));	    if (!pmd_none (*pmd))		printk (", *pte = %08lx", pte_val (*pte_offset (pmd, addr)));	}	printk ("\n");	die_if_kernel ("Oops", regs, mode, 0, SIGKILL);	do_exit (SIGKILL);    }}/* * Handle a data abort.  Note that we have to handle a range of addresses * on ARM2/3 for ldm.  If both pages are zero-mapped, then we have to force * a copy-on-write */asmlinkage voiddo_DataAbort (unsigned long min_addr, unsigned long max_addr, int mode, struct pt_regs *regs){    handle_dataabort (min_addr, mode, regs);    if ((min_addr ^ max_addr) >> PAGE_SHIFT)    	handle_dataabort (max_addr, mode | FAULT_CODE_FORCECOW, regs);}asmlinkage intdo_PrefetchAbort (unsigned long addr, int mode, struct pt_regs *regs){#if 0    if (the memc mapping for this page exists - can check now...) {	printk ("Page in, but got abort (undefined instruction?)\n");	return 0;    }#endif    handle_dataabort (addr, mode, regs);    return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -