arch/powerpc/lib/code-patching.c
Source file repositories/reference/linux-study-clean/arch/powerpc/lib/code-patching.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/lib/code-patching.c- Extension
.c- Size
- 16480 bytes
- Lines
- 650
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- 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/kprobes.hlinux/mmu_context.hlinux/random.hlinux/vmalloc.hlinux/init.hlinux/cpuhotplug.hlinux/uaccess.hlinux/jump_label.hasm/debug.hasm/pgalloc.hasm/tlb.hasm/tlbflush.hasm/page.hasm/text-patching.hasm/inst.h
Detected Declarations
struct patch_contextfunction __patch_memfunction raw_patch_instructionfunction mm_patch_enabledfunction switch_mm_irqs_offfunction stop_using_temp_mmfunction text_area_cpu_upfunction text_area_cpu_downfunction put_patching_mmfunction text_area_cpu_up_mmfunction text_area_cpu_down_mmfunction poking_initfunction get_patch_pfnfunction __do_patch_mem_mmfunction __do_patch_memfunction patch_memfunction patch_instructionfunction patch_uintfunction patch_ulongfunction patch_instructionfunction patch_memset64function patch_memset32function __patch_instructionsfunction __do_patch_instructions_mmfunction __do_patch_instructionsfunction patch_instructionsfunction patch_branchfunction analyse_instrfunction create_cond_branchfunction instr_is_relative_branchfunction instr_is_relative_link_branchfunction branch_iform_targetfunction branch_bform_targetfunction branch_targetfunction translate_branch
Annotated Snippet
struct patch_context {
union {
struct vm_struct *area;
struct mm_struct *mm;
};
unsigned long addr;
pte_t *pte;
};
static DEFINE_PER_CPU(struct patch_context, cpu_patching_context);
static bool mm_patch_enabled(void)
{
return IS_ENABLED(CONFIG_SMP) && radix_enabled();
}
/*
* The following applies for Radix MMU. Hash MMU has different requirements,
* and so is not supported.
*
* Changing mm requires context synchronising instructions on both sides of
* the context switch, as well as a hwsync between the last instruction for
* which the address of an associated storage access was translated using
* the current context.
*
* switch_mm_irqs_off() performs an isync after the context switch. It is
* the responsibility of the caller to perform the CSI and hwsync before
* starting/stopping the temp mm.
*/
static struct mm_struct *start_using_temp_mm(struct mm_struct *temp_mm)
{
struct mm_struct *orig_mm = current->active_mm;
lockdep_assert_irqs_disabled();
switch_mm_irqs_off(orig_mm, temp_mm, current);
WARN_ON(!mm_is_thread_local(temp_mm));
suspend_breakpoints();
return orig_mm;
}
static void stop_using_temp_mm(struct mm_struct *temp_mm,
struct mm_struct *orig_mm)
{
lockdep_assert_irqs_disabled();
switch_mm_irqs_off(temp_mm, orig_mm, current);
restore_breakpoints();
}
static int text_area_cpu_up(unsigned int cpu)
{
struct vm_struct *area;
unsigned long addr;
int err;
area = get_vm_area(PAGE_SIZE, 0);
if (!area) {
WARN_ONCE(1, "Failed to create text area for cpu %d\n",
cpu);
return -1;
}
// Map/unmap the area to ensure all page tables are pre-allocated
addr = (unsigned long)area->addr;
err = map_kernel_page(addr, __pa_symbol(empty_zero_page), PAGE_KERNEL_RO);
if (err)
return err;
unmap_kernel_page(addr);
this_cpu_write(cpu_patching_context.area, area);
this_cpu_write(cpu_patching_context.addr, addr);
this_cpu_write(cpu_patching_context.pte, virt_to_kpte(addr));
return 0;
}
static int text_area_cpu_down(unsigned int cpu)
{
free_vm_area(this_cpu_read(cpu_patching_context.area));
this_cpu_write(cpu_patching_context.area, NULL);
this_cpu_write(cpu_patching_context.addr, 0);
this_cpu_write(cpu_patching_context.pte, NULL);
return 0;
}
static void put_patching_mm(struct mm_struct *mm, unsigned long patching_addr)
{
struct mmu_gather tlb;
Annotation
- Immediate include surface: `linux/kprobes.h`, `linux/mmu_context.h`, `linux/random.h`, `linux/vmalloc.h`, `linux/init.h`, `linux/cpuhotplug.h`, `linux/uaccess.h`, `linux/jump_label.h`.
- Detected declarations: `struct patch_context`, `function __patch_mem`, `function raw_patch_instruction`, `function mm_patch_enabled`, `function switch_mm_irqs_off`, `function stop_using_temp_mm`, `function text_area_cpu_up`, `function text_area_cpu_down`, `function put_patching_mm`, `function text_area_cpu_up_mm`.
- Atlas domain: Architecture Layer / arch/powerpc.
- 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.