Linux page fault handling--User space "Go"

Source: Internet
Author: User

Transferred from: http://blog.csdn.net/vanbreaker/article/details/7870769

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

There are two types of fault pages in user space--

1. The linear address that triggered the exception is in the VMA of the user space, but the physical page is not assigned, and if Access is OK, the kernel assigns the corresponding physical page to the process.

2. The linear address of the triggering exception is not in the VMA of the user space, this situation is determined not because the user process stack space consumed by the page fault triggered by the exception, if it is in the user space to expand the stack area, and assign the corresponding physical page, if not as an illegal address access to deal with, The kernel will end the process

Here's how the Do_page_fault () function handles the error of user space pages

[CPP]View PlainCopy
  1. Dotraplinkage void __kprobes
  2. Do_page_fault (struct pt_regs *regs, unsigned long error_code)
  3. {
  4. struct vm_area_struct *vma;
  5. struct task_struct *tsk;
  6. unsigned long address;
  7. struct mm_struct *mm;
  8. int write;
  9. int fault;
  10. Tsk = current; //Get current process
  11. MM = tsk->mm; //Gets the address space of the current process
  12. /* Get the faulting address: */
  13. Address = Read_cr2 (); //Read the CR2 register to get the access address that triggered the exception
  14. ...
  15. ...
  16. ...
  17. ...
  18. VMA = FIND_VMA (mm, address); //Try to find a vma,vma that is closest to address contains address or after address
  19. / * Does not find such a VMA that there is no virtual memory area after address, so the address is definitely invalid,
  20. Handled by the Bad_area () path, the body of the Bad_area () is __bad_area ()-->bad_area_nosemaphore () */
  21. if (unlikely (!VMA)) {
  22. Bad_area (Regs, Error_code, address);
  23. return;
  24. }
  25. / * If the address is included in VMA, jump to good_area for processing * /
  26. if (likely (Vma->vm_start <= address))
  27. Goto Good_area;
  28. /* is not the first two cases, the decision is not due to the user stack occupied by the page box has been used, and a push instruction
  29. An exception that is referenced by a virtual memory region that has not yet been bound to the page box, which belongs to the virtual memory area of the stack, its vm_growsdown bit
  30. Be placed */
  31. if (Unlikely (!) ( Vma->vm_flags & Vm_growsdown )) {
  32. Bad_area (Regs, Error_code, address); //Is not a stack area, it is handled with Bad_area ()
  33. return;
  34. }
  35. if (Error_code & pf_user) {//must be in user space
  36. /* 
  37. * Accessing the stack below%SP is always a bug.
  38. * The large cushion allows instructions like enter
  39. * and Pusha to work. ("Enter $65535, $31" pushes
  40. * Pointers and then decrements%sp by 65535.)
  41. */
  42. / * Here, only the address is high enough (the difference from the stack pointer is not greater than 65536+32*sizeof (unsigned long)),
  43. To allow the user process to extend its stack address space, otherwise bad_area () processing */
  44. if (unlikely (address + 65536 + * sizeof (unsigned long) < REGS->SP)) {
  45. Bad_area (Regs, Error_code, address);
  46. return;
  47. }
  48. }
  49. if (Unlikely (Expand_stack (VMA, address))) {//stack extension not successful also handled by Bad_area ()
  50. Bad_area (Regs, Error_code, address);
  51. return;
  52. }
  53. /* 
  54. * Ok, we have a good vm_area for this memory access, so
  55. * We can handle it.
  56. */
  57. Good_area:
  58. Write = Error_code & pf_write;
  59. / * Insufficient access is handled by Bad_area_access_error (), which is the encapsulation of __bad_area (), except
  60. The signal sent to the user process is segv_accerr*/
  61. if (Unlikely (Access_error (Error_code, write, VMA))) {
  62. Bad_area_access_error (Regs, Error_code, address);
  63. return;
  64. }
  65. /* 
  66. * If for any reason at all we couldn ' t handle the fault,
  67. * Make sure we exit gracefully rather than endlessly redo
  68. * The fault:
  69. */
  70. /* Assign a new Page table and Page box */
  71. Fault = Handle_mm_fault (mm, VMA, address, write?) fault_flag_write:0);
  72. if (Unlikely (Fault & Vm_fault_error)) {
  73. Mm_fault_error (Regs, Error_code, address, fault);
  74. return;
  75. }
  76. if (fault & vm_fault_major) {
  77. tsk->maj_flt++;
  78. Perf_sw_event (Perf_count_sw_page_faults_maj, 1, 0,
  79. Regs, address);
  80. } Else {
  81. tsk->min_flt++;
  82. Perf_sw_event (perf_count_sw_page_faults_min, 1, 0,
  83. Regs, address);
  84. }
  85. Check_v8086_mode (regs, Address, tsk);
  86. Up_read (&mm->mmap_sem);
  87. }


