arch/powerpc/kernel/optprobes.c
Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/optprobes.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/kernel/optprobes.c- Extension
.c- Size
- 8661 bytes
- Lines
- 305
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kprobes.hlinux/jump_label.hlinux/types.hlinux/slab.hlinux/list.hasm/kprobes.hasm/ptrace.hasm/cacheflush.hasm/text-patching.hasm/sstep.hasm/ppc-opcode.hasm/inst.h
Detected Declarations
function free_optinsn_pagefunction can_optimizefunction addressfunction optimized_callbackfunction arch_remove_optimized_kprobefunction patch_imm32_load_insnsfunction patch_imm64_load_insnsfunction patch_imm_load_insnsfunction arch_prepare_optimized_kprobefunction arch_prepared_optinsnfunction arch_check_optimized_kprobefunction arch_optimize_kprobesfunction list_for_each_entry_safefunction arch_unoptimize_kprobefunction arch_unoptimize_kprobesfunction list_for_each_entry_safefunction arch_within_optimized_kprobe
Annotated Snippet
analyse_instr(&op, ®s, ppc_inst_read(p->ainsn.insn)) == 1) {
emulate_update_regs(®s, &op);
nip = regs.nip;
}
return nip;
}
static void optimized_callback(struct optimized_kprobe *op,
struct pt_regs *regs)
{
/* This is possible if op is under delayed unoptimizing */
if (kprobe_disabled(&op->kp))
return;
preempt_disable();
if (kprobe_running()) {
kprobes_inc_nmissed_count(&op->kp);
} else {
__this_cpu_write(current_kprobe, &op->kp);
regs_set_return_ip(regs, (unsigned long)op->kp.addr);
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
opt_pre_handler(&op->kp, regs);
__this_cpu_write(current_kprobe, NULL);
}
preempt_enable();
}
NOKPROBE_SYMBOL(optimized_callback);
void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
{
if (op->optinsn.insn) {
free_optinsn_slot(op->optinsn.insn, 1);
op->optinsn.insn = NULL;
}
}
static void patch_imm32_load_insns(unsigned long val, int reg, kprobe_opcode_t *addr)
{
patch_instruction(addr++, ppc_inst(PPC_RAW_LIS(reg, PPC_HI(val))));
patch_instruction(addr, ppc_inst(PPC_RAW_ORI(reg, reg, PPC_LO(val))));
}
/*
* Generate instructions to load provided immediate 64-bit value
* to register 'reg' and patch these instructions at 'addr'.
*/
static void patch_imm64_load_insns(unsigned long long val, int reg, kprobe_opcode_t *addr)
{
patch_instruction(addr++, ppc_inst(PPC_RAW_LIS(reg, PPC_HIGHEST(val))));
patch_instruction(addr++, ppc_inst(PPC_RAW_ORI(reg, reg, PPC_HIGHER(val))));
patch_instruction(addr++, ppc_inst(PPC_RAW_SLDI(reg, reg, 32)));
patch_instruction(addr++, ppc_inst(PPC_RAW_ORIS(reg, reg, PPC_HI(val))));
patch_instruction(addr, ppc_inst(PPC_RAW_ORI(reg, reg, PPC_LO(val))));
}
static void patch_imm_load_insns(unsigned long val, int reg, kprobe_opcode_t *addr)
{
if (IS_ENABLED(CONFIG_PPC64))
patch_imm64_load_insns(val, reg, addr);
else
patch_imm32_load_insns(val, reg, addr);
}
int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
{
ppc_inst_t branch_op_callback, branch_emulate_step, temp;
unsigned long op_callback_addr, emulate_step_addr;
kprobe_opcode_t *buff;
long b_offset;
unsigned long nip, size;
int rc, i;
nip = can_optimize(p);
if (!nip)
return -EILSEQ;
/* Allocate instruction slot for detour buffer */
buff = get_optinsn_slot();
if (!buff)
return -ENOMEM;
/*
* OPTPROBE uses 'b' instruction to branch to optinsn.insn.
*
* The target address has to be relatively nearby, to permit use
* of branch instruction in powerpc, because the address is specified
* in an immediate field in the instruction opcode itself, ie 24 bits
Annotation
- Immediate include surface: `linux/kprobes.h`, `linux/jump_label.h`, `linux/types.h`, `linux/slab.h`, `linux/list.h`, `asm/kprobes.h`, `asm/ptrace.h`, `asm/cacheflush.h`.
- Detected declarations: `function free_optinsn_page`, `function can_optimize`, `function address`, `function optimized_callback`, `function arch_remove_optimized_kprobe`, `function patch_imm32_load_insns`, `function patch_imm64_load_insns`, `function patch_imm_load_insns`, `function arch_prepare_optimized_kprobe`, `function arch_prepared_optinsn`.
- 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.