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

📄 traps.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (exception == 0) {			/* emulation was successful */			ia64_increment_ip(regs);		} else if (exception == -1) {			printk(KERN_ERR "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 = __SI_FAULT;	/* default code */			siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);			if (isr & 0x11) {				siginfo.si_code = FPE_FLTINV;			} else if (isr & 0x22) {				/* denormal operand gets the same si_code as underflow 				* see arch/i386/kernel/traps.c:math_error()  */				siginfo.si_code = FPE_FLTUND;			} else if (isr & 0x44) {				siginfo.si_code = FPE_FLTDIV;			}			siginfo.si_isr = isr;			siginfo.si_flags = __ISR_VALID;			siginfo.si_imm = 0;			force_sig_info(SIGFPE, &siginfo, current);		}	} else {		if (exception == -1) {			printk(KERN_ERR "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 = __SI_FAULT;	/* default code */			siginfo.si_addr = (void __user *) (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;			siginfo.si_flags = __ISR_VALID;			siginfo.si_imm = 0;			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, long arg1, long arg2, long arg3,		       long arg4, long arg5, long arg6, long arg7,		       struct pt_regs regs){	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 __user *) (regs.cr_iip + ia64_psr(&regs)->ri);	force_sig_info(SIGILL, &si, current);	rv.fkt = 0;	return rv;}void __kprobesia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,	    unsigned long iim, unsigned long itir, long arg5, long arg6,	    long arg7, struct pt_regs regs){	unsigned long code, error = isr, iip;	struct siginfo siginfo;	char buf[128];	int result, sig;	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 ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {		/*		 * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel		 * the lfetch.		 */		ia64_psr(&regs)->ed = 1;		return;	}	iip = regs.cr_iip + ia64_psr(&regs)->ri;	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)") : "");		if (code == 8) {# ifdef CONFIG_IA64_PRINT_HAZARDS			printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",			       current->comm, task_pid_nr(current),			       regs.cr_iip + ia64_psr(&regs)->ri, regs.pr);# endif			return;		}		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 */		if (user_mode(&regs)) {			void __user *addr;			if (((isr >> 4) & 0xf) == 2) {				/* NaT page consumption */				sig = SIGSEGV;				code = SEGV_ACCERR;				addr = (void __user *) ifa;			} else {				/* register NaT consumption */				sig = SIGILL;				code = ILL_ILLOPN;				addr = (void __user *) (regs.cr_iip							+ ia64_psr(&regs)->ri);			}			siginfo.si_signo = sig;			siginfo.si_code = code;			siginfo.si_errno = 0;			siginfo.si_addr = addr;			siginfo.si_imm = vector;			siginfo.si_flags = __ISR_VALID;			siginfo.si_isr = isr;			force_sig_info(sig, &siginfo, current);			return;		} else if (ia64_done_with_exception(&regs))			return;		sprintf(buf, "NaT consumption");		break;	      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 __user *) iip;			siginfo.si_imm = vector;			siginfo.si_flags = __ISR_VALID;			siginfo.si_isr = isr;			force_sig_info(SIGILL, &siginfo, current);			return;		}		sprintf(buf, "Unsupported data reference");		break;	      case 29: /* Debug */	      case 35: /* Taken Branch Trap */	      case 36: /* Single Step Trap */		if (fsys_mode(current, &regs)) {			extern char __kernel_syscall_via_break[];			/*			 * Got a trap in fsys-mode: Taken Branch Trap			 * and Single Step trap need special handling;			 * Debug trap is ignored (we disable it here			 * and re-enable it in the lower-privilege trap).			 */			if (unlikely(vector == 29)) {				set_thread_flag(TIF_DB_DISABLED);				ia64_psr(&regs)->db = 0;				ia64_psr(&regs)->lp = 1;				return;			}			/* re-do the system call via break 0x100000: */			regs.cr_iip = (unsigned long) __kernel_syscall_via_break;			ia64_psr(&regs)->ri = 0;			ia64_psr(&regs)->cpl = 3;			return;		}		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			break;		      case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;		      case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;		}		if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, siginfo.si_code, SIGTRAP)			       	== NOTIFY_STOP)			return;		siginfo.si_signo = SIGTRAP;		siginfo.si_errno = 0;		siginfo.si_addr  = (void __user *) ifa;		siginfo.si_imm   = 0;		siginfo.si_flags = __ISR_VALID;		siginfo.si_isr   = isr;		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) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {			siginfo.si_signo = SIGFPE;			siginfo.si_errno = 0;			siginfo.si_code = FPE_FLTINV;			siginfo.si_addr = (void __user *) iip;			siginfo.si_flags = __ISR_VALID;			siginfo.si_isr = isr;			siginfo.si_imm = 0;			force_sig_info(SIGFPE, &siginfo, current);		}		return;	      case 34:		if (isr & 0x2) {			/* Lower-Privilege Transfer Trap */			/* If we disabled debug traps during an fsyscall,			 * re-enable them here.			 */			if (test_thread_flag(TIF_DB_DISABLED)) {				clear_thread_flag(TIF_DB_DISABLED);				ia64_psr(&regs)->db = 1;			}			/*			 * Just clear PSR.lp and then return immediately:			 * all the interesting work (e.g., signal delivery)			 * is done in the kernel exit path.			 */			ia64_psr(&regs)->lp = 0;			return;		} else {			/* Unimplemented Instr. Address Trap */			if (user_mode(&regs)) {				siginfo.si_signo = SIGILL;				siginfo.si_code = ILL_BADIADDR;				siginfo.si_errno = 0;				siginfo.si_flags = 0;				siginfo.si_isr = 0;				siginfo.si_imm = 0;				siginfo.si_addr = (void __user *) iip;				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(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",		       iip, ifa, isr);		force_sig(SIGSEGV, current);		break;	      case 46:#ifdef CONFIG_IA32_SUPPORT		if (ia32_intercept(&regs, isr) == 0)			return;#endif		printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",		       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 + -