/*
 * Copyright (C) 1991, 1992  Linus Torvalds
 * Copyright 2010 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 */

#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/personality.h>
#include <linux/suspend.h>
#include <linux/ptrace.h>
#include <linux/elf.h>
#include <linux/compat.h>
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <asm/processor.h>
#include <asm/ucontext.h>
#include <asm/sigframe.h>
#include <asm/syscalls.h>
#include <asm/vdso.h>
#include <arch/interrupts.h>

#define DEBUG_SIG 0

/*
 * Do a signal return; undo the signal stack.
 */

int restore_sigcontext(struct pt_regs *regs,
		       struct sigcontext __user *sc)
{
	int err;

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

	/*
	 * Enforce that sigcontext is like pt_regs, and doesn't mess
	 * up our stack alignment rules.
	 */
	BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs));
	BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0);
	err = __copy_from_user(regs, sc, sizeof(*regs));

	/* Ensure that the PL is always set to USER_PL. */
	regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1));

	regs->faultnum = INT_SWINT_1_SIGRETURN;

	return err;
}

void signal_fault(const char *type, struct pt_regs *regs,
		  void __user *frame, int sig)
{
	trace_unhandled_signal(type, regs, (unsigned long)frame, SIGSEGV);
	force_sigsegv(sig, current);
}

/* The assembly shim for this function arranges to ignore the return value. */
SYSCALL_DEFINE0(rt_sigreturn)
{
	struct pt_regs *regs = current_pt_regs();
	struct rt_sigframe __user *frame =
		(struct rt_sigframe __user *)(regs->sp);
	sigset_t set;

	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
		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;

	return 0;

badframe:
	signal_fault("bad sigreturn frame", regs, frame, 0);
	return 0;
}

/*
 * Set up a signal frame.
 */

int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
{
	return  __copy_to_user(sc, regs, sizeof(*regs));
}

/*
 * Determine which stack to use..
 */
static inline void __user *get_sigframe(struct k_sigaction *ka,
					struct pt_regs *regs,
					size_t frame_size)
{
	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.
	 */
	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
		return (void __user __force *)-1UL;

	/* This is the X/Open sanctioned signal stack switching.  */
	if (ka->sa.sa_flags & SA_ONSTACK) {
		if (sas_ss_flags(sp) == 0)
			sp = current->sas_ss_sp + current->sas_ss_size;
	}

	sp -= frame_size;
	/*
	 * Align the stack pointer according to the TILE ABI,
	 * i.e. so that on function entry (sp & 15) == 0.
	 */
	sp &= -16UL;
	return (void __user *) sp;
}

static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
			  struct pt_regs *regs)
{
	unsigned long restorer;
	struct rt_sigframe __user *frame;
	int err = 0, sig = ksig->sig;

	frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		goto err;

	/* Always write at least the signal number for the stack backtracer. */
	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
		/* At sigreturn time, restore the callee-save registers too. */
		err |= copy_siginfo_to_user(&frame->info, &ksig->info);
		regs->flags |= PT_FLAGS_RESTORE_REGS;
	} else {
		err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
	}

	/* Create the ucontext.  */
	err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
	err |= __put_user(0, &frame->uc.uc_flags);
	err |= __put_user(NULL, &frame->uc.uc_link);
	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
	if (err)
		goto err;

	restorer = VDSO_SYM(&__vdso_rt_sigreturn);
	if (ksig->ka.sa.sa_flags & SA_RESTORER)
		restorer = (unsigned long) ksig->ka.sa.sa_restorer;

	/*
	 * Set up registers for signal handler.
	 * Registers that we don't modify keep the value they had from
	 * user-space at the time we took the signal.
	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
	 * since some things rely on this (e.g. glibc's debug/segfault.c).
	 */
	regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
	regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
	regs->sp = (unsigned long) frame;
	regs->lr = restorer;
	regs->regs[0] = (unsigned long) sig;
	regs->regs[1] = (unsigned long) &frame->info;
	regs->regs[2] = (unsigned long) &frame->uc;
	regs->flags |= PT_FLAGS_CALLER_SAVES;
	return 0;

err:
	trace_unhandled_signal("bad sigreturn frame", regs,
			      (unsigned long)frame, SIGSEGV);
	return -EFAULT;
}

/*
 * OK, we're invoking a handler
 */

static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
	sigset_t *oldset = sigmask_to_save();
	int ret;

	/* Are we from a system call? */
	if (regs->faultnum == INT_SWINT_1) {
		/* If so, check system call restarting.. */
		switch (regs->regs[0]) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			regs->regs[0] = -EINTR;
			break;

		case -ERESTARTSYS:
			if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
				regs->regs[0] = -EINTR;
				break;
			}
			/* fallthrough */
		case -ERESTARTNOINTR:
			/* Reload caller-saves to restore r0..r5 and r10. */
			regs->flags |= PT_FLAGS_CALLER_SAVES;
			regs->regs[0] = regs->orig_r0;
			regs->pc -= 8;
		}
	}

	/* Set up the stack frame */
