arch/arc/kernel/signal.c

Source file repositories/reference/linux-study-clean/arch/arc/kernel/signal.c

File Facts

System
Linux kernel
Corpus path
arch/arc/kernel/signal.c
Extension
.c
Size
12258 bytes
Lines
445
Domain
Architecture Layer
Bucket
arch/arc
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.

Dependency Surface

Detected Declarations

Annotated Snippet

SYSCALL_DEFINE0(rt_sigreturn)
{
	struct rt_sigframe __user *sf;
	unsigned int magic;
	struct pt_regs *regs = current_pt_regs();

	/* Always make any pending restarted system calls return -EINTR */
	current->restart_block.fn = do_no_restart_syscall;

	/* Since we stacked the signal on a word boundary,
	 * then 'sp' should be word aligned here.  If it's
	 * not, then the user is trying to mess with us.
	 */
	if (regs->sp & 3)
		goto badframe;

	sf = (struct rt_sigframe __force __user *)(regs->sp);

	if (!access_ok(sf, sizeof(*sf)))
		goto badframe;

	if (__get_user(magic, &sf->sigret_magic))
		goto badframe;

	if (unlikely(is_do_ss_needed(magic)))
		if (restore_altstack(&sf->uc.uc_stack))
			goto badframe;

	if (restore_usr_regs(regs, sf))
		goto badframe;

	/* Don't restart from sigreturn */
	syscall_wont_restart(regs);

	/*
	 * Ensure that sigreturn always returns to user mode (in case the
	 * regs saved on user stack got fudged between save and sigreturn)
	 * Otherwise it is easy to panic the kernel with a custom
	 * signal handler and/or restorer which clobberes the status32/ret
	 * to return to a bogus location in kernel mode.
	 */
	regs->status32 |= STATUS_U_MASK;

	return regs->r0;

badframe:
	force_sig(SIGSEGV);
	return 0;
}

/*
 * Determine which stack to use..
 */
static inline void __user *get_sigframe(struct ksignal *ksig,
					struct pt_regs *regs,
					unsigned long framesize)
{
	unsigned long sp = sigsp(regs->sp, ksig);
	void __user *frame;

	/* No matter what happens, 'sp' must be word
	 * aligned otherwise nasty things could happen
	 */

	/* ATPCS B01 mandates 8-byte alignment */
	frame = (void __user *)((sp - framesize) & ~7);

	/* Check that we can actually write to the signal frame */
	if (!access_ok(frame, framesize))
		frame = NULL;

	return frame;
}

static int
setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe __user *sf;
	unsigned int magic = 0;
	int err = 0;

	sf = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));
	if (!sf)
		return 1;

	/*
	 * w/o SA_SIGINFO, struct ucontext is partially populated (only
	 * uc_mcontext/uc_sigmask) for kernel's normal user state preservation
	 * during signal handler execution. This works for SA_SIGINFO as well
	 * although the semantics are now overloaded (the same reg state can be

Annotation

Implementation Notes