/*
 * 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/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>
#include <linux/pfn.h>
#include <linux/kallsyms.h>
#include <linux/stacktrace.h>
#include <linux/uaccess.h>
#include <linux/mmzone.h>
#include <linux/dcache.h>
#include <linux/fs.h>
#include <asm/backtrace.h>
#include <asm/page.h>
#include <asm/ucontext.h>
#include <asm/switch_to.h>
#include <asm/sigframe.h>
#include <asm/stack.h>
#include <arch/abi.h>
#include <arch/interrupts.h>

#define KBT_ONGOING	0  /* Backtrace still ongoing */
#define KBT_DONE	1  /* Backtrace cleanly completed */
#define KBT_RUNNING	2  /* Can't run backtrace on a running task */
#define KBT_LOOP	3  /* Backtrace entered a loop */

/* Is address on the specified kernel stack? */
static int in_kernel_stack(struct KBacktraceIterator *kbt, unsigned long sp)
{
	ulong kstack_base = (ulong) kbt->task->stack;
	if (kstack_base == 0)  /* corrupt task pointer; just follow stack... */
		return sp >= PAGE_OFFSET && sp < (unsigned long)high_memory;
	return sp >= kstack_base && sp < kstack_base + THREAD_SIZE;
}

/* Callback for backtracer; basically a glorified memcpy */
static bool read_memory_func(void *result, unsigned long address,
			     unsigned int size, void *vkbt)
{
	int retval;
	struct KBacktraceIterator *kbt = (struct KBacktraceIterator *)vkbt;

	if (address == 0)
		return 0;
	if (__kernel_text_address(address)) {
		/* OK to read kernel code. */
	} else if (address >= PAGE_OFFSET) {
		/* We only tolerate kernel-space reads of this task's stack */
		if (!in_kernel_stack(kbt, address))
			return 0;
	} else if (!kbt->is_current) {
		return 0;	/* can't read from other user address spaces */
	}
	pagefault_disable();
	retval = __copy_from_user_inatomic(result,
					   (void __user __force *)address,
					   size);
	pagefault_enable();
	return (retval == 0);
}

/* Return a pt_regs pointer for a valid fault handler frame */
static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
{
	const char *fault = NULL;  /* happy compiler */
	char fault_buf[64];
	unsigned long sp = kbt->it.sp;
	struct pt_regs *p;

	if (sp % sizeof(long) != 0)
		return NULL;
	if (!in_kernel_stack(kbt, sp))
		return NULL;
	if (!in_kernel_stack(kbt, sp + C_ABI_SAVE_AREA_SIZE + PTREGS_SIZE-1))
		return NULL;
	p = (struct pt_regs *)(sp + C_ABI_SAVE_AREA_SIZE);
	if (p->faultnum == INT_SWINT_1 || p->faultnum == INT_SWINT_1_SIGRETURN)
		fault = "syscall";
	else {
		if (kbt->verbose) {     /* else we aren't going to use it */
			snprintf(fault_buf, sizeof(fault_buf),
				 "interrupt %ld", p->faultnum);
			fault = fault_buf;
		}
	}
	if (EX1_PL(p->ex1) == KERNEL_PL &&
	    __kernel_text_address(p->pc) &&
	    in_kernel_stack(kbt, p->sp) &&
	    p->sp >= sp) {
		if (kbt->verbose)
			pr_err("  <%s while in kernel mode>\n", fault);
	} else if (EX1_PL(p->ex1) == USER_PL &&
	    p->pc < PAGE_OFFSET &&
	    p->sp < PAGE_OFFSET) {
		if (kbt->verbose)
			pr_err("  <%s while in user mode>\n", fault);
	} else if (kbt->verbose) {
		pr_err("  (odd fault: pc %#lx, sp %#lx, ex1 %#lx?)\n",
		       p->pc, p->sp, p->ex1);
		p = NULL;
	}
	if (!kbt->profile || ((1ULL << p->faultnum) & QUEUED_INTERRUPTS) == 0)
		return p;
	return NULL;
}

