I’m trying to write a function that write-protects every pte in a given vm_area_struct. What is the function that gives me the ptep for a given address? I have:
pte_t *ptep;
for (addr = start; addr < end; addr += PAGE_SIZE) {
ptep = WHATS_THIS_FUNCTION_CALLED(addr);
ptep_set_wrprotect(mm, addr, ptep);
}
What’s the WHATS_THIS_FUNCTION_CALLED called?
The short answer to your question is to use
__get_locked_pte. However, I would advise against it since there are much better (efficient and fair in terms of resource contention) ways to accomplish your goal.In linux, the typical idiom for traversing page tables is with a nested for loop four levels deep (four is the number of page table levels linux supports). For examples, see
copy_page_rangeandapply_to_page_rangein mm/memory.c. In fact, if you look closely atcopy_page_range, it is called when forking fromdup_mmapin kernel/fork.c. It operates on an entirevm_area_structessentially.You can replicate the idiom used in either of those functions. There are some caveats, however. For example,
copy_page_rangefully supports transparent hugepages (2.6.38) by using a completely separatecopy_huge_pmdinsidecopy_pmd_range. Unless you want to write two separate functions (one for normal pages and one for transparent huge pages, seeGracefull fallbackinDocumentation/vm/transhuge.txt.The point is that virtual memory in linux is very complicated, so be sure to completely understand every possible use case.
follow_pagein mm/memory.c should demonstrate how to cover all of your bases.