arch/x86/kernel/uprobes.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/uprobes.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/uprobes.c- Extension
.c- Size
- 52944 bytes
- Lines
- 1850
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: syscall or user/kernel boundary
- Status
- core 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 participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- 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.
- 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/sched.hlinux/ptrace.hlinux/uprobes.hlinux/uaccess.hlinux/syscalls.hlinux/kdebug.hasm/processor.hasm/insn.hasm/insn-eval.hasm/mmu_context.hasm/nops.h
Detected Declarations
syscall uretprobesyscall uprobestruct uretprobe_syscall_argsstruct uprobe_trampolinestruct uprobe_syscall_argsstruct write_opcode_ctxstruct uprobe_xol_opsfunction is_prefix_badfunction for_each_insn_prefixfunction uprobe_init_insnfunction trampoline_check_ipfunction areafunction insn_rip_relativefunction sifunction scratch_regfunction riprel_pre_xolfunction riprel_post_xolfunction tramp_mremapfunction is_reachable_by_callfunction find_nearest_trampolinefunction hlist_for_each_entryfunction destroy_uprobe_trampolinefunction arch_uprobe_init_statefunction arch_uprobe_clear_statefunction __in_uprobe_trampolinefunction in_uprobe_trampolinefunction arch_uprobes_initfunction is_call_insnfunction verify_insnfunction stop_machinefunction swbp_optimizefunction swbp_unoptimizefunction copy_from_vaddrfunction __is_optimizedfunction is_optimizedfunction should_optimizefunction set_swbpfunction set_orig_insnfunction __arch_uprobe_optimizefunction arch_uprobe_optimizefunction can_optimizefunction riprel_analyzefunction sizeof_longfunction default_pre_xol_opfunction emulate_push_stackfunction instructionfunction default_abort_opfunction branch_is_call
Annotated Snippet
SYSCALL_DEFINE0(uretprobe)
{
struct pt_regs *regs = task_pt_regs(current);
struct uretprobe_syscall_args args;
unsigned long err, ip, sp, tramp;
/* If there's no trampoline, we are called from wrong place. */
tramp = uprobe_get_trampoline_vaddr();
if (unlikely(tramp == UPROBE_NO_TRAMPOLINE_VADDR))
goto sigill;
/* Make sure the ip matches the only allowed sys_uretprobe caller. */
if (unlikely(regs->ip != trampoline_check_ip(tramp)))
goto sigill;
err = copy_from_user(&args, (void __user *)regs->sp, sizeof(args));
if (err)
goto sigill;
/* expose the "right" values of r11/cx/ax/sp to uprobe_consumer/s */
regs->r11 = args.r11;
regs->cx = args.cx;
regs->ax = args.ax;
regs->sp += sizeof(args);
regs->orig_ax = -1;
ip = regs->ip;
sp = regs->sp;
uprobe_handle_trampoline(regs);
/*
* Some of the uprobe consumers has changed sp, we can do nothing,
* just return via iret.
* .. or shadow stack is enabled, in which case we need to skip
* return through the user space stack address.
*/
if (regs->sp != sp || shstk_is_enabled())
return regs->ax;
regs->sp -= sizeof(args);
/* for the case uprobe_consumer has changed r11/cx */
args.r11 = regs->r11;
args.cx = regs->cx;
/*
* ax register is passed through as return value, so we can use
* its space on stack for ip value and jump to it through the
* trampoline's ret instruction
*/
args.ax = regs->ip;
regs->ip = ip;
err = copy_to_user((void __user *)regs->sp, &args, sizeof(args));
if (err)
goto sigill;
/* ensure sysret, see do_syscall_64() */
regs->r11 = regs->flags;
regs->cx = regs->ip;
return regs->ax;
sigill:
force_sig(SIGILL);
return -1;
}
/*
* If arch_uprobe->insn doesn't use rip-relative addressing, return
* immediately. Otherwise, rewrite the instruction so that it accesses
* its memory operand indirectly through a scratch register. Set
* defparam->fixups accordingly. (The contents of the scratch register
* will be saved before we single-step the modified instruction,
* and restored afterward).
*
* We do this because a rip-relative instruction can access only a
* relatively small area (+/- 2 GB from the instruction), and the XOL
* area typically lies beyond that area. At least for instructions
* that store to memory, we can't execute the original instruction
* and "fix things up" later, because the misdirected store could be
* disastrous.
*
* Some useful facts about rip-relative instructions:
*
* - There's always a modrm byte with bit layout "00 reg 101".
* - There's never a SIB byte.
* - The displacement is always 4 bytes.
* - REX.B=1 bit in REX prefix, which normally extends r/m field,
* has no effect on rip-relative mode. It doesn't make modrm byte
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched.h`, `linux/ptrace.h`, `linux/uprobes.h`, `linux/uaccess.h`, `linux/syscalls.h`, `linux/kdebug.h`, `asm/processor.h`.
- Detected declarations: `syscall uretprobe`, `syscall uprobe`, `struct uretprobe_syscall_args`, `struct uprobe_trampoline`, `struct uprobe_syscall_args`, `struct write_opcode_ctx`, `struct uprobe_xol_ops`, `function is_prefix_bad`, `function for_each_insn_prefix`, `function uprobe_init_insn`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: core 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.