コード例 #1
0
/*
 * Note that we play around with the 'TS' bit in an attempt to get
 * the correct behaviour even in the presence of the asynchronous
 * IRQ13 behaviour
 */
void math_error(void __user *ip)
{
	struct task_struct *task;
	siginfo_t info;
	unsigned short cwd, swd, err;

	/*
	 * Save the info for the exception handler and clear the error.
	 */
	task = current;
	save_init_fpu(task);
	task->thread.trap_no = 16;
	task->thread.error_code = 0;
	info.si_signo = SIGFPE;
	info.si_errno = 0;
	info.si_addr = ip;
	/*
	 * (~cwd & swd) will mask out exceptions that are not set to unmasked
	 * status.  0x3f is the exception bits in these regs, 0x200 is the
	 * C1 reg you need in case of a stack fault, 0x040 is the stack
	 * fault bit.  We should only be taking one exception at a time,
	 * so if this combination doesn't produce any single exception,
	 * then we have a bad program that isn't synchronizing its FPU usage
	 * and it will suffer the consequences since we won't be able to
	 * fully reproduce the context of the exception
	 */
	cwd = get_fpu_cwd(task);
	swd = get_fpu_swd(task);

	err = swd & ~cwd;

	if (err & 0x001) {	/* Invalid op */
		/*
		 * swd & 0x240 == 0x040: Stack Underflow
		 * swd & 0x240 == 0x240: Stack Overflow
		 * User must clear the SF bit (0x40) if set
		 */
		info.si_code = FPE_FLTINV;
	} else if (err & 0x004) { /* Divide by Zero */
		info.si_code = FPE_FLTDIV;
	} else if (err & 0x008) { /* Overflow */
		info.si_code = FPE_FLTOVF;
	} else if (err & 0x012) { /* Denormal, Underflow */
		info.si_code = FPE_FLTUND;
	} else if (err & 0x020) { /* Precision */
		info.si_code = FPE_FLTRES;
	} else {
		/*
		 * If we're using IRQ 13, or supposedly even some trap 16
		 * implementations, it's possible we get a spurious trap...
		 */
		return;		/* Spurious trap, no error */
	}
	force_sig_info(SIGFPE, &info, task);
}
コード例 #2
0
void __rk_force_signal(struct task_struct *tsk, unsigned long addr,
		unsigned int sig, int code )
{
	struct siginfo si;
                printk("%s::send sig %d to task %s\n" , __func__ , sig , tsk->comm );
	si.si_signo = sig;
	si.si_errno = 0;
	si.si_code = code;
	si.si_addr = (void __user *)addr;
	force_sig_info(sig, &si, tsk);
}
コード例 #3
0
ファイル: fault.c プロジェクト: Daniel-Abrecht/linux
/*
 * Send SIGSEGV to task.  This is an external routine
 * to keep the stack usage of do_page_fault small.
 */
static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
{
	struct siginfo si;

	report_user_fault(regs, SIGSEGV, 1);
	si.si_signo = SIGSEGV;
	si.si_errno = 0;
	si.si_code = si_code;
	si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
	force_sig_info(SIGSEGV, &si, current);
}
コード例 #4
0
/*
 * Handle hitting a breakpoint.
 */
void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
{
	siginfo_t info;

	info.si_signo = SIGTRAP;
	info.si_errno = 0;
	info.si_code  = TRAP_BRKPT;
	info.si_addr  = (void __user *)instruction_pointer(regs);

	force_sig_info(SIGTRAP, &info, tsk);
}
コード例 #5
0
ファイル: fault.c プロジェクト: Blackburn29/PsycoKernel
static noinline void do_sigbus(struct pt_regs *regs)
{
	struct task_struct *tsk = current;
	struct siginfo si;

	si.si_signo = SIGBUS;
	si.si_errno = 0;
	si.si_code = BUS_ADRERR;
	si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
	force_sig_info(SIGBUS, &si, tsk);
}
コード例 #6
0
ファイル: traps.c プロジェクト: AshishNamdev/linux
asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
{
	siginfo_t info;
	memset(&info, 0, sizeof(info));
	info.si_signo = SIGTRAP;
	info.si_code = TRAP_TRACE;
	info.si_addr = (void *)address;
	force_sig_info(SIGTRAP, &info, current);

	regs->pc += 4;
}
コード例 #7
0
void arm64_notify_die(const char *str, struct pt_regs *regs,
		      struct siginfo *info, int err)
{
	if (user_mode(regs)) {
		current->thread.fault_address = 0;
		current->thread.fault_code = err;
		force_sig_info(info->si_signo, info, current);
	} else {
		die(str, regs, err);
	}
}
コード例 #8
0
ファイル: traps.c プロジェクト: Gangfeng/linux-1
asmlinkage void do_ov(struct pt_regs *regs)
{
	siginfo_t info;

	die_if_kernel("do_ov execution Exception", regs);

	info.si_code = FPE_INTOVF;
	info.si_signo = SIGFPE;
	info.si_errno = 0;
	info.si_addr = (void *)regs->cp0_epc;
	force_sig_info(SIGFPE, &info, current);
}
コード例 #9
0
ファイル: seccomp.c プロジェクト: Astralix/mainline-dss11
/**
 * seccomp_send_sigsys - signals the task to allow in-process syscall emulation
 * @syscall: syscall number to send to userland
 * @reason: filter-supplied reason code to send to userland (via si_errno)
 *
 * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info.
 */
