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

📄 traps.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 	__asm__ ("ldf.fill f10=%0%P0" :: "m"(f6_15[4])); 	__asm__ ("ldf.fill f11=%0%P0" :: "m"(f6_15[5])); 	__asm__ ("ldf.fill f12=%0%P0" :: "m"(f6_15[6])); 	__asm__ ("ldf.fill f13=%0%P0" :: "m"(f6_15[7])); 	__asm__ ("ldf.fill f14=%0%P0" :: "m"(f6_15[8])); 	__asm__ ("ldf.fill f15=%0%P0" :: "m"(f6_15[9]));	regs->f6 = f6_15[0];	regs->f7 = f6_15[1];	regs->f8 = f6_15[2];	regs->f9 = f6_15[3];#endif	return ret.status;}/* * Handle floating-point assist faults and traps. */static inthandle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr){	long exception, bundle[2];	unsigned long fault_ip;	struct siginfo siginfo;	static int fpu_swa_count = 0;	static unsigned long last_time;	fault_ip = regs->cr_iip;	if (!fp_fault && (ia64_psr(regs)->ri == 0))		fault_ip -= 16;	if (copy_from_user(bundle, (void *) fault_ip, sizeof(bundle)))		return -1;#ifdef FPSWA_DEBUG	if (fpu_swa_count > 5 && jiffies - last_time > 5*HZ)		fpu_swa_count = 0;	if (++fpu_swa_count < 5) {		last_time = jiffies;		printk("%s(%d): floating-point assist fault at ip %016lx\n",		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri);	}#endif	exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr, 			       &regs->cr_ifs, regs);	if (fp_fault) {		if (exception == 0) {			/* emulation was successful */ 			ia64_increment_ip(regs);		} else if (exception == -1) {			printk("handle_fpu_swa: fp_emulate() returned -1\n");			return -1;		} else {			/* is next instruction a trap? */			if (exception & 2) {				ia64_increment_ip(regs);			}			siginfo.si_signo = SIGFPE;			siginfo.si_errno = 0;			siginfo.si_code = 0;			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);			if (isr & 0x11) {				siginfo.si_code = FPE_FLTINV;			} else if (isr & 0x44) {				siginfo.si_code = FPE_FLTDIV;			}			siginfo.si_isr = isr;			force_sig_info(SIGFPE, &siginfo, current);		}	} else {		if (exception == -1) {			printk("handle_fpu_swa: fp_emulate() returned -1\n");			return -1;		} else if (exception != 0) {			/* raise exception */			siginfo.si_signo = SIGFPE;			siginfo.si_errno = 0;			siginfo.si_code = 0;			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);			if (isr & 0x880) {				siginfo.si_code = FPE_FLTOVF;			} else if (isr & 0x1100) {				siginfo.si_code = FPE_FLTUND;			} else if (isr & 0x2200) {				siginfo.si_code = FPE_FLTRES;			}			siginfo.si_isr = isr;			force_sig_info(SIGFPE, &siginfo, current);		}	}	return 0;}struct illegal_op_return {	unsigned long fkt, arg1, arg2, arg3;};struct illegal_op_returnia64_illegal_op_fault (unsigned long ec, unsigned long arg1, unsigned long arg2,		       unsigned long arg3, unsigned long arg4, unsigned long arg5,		       unsigned long arg6, unsigned long arg7, unsigned long stack){	struct pt_regs *regs = (struct pt_regs *) &stack;	struct illegal_op_return rv;	struct siginfo si;	char buf[128];#ifdef CONFIG_IA64_BRL_EMU		{		extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);		rv = ia64_emulate_brl(regs, ec);		if (rv.fkt != (unsigned long) -1)			return rv;	}#endif	sprintf(buf, "IA-64 Illegal operation fault");	die_if_kernel(buf, regs, 0);	memset(&si, 0, sizeof(si));	si.si_signo = SIGILL;	si.si_code = ILL_ILLOPC;	si.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);	force_sig_info(SIGILL, &si, current);	rv.fkt = 0;	return rv;}voidia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,	    unsigned long iim, unsigned long itir, unsigned long arg5,	    unsigned long arg6, unsigned long arg7, unsigned long stack){	struct pt_regs *regs = (struct pt_regs *) &stack;	unsigned long code, error = isr;	struct siginfo siginfo;	char buf[128];	int result;	static const char *reason[] = {		"IA-64 Illegal Operation fault",		"IA-64 Privileged Operation fault",		"IA-64 Privileged Register fault",		"IA-64 Reserved Register/Field fault",		"Disabled Instruction Set Transition fault",		"Unknown fault 5", "Unknown fault 6", "Unknown fault 7", "Illegal Hazard fault",		"Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12", 		"Unknown fault 13", "Unknown fault 14", "Unknown fault 15"	};#if 0	/* this is for minimal trust debugging; yeah this kind of stuff is useful at times... */	if (vector != 25) {		static unsigned long last_time;		static char count;		unsigned long n = vector;		char buf[32], *cp;		if (count > 5 && jiffies - last_time > 5*HZ)			count = 0;		if (count++ < 5) {			last_time = jiffies;			cp = buf + sizeof(buf);			*--cp = '\0';			while (n) {				*--cp = "0123456789abcdef"[n & 0xf];				n >>= 4;			}			printk("<0x%s>", cp);		}	}#endif	switch (vector) {	      case 24: /* General Exception */		code = (isr >> 4) & 0xf;		sprintf(buf, "General Exception: %s%s", reason[code],			(code == 3) ? ((isr & (1UL << 37))				       ? " (RSE access)" : " (data access)") : "");#ifndef CONFIG_ITANIUM_ASTEP_SPECIFIC		if (code == 8) {# ifdef CONFIG_IA64_PRINT_HAZARDS			printk("%016lx:possible hazard, pr = %016lx\n", regs->cr_iip, regs->pr);# endif			return;		}#endif		break;	      case 25: /* Disabled FP-Register */		if (isr & 2) {			disabled_fph_fault(regs);			return;		}		sprintf(buf, "Disabled FPL fault---not supposed to happen!");		break;	      case 26: /* NaT Consumption */	      case 31: /* Unsupported Data Reference */		if (user_mode(regs)) {			siginfo.si_signo = SIGILL;			siginfo.si_code = ILL_ILLOPN;			siginfo.si_errno = 0;			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);			siginfo.si_imm = vector;			force_sig_info(SIGILL, &siginfo, current);			return;		}		sprintf(buf, (vector == 26) ? "NaT consumption" : "Unsupported data reference");		break;	      case 29: /* Debug */	      case 35: /* Taken Branch Trap */	      case 36: /* Single Step Trap */		switch (vector) {		      case 29: 			siginfo.si_code = TRAP_HWBKPT;#ifdef CONFIG_ITANIUM			/*			 * Erratum 10 (IFA may contain incorrect address) now has			 * "NoFix" status.  There are no plans for fixing this.			 */			if (ia64_psr(regs)->is == 0)			  ifa = regs->cr_iip;#endif			siginfo.si_addr = (void *) ifa;		        break;		      case 35: siginfo.si_code = TRAP_BRANCH; break;		      case 36: siginfo.si_code = TRAP_TRACE; break;		}		siginfo.si_signo = SIGTRAP;		siginfo.si_errno = 0;		force_sig_info(SIGTRAP, &siginfo, current);		return;	      case 32: /* fp fault */	      case 33: /* fp trap */		result = handle_fpu_swa((vector == 32) ? 1 : 0, regs, isr);		if (result < 0) {			siginfo.si_signo = SIGFPE;			siginfo.si_errno = 0;			siginfo.si_code = FPE_FLTINV;			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);			force_sig(SIGFPE, current);		}		return;	      case 34:		/* Unimplemented Instruction Address Trap */		if (user_mode(regs)) {			siginfo.si_signo = SIGILL;			siginfo.si_code = ILL_BADIADDR;			siginfo.si_errno = 0;			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);			force_sig_info(SIGILL, &siginfo, current);			return;		}		sprintf(buf, "Unimplemented Instruction Address fault");		break;	      case 45:#ifdef CONFIG_IA32_SUPPORT		if (ia32_exception(regs, isr) == 0)			return;#endif		printk("Unexpected IA-32 exception (Trap 45)\n");		printk("  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr);		force_sig(SIGSEGV, current);		break;	      case 46:		printk("Unexpected IA-32 intercept trap (Trap 46)\n");		printk("  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",		       regs->cr_iip, ifa, isr, iim);		force_sig(SIGSEGV, current);		return;	      case 47:		sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);		break;	      default:		sprintf(buf, "Fault %lu", vector);		break;	}	die_if_kernel(buf, regs, error);	force_sig(SIGILL, current);}

⌨️ 快捷键说明

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