#ifdef CONFIG_COMPAT
	if (is_compat_task())
		ret = compat_setup_rt_frame(ksig, oldset, regs);
	else
#endif
		ret = setup_rt_frame(ksig, oldset, regs);

	signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}

/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 */
void do_signal(struct pt_regs *regs)
{
	struct ksignal ksig;

	/*
	 * i386 will check if we're coming from kernel mode and bail out
	 * here.  In my experience this just turns weird crashes into
	 * weird spin-hangs.  But if we find a case where this seems
	 * helpful, we can reinstate the check on "!user_mode(regs)".
	 */

	if (get_signal(&ksig)) {
		/* Whee! Actually deliver the signal.  */
		handle_signal(&ksig, regs);
		goto done;
	}

	/* Did we come from a system call? */
	if (regs->faultnum == INT_SWINT_1) {
		/* Restart the system call - no handlers present */
		switch (regs->regs[0]) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
			regs->flags |= PT_FLAGS_CALLER_SAVES;
			regs->regs[0] = regs->orig_r0;
			regs->pc -= 8;
			break;

		case -ERESTART_RESTARTBLOCK:
			regs->flags |= PT_FLAGS_CALLER_SAVES;
			regs->regs[TREG_SYSCALL_NR] = __NR_restart_syscall;
			regs->pc -= 8;
			break;
		}
	}

	/* If there's no signal to deliver, just put the saved sigmask back. */
	restore_saved_sigmask();

done:
	/* Avoid double syscall restart if there are nested signals. */
	regs->faultnum = INT_SWINT_1_SIGRETURN;
}

int show_unhandled_signals = 1;

static int __init crashinfo(char *str)
{
	const char *word;

	if (*str == '\0')
		show_unhandled_signals = 2;
	else if (*str != '=' || kstrtoint(++str, 0, &show_unhandled_signals) != 0)
		return 0;

	switch (show_unhandled_signals) {
	case 0:
		word = "No";
		break;
	case 1:
		word = "One-line";
		break;
	default:
		word = "Detailed";
		break;
	}
	pr_info("%s crash reports will be generated on the console\n", word);
	return 1;
}
__setup("crashinfo", crashinfo);

static void dump_mem(void __user *address)
{
	void __user *addr;
	enum { region_size = 256, bytes_per_line = 16 };
	int i, j, k;
	int found_readable_mem = 0;

	if (!access_ok(VERIFY_READ, address, 1)) {
		pr_err("Not dumping at address 0x%lx (kernel address)\n",
		       (unsigned long)address);
		return;
	}

	addr = (void __user *)
		(((unsigned long)address & -bytes_per_line) - region_size/2);
	if (addr > address)
		addr = NULL;
	for (i = 0; i < region_size;
	     addr += bytes_per_line, i += bytes_per_line) {
		unsigned char buf[bytes_per_line];
		char line[100];
		if (copy_from_user(buf, addr, bytes_per_line))
			continue;
		if (!found_readable_mem) {
			pr_err("Dumping memory around address 0x%lx:\n",
			       (unsigned long)address);
			found_readable_mem = 1;
		}
		j = sprintf(line, REGFMT ":", (unsigned long)addr);
		for (k = 0; k < bytes_per_line; ++k)
			j += sprintf(&line[j], " %02x", buf[k]);
		pr_err("%s\n", line);
	}
	if (!found_readable_mem)
		pr_err("No readable memory around address 0x%lx\n",
		       (unsigned long)address);
}

void trace_unhandled_signal(const char *type, struct pt_regs *regs,
			    unsigned long address, int sig)
{
	struct task_struct *tsk = current;

	if (show_unhandled_signals == 0)
		return;

	/* If the signal is handled, don't show it here. */
	if (!is_global_init(tsk)) {
		void __user *handler =
			tsk->sighand->action[sig-1].sa.sa_handler;
		if (handler != SIG_IGN && handler != SIG_DFL)
			return;
	}

	/* Rate-limit the one-line output, not the detailed output. */
	if (show_unhandled_signals <= 1 && !printk_ratelimit())
		return;

	printk("%s%s[%d]: %s at %lx pc "REGFMT" signal %d",
	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
	       tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig);

	print_vma_addr(KERN_CONT " in ", regs->pc);

	printk(KERN_CONT "\n");

	if (show_unhandled_signals > 1) {
		switch (sig) {
		case SIGILL:
		case SIGFPE:
		case SIGSEGV:
		case SIGBUS:
			pr_err("User crash: signal %d, trap %ld, address 0x%lx\n",
			       sig, regs->faultnum, address);
			show_regs(regs);
			dump_mem((void __user *)address);
			break;
		default:
			pr_err("User crash: signal %d, trap %ld\n",
			       sig, regs->faultnum);
			break;
		}
	}
}
