Linux缺页异常处理--用户空间
作者:网络转载 发布时间:[ 2012/8/16 11:09:30 ] 推荐标签:
/*
* Ok, we have a good vm_area for this memory access, so
* we can handle it..
*/
good_area:
write = error_code & PF_WRITE;
/*访问权限不够则通过bad_area_access_error()处理,该函数是对__bad_area()的封装,只不过
发送给用户进程的信号为SEGV_ACCERR*/
if (unlikely(access_error(error_code, write, vma))) {
bad_area_access_error(regs, error_code, address);
return;
}
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
* the fault:
*/
/*分配新的页表和页框*/
fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
if (unlikely(fault & VM_FAULT_ERROR)) {
mm_fault_error(regs, error_code, address, fault);
return;
}
if (fault & VM_FAULT_MAJOR) {
tsk->maj_flt++;
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
regs, address);
} else {
tsk->min_flt++;
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
regs, address);
}
check_v8086_mode(regs, address, tsk);
up_read(&mm->mmap_sem);
}
bad_area()函数的主体函数为__bad_area()-->__bad_area_nosemaphore(),这个函数在上一篇博文中分析了其对内核的非法访问的处理,现在看其对用户空间的非法访问的处理
__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 */
/*错误发生在用户态,则向用户进程发送一个SIGSEG信号V*/
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);

sales@spasvo.com