static void seccomp_send_sigsys(int syscall, int reason)
{
	struct siginfo info;
	memset(&info, 0, sizeof(info));
	info.si_signo = SIGSYS;
	info.si_code = SYS_SECCOMP;
	info.si_call_addr = (void __user *)KSTK_EIP(current);
	info.si_errno = reason;
	info.si_arch = syscall_get_arch(current, task_pt_regs(current));
	info.si_syscall = syscall;
	force_sig_info(SIGSYS, &info, current);
}
コード例 #10
0
void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
{
	struct siginfo info;

	memset(&info, 0, sizeof(info));
	info.si_signo = SIGTRAP;
	info.si_code  = TRAP_BRKPT;
	info.si_addr  = (void __user *) regs->pc;

	/*                           */
	force_sig_info(SIGTRAP, &info, tsk);
}
コード例 #11
0
ファイル: traps.c プロジェクト: gnensis/linux-2.6.15
asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
{
	void __user *rip = (void __user *)(regs->rip);
	struct task_struct * task;
	siginfo_t info;
	unsigned short mxcsr;

	conditional_sti(regs);
	if (!user_mode(regs) &&
        	kernel_math_error(regs, "kernel simd math error"))
		return;

	/*
	 * Save the info for the exception handler and clear the error.
	 */
	task = current;
	save_init_fpu(task);
	task->thread.trap_no = 19;
	task->thread.error_code = 0;
	info.si_signo = SIGFPE;
	info.si_errno = 0;
	info.si_code = __SI_FAULT;
	info.si_addr = rip;
	/*
	 * The SIMD FPU exceptions are handled a little differently, as there
	 * is only a single status/control register.  Thus, to determine which
	 * unmasked exception was caught we must mask the exception mask bits
	 * at 0x1f80, and then use these to mask the exception bits at 0x3f.
	 */
	mxcsr = get_fpu_mxcsr(task);
	switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
		case 0x000:
		default:
			break;
		case 0x001: /* Invalid Op */
			info.si_code = FPE_FLTINV;
			break;
		case 0x002: /* Denormalize */
		case 0x010: /* Underflow */
			info.si_code = FPE_FLTUND;
			break;
		case 0x004: /* Zero Divide */
			info.si_code = FPE_FLTDIV;
			break;
		case 0x008: /* Overflow */
			info.si_code = FPE_FLTOVF;
			break;
		case 0x020: /* Precision */
			info.si_code = FPE_FLTRES;
			break;
	}
	force_sig_info(SIGFPE, &info, task);
}
コード例 #12
0
void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs)
{
	struct siginfo info;

	current->thread.trap_nr = TRAP_BRKPT;
	memset(&info, 0, sizeof(info));
	info.si_signo = SIGTRAP;
	info.si_code  = TRAP_BRKPT;
	info.si_addr  = (void __user *) regs->pc;

	/* Send us the fakey SIGTRAP */
	force_sig_info(SIGTRAP, &info, tsk);
}
コード例 #13
0
ファイル: exceptions.c プロジェクト: ANFS/ANFS-kernel
void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
{
	siginfo_t info;

	if (kernel_mode(regs)) {
		die("Exception in kernel mode", regs, signr);
	}
	info.si_signo = signr;
	info.si_errno = 0;
	info.si_code = code;
	info.si_addr = (void __user *) addr;
	force_sig_info(signr, &info, current);
}
コード例 #14
0
asmlinkage void
do_entDbg(struct pt_regs *regs)
{
	siginfo_t info;

	die_if_kernel("Instruction fault", regs, 0, NULL);

	info.si_signo = SIGILL;
	info.si_errno = 0;
	info.si_code = ILL_ILLOPC;
	info.si_addr = (void __user *) regs->pc;
	force_sig_info(SIGILL, &info, current);
}
コード例 #15
0
ファイル: ptrace.c プロジェクト: 420GrayFox/dsl-n55u-bender
/*
 * Handle hitting a breakpoint
 */
