arch/powerpc/mm/book3s64/hash_pgtable.c
Source file repositories/reference/linux-study-clean/arch/powerpc/mm/book3s64/hash_pgtable.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/mm/book3s64/hash_pgtable.c- Extension
.c- Size
- 16566 bytes
- Lines
- 589
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/sched.hlinux/mm_types.hlinux/mm.hlinux/page_table_check.hlinux/stop_machine.hasm/sections.hasm/mmu.hasm/tlb.hasm/firmware.hmm/mmu_decl.htrace/events/thp.h
Detected Declarations
struct change_memory_parmsfunction memoryfunction hash__vmemmap_remove_mappingfunction hash__map_kernel_pagefunction hash__pmd_hugepage_updatefunction do_nothingfunction hash__pmdp_collapse_flushfunction hash__pgtable_trans_huge_depositfunction hash__pgtable_trans_huge_withdrawfunction hpte_do_hugepage_flushfunction hash__pmdp_huge_get_and_clearfunction hash__has_transparent_hugepagefunction change_memory_rangefunction chmem_secondary_loopfunction change_memory_range_fnfunction hash__change_memory_rangefunction hash__mark_rodata_rofunction hash__mark_initmem_nxexport hash__has_transparent_hugepage
Annotated Snippet
struct change_memory_parms {
unsigned long start, end, newpp;
unsigned int step, nr_cpus;
atomic_t master_cpu;
atomic_t cpu_counter;
};
// We'd rather this was on the stack but it has to be in the RMO
static struct change_memory_parms chmem_parms;
// And therefore we need a lock to protect it from concurrent use
static DEFINE_MUTEX(chmem_lock);
static void change_memory_range(unsigned long start, unsigned long end,
unsigned int step, unsigned long newpp)
{
unsigned long idx;
pr_debug("Changing page protection on range 0x%lx-0x%lx, to 0x%lx, step 0x%x\n",
start, end, newpp, step);
for (idx = start; idx < end; idx += step)
/* Not sure if we can do much with the return value */
mmu_hash_ops.hpte_updateboltedpp(newpp, idx, mmu_linear_psize,
mmu_kernel_ssize);
}
static int notrace chmem_secondary_loop(struct change_memory_parms *parms)
{
unsigned long msr, tmp, flags;
int *p;
p = &parms->cpu_counter.counter;
local_irq_save(flags);
hard_irq_disable();
asm volatile (
// Switch to real mode and leave interrupts off
"mfmsr %[msr] ;"
"li %[tmp], %[MSR_IR_DR] ;"
"andc %[tmp], %[msr], %[tmp] ;"
"mtmsrd %[tmp] ;"
// Tell the master we are in real mode
"1: "
"lwarx %[tmp], 0, %[p] ;"
"addic %[tmp], %[tmp], -1 ;"
"stwcx. %[tmp], 0, %[p] ;"
"bne- 1b ;"
// Spin until the counter goes to zero
"2: ;"
"lwz %[tmp], 0(%[p]) ;"
"cmpwi %[tmp], 0 ;"
"bne- 2b ;"
// Switch back to virtual mode
"mtmsrd %[msr] ;"
: // outputs
[msr] "=&r" (msr), [tmp] "=&b" (tmp), "+m" (*p)
: // inputs
[p] "b" (p), [MSR_IR_DR] "i" (MSR_IR | MSR_DR)
: // clobbers
"cc", "xer"
);
local_irq_restore(flags);
return 0;
}
static int change_memory_range_fn(void *data)
{
struct change_memory_parms *parms = data;
// First CPU goes through, all others wait.
if (atomic_xchg(&parms->master_cpu, 1) == 1)
return chmem_secondary_loop(parms);
// Wait for all but one CPU (this one) to call-in
while (atomic_read(&parms->cpu_counter) > 1)
barrier();
change_memory_range(parms->start, parms->end, parms->step, parms->newpp);
mb();
// Signal the other CPUs that we're done
Annotation
- Immediate include surface: `linux/sched.h`, `linux/mm_types.h`, `linux/mm.h`, `linux/page_table_check.h`, `linux/stop_machine.h`, `asm/sections.h`, `asm/mmu.h`, `asm/tlb.h`.
- Detected declarations: `struct change_memory_parms`, `function memory`, `function hash__vmemmap_remove_mapping`, `function hash__map_kernel_page`, `function hash__pmd_hugepage_update`, `function do_nothing`, `function hash__pmdp_collapse_flush`, `function hash__pgtable_trans_huge_deposit`, `function hash__pgtable_trans_huge_withdraw`, `function hpte_do_hugepage_flush`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: integration implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.