/* Is the pc pointing to a sigreturn trampoline? */
static int is_sigreturn(unsigned long pc)
{
	return (pc == VDSO_BASE);
}

/* Return a pt_regs pointer for a valid signal handler frame */
static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt,
				      struct rt_sigframe* kframe)
{
	BacktraceIterator *b = &kbt->it;

	if (b->pc == VDSO_BASE && b->sp < PAGE_OFFSET &&
	    b->sp % sizeof(long) == 0) {
		int retval;
		pagefault_disable();
		retval = __copy_from_user_inatomic(
			kframe, (void __user __force *)b->sp,
			sizeof(*kframe));
		pagefault_enable();
		if (retval != 0 ||
		    (unsigned int)(kframe->info.si_signo) >= _NSIG)
			return NULL;
		if (kbt->verbose) {
			pr_err("  <received signal %d>\n",
			       kframe->info.si_signo);
		}
		return (struct pt_regs *)&kframe->uc.uc_mcontext;
	}
	return NULL;
}

static int KBacktraceIterator_is_sigreturn(struct KBacktraceIterator *kbt)
{
	return is_sigreturn(kbt->it.pc);
}

static int KBacktraceIterator_restart(struct KBacktraceIterator *kbt)
{
	struct pt_regs *p;
	struct rt_sigframe kframe;

	p = valid_fault_handler(kbt);
	if (p == NULL)
		p = valid_sigframe(kbt, &kframe);
	if (p == NULL)
		return 0;
	backtrace_init(&kbt->it, read_memory_func, kbt,
		       p->pc, p->lr, p->sp, p->regs[52]);
	kbt->new_context = 1;
	return 1;
}

/* Find a frame that isn't a sigreturn, if there is one. */
static int KBacktraceIterator_next_item_inclusive(
	struct KBacktraceIterator *kbt)
{
	for (;;) {
		do {
			if (!KBacktraceIterator_is_sigreturn(kbt))
				return KBT_ONGOING;
		} while (backtrace_next(&kbt->it));

		if (!KBacktraceIterator_restart(kbt))
			return KBT_DONE;
	}
}

/*
 * If the current sp is on a page different than what we recorded
 * as the top-of-kernel-stack last time we context switched, we have
 * probably blown the stack, and nothing is going to work out well.
 * If we can at least get out a warning, that may help the debug,
 * though we probably won't be able to backtrace into the code that
 * actually did the recursive damage.
 */
static void validate_stack(struct pt_regs *regs)
{
	int cpu = smp_processor_id();
	unsigned long ksp0 = get_current_ksp0();
	unsigned long ksp0_base = ksp0 - THREAD_SIZE;
	unsigned long sp = stack_pointer;

	if (EX1_PL(regs->ex1) == KERNEL_PL && regs->sp >= ksp0) {
		pr_err("WARNING: cpu %d: kernel stack page %#lx underrun!\n"
		       "  sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
		       cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr);
	}

	else if (sp < ksp0_base + sizeof(struct thread_info)) {
		pr_err("WARNING: cpu %d: kernel stack page %#lx overrun!\n"
		       "  sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
		       cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr);
	}
}

void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
			     struct task_struct *t, struct pt_regs *regs)
{
	unsigned long pc, lr, sp, r52;
	int is_current;

	/*
	 * Set up callback information.  We grab the kernel stack base
	 * so we will allow reads of that address range.
	 */
	is_current = (t == NULL || t == current);
	kbt->is_current = is_current;
	if (is_current)
		t = validate_current();
	kbt->task = t;
	kbt->verbose = 0;   /* override in caller if desired */
	kbt->profile = 0;   /* override in caller if desired */
	kbt->end = KBT_ONGOING;
	kbt->new_context = 1;
	if (is_current)
		validate_stack(regs);

	if (regs == NULL) {
		if (is_current || t->state == TASK_RUNNING) {
			/* Can't do this; we need registers */
			kbt->end = KBT_RUNNING;
			return;
		}
		pc = get_switch_to_pc();
		lr = t->thread.pc;
		sp = t->thread.ksp;
		r52 = 0;
	} else {
		pc = regs->pc;
		lr = regs->lr;
		sp = regs->sp;
		r52 = regs->regs[52];
	}

