Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1044972
  • 博文数量: 277
  • 博客积分: 8313
  • 博客等级: 中将
  • 技术积分: 2976
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-22 11:25
文章分类

全部博文(277)

文章存档

2013年(17)

2012年(66)

2011年(104)

2010年(90)

我的朋友

分类: LINUX

2012-06-21 10:03:46

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

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

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

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

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

[cpp] view plaincopyprint?

1.       static void  

2.       __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,  

3.                      unsigned long address, int si_code)  

4.       {  

5.           struct task_struct *tsk = current;  

6.         

7.           /* User mode accesses just cause a SIGSEGV */  

8.           /*如果用户态*/  

9.           if (error_code & PF_USER) {  

10.             /* 

11.              * It's possible to have interrupts off here: 

12.              */  

13.             local_irq_enable();  

14.       

15.             /* 

16.              * Valid to do another page fault here because this one came 

17.              * from user space: 

18.              */  

19.             if (is_prefetch(regs, error_code, address))  

20.                 return;  

21.       

22.             if (is_errata100(regs, address))  

23.                 return;  

24.       

25.             if (unlikely(show_unhandled_signals))  

26.                 show_signal_msg(regs, error_code, address, tsk);  

27.       

28.             /* Kernel addresses are always protection faults: */  

29.             tsk->thread.cr2      = address;  

30.             tsk->thread.error_code   = error_code | (address >= TASK_SIZE);  

31.             tsk->thread.trap_no  = 14;  

32.             /*发送SIGSEGV信号*/  

33.             force_sig_info_fault(SIGSEGV, si_code, address, tsk);  

34.       

35.             return;  

36.         }  

37.       

38.         if (is_f00f_bug(regs, address))  

39.             return;  

40.         /*内核态访问*/  

41.         no_context(regs, error_code, address);  

42.     }  

内核访问时

[cpp] view plaincopyprint?

1.       static noinline void  

2.       no_context(struct pt_regs *regs, unsigned long error_code,  

3.              unsigned long address)  

4.       {  

5.           struct task_struct *tsk = current;  

6.           unsigned long *stackend;  

7.           unsigned long flags;  

8.           int sig;  

9.         

10.         /* Are we prepared to handle this kernel fault? */  

11.         /*地址是一个系统调用参数,"修正码",典型情况是发送 

12.         SIGSEGV信号*/  

13.         if (fixup_exception(regs))  

14.             return;  

15.       

16.         /* 

17.          * 32-bit: 

18.          * 

19.          *   Valid to do another page fault here, because if this fault 

20.          *   had been triggered by is_prefetch fixup_exception would have 

21.          *   handled it. 

22.          * 

23.          * 64-bit: 

24.          * 

25.          *   Hall of shame of CPU/BIOS bugs. 

26.          */  

27.         if (is_prefetch(regs, error_code, address))  

28.             return;  

29.       

30.         if (is_errata93(regs, address))  

31.             return;  

32.       

33.         /* 

34.          * Oops. The kernel tried to access some bad page. We'll have to 

35.          * terminate things with extreme prejudice: 

36.          */  

37.          /*下面代码用于oops信息的显示和杀死当前 

38.          进程*/  

39.         flags = oops_begin();  

40.       

41.         show_fault_oops(regs, error_code, address);  

42.       

43.         stackend = end_of_stack(tsk);  

44.         if (*stackend != STACK_END_MAGIC)  

45.             printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");  

46.       

47.         tsk->thread.cr2      = address;  

48.         tsk->thread.trap_no  = 14;  

49.         tsk->thread.error_code   = error_code;  

50.       

51.         sig = SIGKILL;  

52.         if (__die("Oops", regs, error_code))  

53.             sig = 0;  

54.       

55.         /* Executive summary in case the body of the oops scrolled away */  

56.         printk(KERN_EMERG "CR2: %016lx\n", address);  

57.       

58.         oops_end(flags, regs, sig);  

59.     }  

 

阅读(1112) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~