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

📄 traps.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define CE_STATUS_UDBH_UE		(1UL << (43 + 9))#define CE_STATUS_UDBH_CE		(1UL << (43 + 8))#define CE_STATUS_UDBH_ESYNDR		(0xffUL << 43)#define CE_STATUS_UDBH_SHIFT		43#define CE_STATUS_UDBL_UE		(1UL << (33 + 9))#define CE_STATUS_UDBL_CE		(1UL << (33 + 8))#define CE_STATUS_UDBL_ESYNDR		(0xffUL << 33)#define CE_STATUS_UDBL_SHIFT		33#define CE_STATUS_AFSR_MASK		(0x1ffffffffUL)#define CE_STATUS_AFSR_ME		(1UL << 32)#define CE_STATUS_AFSR_PRIV		(1UL << 31)#define CE_STATUS_AFSR_ISAP		(1UL << 30)#define CE_STATUS_AFSR_ETP		(1UL << 29)#define CE_STATUS_AFSR_IVUE		(1UL << 28)#define CE_STATUS_AFSR_TO		(1UL << 27)#define CE_STATUS_AFSR_BERR		(1UL << 26)#define CE_STATUS_AFSR_LDP		(1UL << 25)#define CE_STATUS_AFSR_CP		(1UL << 24)#define CE_STATUS_AFSR_WP		(1UL << 23)#define CE_STATUS_AFSR_EDP		(1UL << 22)#define CE_STATUS_AFSR_UE		(1UL << 21)#define CE_STATUS_AFSR_CE		(1UL << 20)#define CE_STATUS_AFSR_ETS		(0xfUL << 16)#define CE_STATUS_AFSR_ETS_SHIFT	16#define CE_STATUS_AFSR_PSYND		(0xffffUL << 0)#define CE_STATUS_AFSR_PSYND_SHIFT	0/* Layout of Ecache TAG Parity Syndrome of AFSR */#define AFSR_ETSYNDROME_7_0		0x1UL /* E$-tag bus bits  <7:0> */#define AFSR_ETSYNDROME_15_8		0x2UL /* E$-tag bus bits <15:8> */#define AFSR_ETSYNDROME_21_16		0x4UL /* E$-tag bus bits <21:16> */#define AFSR_ETSYNDROME_24_22		0x8UL /* E$-tag bus bits <24:22> */static char *syndrome_unknown = "<Unknown>";asmlinkage void cee_log(unsigned long ce_status,			unsigned long afar,			struct pt_regs *regs){	char memmod_str[64];	char *p;	unsigned short scode, udb_reg;	printk(KERN_WARNING "CPU[%d]: Correctable ECC Error "	       "AFSR[%lx] AFAR[%016lx] UDBL[%lx] UDBH[%lx]\n",	       smp_processor_id(),	       (ce_status & CE_STATUS_AFSR_MASK),	       afar,	       ((ce_status >> CE_STATUS_UDBL_SHIFT) & 0x3ffUL),	       ((ce_status >> CE_STATUS_UDBH_SHIFT) & 0x3ffUL));	udb_reg = ((ce_status >> CE_STATUS_UDBL_SHIFT) & 0x3ffUL);	if (udb_reg & (1 << 8)) {		scode = ecc_syndrome_table[udb_reg & 0xff];		if (prom_getunumber(scode, afar,				    memmod_str, sizeof(memmod_str)) == -1)			p = syndrome_unknown;		else			p = memmod_str;		printk(KERN_WARNING "CPU[%d]: UDBL Syndrome[%x] "		       "Memory Module \"%s\"\n",		       smp_processor_id(), scode, p);	}	udb_reg = ((ce_status >> CE_STATUS_UDBH_SHIFT) & 0x3ffUL);	if (udb_reg & (1 << 8)) {		scode = ecc_syndrome_table[udb_reg & 0xff];		if (prom_getunumber(scode, afar,				    memmod_str, sizeof(memmod_str)) == -1)			p = syndrome_unknown;		else			p = memmod_str;		printk(KERN_WARNING "CPU[%d]: UDBH Syndrome[%x] "		       "Memory Module \"%s\"\n",		       smp_processor_id(), scode, p);	}}void do_fpe_common(struct pt_regs *regs){	if(regs->tstate & TSTATE_PRIV) {		regs->tpc = regs->tnpc;		regs->tnpc += 4;	} else {		unsigned long fsr = current->thread.xfsr[0];		siginfo_t info;		info.si_signo = SIGFPE;		info.si_errno = 0;		info.si_addr = (void *)regs->tpc;		info.si_trapno = 0;		info.si_code = __SI_FAULT;		if ((fsr & 0x1c000) == (1 << 14)) {			if (fsr & 0x10)				info.si_code = FPE_FLTINV;			else if (fsr & 0x08)				info.si_code = FPE_FLTOVF;			else if (fsr & 0x04)				info.si_code = FPE_FLTUND;			else if (fsr & 0x02)				info.si_code = FPE_FLTDIV;			else if (fsr & 0x01)				info.si_code = FPE_FLTRES;		}		force_sig_info(SIGFPE, &info, current);	}}void do_fpieee(struct pt_regs *regs){#ifdef DEBUG_FPU	printk("fpieee %016lx\n", current->thread.xfsr[0]);#endif	do_fpe_common(regs);}extern int do_mathemu(struct pt_regs *, struct fpustate *);void do_fpother(struct pt_regs *regs){	struct fpustate *f = FPUSTATE;	int ret = 0;	switch ((current->thread.xfsr[0] & 0x1c000)) {	case (2 << 14): /* unfinished_FPop */	case (3 << 14): /* unimplemented_FPop */		ret = do_mathemu(regs, f);		break;	}	if (ret) return;#ifdef DEBUG_FPU	printk("fpother %016lx\n", current->thread.xfsr[0]);#endif	do_fpe_common(regs);}void do_tof(struct pt_regs *regs){	siginfo_t info;	if(regs->tstate & TSTATE_PRIV)		die_if_kernel("Penguin overflow trap from kernel mode", regs);	info.si_signo = SIGEMT;	info.si_errno = 0;	info.si_code = EMT_TAGOVF;	info.si_addr = (void *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGEMT, &info, current);}void do_div0(struct pt_regs *regs){	siginfo_t info;	info.si_signo = SIGFPE;	info.si_errno = 0;	info.si_code = FPE_INTDIV;	info.si_addr = (void *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGFPE, &info, current);}void instruction_dump (unsigned int *pc){	int i;	if((((unsigned long) pc) & 3))		return;	printk("Instruction DUMP:");	for(i = -3; i < 6; i++)		printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>');	printk("\n");}void user_instruction_dump (unsigned int *pc){	int i;	unsigned int buf[9];		if((((unsigned long) pc) & 3))		return;			if(copy_from_user(buf, pc - 3, sizeof(buf)))		return;	printk("Instruction DUMP:");	for(i = 0; i < 9; i++)		printk("%c%08x%c",i==3?' ':'<',buf[i],i==3?' ':'>');	printk("\n");}void die_if_kernel(char *str, struct pt_regs *regs){	extern void __show_regs(struct pt_regs * regs);	extern void smp_report_regs(void);	int count = 0;	struct reg_window *lastrw;		/* Amuse the user. */	printk("              \\|/ ____ \\|/\n""              \"@'/ .. \\`@\"\n""              /_| \\__/ |_\\\n""                 \\__U_/\n");	printk("%s(%d): %s\n", current->comm, current->pid, str);	__asm__ __volatile__("flushw");	__show_regs(regs);	if(regs->tstate & TSTATE_PRIV) {		struct reg_window *rw = (struct reg_window *)			(regs->u_regs[UREG_FP] + STACK_BIAS);		/* Stop the back trace when we hit userland or we		 * find some badly aligned kernel stack.		 */		lastrw = (struct reg_window *)current;		while(rw					&&		      count++ < 30				&&		      rw >= lastrw				&&		      (char *) rw < ((char *) current)		        + sizeof (union task_union) 		&&		      !(((unsigned long) rw) & 0x7)) {			printk("Caller[%016lx]\n", rw->ins[7]);			lastrw = rw;			rw = (struct reg_window *)				(rw->ins[6] + STACK_BIAS);		}		instruction_dump ((unsigned int *) regs->tpc);	} else		user_instruction_dump ((unsigned int *) regs->tpc);#ifdef CONFIG_SMP	smp_report_regs();#endif                                                		if(regs->tstate & TSTATE_PRIV)		do_exit(SIGKILL);	do_exit(SIGSEGV);}extern int handle_popc(u32 insn, struct pt_regs *regs);extern int handle_ldf_stq(u32 insn, struct pt_regs *regs);void do_illegal_instruction(struct pt_regs *regs){	unsigned long pc = regs->tpc;	unsigned long tstate = regs->tstate;	u32 insn;	siginfo_t info;	if(tstate & TSTATE_PRIV)		die_if_kernel("Kernel illegal instruction", regs);	if(current->thread.flags & SPARC_FLAG_32BIT)		pc = (u32)pc;	if (get_user(insn, (u32 *)pc) != -EFAULT) {		if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ {			if (handle_popc(insn, regs))				return;		} else if ((insn & 0xc1580000) == 0xc1100000) /* LDQ/STQ */ {			if (handle_ldf_stq(insn, regs))				return;		}	}	info.si_signo = SIGILL;	info.si_errno = 0;	info.si_code = ILL_ILLOPC;	info.si_addr = (void *)pc;	info.si_trapno = 0;	force_sig_info(SIGILL, &info, current);}void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr){	siginfo_t info;	if(regs->tstate & TSTATE_PRIV) {		extern void kernel_unaligned_trap(struct pt_regs *regs,						  unsigned int insn, 						  unsigned long sfar, unsigned long sfsr);		return kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc), sfar, sfsr);	}	info.si_signo = SIGBUS;	info.si_errno = 0;	info.si_code = BUS_ADRALN;	info.si_addr = (void *)sfar;	info.si_trapno = 0;	force_sig_info(SIGBUS, &info, current);}void do_privop(struct pt_regs *regs){	siginfo_t info;	info.si_signo = SIGILL;	info.si_errno = 0;	info.si_code = ILL_PRVOPC;	info.si_addr = (void *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGILL, &info, current);}void do_privact(struct pt_regs *regs){	do_privop(regs);}/* Trap level 1 stuff or other traps we should never see... */void do_cee(struct pt_regs *regs){	die_if_kernel("TL0: Cache Error Exception", regs);}void do_cee_tl1(struct pt_regs *regs){	die_if_kernel("TL1: Cache Error Exception", regs);}void do_dae_tl1(struct pt_regs *regs){	die_if_kernel("TL1: Data Access Exception", regs);}void do_iae_tl1(struct pt_regs *regs){	die_if_kernel("TL1: Instruction Access Exception", regs);}void do_div0_tl1(struct pt_regs *regs){	die_if_kernel("TL1: DIV0 Exception", regs);}void do_fpdis_tl1(struct pt_regs *regs){	die_if_kernel("TL1: FPU Disabled", regs);}void do_fpieee_tl1(struct pt_regs *regs){	die_if_kernel("TL1: FPU IEEE Exception", regs);}void do_fpother_tl1(struct pt_regs *regs){	die_if_kernel("TL1: FPU Other Exception", regs);}void do_ill_tl1(struct pt_regs *regs){	die_if_kernel("TL1: Illegal Instruction Exception", regs);}void do_irq_tl1(struct pt_regs *regs){	die_if_kernel("TL1: IRQ Exception", regs);}void do_lddfmna_tl1(struct pt_regs *regs){	die_if_kernel("TL1: LDDF Exception", regs);}void do_stdfmna_tl1(struct pt_regs *regs){	die_if_kernel("TL1: STDF Exception", regs);}void do_paw(struct pt_regs *regs){	die_if_kernel("TL0: Phys Watchpoint Exception", regs);}void do_paw_tl1(struct pt_regs *regs){	die_if_kernel("TL1: Phys Watchpoint Exception", regs);}void do_vaw(struct pt_regs *regs){	die_if_kernel("TL0: Virt Watchpoint Exception", regs);}void do_vaw_tl1(struct pt_regs *regs){	die_if_kernel("TL1: Virt Watchpoint Exception", regs);}void do_tof_tl1(struct pt_regs *regs){	die_if_kernel("TL1: Tag Overflow Exception", regs);}#ifdef CONFIG_EC_FLUSH_TRAPvoid cache_flush_trap(struct pt_regs *regs){#ifndef CONFIG_SMP	unsigned node = linux_cpus[get_cpuid()].prom_node;#else#error cache_flush_trap not supported on sparc64/SMP yet#endif#if 0/* Broken */	int size = prom_getintdefault(node, "ecache-size", 512*1024);	int i, j;	unsigned long addr;	struct page *page, *end;	regs->tpc = regs->tnpc;	regs->tnpc = regs->tnpc + 4;	if (!capable(CAP_SYS_ADMIN)) return;	size >>= PAGE_SHIFT;	addr = PAGE_OFFSET - PAGE_SIZE;	page = mem_map - 1;	end = mem_map + max_mapnr;	for (i = 0; i < size; i++) {		do {			addr += PAGE_SIZE;			page++;			if (page >= end)				return;		} while (!PageReserved(page));		/* E-Cache line size is 64B. Let us pollute it :)) */		for (j = 0; j < PAGE_SIZE; j += 64)			__asm__ __volatile__ ("ldx [%0 + %1], %%g1" : : "r" (j), "r" (addr) : "g1");	}#endif}#endifvoid do_getpsr(struct pt_regs *regs){	regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate);	regs->tpc   = regs->tnpc;	regs->tnpc += 4;}void trap_init(void){	/* Attach to the address space of init_task. */	atomic_inc(&init_mm.mm_count);	current->active_mm = &init_mm;	/* NOTE: Other cpus have this done as they are started	 *       up on SMP.	 */}

⌨️ 快捷键说明

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