linux内核分析之缺页中断(二)

来源:互联网 发布:如何防止java 内存泄露 编辑:程序博客网 时间:2024/05/17 02:21

对于缺页中断的非法访问由函数bad_area执行,该函数的执行情况分为:

1,如果在用户空间访问,直接发送SEGSEGV信号;

2,如果在内核空间访问分为两种情况:

1)地址是一个错误的系统调用参数,修正码(典型是发送SIGSEGV信号);

2)反之,杀死进程并显示内核的OOPS信息;

static void__bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,       unsigned long address, int si_code){struct task_struct *tsk = current;/* User mode accesses just cause a SIGSEGV *//*如果用户态*/if (error_code & PF_USER) {/* * It's possible to have interrupts off here: */local_irq_enable();/* * Valid to do another page fault here because this one came * from user space: */if (is_prefetch(regs, error_code, address))return;if (is_errata100(regs, address))return;if (unlikely(show_unhandled_signals))show_signal_msg(regs, error_code, address, tsk);/* Kernel addresses are always protection faults: */tsk->thread.cr2= address;tsk->thread.error_code= error_code | (address >= TASK_SIZE);tsk->thread.trap_no= 14;/*发送SIGSEGV信号*/force_sig_info_fault(SIGSEGV, si_code, address, tsk);return;}if (is_f00f_bug(regs, address))return;/*内核态访问*/no_context(regs, error_code, address);}

内核访问时

static noinline voidno_context(struct pt_regs *regs, unsigned long error_code,   unsigned long address){struct task_struct *tsk = current;unsigned long *stackend;unsigned long flags;int sig;/* Are we prepared to handle this kernel fault? *//*地址是一个系统调用参数,"修正码",典型情况是发送SIGSEGV信号*/if (fixup_exception(regs))return;/* * 32-bit: * *   Valid to do another page fault here, because if this fault *   had been triggered by is_prefetch fixup_exception would have *   handled it. * * 64-bit: * *   Hall of shame of CPU/BIOS bugs. */if (is_prefetch(regs, error_code, address))return;if (is_errata93(regs, address))return;/* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice: */ /*下面代码用于oops信息的显示和杀死当前 进程*/flags = oops_begin();show_fault_oops(regs, error_code, address);stackend = end_of_stack(tsk);if (*stackend != STACK_END_MAGIC)printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");tsk->thread.cr2= address;tsk->thread.trap_no= 14;tsk->thread.error_code= error_code;sig = SIGKILL;if (__die("Oops", regs, error_code))sig = 0;/* Executive summary in case the body of the oops scrolled away */printk(KERN_EMERG "CR2: %016lx\n", address);oops_end(flags, regs, sig);}



 

 

原创粉丝点击