Chapter 4: Virtual Process Memory
VM_NONLINEAR notset?
Check flags and sizes
vma_prio_tree_remove
vma_nonlinear_insert
populate_range
make_pages_present
sys_remap_file_pages
Set VM_NONLINEAR
MAP_NONBLOCK not set?
Figure 4-15: Code flow diagram forsys_remap_file_pages.
After all flags have been checked and the kernel hasensured that the range to be remapped is valid, the
vm_area_structinstance of the target region is selected byfind_vma. If the destination has not been
nonlinearly remapped before, the flagVM_NONLINEARis not set invm_area_struct->vm_flags.Inthis
case, the linear mapping has to be removed from the prio tree withvma_prio_tree_remove, and it is
inserted into the list of nonlinear mappings usingvma_nonlinear_insert.
The crucial step is to install the modified page table entries. The auxiliary routinepopulate_rangeis
responsible for this:
mm/fremap.c
static int populate_range(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, unsigned long size, pgoff_t pgoff)
{
int err;
...
The mapping is described byvma. The region starting currently at page offsetpgoffwith lengthlength
is to be remapped to addressaddr. Since this can involve multiple pages, the kernel needs to iterate over
all of them and install new page table entries withinstall_file_pte:
mm/fremap.c
do {
err = install_file_pte(mm, vma, addr, pgoff, vma->vm_page_prot);
if (err)
return err;
size -= PAGE_SIZE;
addr += PAGE_SIZE;
pgoff++;
} while (size);
return 0;
}