⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 traps_32.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  Copyright (C) 1991, 1992  Linus Torvalds * *  Pentium III FXSR, SSE support *	Gareth Hughes <gareth@valinux.com>, May 2000 *//* * 'Traps.c' handles hardware traps and faults after we have saved some * state in 'asm.s'. */#include <linux/sched.h>#include <linux/kernel.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/timer.h>#include <linux/mm.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/spinlock.h>#include <linux/interrupt.h>#include <linux/highmem.h>#include <linux/kallsyms.h>#include <linux/ptrace.h>#include <linux/utsname.h>#include <linux/kprobes.h>#include <linux/kexec.h>#include <linux/unwind.h>#include <linux/uaccess.h>#include <linux/nmi.h>#include <linux/bug.h>#ifdef CONFIG_EISA#include <linux/ioport.h>#include <linux/eisa.h>#endif#ifdef CONFIG_MCA#include <linux/mca.h>#endif#if defined(CONFIG_EDAC)#include <linux/edac.h>#endif#include <asm/processor.h>#include <asm/system.h>#include <asm/io.h>#include <asm/atomic.h>#include <asm/debugreg.h>#include <asm/desc.h>#include <asm/i387.h>#include <asm/nmi.h>#include <asm/unwind.h>#include <asm/smp.h>#include <asm/arch_hooks.h>#include <linux/kdebug.h>#include <asm/stacktrace.h>#include <linux/module.h>#include "mach_traps.h"int panic_on_unrecovered_nmi;DECLARE_BITMAP(used_vectors, NR_VECTORS);EXPORT_SYMBOL_GPL(used_vectors);asmlinkage int system_call(void);/* Do we ignore FPU interrupts ? */char ignore_fpu_irq = 0;/* * The IDT has to be page-aligned to simplify the Pentium * F0 0F bug workaround.. We have a special link segment * for this. */struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };asmlinkage void divide_error(void);asmlinkage void debug(void);asmlinkage void nmi(void);asmlinkage void int3(void);asmlinkage void overflow(void);asmlinkage void bounds(void);asmlinkage void invalid_op(void);asmlinkage void device_not_available(void);asmlinkage void coprocessor_segment_overrun(void);asmlinkage void invalid_TSS(void);asmlinkage void segment_not_present(void);asmlinkage void stack_segment(void);asmlinkage void general_protection(void);asmlinkage void page_fault(void);asmlinkage void coprocessor_error(void);asmlinkage void simd_coprocessor_error(void);asmlinkage void alignment_check(void);asmlinkage void spurious_interrupt_bug(void);asmlinkage void machine_check(void);int kstack_depth_to_print = 24;static unsigned int code_bytes = 64;static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size){	return	p > (void *)tinfo &&		p <= (void *)tinfo + THREAD_SIZE - size;}/* The form of the top of the frame on the stack */struct stack_frame {	struct stack_frame *next_frame;	unsigned long return_address;};static inline unsigned long print_context_stack(struct thread_info *tinfo,				unsigned long *stack, unsigned long ebp,				const struct stacktrace_ops *ops, void *data){#ifdef	CONFIG_FRAME_POINTER	struct stack_frame *frame = (struct stack_frame *)ebp;	while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) {		struct stack_frame *next;		unsigned long addr;		addr = frame->return_address;		ops->address(data, addr);		/*		 * break out of recursive entries (such as		 * end_of_stack_stop_unwind_function). Also,		 * we can never allow a frame pointer to		 * move downwards!		 */		next = frame->next_frame;		if (next <= frame)			break;		frame = next;	}#else	while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) {		unsigned long addr;		addr = *stack++;		if (__kernel_text_address(addr))			ops->address(data, addr);	}#endif	return ebp;}#define MSG(msg) ops->warning(data, msg)void dump_trace(struct task_struct *task, struct pt_regs *regs,	        unsigned long *stack,		const struct stacktrace_ops *ops, void *data){	unsigned long ebp = 0;	if (!task)		task = current;	if (!stack) {		unsigned long dummy;		stack = &dummy;		if (task != current)			stack = (unsigned long *)task->thread.esp;	}#ifdef CONFIG_FRAME_POINTER	if (!ebp) {		if (task == current) {			/* Grab ebp right from our regs */			asm ("movl %%ebp, %0" : "=r" (ebp) : );		} else {			/* ebp is the last reg pushed by switch_to */			ebp = *(unsigned long *) task->thread.esp;		}	}#endif	while (1) {		struct thread_info *context;		context = (struct thread_info *)			((unsigned long)stack & (~(THREAD_SIZE - 1)));		ebp = print_context_stack(context, stack, ebp, ops, data);		/* Should be after the line below, but somewhere		   in early boot context comes out corrupted and we		   can't reference it -AK */		if (ops->stack(data, "IRQ") < 0)			break;		stack = (unsigned long*)context->previous_esp;		if (!stack)			break;		touch_nmi_watchdog();	}}EXPORT_SYMBOL(dump_trace);static voidprint_trace_warning_symbol(void *data, char *msg, unsigned long symbol){	printk(data);	print_symbol(msg, symbol);	printk("\n");}static void print_trace_warning(void *data, char *msg){	printk("%s%s\n", (char *)data, msg);}static int print_trace_stack(void *data, char *name){	return 0;}/* * Print one address/symbol entries per line. */static void print_trace_address(void *data, unsigned long addr){	printk("%s [<%08lx>] ", (char *)data, addr);	print_symbol("%s\n", addr);	touch_nmi_watchdog();}static const struct stacktrace_ops print_trace_ops = {	.warning = print_trace_warning,	.warning_symbol = print_trace_warning_symbol,	.stack = print_trace_stack,	.address = print_trace_address,};static voidshow_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,		   unsigned long * stack, char *log_lvl){	dump_trace(task, regs, stack, &print_trace_ops, log_lvl);	printk("%s =======================\n", log_lvl);}void show_trace(struct task_struct *task, struct pt_regs *regs,		unsigned long * stack){	show_trace_log_lvl(task, regs, stack, "");}static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,			       unsigned long *esp, char *log_lvl){	unsigned long *stack;	int i;	if (esp == NULL) {		if (task)			esp = (unsigned long*)task->thread.esp;		else			esp = (unsigned long *)&esp;	}	stack = esp;	for(i = 0; i < kstack_depth_to_print; i++) {		if (kstack_end(stack))			break;		if (i && ((i % 8) == 0))			printk("\n%s       ", log_lvl);		printk("%08lx ", *stack++);	}	printk("\n%sCall Trace:\n", log_lvl);	show_trace_log_lvl(task, regs, esp, log_lvl);}void show_stack(struct task_struct *task, unsigned long *esp){	printk("       ");	show_stack_log_lvl(task, NULL, esp, "");}/* * The architecture-independent dump_stack generator */void dump_stack(void){	unsigned long stack;	printk("Pid: %d, comm: %.20s %s %s %.*s\n",		current->pid, current->comm, print_tainted(),		init_utsname()->release,		(int)strcspn(init_utsname()->version, " "),		init_utsname()->version);	show_trace(current, NULL, &stack);}EXPORT_SYMBOL(dump_stack);void show_registers(struct pt_regs *regs){	int i;	print_modules();	__show_registers(regs, 0);	printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",		TASK_COMM_LEN, current->comm, task_pid_nr(current),		current_thread_info(), current, task_thread_info(current));	/*	 * When in-kernel, we also print out the stack and code at the	 * time of the fault..	 */	if (!user_mode_vm(regs)) {		u8 *eip;		unsigned int code_prologue = code_bytes * 43 / 64;		unsigned int code_len = code_bytes;		unsigned char c;		printk("\n" KERN_EMERG "Stack: ");		show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);		printk(KERN_EMERG "Code: ");		eip = (u8 *)regs->eip - code_prologue;		if (eip < (u8 *)PAGE_OFFSET ||			probe_kernel_address(eip, c)) {			/* try starting at EIP */			eip = (u8 *)regs->eip;			code_len = code_len - code_prologue + 1;		}		for (i = 0; i < code_len; i++, eip++) {			if (eip < (u8 *)PAGE_OFFSET ||				probe_kernel_address(eip, c)) {				printk(" Bad EIP value.");				break;			}			if (eip == (u8 *)regs->eip)				printk("<%02x> ", c);			else				printk("%02x ", c);		}	}	printk("\n");}	int is_valid_bugaddr(unsigned long eip){	unsigned short ud2;	if (eip < PAGE_OFFSET)		return 0;	if (probe_kernel_address((unsigned short *)eip, ud2))		return 0;	return ud2 == 0x0b0f;}/* * This is gone through when something in the kernel has done something bad and * is about to be terminated. */void die(const char * str, struct pt_regs * regs, long err){	static struct {		raw_spinlock_t lock;		u32 lock_owner;		int lock_owner_depth;	} die = {		.lock =			__RAW_SPIN_LOCK_UNLOCKED,		.lock_owner =		-1,		.lock_owner_depth =	0	};	static int die_counter;	unsigned long flags;	oops_enter();	if (die.lock_owner != raw_smp_processor_id()) {		console_verbose();		raw_local_irq_save(flags);		__raw_spin_lock(&die.lock);		die.lock_owner = smp_processor_id();		die.lock_owner_depth = 0;		bust_spinlocks(1);	} else		raw_local_irq_save(flags);	if (++die.lock_owner_depth < 3) {		unsigned long esp;		unsigned short ss;		report_bug(regs->eip, regs);		printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff,		       ++die_counter);#ifdef CONFIG_PREEMPT		printk("PREEMPT ");#endif#ifdef CONFIG_SMP		printk("SMP ");#endif#ifdef CONFIG_DEBUG_PAGEALLOC		printk("DEBUG_PAGEALLOC");#endif		printk("\n");		if (notify_die(DIE_OOPS, str, regs, err,					current->thread.trap_no, SIGSEGV) !=				NOTIFY_STOP) {			show_registers(regs);			/* Executive summary in case the oops scrolled away */			esp = (unsigned long) (&regs->esp);			savesegment(ss, ss);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -