arch/s390/kernel/ptrace.c
Source file repositories/reference/linux-study-clean/arch/s390/kernel/ptrace.c
File Facts
- System
- Linux kernel
- Corpus path
arch/s390/kernel/ptrace.c- Extension
.c- Size
- 27628 bytes
- Lines
- 1022
- Domain
- Architecture Layer
- Bucket
- arch/s390
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/sched/task_stack.hlinux/cpufeature.hlinux/mm.hlinux/smp.hlinux/errno.hlinux/ptrace.hlinux/user.hlinux/security.hlinux/audit.hlinux/signal.hlinux/elf.hlinux/regset.hlinux/seccomp.htrace/syscall.hasm/guarded_storage.hasm/access-regs.hasm/page.hlinux/uaccess.hasm/unistd.hasm/runtime_instr.hasm/facility.hasm/machine.hasm/ptrace.hasm/rwonce.hasm/fpu.hentry.h
Detected Declarations
function Authorfunction test_tsk_thread_flagfunction user_enable_single_stepfunction user_disable_single_stepfunction user_enable_block_stepfunction ptrace_disablefunction __peek_user_perfunction __peek_userfunction peek_userfunction __poke_user_perfunction __poke_userfunction poke_userfunction arch_ptracefunction s390_regs_getfunction s390_regs_setfunction s390_fpregs_getfunction s390_fpregs_setfunction s390_last_break_getfunction s390_last_break_setfunction s390_tdb_getfunction s390_tdb_setfunction s390_vxrs_low_getfunction s390_vxrs_low_setfunction s390_vxrs_high_getfunction s390_vxrs_high_setfunction s390_system_call_getfunction s390_system_call_setfunction s390_gs_cb_getfunction s390_gs_cb_setfunction s390_gs_bc_getfunction s390_gs_bc_setfunction is_ri_cb_validfunction s390_runtime_instr_getfunction s390_runtime_instr_setfunction regs_query_register_offset
Annotated Snippet
if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) {
if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND)
cr2_new.tdc = 1;
else
cr2_new.tdc = 2;
}
}
/* Take care of enable/disable of guarded storage. */
if (cpu_has_gs()) {
cr2_new.gse = 0;
if (task->thread.gs_cb)
cr2_new.gse = 1;
}
/* Load control register 0/2 iff changed */
cr0_changed = cr0_new.val != cr0_old.val;
cr2_changed = cr2_new.val != cr2_old.val;
if (cr0_changed)
local_ctl_load(0, &cr0_new.reg);
if (cr2_changed)
local_ctl_load(2, &cr2_new.reg);
/* Copy user specified PER registers */
new.control.val = thread->per_user.control;
new.start.val = thread->per_user.start;
new.end.val = thread->per_user.end;
/* merge TIF_SINGLE_STEP into user specified PER registers. */
if (test_tsk_thread_flag(task, TIF_SINGLE_STEP) ||
test_tsk_thread_flag(task, TIF_UPROBE_SINGLESTEP)) {
if (test_tsk_thread_flag(task, TIF_BLOCK_STEP))
new.control.val |= PER_EVENT_BRANCH;
else
new.control.val |= PER_EVENT_IFETCH;
new.control.val |= PER_CONTROL_SUSPENSION;
new.control.val |= PER_EVENT_TRANSACTION_END;
if (test_tsk_thread_flag(task, TIF_UPROBE_SINGLESTEP))
new.control.val |= PER_EVENT_IFETCH;
new.start.val = 0;
new.end.val = -1UL;
}
/* Take care of the PER enablement bit in the PSW. */
if (!(new.control.val & PER_EVENT_MASK)) {
regs->psw.mask &= ~PSW_MASK_PER;
return;
}
regs->psw.mask |= PSW_MASK_PER;
__local_ctl_store(9, 11, old.regs);
if (memcmp(&new, &old, sizeof(struct per_regs)) != 0)
__local_ctl_load(9, 11, new.regs);
}
void user_enable_single_step(struct task_struct *task)
{
clear_tsk_thread_flag(task, TIF_BLOCK_STEP);
set_tsk_thread_flag(task, TIF_SINGLE_STEP);
}
void user_disable_single_step(struct task_struct *task)
{
clear_tsk_thread_flag(task, TIF_BLOCK_STEP);
clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
}
void user_enable_block_step(struct task_struct *task)
{
set_tsk_thread_flag(task, TIF_SINGLE_STEP);
set_tsk_thread_flag(task, TIF_BLOCK_STEP);
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Clear all debugging related fields.
*/
void ptrace_disable(struct task_struct *task)
{
memset(&task->thread.per_user, 0, sizeof(task->thread.per_user));
memset(&task->thread.per_event, 0, sizeof(task->thread.per_event));
clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
clear_tsk_thread_flag(task, TIF_PER_TRAP);
task->thread.per_flags = 0;
}
#define __ADDR_MASK 7
static inline unsigned long __peek_user_per(struct task_struct *child,
addr_t addr)
{
if (addr == offsetof(struct per_struct_kernel, cr9))
/* Control bits of the active per set. */
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched.h`, `linux/sched/task_stack.h`, `linux/cpufeature.h`, `linux/mm.h`, `linux/smp.h`, `linux/errno.h`, `linux/ptrace.h`.
- Detected declarations: `function Author`, `function test_tsk_thread_flag`, `function user_enable_single_step`, `function user_disable_single_step`, `function user_enable_block_step`, `function ptrace_disable`, `function __peek_user_per`, `function __peek_user`, `function peek_user`, `function __poke_user_per`.
- Atlas domain: Architecture Layer / arch/s390.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
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.