/*
 * Stack dumping functions
 *
 *  Copyright IBM Corp. 1999, 2013
 */

#include <linux/kallsyms.h>
#include <linux/hardirq.h>
#include <linux/kprobes.h>
#include <linux/utsname.h>
#include <linux/export.h>
#include <linux/kdebug.h>
#include <linux/ptrace.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <asm/processor.h>
#include <asm/debug.h>
#include <asm/dis.h>
#include <asm/ipl.h>

/*
 * For dump_trace we have tree different stack to consider:
 *   - the panic stack which is used if the kernel stack has overflown
 *   - the asynchronous interrupt stack (cpu related)
 *   - the synchronous kernel stack (process related)
 * The stack trace can start at any of the three stacks and can potentially
 * touch all of them. The order is: panic stack, async stack, sync stack.
 */
static unsigned long
__dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
	     unsigned long low, unsigned long high)
{
	struct stack_frame *sf;
	struct pt_regs *regs;

	while (1) {
		if (sp < low || sp > high - sizeof(*sf))
			return sp;
		sf = (struct stack_frame *) sp;
		if (func(data, sf->gprs[8], 0))
			return sp;
		/* Follow the backchain. */
		while (1) {
			low = sp;
			sp = sf->back_chain;
			if (!sp)
				break;
			if (sp <= low || sp > high - sizeof(*sf))
				return sp;
			sf = (struct stack_frame *) sp;
			if (func(data, sf->gprs[8], 1))
				return sp;
		}
		/* Zero backchain detected, check for interrupt frame. */
		sp = (unsigned long) (sf + 1);
		if (sp <= low || sp > high - sizeof(*regs))
			return sp;
		regs = (struct pt_regs *) sp;
		if (!user_mode(regs)) {
			if (func(data, regs->psw.addr, 1))
				return sp;
		}
		low = sp;
		sp = regs->gprs[15];
	}
}

void dump_trace(dump_trace_func_t func, void *data, struct task_struct *task,
		unsigned long sp)
{
	unsigned long frame_size;

	frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
#ifdef CONFIG_CHECK_STACK
	sp = __dump_trace(func, data, sp,
			  S390_lowcore.panic_stack + frame_size - 4096,
			  S390_lowcore.panic_stack + frame_size);
#endif
	sp = __dump_trace(func, data, sp,
			  S390_lowcore.async_stack + frame_size - ASYNC_SIZE,
			  S390_lowcore.async_stack + frame_size);
	task = task ?: current;
	__dump_trace(func, data, sp,
		     (unsigned long)task_stack_page(task),
		     (unsigned long)task_stack_page(task) + THREAD_SIZE);
}
EXPORT_SYMBOL_GPL(dump_trace);

static int show_address(void *data, unsigned long address, int reliable)
{
	if (reliable)
		printk(" [<%016lx>] %pSR \n", address, (void *)address);
	else
		printk("([<%016lx>] %pSR)\n", address, (void *)address);
	return 0;
}

static void show_trace(struct task_struct *task, unsigned long sp)
{
	if (!sp)
		sp = task ? task->thread.ksp : current_stack_pointer();
	printk("Call Trace:\n");
	dump_trace(show_address, NULL, task, sp);
	if (!task)
		task = current;
	debug_show_held_locks(task);
}

void show_stack(struct task_struct *task, unsigned long *sp)
{
	unsigned long *stack;
	int i;

	stack = sp;
	if (!stack) {
		if (!task)
			stack = (unsigned long *)current_stack_pointer();
		else
			stack = (unsigned long *)task->thread.ksp;
	}
	printk(KERN_DEFAULT "Stack:\n");
	for (i = 0; i < 20; i++) {
		if (((addr_t) stack & (THREAD_SIZE-1)) == 0)
			break;
		if (i % 4 == 0)
			printk(KERN_DEFAULT "       ");
		pr_cont("%016lx%c", *stack++, i % 4 == 3 ? '\n' : ' ');
	}
	show_trace(task, (unsigned long)sp);
}

static void show_last_breaking_event(struct pt_regs *regs)
{
	printk("Last Breaking-Event-Address:\n");
	printk(" [<%016lx>] %pSR\n", regs->args[0], (void *)regs->args[0]);
}

void show_registers(struct pt_regs *regs)
{
	struct psw_bits *psw = &psw_bits(regs->psw);
	char *mode;

	mode = user_mode(regs) ? "User" : "Krnl";
	printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);
	if (!user_mode(regs))
		pr_cont(" (%pSR)", (void *)regs->psw.addr);
	pr_cont("\n");
	printk("           R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
	       "P:%x AS:%x CC:%x PM:%x", psw->r, psw->t, psw->i, psw->e,
	       psw->key, psw->m, psw->w, psw->p, psw->as, psw->cc, psw->pm);
	pr_cont(" RI:%x EA:%x\n", psw->ri, psw->eaba);
	printk("%s GPRS: %016lx %016lx %016lx %016lx\n", mode,
	       regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]);
	printk("           %016lx %016lx %016lx %016lx\n",
	       regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]);
	printk("           %016lx %016lx %016lx %016lx\n",
	       regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]);
	printk("           %016lx %016lx %016lx %016lx\n",
	       regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]);
	show_code(regs);
}

void show_regs(struct pt_regs *regs)
{
	show_regs_print_info(KERN_DEFAULT);
	show_registers(regs);
	/* Show stack backtrace if pt_regs is from kernel mode */
	if (!user_mode(regs))
		show_trace(NULL, regs->gprs[15]);
	show_last_breaking_event(regs);
}

static DEFINE_SPINLOCK(die_lock);

void die(struct pt_regs *regs, const char *str)
{
	static int die_counter;

	oops_enter();
	lgr_info_log();
	debug_stop_all();
	console_verbose();
	spin_lock_irq(&die_lock);
	bust_spinlocks(1);
	printk("%s: %04x ilc:%d [#%d] ", str, regs->int_code & 0xffff,
	       regs->int_code >> 17, ++die_counter);
#ifdef CONFIG_PREEMPT
	pr_cont("PREEMPT ");
#endif
#ifdef CONFIG_SMP
	pr_cont("SMP ");
#endif
	if (debug_pagealloc_enabled())
		pr_cont("DEBUG_PAGEALLOC");
	pr_cont("\n");
	notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV);
	print_modules();
	show_regs(regs);
	bust_spinlocks(0);
	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
	spin_unlock_irq(&die_lock);
	if (in_interrupt())
		panic("Fatal exception in interrupt");
	if (panic_on_oops)
		panic("Fatal exception: panic_on_oops");
	oops_exit();
	do_exit(SIGSEGV);
}
