arch/mips/kernel/traps.c

Source file repositories/reference/linux-study-clean/arch/mips/kernel/traps.c

File Facts

System
Linux kernel
Corpus path
arch/mips/kernel/traps.c
Extension
.c
Size
63046 bytes
Lines
2534
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration 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

if (__get_addr(&addr, sp++, user)) {
			printk("%s (Bad stack address)", loglvl);
			break;
		}
		if (__kernel_text_address(addr))
			print_ip_sym(loglvl, addr);
	}
	printk("%s\n", loglvl);
}

#ifdef CONFIG_KALLSYMS
int raw_show_trace;
static int __init set_raw_show_trace(char *str)
{
	raw_show_trace = 1;
	return 1;
}
__setup("raw_show_trace", set_raw_show_trace);
#endif

static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
			   const char *loglvl, bool user)
{
	unsigned long sp = regs->regs[29];
	unsigned long ra = regs->regs[31];
	unsigned long pc = regs->cp0_epc;

	if (!task)
		task = current;

	if (raw_show_trace || user_mode(regs) || !__kernel_text_address(pc)) {
		show_raw_backtrace(sp, loglvl, user);
		return;
	}
	printk("%sCall Trace:\n", loglvl);
	do {
		print_ip_sym(loglvl, pc);
		pc = unwind_stack(task, &sp, pc, &ra);
	} while (pc);
	pr_cont("\n");
}

/*
 * This routine abuses get_user()/put_user() to reference pointers
 * with at least a bit of error checking ...
 */
static void show_stacktrace(struct task_struct *task,
	const struct pt_regs *regs, const char *loglvl, bool user)
{
	const int field = 2 * sizeof(unsigned long);
	unsigned long stackdata;
	int i;
	unsigned long *sp = (unsigned long *)regs->regs[29];

	printk("%sStack :", loglvl);
	i = 0;
	while ((unsigned long) sp & (PAGE_SIZE - 1)) {
		if (i && ((i % (64 / field)) == 0)) {
			pr_cont("\n");
			printk("%s       ", loglvl);
		}
		if (i > 39) {
			pr_cont(" ...");
			break;
		}

		if (__get_addr(&stackdata, sp++, user)) {
			pr_cont(" (Bad stack address)");
			break;
		}

		pr_cont(" %0*lx", field, stackdata);
		i++;
	}
	pr_cont("\n");
	show_backtrace(task, regs, loglvl, user);
}

void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
{
	struct pt_regs regs;

	regs.cp0_status = KSU_KERNEL;
	if (sp) {
		regs.regs[29] = (unsigned long)sp;
		regs.regs[31] = 0;
		regs.cp0_epc = 0;
	} else {
		if (task && task != current) {
			regs.regs[29] = task->thread.reg29;

Annotation

Implementation Notes