arch/riscv/kernel/ftrace.c
Source file repositories/reference/linux-study-clean/arch/riscv/kernel/ftrace.c
File Facts
- System
- Linux kernel
- Corpus path
arch/riscv/kernel/ftrace.c- Extension
.c- Size
- 6820 bytes
- Lines
- 272
- Domain
- Architecture Layer
- Bucket
- arch/riscv
- 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.
- 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/ftrace.hlinux/uaccess.hlinux/memory.hlinux/irqflags.hlinux/stop_machine.hasm/cacheflush.hasm/text-patching.h
Detected Declarations
function Copyrightfunction ftrace_arch_code_modify_post_processfunction ftrace_call_adjustfunction arch_ftrace_get_symaddrfunction arch_ftrace_update_codefunction __ftrace_modify_callfunction ftrace_rec_set_opsfunction ftrace_rec_set_nop_opsfunction ftrace_rec_update_opsfunction ftrace_rec_set_nop_opsfunction ftrace_rec_update_opsfunction ftrace_make_callfunction ftrace_make_nopfunction ftrace_init_nopfunction ftrace_update_ftrace_funcfunction ftrace_call_adjustfunction ftrace_modify_callfunction prepare_ftrace_returnfunction ftrace_graph_func
Annotated Snippet
if (replaced[0] != call[0]) {
pr_err("%p: expected (%08x) but got (%08x)\n",
(void *)source, call[0], replaced[0]);
return -EINVAL;
}
}
/* Replace the jalr at once. Return -EPERM on write error. */
if (patch_insn_write((void *)(source + MCOUNT_AUIPC_SIZE), call + 1, MCOUNT_JALR_SIZE))
return -EPERM;
return 0;
}
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
static const struct ftrace_ops *riscv64_rec_get_ops(struct dyn_ftrace *rec)
{
const struct ftrace_ops *ops = NULL;
if (rec->flags & FTRACE_FL_CALL_OPS_EN) {
ops = ftrace_find_unique_ops(rec);
WARN_ON_ONCE(!ops);
}
if (!ops)
ops = &ftrace_list_ops;
return ops;
}
static int ftrace_rec_set_ops(const struct dyn_ftrace *rec, const struct ftrace_ops *ops)
{
unsigned long literal = ALIGN_DOWN(rec->ip - 12, 8);
return patch_text_nosync((void *)literal, &ops, sizeof(ops));
}
static int ftrace_rec_set_nop_ops(struct dyn_ftrace *rec)
{
return ftrace_rec_set_ops(rec, &ftrace_nop_ops);
}
static int ftrace_rec_update_ops(struct dyn_ftrace *rec)
{
return ftrace_rec_set_ops(rec, riscv64_rec_get_ops(rec));
}
#else
static int ftrace_rec_set_nop_ops(struct dyn_ftrace *rec) { return 0; }
static int ftrace_rec_update_ops(struct dyn_ftrace *rec) { return 0; }
#endif
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
unsigned long distance, orig_addr, pc = rec->ip - MCOUNT_AUIPC_SIZE;
int ret;
ret = ftrace_rec_update_ops(rec);
if (ret)
return ret;
orig_addr = (unsigned long)&ftrace_caller;
distance = addr > orig_addr ? addr - orig_addr : orig_addr - addr;
if (distance > JALR_RANGE)
addr = FTRACE_ADDR;
return __ftrace_modify_call(pc, addr, false);
}
int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr)
{
u32 nop4 = RISCV_INSN_NOP4;
int ret;
ret = ftrace_rec_set_nop_ops(rec);
if (ret)
return ret;
if (patch_insn_write((void *)rec->ip, &nop4, MCOUNT_NOP4_SIZE))
return -EPERM;
return 0;
}
/*
* This is called early on, and isn't wrapped by
* ftrace_arch_code_modify_{prepare,post_process}() and therefore doesn't hold
* text_mutex, which triggers a lockdep failure. SMP isn't running so we could
* just directly poke the text, but it's simpler to just take the lock
* ourselves.
*/
Annotation
- Immediate include surface: `linux/ftrace.h`, `linux/uaccess.h`, `linux/memory.h`, `linux/irqflags.h`, `linux/stop_machine.h`, `asm/cacheflush.h`, `asm/text-patching.h`.
- Detected declarations: `function Copyright`, `function ftrace_arch_code_modify_post_process`, `function ftrace_call_adjust`, `function arch_ftrace_get_symaddr`, `function arch_ftrace_update_code`, `function __ftrace_modify_call`, `function ftrace_rec_set_ops`, `function ftrace_rec_set_nop_ops`, `function ftrace_rec_update_ops`, `function ftrace_rec_set_nop_ops`.
- Atlas domain: Architecture Layer / arch/riscv.
- Implementation status: source implementation candidate.
- 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.