arch/arm64/mm/pageattr.c
Source file repositories/reference/linux-study-clean/arch/arm64/mm/pageattr.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/mm/pageattr.c- Extension
.c- Size
- 11032 bytes
- Lines
- 426
- Domain
- Architecture Layer
- Bucket
- arch/arm64
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- 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/kernel.hlinux/mm.hlinux/module.hlinux/mem_encrypt.hlinux/sched.hlinux/vmalloc.hlinux/pagewalk.hasm/cacheflush.hasm/pgtable-prot.hasm/set_memory.hasm/tlbflush.hasm/kfence.h
Detected Declarations
struct page_change_datafunction set_pageattr_masksfunction pageattr_pud_entryfunction pageattr_pmd_entryfunction pageattr_pte_entryfunction can_set_direct_mapfunction update_range_protfunction __change_memory_commonfunction change_memory_commonfunction pgprot_valfunction set_memory_rofunction set_memory_rwfunction set_memory_nxfunction set_memory_xfunction set_memory_validfunction set_direct_map_invalid_noflushfunction set_direct_map_default_noflushfunction __set_memory_enc_decfunction realm_set_memory_encryptedfunction realm_set_memory_decryptedfunction realm_register_memory_enc_opsfunction set_direct_map_valid_noflushfunction set_direct_map_valid_noflushfunction kernel_page_present
Annotated Snippet
struct page_change_data {
pgprot_t set_mask;
pgprot_t clear_mask;
};
static ptval_t set_pageattr_masks(ptval_t val, struct mm_walk *walk)
{
struct page_change_data *masks = walk->private;
/*
* Some users clear and set bits which alias each other (e.g. PTE_NG and
* PTE_PRESENT_INVALID). It is therefore important that we always clear
* first then set.
*/
val &= ~(pgprot_val(masks->clear_mask));
val |= (pgprot_val(masks->set_mask));
return val;
}
static int pageattr_pud_entry(pud_t *pud, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
pud_t val = pudp_get(pud);
if (pud_leaf(val)) {
if (WARN_ON_ONCE((next - addr) != PUD_SIZE))
return -EINVAL;
val = __pud(set_pageattr_masks(pud_val(val), walk));
set_pud(pud, val);
walk->action = ACTION_CONTINUE;
}
return 0;
}
static int pageattr_pmd_entry(pmd_t *pmd, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
pmd_t val = pmdp_get(pmd);
if (pmd_leaf(val)) {
if (WARN_ON_ONCE((next - addr) != PMD_SIZE))
return -EINVAL;
val = __pmd(set_pageattr_masks(pmd_val(val), walk));
set_pmd(pmd, val);
walk->action = ACTION_CONTINUE;
}
return 0;
}
static int pageattr_pte_entry(pte_t *pte, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
pte_t val = __ptep_get(pte);
val = __pte(set_pageattr_masks(pte_val(val), walk));
__set_pte(pte, val);
return 0;
}
static const struct mm_walk_ops pageattr_ops = {
.pud_entry = pageattr_pud_entry,
.pmd_entry = pageattr_pmd_entry,
.pte_entry = pageattr_pte_entry,
};
bool rodata_full __ro_after_init = true;
bool can_set_direct_map(void)
{
/*
* rodata_full, DEBUG_PAGEALLOC and a Realm guest all require linear
* map to be mapped at page granularity, so that it is possible to
* protect/unprotect single pages.
*
* KFENCE pool requires page-granular mapping if initialized late.
*
* Realms need to make pages shared/protected at page granularity.
*/
return rodata_full || debug_pagealloc_enabled() ||
arm64_kfence_can_set_direct_map() || is_realm_world();
}
static int update_range_prot(unsigned long start, unsigned long size,
pgprot_t set_mask, pgprot_t clear_mask)
{
struct page_change_data data;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/mm.h`, `linux/module.h`, `linux/mem_encrypt.h`, `linux/sched.h`, `linux/vmalloc.h`, `linux/pagewalk.h`, `asm/cacheflush.h`.
- Detected declarations: `struct page_change_data`, `function set_pageattr_masks`, `function pageattr_pud_entry`, `function pageattr_pmd_entry`, `function pageattr_pte_entry`, `function can_set_direct_map`, `function update_range_prot`, `function __change_memory_common`, `function change_memory_common`, `function pgprot_val`.
- Atlas domain: Architecture Layer / arch/arm64.
- Implementation status: source implementation candidate.
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.