static void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
{
	siginfo_t info;

	info.si_signo = SIGTRAP;
	info.si_errno = 0;
	info.si_code  = TRAP_BRKPT;
	info.si_addr  = (void __user *)instruction_pointer(regs);

	pr_debug("ptrace_break: Sending SIGTRAP to PID %u (pc = 0x%p)\n",
		 tsk->pid, info.si_addr);
	force_sig_info(SIGTRAP, &info, tsk);
}
コード例 #16
0
void handle_break(unsigned iir, struct pt_regs *regs)
{
	struct siginfo si;

	switch(iir) {
	case 0x00:
#ifdef PRINT_USER_FAULTS
		printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n",
		       current->pid, current->comm);
#endif
		die_if_kernel("Breakpoint", regs, 0);
#ifdef PRINT_USER_FAULTS
		show_regs(regs);
#endif
		si.si_code = TRAP_BRKPT;
		si.si_addr = (void *) (regs->iaoq[0] & ~3);
		si.si_signo = SIGTRAP;
		force_sig_info(SIGTRAP, &si, current);
		break;

	case GDB_BREAK_INSN:
		die_if_kernel("Breakpoint", regs, 0);
		handle_gdb_break(regs, TRAP_BRKPT);
		break;

	default:
#ifdef PRINT_USER_FAULTS
		printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n",
		       iir, current->pid, current->comm);
		show_regs(regs);
#endif
		si.si_signo = SIGTRAP;
		si.si_code = TRAP_BRKPT;
		si.si_addr = (void *) (regs->iaoq[0] & ~3);
		force_sig_info(SIGTRAP, &si, current);
		return;
	}
}
コード例 #17
0
ファイル: fault.c プロジェクト: 3sOx/asuswrt-merlin
int send_fault_sig(struct pt_regs *regs)
{
	siginfo_t siginfo = { 0, 0, 0, };

	siginfo.si_signo = current->thread.signo;
	siginfo.si_code = current->thread.code;
	siginfo.si_addr = (void *)current->thread.faddr;
#ifdef DEBUG
	printk("send_fault_sig: %p,%d,%d\n", siginfo.si_addr, siginfo.si_signo, siginfo.si_code);
#endif

	if (user_mode(regs)) {
		force_sig_info(siginfo.si_signo,
			       &siginfo, current);
	} else {
		const struct exception_table_entry *fixup;

		/* Are we prepared to handle this kernel fault? */
		if ((fixup = search_exception_tables(regs->pc))) {
			struct pt_regs *tregs;
			/* Create a new four word stack frame, discarding the old
			   one.  */
			regs->stkadj = frame_extra_sizes[regs->format];
			tregs =	(struct pt_regs *)((ulong)regs + regs->stkadj);
			tregs->vector = regs->vector;
			tregs->format = 0;
			tregs->pc = fixup->fixup;
			tregs->sr = regs->sr;
			return -1;
		}

		//if (siginfo.si_signo == SIGBUS)
		//	force_sig_info(siginfo.si_signo,
		//		       &siginfo, current);

		/*
		 * Oops. The kernel tried to access some bad page. We'll have to
		 * terminate things with extreme prejudice.
		 */
		if ((unsigned long)siginfo.si_addr < PAGE_SIZE)
			printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
		else
			printk(KERN_ALERT "Unable to handle kernel access");
		printk(" at virtual address %p\n", siginfo.si_addr);
		die_if_kernel("Oops", regs, 0 /*error_code*/);
		do_exit(SIGKILL);
	}

	return 1;
}
コード例 #18
0
/*
 * Send SIGSEGV to task.  This is an external routine
 * to keep the stack usage of do_page_fault small.
 */
