Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 4: Virtual Process Memory


arch/i386/mm/fault.c
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
...
if (expand_stack(vma, address))
goto bad_area;

good_areaandbad_areaare labels to which the kernel jumps once it has discovered whether the address
is valid or invalid.

The search can yield various results:

❑ No region is found whose end address is afteraddress, in which case access is invalid.
❑ The fault address is within the region found, in which case access is valid and the page fault is
corrected by the kernel.
❑ A region is found whose end address is after the fault address but the fault address isnotwithin
the region. There may be two reasons for this:


  1. TheVM_GROWSDOWNflag of the region is set; this means that the region is a stack that grows
    from top to bottom.expand_stackis then invoked to enlarge the stack accordingly. If it
    succeeds, 0 is returned as the result, and the kernel resumes execution atgood_area.Oth-
    erwise, access is interpreted as invalid.

  2. The region found is not a stack, so access is invalid.


good_areafollows on immediately after the above code.

arch/i386/mm/fault.c
...
good_area:
si_code = SEGV_ACCERR;
write = 0;
switch (error_code & 3) {
default: /* 3: write, present */
/* fall through */
case 2: /* write, not present */
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
write++;
break;
case 1: /* read, present */
goto bad_area;
case 0: /* read, not present */
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
...
Free download pdf