	backtrace_init(&kbt->it, read_memory_func, kbt, pc, lr, sp, r52);
	kbt->end = KBacktraceIterator_next_item_inclusive(kbt);
}
EXPORT_SYMBOL(KBacktraceIterator_init);

int KBacktraceIterator_end(struct KBacktraceIterator *kbt)
{
	return kbt->end != KBT_ONGOING;
}
EXPORT_SYMBOL(KBacktraceIterator_end);

void KBacktraceIterator_next(struct KBacktraceIterator *kbt)
{
	unsigned long old_pc = kbt->it.pc, old_sp = kbt->it.sp;
	kbt->new_context = 0;
	if (!backtrace_next(&kbt->it) && !KBacktraceIterator_restart(kbt)) {
		kbt->end = KBT_DONE;
		return;
	}
	kbt->end = KBacktraceIterator_next_item_inclusive(kbt);
	if (old_pc == kbt->it.pc && old_sp == kbt->it.sp) {
		/* Trapped in a loop; give up. */
		kbt->end = KBT_LOOP;
	}
}
EXPORT_SYMBOL(KBacktraceIterator_next);

static void describe_addr(struct KBacktraceIterator *kbt,
			  unsigned long address,
			  int have_mmap_sem, char *buf, size_t bufsize)
{
	struct vm_area_struct *vma;
	size_t namelen, remaining;
	unsigned long size, offset, adjust;
	char *p, *modname;
	const char *name;
	int rc;

	/*
	 * Look one byte back for every caller frame (i.e. those that
	 * aren't a new context) so we look up symbol data for the
	 * call itself, not the following instruction, which may be on
	 * a different line (or in a different function).
	 */
	adjust = !kbt->new_context;
	address -= adjust;

	if (address >= PAGE_OFFSET) {
		/* Handle kernel symbols. */
		BUG_ON(bufsize < KSYM_NAME_LEN);
		name = kallsyms_lookup(address, &size, &offset,
				       &modname, buf);
		if (name == NULL) {
			buf[0] = '\0';
			return;
		}
		namelen = strlen(buf);
		remaining = (bufsize - 1) - namelen;
		p = buf + namelen;
		rc = snprintf(p, remaining, "+%#lx/%#lx ",
			      offset + adjust, size);
		if (modname && rc < remaining)
			snprintf(p + rc, remaining - rc, "[%s] ", modname);
		buf[bufsize-1] = '\0';
		return;
	}

	/* If we don't have the mmap_sem, we can't show any more info. */
	buf[0] = '\0';
	if (!have_mmap_sem)
		return;

	/* Find vma info. */
	vma = find_vma(kbt->task->mm, address);
	if (vma == NULL || address < vma->vm_start) {
		snprintf(buf, bufsize, "[unmapped address] ");
		return;
	}

	if (vma->vm_file) {
		char *s;
		p = d_path(&vma->vm_file->f_path, buf, bufsize);
		if (IS_ERR(p))
			p = "?";
		s = strrchr(p, '/');
		if (s)
			p = s+1;
	} else {
		p = "anon";
	}

	/* Generate a string description of the vma info. */
	namelen = strlen(p);
	remaining = (bufsize - 1) - namelen;
	memmove(buf, p, namelen);
	snprintf(buf + namelen, remaining, "[%lx+%lx] ",
		 vma->vm_start, vma->vm_end - vma->vm_start);
}

/*
 * This method wraps the backtracer's more generic support.
 * It is only invoked from the architecture-specific code; show_stack()
 * and dump_stack() (in entry.S) are architecture-independent entry points.
 */