static noinline void do_sigsegv(struct pt_regs *regs, long int_code,
				int si_code, unsigned long trans_exc_code)
{
	struct siginfo si;
	unsigned long address;

	address = trans_exc_code & __FAIL_ADDR_MASK;
	current->thread.prot_addr = address;
	current->thread.trap_no = int_code;
	report_user_fault(regs, int_code, SIGSEGV, address);
	si.si_signo = SIGSEGV;
	si.si_code = si_code;
	si.si_addr = (void __user *) address;
	force_sig_info(SIGSEGV, &si, current);
}
コード例 #19
0
ファイル: ptrace.c プロジェクト: andi34/Dhollmen_Kernel
static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
		  int error_code)
{
	struct siginfo info;

	memset(&info, 0, sizeof(info));
	info.si_signo = SIGTRAP;
	info.si_code = TRAP_BRKPT;

	/* User-mode eip? */
	info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL;

	/* Send us the fake SIGTRAP */
	force_sig_info(SIGTRAP, &info, tsk);
}
コード例 #20
0
static noinline void do_sigbus(struct pt_regs *regs)
{
	struct task_struct *tsk = current;
	struct siginfo si;

	/*
	 * Send a sigbus, regardless of whether we were in kernel
	 * or user mode.
	 */
	si.si_signo = SIGBUS;
	si.si_errno = 0;
	si.si_code = BUS_ADRERR;
	si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
	force_sig_info(SIGBUS, &si, tsk);
}
コード例 #21
0
ファイル: traps.c プロジェクト: lilinj2000/linux-4.3.3
void do_per_trap(struct pt_regs *regs)
{
    siginfo_t info;

    if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP)
        return;
    if (!current->ptrace)
        return;
    info.si_signo = SIGTRAP;
    info.si_errno = 0;
    info.si_code = TRAP_HWBKPT;
    info.si_addr =
        (void __force __user *) current->thread.per_event.address;
    force_sig_info(SIGTRAP, &info, current);
}
コード例 #22
0
ファイル: traps.c プロジェクト: romanalexander/Trickles
void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc,
		       unsigned long psr)
{
	siginfo_t info;

#ifdef TRAP_DEBUG
	printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n",
	       pc, npc, psr);
#endif
	info.si_signo = SIGBUS;
	info.si_errno = 0;
	info.si_code = BUS_OBJERR;
	info.si_addr = (void *)pc;
	info.si_trapno = 0;
	force_sig_info(SIGBUS, &info, current);
}
コード例 #23
0
ファイル: traps.c プロジェクト: ForayJones/iods
asmlinkage void media_exception(unsigned long msr0, unsigned long msr1)
{
	siginfo_t info;

	die_if_kernel("-- Media Exception --\n"
		      "MSR0 : %08lx\n"
		      "MSR1 : %08lx\n",
		      msr0, msr1);

	info.si_signo	= SIGFPE;
	info.si_code	= FPE_MDAOVF;
	info.si_errno	= 0;
	info.si_addr	= (void *) __frame->pc;

	force_sig_info(info.si_signo, &info, current);
} /* end media_exception() */
コード例 #24
0
void do_send_trap(struct pt_regs *regs, unsigned long address,
		  unsigned long error_code, int signal_code, int breakpt)
{
	siginfo_t info;

	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
			11, SIGSEGV) == NOTIFY_STOP)
		return;

	/* Deliver the signal to userspace */
	info.si_signo = SIGTRAP;
	info.si_errno = breakpt;	/* breakpoint or watchpoint id */
	info.si_code = signal_code;
	info.si_addr = (void __user *)address;
	force_sig_info(SIGTRAP, &info, current);
}
コード例 #25
0
ファイル: traps.c プロジェクト: ForayJones/iods
/*
 * instruction access error
 */
asmlinkage void insn_access_error(unsigned long esfr1, unsigned long epcr0, unsigned long esr0)
{
	siginfo_t info;

	die_if_kernel("-- Insn Access Error --\n"
		      "EPCR0 : %08lx\n"
		      "ESR0  : %08lx\n",
		      epcr0, esr0);

	info.si_signo	= SIGSEGV;
	info.si_code	= SEGV_ACCERR;
	info.si_errno	= 0;
	info.si_addr	= (void *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);

	force_sig_info(info.si_signo, &info, current);
} /* end insn_access_error() */
コード例 #26
0
ファイル: traps.c プロジェクト: ForayJones/iods
asmlinkage void division_exception(unsigned long esfr1, unsigned long esr0, unsigned long isr)
{
	siginfo_t info;

	die_if_kernel("-- Division Exception --\n"
		      "ESR0 : %08lx\n"
		      "ISR  : %08lx\n",
		      esr0, isr);

	info.si_signo	= SIGFPE;
	info.si_code	= FPE_INTDIV;
	info.si_errno	= 0;
	info.si_addr	= (void *) __frame->pc;

	force_sig_info(info.si_signo, &info, current);
} /* end division_exception() */
コード例 #27
0
/*
 * Handle bad IA32 interrupt via syscall
 */
