예제 #1
0
파일: exception.c 프로젝트: Prajna/xnu
kern_return_t
bsd_exception(
	exception_type_t	exception,
	mach_exception_data_t	code,
	mach_msg_type_number_t  codeCnt)
{
	task_t			task;
	struct exception_action *excp;
	lck_mtx_t		*mutex;
	thread_t		self = current_thread();
	kern_return_t		kr;

	/*
	 * Maybe the task level will handle it.
	 */
	task = current_task();
	mutex = &task->lock;
	excp = &task->exc_actions[exception];

	kr = exception_deliver(self, exception, code, codeCnt, excp, mutex);

	if (kr == KERN_SUCCESS || kr == MACH_RCV_PORT_DIED)
		return(KERN_SUCCESS);
	return(KERN_FAILURE);
}
예제 #2
0
파일: trap.c 프로젝트: m943040028/prex
/*
 * Trap handler
 * Invoke the exception handler if it is needed.
 */
void
trap_handler(struct cpu_regs *regs)
{
	uint32_t trap_no = regs->trap_no;

#ifdef CONFIG_MMU
	switch (trap_no) {
	case TRAP_DATA_TLB_MISS:
	case TRAP_INST_TLB_MISS:
		handle_tlb_miss(regs);
		return;
	};
#endif
#ifdef DEBUG
	printf("============================\n");
	printf("Trap %x: %s\n", trap_no, trap_name[trap_no]);
	printf("============================\n");

	trap_dump(regs);
	for (;;) ;
#endif
	if ((regs->srr1 & MSR_PR) != MSR_PR)
		panic("Kernel exception");

	exception_mark(exception_map[trap_no]);
	exception_deliver();
}
예제 #3
0
/*
 *	Handle interface for special performance monitoring
 *	This is a special case of the host exception handler
 */
kern_return_t sys_perf_notify(thread_t thread, int pid)
{

    host_priv_t		hostp;
    struct exception_action *excp;
    ipc_port_t		xport;
    wait_interrupt_t	wsave;
    kern_return_t		ret;

    hostp = host_priv_self();	/* Get the host privileged ports */
    mach_exception_data_type_t	code[EXCEPTION_CODE_MAX];
    code[0] = 0xFF000001;		/* Set terminate code */
    code[1] = pid;		/* Pass out the pid */

    struct task *task = thread->task;
    excp = &hostp->exc_actions[EXC_RPC_ALERT];
    xport = excp->port;

    /* Make sure we're not catching our own exception */
    if (!IP_VALID(xport) ||
            !ip_active(xport) ||
            task->itk_space == xport->data.receiver) {

        return(KERN_FAILURE);
    }

    wsave = thread_interrupt_level(THREAD_UNINT);
    ret = exception_deliver(
              thread,
              EXC_RPC_ALERT,
              code,
              2,
              excp,
              &hostp->lock);
    (void)thread_interrupt_level(wsave);

    return(ret);
}
예제 #4
0
파일: exception.c 프로젝트: Prajna/xnu
/*
 *	Routine:	exception
 *	Purpose:
 *		The current thread caught an exception.
 *		We make an up-call to the thread's exception server.
 *	Conditions:
 *		Nothing locked and no resources held.
 *		Called from an exception context, so
 *		thread_exception_return and thread_kdb_return
 *		are possible.
 *	Returns:
 *		Doesn't return.
 */
void
exception_triage(
	exception_type_t	exception,
	mach_exception_data_t	code,
	mach_msg_type_number_t  codeCnt)
{
	thread_t		thread;
	task_t			task;
	host_priv_t		host_priv;
	struct exception_action *excp;
	lck_mtx_t			*mutex;
	kern_return_t		kr;

	assert(exception != EXC_RPC_ALERT);

	if (exception == KERN_SUCCESS)
		panic("exception");

	/*
	 * Try to raise the exception at the activation level.
	 */
	thread = current_thread();
	mutex = &thread->mutex;
	excp = &thread->exc_actions[exception];
	kr = exception_deliver(thread, exception, code, codeCnt, excp, mutex);
	if (kr == KERN_SUCCESS || kr == MACH_RCV_PORT_DIED)
		goto out;

	/*
	 * Maybe the task level will handle it.
	 */
	task = current_task();
	mutex = &task->lock;
	excp = &task->exc_actions[exception];
	kr = exception_deliver(thread, exception, code, codeCnt, excp, mutex);
	if (kr == KERN_SUCCESS || kr == MACH_RCV_PORT_DIED)
		goto out;

	/*
	 * How about at the host level?
	 */
	host_priv = host_priv_self();
	mutex = &host_priv->lock;
	excp = &host_priv->exc_actions[exception];
	kr = exception_deliver(thread, exception, code, codeCnt, excp, mutex);
	if (kr == KERN_SUCCESS || kr == MACH_RCV_PORT_DIED)
		goto out;

	/*
	 * Nobody handled it, terminate the task.
	 */

#if	MACH_KDB
	if (debug_user_with_kdb) {
		/*
		 *	Debug the exception with kdb.
		 *	If kdb handles the exception,
		 *	then thread_kdb_return won't return.
		 */
		db_printf("No exception server, calling kdb...\n");
		thread_kdb_return();
	}
#endif	/* MACH_KDB */

	(void) task_terminate(task);

out:
	if (exception != EXC_CRASH)
		thread_exception_return();
	return;
}