arch/hexagon/kernel/traps.c

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

File Facts

System
Linux kernel
Corpus path
arch/hexagon/kernel/traps.c
Extension
.c
Size
10139 bytes
Lines
433
Domain
Architecture Layer
Bucket
arch/hexagon
Inferred role
Architecture Layer: implementation source
Status
source 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 (task == current) {
			asm("%0 = r30" : "=r" (fp));
		} else {
			fp = (unsigned long *)
			     ((struct hexagon_switch_stack *)
			     task->thread.switch_sp)->fp;
		}
	}

	if ((((unsigned long) fp) & 0x3) || ((unsigned long) fp < 0x1000)) {
		printk("%s-- Corrupt frame pointer %p\n", loglvl, fp);
		return;
	}

	/* Saved link reg is one word above FP */
	if (!ip)
		ip = *(fp+1);

	/* Expect kernel stack to be in-bounds */
	low = (unsigned long)task_stack_page(task);
	high = low + THREAD_SIZE - 8;
	low += sizeof(struct thread_info);

	for (i = 0; i < kstack_depth_to_print; i++) {

		name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr);

		printk("%s[%p] 0x%lx: %s + 0x%lx", loglvl, fp, ip, name, offset);
		if (((unsigned long) fp < low) || (high < (unsigned long) fp))
			printk(KERN_CONT " (FP out of bounds!)");
		if (modname)
			printk(KERN_CONT " [%s] ", modname);
		printk(KERN_CONT "\n");

		newfp = (unsigned long *) *fp;

		if (((unsigned long) newfp) & 0x3) {
			printk("%s-- Corrupt frame pointer %p\n", loglvl, newfp);
			break;
		}

		/* Attempt to continue past exception. */
		if (!newfp) {
			struct pt_regs *regs = (struct pt_regs *) (((void *)fp)
						+ 8);

			if (regs->syscall_nr != -1) {
				printk("%s-- trap0 -- syscall_nr: %ld", loglvl,
					regs->syscall_nr);
				printk(KERN_CONT "  psp: %lx  elr: %lx\n",
					 pt_psp(regs), pt_elr(regs));
				break;
			} else {
				/* really want to see more ... */
				kstack_depth_to_print += 6;
				printk("%s-- %s (0x%lx)  badva: %lx\n", loglvl,
					ex_name(pt_cause(regs)), pt_cause(regs),
					pt_badva(regs));
			}

			newfp = (unsigned long *) regs->r30;
			ip = pt_elr(regs);
		} else {
			ip = *(newfp + 1);
		}

		/* If link reg is null, we are done. */
		if (ip == 0x0)
			break;

		/* If newfp isn't larger, we're tracing garbage. */
		if (newfp > fp)
			fp = newfp;
		else
			break;
	}
}

void show_stack(struct task_struct *task, unsigned long *fp, const char *loglvl)
{
	/* Saved link reg is one word above FP */
	do_show_stack(task, fp, 0, loglvl);
}

int die(const char *str, struct pt_regs *regs, long err)
{
	static struct {
		spinlock_t lock;
		int counter;
	} die = {

Annotation

Implementation Notes