void
ia32_bad_interrupt (unsigned long int_num, struct pt_regs *regs)
{
	siginfo_t siginfo;

	die_if_kernel("Bad IA-32 interrupt", regs, int_num);

	siginfo.si_signo = SIGTRAP;
	siginfo.si_errno = int_num;	/* XXX is it OK to abuse si_errno like this? */
	siginfo.si_flags = 0;
	siginfo.si_isr = 0;
	siginfo.si_addr = NULL;
	siginfo.si_imm = 0;
	siginfo.si_code = TRAP_BRKPT;
	force_sig_info(SIGTRAP, &siginfo, current);
}
コード例 #28
0
ファイル: driver.c プロジェクト: 12019/hg556a_source
/* Handle a floating point exception.  Return zero if the faulting
   instruction can be completed successfully. */
int
handle_fpe(struct pt_regs *regs)
{
	extern void printbinary(unsigned long x, int nbits);
	struct siginfo si;
	unsigned int orig_sw, sw;
	int signalcode;
	/* need an intermediate copy of float regs because FPU emulation
	 * code expects an artificial last entry which contains zero
	 *
	 * also, the passed in fr registers contain one word that defines
	 * the fpu type. the fpu type information is constructed 
	 * inside the emulation code
	 */
	__u64 frcopy[36];

	memcpy(frcopy, regs->fr, sizeof regs->fr);
	frcopy[32] = 0;

	memcpy(&orig_sw, frcopy, sizeof(orig_sw));

	if (FPUDEBUG) {
		printk(KERN_DEBUG "FP VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI ->\n   ");
		printbinary(orig_sw, 32);
		printk(KERN_DEBUG "\n");
	}

	signalcode = decode_fpu(frcopy, 0x666);

	/* Status word = FR0L. */
	memcpy(&sw, frcopy, sizeof(sw));
	if (FPUDEBUG) {
		printk(KERN_DEBUG "VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI decode_fpu returns %d|0x%x\n",
			signalcode >> 24, signalcode & 0xffffff);
		printbinary(sw, 32);
		printk(KERN_DEBUG "\n");
	}

	memcpy(regs->fr, frcopy, sizeof regs->fr);
	if (signalcode != 0) {
	    si.si_signo = signalcode >> 24;
	    si.si_errno = 0;
	    si.si_code = signalcode & 0xffffff;
	    si.si_addr = (void *) regs->iaoq[0];
	    force_sig_info(si.si_signo, &si, current);
	    return -1;
	}
コード例 #29
0
ファイル: traps.c プロジェクト: ForayJones/iods
/*
 * data access error
 * - double-word data load from CPU control area (0xFExxxxxx)
 * - read performed on inactive or self-refreshing SDRAM
 * - error notification from slave device
 * - misaligned address
 * - access to out of bounds memory region
 * - user mode accessing privileged memory region
 * - write to R/O memory region
 */
asmlinkage void data_access_error(unsigned long esfr1, unsigned long esr15, unsigned long ear15)
{
	siginfo_t info;

	die_if_kernel("-- Data Access Error --\n"
		      "ESR15 : %08lx\n"
		      "EAR15 : %08lx\n",
		      esr15, ear15);

	info.si_signo	= SIGSEGV;
	info.si_code	= SEGV_ACCERR;
	info.si_errno	= 0;
	info.si_addr	= (void *)
		(((esr15 & (ESRx_VALID|ESR15_EAV)) == (ESRx_VALID|ESR15_EAV)) ? ear15 : 0);

	force_sig_info(info.si_signo, &info, current);
} /* end data_access_error() */
コード例 #30
0
ファイル: traps.c プロジェクト: AshishNamdev/linux
asmlinkage void do_bus_fault(struct pt_regs *regs, unsigned long address)
{
	siginfo_t info;

	if (user_mode(regs)) {
		/* Send a SIGBUS */
		info.si_signo = SIGBUS;
		info.si_errno = 0;
		info.si_code = BUS_ADRERR;
		info.si_addr = (void *)address;
		force_sig_info(SIGBUS, &info, current);
	} else {		/* Kernel mode */
		printk("KERNEL: Bus error (SIGBUS) 0x%.8lx\n", address);
		show_registers(regs);
		die("Die:", regs, address);
	}
}