arch/riscv/kernel/signal.c
Source file repositories/reference/linux-study-clean/arch/riscv/kernel/signal.c
File Facts
- System
- Linux kernel
- Corpus path
arch/riscv/kernel/signal.c- Extension
.c- Size
- 16802 bytes
- Lines
- 590
- Domain
- Architecture Layer
- Bucket
- arch/riscv
- 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/compat.hlinux/signal.hlinux/uaccess.hlinux/syscalls.hlinux/resume_user_mode.hlinux/linkage.hlinux/entry-common.hasm/ucontext.hasm/vdso.hasm/signal.hasm/signal32.hasm/switch_to.hasm/vector.hasm/csr.hasm/cacheflush.hasm/usercfi.h
Detected Declarations
syscall rt_sigreturnstruct rt_sigframestruct arch_ext_privfunction restore_fp_statefunction save_fp_statefunction save_v_statefunction __restore_v_statefunction save_cfiss_statefunction __restore_cfiss_statefunction restore_sigcontextfunction get_rt_frame_sizefunction setup_sigcontextfunction setup_rt_framefunction handle_signalfunction arch_do_signal_or_restartfunction init_rt_signal_envfunction sigaltstack_size_valid
Annotated Snippet
SYSCALL_DEFINE0(rt_sigreturn)
{
struct pt_regs *regs = current_pt_regs();
struct rt_sigframe __user *frame;
struct task_struct *task;
sigset_t set;
size_t frame_size = get_rt_frame_size(false);
/* Always make any pending restarted system calls return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
frame = (struct rt_sigframe __user *)regs->sp;
if (!access_ok(frame, frame_size))
goto badframe;
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
set_current_blocked(&set);
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;
if (restore_altstack(&frame->uc.uc_stack))
goto badframe;
regs->cause = -1UL;
return regs->a0;
badframe:
task = current;
if (show_unhandled_signals) {
pr_info_ratelimited(
"%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
task->comm, task_pid_nr(task), __func__,
frame, (void *)regs->epc, (void *)regs->sp);
}
force_sig(SIGSEGV);
return 0;
}
static long setup_sigcontext(struct rt_sigframe __user *frame,
struct pt_regs *regs)
{
struct sigcontext __user *sc = &frame->uc.uc_mcontext;
struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
struct arch_ext_priv *arch_ext;
long err, i, ext_size;
/* sc_regs is structured the same as the start of pt_regs */
err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
/* Save the floating-point state. */
if (has_fpu())
err |= save_fp_state(regs, &sc->sc_fpregs);
/* Save the vector state. */
for (i = 0; i < nr_arch_exts; i++) {
arch_ext = &arch_ext_list[i];
if (!arch_ext->save)
continue;
ext_size = arch_ext->save(regs, sc_ext_ptr + 1);
if (ext_size <= 0) {
err |= ext_size;
} else {
err |= __put_user(arch_ext->magic, &sc_ext_ptr->magic);
err |= __put_user(ext_size, &sc_ext_ptr->size);
sc_ext_ptr = (void __user *)sc_ext_ptr + ext_size;
}
}
/* Write zero to fp-reserved space and check it on restore_sigcontext */
err |= __put_user(0, &sc->sc_extdesc.reserved);
/* And put END __riscv_ctx_hdr at the end. */
err |= __put_user(END_MAGIC, &sc_ext_ptr->magic);
err |= __put_user(END_HDR_SIZE, &sc_ext_ptr->size);
return err;
}
static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs, size_t framesize)
{
unsigned long sp;
/* Default to using normal stack */
sp = regs->sp;
/*
* If we are on the alternate signal stack and would overflow it, don't.
* Return an always-bogus address instead so we will die with SIGSEGV.
Annotation
- Immediate include surface: `linux/compat.h`, `linux/signal.h`, `linux/uaccess.h`, `linux/syscalls.h`, `linux/resume_user_mode.h`, `linux/linkage.h`, `linux/entry-common.h`, `asm/ucontext.h`.
- Detected declarations: `syscall rt_sigreturn`, `struct rt_sigframe`, `struct arch_ext_priv`, `function restore_fp_state`, `function save_fp_state`, `function save_v_state`, `function __restore_v_state`, `function save_cfiss_state`, `function __restore_cfiss_state`, `function restore_sigcontext`.
- Atlas domain: Architecture Layer / arch/riscv.
- 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.