arch/arm/kernel/traps.c

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

File Facts

System
Linux kernel
Corpus path
arch/arm/kernel/traps.c
Extension
.c
Size
24273 bytes
Lines
966
Domain
Architecture Layer
Bucket
arch/arm
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 (instruction & BIT(reg)) {
			p += sprintf(p, " r%d:%08x", reg, *stack--);
			if (++x == 6) {
				x = 0;
				p = str;
				printk("%s%s\n", loglvl, str);
			}
		}
	}
	if (p != str)
		printk("%s%s\n", loglvl, str);
}

#ifndef CONFIG_ARM_UNWIND
/*
 * Stack pointers should always be within the kernels view of
 * physical memory.  If it is not there, then we can't dump
 * out any information relating to the stack.
 */
static int verify_stack(unsigned long sp)
{
	if (sp < PAGE_OFFSET ||
	    (!IS_ENABLED(CONFIG_VMAP_STACK) &&
	     sp > (unsigned long)high_memory && high_memory != NULL))
		return -EFAULT;

	return 0;
}
#endif

/*
 * Dump out the contents of some memory nicely...
 */
void dump_mem(const char *lvl, const char *str, unsigned long bottom,
	      unsigned long top)
{
	unsigned long first;
	int i;

	printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);

	for (first = bottom & ~31; first < top; first += 32) {
		unsigned long p;
		char str[sizeof(" 12345678") * 8 + 1];

		memset(str, ' ', sizeof(str));
		str[sizeof(str) - 1] = '\0';

		for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
			if (p >= bottom && p < top) {
				unsigned long val;
				if (!get_kernel_nofault(val, (unsigned long *)p))
					sprintf(str + i * 9, " %08lx", val);
				else
					sprintf(str + i * 9, " ????????");
			}
		}
		printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
	}
}

static void dump_instr(const char *lvl, struct pt_regs *regs)
{
	unsigned long addr = instruction_pointer(regs);
	const int thumb = thumb_mode(regs);
	const int width = thumb ? 4 : 8;
	char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
	int i;

	/*
	 * Note that we now dump the code first, just in case the backtrace
	 * kills us.
	 */

	for (i = -4; i < 1 + !!thumb; i++) {
		unsigned int val, bad;

		if (thumb) {
			u16 tmp;

			if (user_mode(regs))
				bad = get_user(tmp, &((u16 __user *)addr)[i]);
			else
				bad = get_kernel_nofault(tmp, &((u16 *)addr)[i]);

			val = __mem_to_opcode_thumb16(tmp);
		} else {
			if (user_mode(regs))
				bad = get_user(val, &((u32 __user *)addr)[i]);
			else

Annotation

Implementation Notes