mm/pagewalk.c
Source file repositories/reference/linux-study-clean/mm/pagewalk.c
File Facts
- System
- Linux kernel
- Corpus path
mm/pagewalk.c- Extension
.c- Size
- 29048 bytes
- Lines
- 1027
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/pagewalk.hlinux/highmem.hlinux/sched.hlinux/hugetlb.hlinux/mmu_context.hlinux/swap.hasm/tlbflush.hinternal.h
Detected Declarations
function real_depthfunction walk_pte_range_innerfunction walk_pte_rangefunction walk_pmd_rangefunction walk_pud_rangefunction walk_p4d_rangefunction walk_pgd_rangefunction hugetlb_entry_endfunction walk_hugetlb_rangefunction walk_hugetlb_rangefunction walk_page_testfunction vmafunction __walk_page_rangefunction process_mm_walk_lockfunction process_vma_walk_lockfunction walk_page_rangefunction check_ops_safefunction pte_entryfunction walk_page_rangefunction walk_kernel_page_table_range_locklessfunction walk_page_rangefunction walk_page_range_vma_unsafefunction walk_page_range_vmafunction walk_page_vmafunction walk_page_rangefunction vm_normal_pagefunction is_huge_zero_pmd
Annotated Snippet
if (ops->install_pte && pte_none(ptep_get(pte))) {
pte_t new_pte;
err = ops->install_pte(addr, addr + PAGE_SIZE, &new_pte,
walk);
if (err)
break;
set_pte_at(walk->mm, addr, pte, new_pte);
/* Non-present before, so for arches that need it. */
if (!WARN_ON_ONCE(walk->no_vma))
update_mmu_cache(walk->vma, addr, pte);
} else {
err = ops->pte_entry(pte, addr, addr + PAGE_SIZE, walk);
if (err)
break;
}
if (addr >= end - PAGE_SIZE)
break;
addr += PAGE_SIZE;
pte++;
}
return err;
}
static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
pte_t *pte;
int err = 0;
spinlock_t *ptl;
if (walk->no_vma) {
/*
* pte_offset_map() might apply user-specific validation.
* Indeed, on x86_64 the pmd entries set up by init_espfix_ap()
* fit its pmd_bad() check (_PAGE_NX set and _PAGE_RW clear),
* and CONFIG_EFI_PGT_DUMP efi_mm goes so far as to walk them.
*/
if (walk->mm == &init_mm || addr >= TASK_SIZE)
pte = pte_offset_kernel(pmd, addr);
else
pte = pte_offset_map(pmd, addr);
if (pte) {
err = walk_pte_range_inner(pte, addr, end, walk);
if (walk->mm != &init_mm && addr < TASK_SIZE)
pte_unmap(pte);
}
} else {
pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
if (pte) {
err = walk_pte_range_inner(pte, addr, end, walk);
pte_unmap_unlock(pte, ptl);
}
}
if (!pte)
walk->action = ACTION_AGAIN;
return err;
}
static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
pud_t pudval = pudp_get(pud);
pmd_t *pmd;
unsigned long next;
const struct mm_walk_ops *ops = walk->ops;
bool has_handler = ops->pte_entry;
bool has_install = ops->install_pte;
int err = 0;
int depth = real_depth(3);
/*
* For PTE handling, pte_offset_map_lock() takes care of checking
* whether there actually is a page table. But it also has to be
* very careful about concurrent page table reclaim.
*
* Similarly, we have to be careful here - a PUD entry that points
* to a PMD table cannot go away, so we can just walk it. But if
* it's something else, we need to ensure we didn't race something,
* so need to retry.
*
* A pertinent example of this is a PUD refault after PUD split -
* we will need to split again or risk accessing invalid memory.
*/
if (!pud_present(pudval) || pud_leaf(pudval)) {
walk->action = ACTION_AGAIN;
return 0;
}
Annotation
- Immediate include surface: `linux/pagewalk.h`, `linux/highmem.h`, `linux/sched.h`, `linux/hugetlb.h`, `linux/mmu_context.h`, `linux/swap.h`, `asm/tlbflush.h`, `internal.h`.
- Detected declarations: `function real_depth`, `function walk_pte_range_inner`, `function walk_pte_range`, `function walk_pmd_range`, `function walk_pud_range`, `function walk_p4d_range`, `function walk_pgd_range`, `function hugetlb_entry_end`, `function walk_hugetlb_range`, `function walk_hugetlb_range`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.