void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
{
	int i;
	int have_mmap_sem = 0;

	if (headers) {
		/*
		 * Add a blank line since if we are called from panic(),
		 * then bust_spinlocks() spit out a space in front of us
		 * and it will mess up our KERN_ERR.
		 */
		pr_err("\n");
		pr_err("Starting stack dump of tid %d, pid %d (%s)"
		       " on cpu %d at cycle %lld\n",
		       kbt->task->pid, kbt->task->tgid, kbt->task->comm,
		       smp_processor_id(), get_cycles());
	}
	kbt->verbose = 1;
	i = 0;
	for (; !KBacktraceIterator_end(kbt); KBacktraceIterator_next(kbt)) {
		char namebuf[KSYM_NAME_LEN+100];
		unsigned long address = kbt->it.pc;

		/* Try to acquire the mmap_sem as we pass into userspace. */
		if (address < PAGE_OFFSET && !have_mmap_sem && kbt->task->mm)
			have_mmap_sem =
				down_read_trylock(&kbt->task->mm->mmap_sem);

		describe_addr(kbt, address, have_mmap_sem,
			      namebuf, sizeof(namebuf));

		pr_err("  frame %d: 0x%lx %s(sp 0x%lx)\n",
		       i++, address, namebuf, (unsigned long)(kbt->it.sp));

		if (i >= 100) {
			pr_err("Stack dump truncated"
			       " (%d frames)\n", i);
			break;
		}
	}
	if (kbt->end == KBT_LOOP)
		pr_err("Stack dump stopped; next frame identical to this one\n");
	if (headers)
		pr_err("Stack dump complete\n");
	if (have_mmap_sem)
		up_read(&kbt->task->mm->mmap_sem);
}
EXPORT_SYMBOL(tile_show_stack);


/* This is called from show_regs() and _dump_stack() */
void dump_stack_regs(struct pt_regs *regs)
{
	struct KBacktraceIterator kbt;
	KBacktraceIterator_init(&kbt, NULL, regs);
	tile_show_stack(&kbt, 1);
}
EXPORT_SYMBOL(dump_stack_regs);

static struct pt_regs *regs_to_pt_regs(struct pt_regs *regs,
				       ulong pc, ulong lr, ulong sp, ulong r52)
{
	memset(regs, 0, sizeof(struct pt_regs));
	regs->pc = pc;
	regs->lr = lr;
	regs->sp = sp;
	regs->regs[52] = r52;
	return regs;
}

/* This is called from dump_stack() and just converts to pt_regs */
void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52)
{
	struct pt_regs regs;
	dump_stack_regs(regs_to_pt_regs(&regs, pc, lr, sp, r52));
}

/* This is called from KBacktraceIterator_init_current() */
void _KBacktraceIterator_init_current(struct KBacktraceIterator *kbt, ulong pc,
				      ulong lr, ulong sp, ulong r52)
{
	struct pt_regs regs;
	KBacktraceIterator_init(kbt, NULL,
				regs_to_pt_regs(&regs, pc, lr, sp, r52));
}

/* This is called only from kernel/sched.c, with esp == NULL */
void show_stack(struct task_struct *task, unsigned long *esp)
{
	struct KBacktraceIterator kbt;
	if (task == NULL || task == current)
		KBacktraceIterator_init_current(&kbt);
	else
		KBacktraceIterator_init(&kbt, task, NULL);
	tile_show_stack(&kbt, 0);
}

#ifdef CONFIG_STACKTRACE

/* Support generic Linux stack API too */

void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
{
	struct KBacktraceIterator kbt;
	int skip = trace->skip;
	int i = 0;

	if (task == NULL || task == current)
		KBacktraceIterator_init_current(&kbt);
	else
		KBacktraceIterator_init(&kbt, task, NULL);
	for (; !KBacktraceIterator_end(&kbt); KBacktraceIterator_next(&kbt)) {
		if (skip) {
			--skip;
			continue;
		}
		if (i >= trace->max_entries || kbt.it.pc < PAGE_OFFSET)
			break;
		trace->entries[i++] = kbt.it.pc;
	}
	trace->nr_entries = i;
}
EXPORT_SYMBOL(save_stack_trace_tsk);

void save_stack_trace(struct stack_trace *trace)
{
	save_stack_trace_tsk(NULL, trace);
}
EXPORT_SYMBOL_GPL(save_stack_trace);

#endif

/* In entry.S */
EXPORT_SYMBOL(KBacktraceIterator_init_current);