The body function of the Bad_area () function is __bad_area ()-->__bad_area_nosemaphore (), which analyzes its handling of illegal access to the kernel in its previous blog post, and now sees its handling of illegal access to user space

[CPP]View PlainCopy
  1. __bad_area_nosemaphore (struct pt_regs *regs, unsigned long error_code,
  2. Unsigned long address, int si_code)
  3. {
  4. struct Task_struct *tsk = current;
  5. / * User mode accesses just cause a SIGSEGV * /
  6. / * error occurs in the user state, then a sigseg signal is sent to the user process v*/
  7. if (Error_code & Pf_user) {
  8. /* 
  9. * It ' s possible to has interrupts off here:
  10. */
  11. Local_irq_enable ();
  12. /* 
  13. * Valid to does another page fault here because this one came
  14. * FROM User space:
  15. */
  16. if (Is_prefetch (regs, Error_code, address))
  17. return;
  18. if (is_errata100 (regs, address))
  19. return;
  20. if (unlikely (show_unhandled_signals))
  21. Show_signal_msg (Regs, Error_code, Address, tsk);
  22. /* Kernel addresses is always protection faults: */
  23. tsk->thread.cr2 = address;
  24. tsk->Thread.error_code = Error_code |  (Address >= task_size);
  25. tsk->thread.trap_no = 14;
  26. Force_sig_info_fault (SIGSEGV, Si_code, Address, tsk);
  27. return;
  28. }
  29. ...
  30. ...
  31. }

After determining that the exception is due to the physical page is not assigned, and then through the Good_area path to processing, it is conceivable that the path in determining the access rights sufficient, will complete the page table and the physical page allocation, the task has Handle_mm_fault () function to complete

[CPP]View PlainCopy
  1. int Handle_mm_fault (struct mm_struct *mm, struct vm_area_struct *vma,
  2. Unsigned long address, unsigned int flags)
  3. {
  4. pgd_t *PGD;
  5. pud_t *pud;
  6. pmd_t *PMD;
  7. pte_t *pte;
  8. __set_current_state (task_running);
  9. Count_vm_event (Pgfault);
  10. if (Unlikely (Is_vm_hugetlb_page (VMA)))
  11. return Hugetlb_fault (mm, VMA, address, flags);
  12. PGD = Pgd_offset (mm, address);
  13. PUD = Pud_alloc (mm, PGD, address); //Assign the PUD directory
  14. if (!pud)
  15. return vm_fault_oom;
  16. PMD = Pmd_alloc (mm, pud, address); //Assign PMD directory
  17. if (!PMD)
  18. return vm_fault_oom;
  19. Pte = Pte_alloc_map (mm, PMD, address); //Allocation Pte Table
  20. if (!pte)
  21. return vm_fault_oom;
  22. the task of/*handle_pte_fault () is to bind the PTE with a new page box, which will be processed differently depending on the condition of the PTEs page table entry.
  23. return Handle_pte_fault (mm, VMA, address, PTE, PMD, flags);
  24. }

The processing of the Handle_pte_fault () function is complicated, because it has to do a variety of different processing according to the different state of the physical page corresponding to the PTE page table item, and the specific analysis is given later.

Linux page fault handling--User space "Go"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.