arch/x86/um/signal.c
Source file repositories/reference/linux-study-clean/arch/x86/um/signal.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/um/signal.c- Extension
.c- Size
- 12554 bytes
- Lines
- 471
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/personality.hlinux/ptrace.hlinux/kernel.hlinux/syscalls.hasm/unistd.hlinux/uaccess.hasm/ucontext.hframe_kern.hregisters.hskas.hlinux/regset.hasm/sigframe.h
Detected Declarations
syscall sigreturnsyscall rt_sigreturnstruct _xstate_64function copy_sc_from_userfunction copy_sc_to_userfunction copy_ucontext_to_userfunction setup_signal_stack_scfunction setup_signal_stack_sifunction setup_signal_stack_si
Annotated Snippet
SYSCALL_DEFINE0(sigreturn)
{
unsigned long sp = PT_REGS_SP(¤t->thread.regs);
struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
sigset_t set;
struct sigcontext __user *sc = &frame->sc;
int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
if (copy_from_user(&set.sig[0], &sc->oldmask, sizeof(set.sig[0])) ||
copy_from_user(&set.sig[1], frame->extramask, sig_size))
goto segfault;
set_current_blocked(&set);
if (copy_sc_from_user(¤t->thread.regs, sc))
goto segfault;
/* Avoid ERESTART handling */
PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1;
return PT_REGS_SYSCALL_RET(¤t->thread.regs);
segfault:
force_sig(SIGSEGV);
return 0;
}
#else
int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set)
{
unsigned long math_size = host_fp_size + FP_XSTATE_MAGIC2_SIZE;
struct rt_sigframe __user *frame;
int err = 0, sig = ksig->sig;
unsigned long fp_to;
frame = (void __user *)stack_top - sizeof(struct rt_sigframe);
/* Add required space for math frame */
frame = (void __user *)((unsigned long)frame - math_size);
/* ABI requires 16 byte boundary alignment */
frame = (void __user *)round_down((unsigned long)frame, 16);
/* Subtract 128 for a red zone and 8 for proper alignment */
frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8);
if (!access_ok(frame, sizeof(*frame) + math_size))
goto out;
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err)
goto out;
}
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(NULL, &frame->uc.uc_link);
err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
fp_to = (unsigned long)frame + sizeof(*frame);
err |= copy_sc_to_user(&frame->uc.uc_mcontext,
(struct _xstate __user *)fp_to,
regs, set->sig[0]);
err |= __put_user(fp_to, &frame->uc.uc_mcontext.fpstate);
if (sizeof(*set) == 16) {
err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
}
else
err |= __copy_to_user(&frame->uc.uc_sigmask, set,
sizeof(*set));
/*
* Set up to return from userspace. If provided, use a stub
* already in userspace.
*/
/* x86-64 should always use SA_RESTORER. */
if (ksig->ka.sa.sa_flags & SA_RESTORER)
err |= __put_user((void __user *)ksig->ka.sa.sa_restorer,
&frame->pretcode);
else
/* could use a vstub here */
return err;
if (err)
return err;
Annotation
- Immediate include surface: `linux/personality.h`, `linux/ptrace.h`, `linux/kernel.h`, `linux/syscalls.h`, `asm/unistd.h`, `linux/uaccess.h`, `asm/ucontext.h`, `frame_kern.h`.
- Detected declarations: `syscall sigreturn`, `syscall rt_sigreturn`, `struct _xstate_64`, `function copy_sc_from_user`, `function copy_sc_to_user`, `function copy_ucontext_to_user`, `function setup_signal_stack_sc`, `function setup_signal_stack_si`, `function setup_signal_stack_si`.
- 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.
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.