Example #1
0
int fastcall __ipipe_divert_exception(struct pt_regs *regs, int vector)
{
	if (__ipipe_event_monitored_p(vector) &&
	    __ipipe_dispatch_event(vector,regs) != 0)
		return 1;

	__fixup_if(regs);

	return 0;
}
Example #2
0
asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)
{
    struct ipipe_percpu_domain_data *p;
    void (*hook)(void);
    int ret;

    WARN_ON_ONCE(irqs_disabled_hw());

    /*
     * We need to run the IRQ tail hook each time we intercept a
     * syscall, because we know that important operations might be
     * pending there (e.g. Xenomai deferred rescheduling).
     */
    hook = (__typeof__(hook))__ipipe_irq_tail_hook;
    hook();

    /*
     * This routine either returns:
     * 0 -- if the syscall is to be passed to Linux;
     * >0 -- if the syscall should not be passed to Linux, and no
     * tail work should be performed;
     * <0 -- if the syscall should not be passed to Linux but the
     * tail work has to be performed (for handling signals etc).
     */

    if (!__ipipe_syscall_watched_p(current, regs->orig_p0) ||
            !__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL))
        return 0;

    ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs);

    hard_local_irq_disable();

    /*
     * This is the end of the syscall path, so we may
     * safely assume a valid Linux task stack here.
     */
    if (current->ipipe_flags & PF_EVTRET) {
        current->ipipe_flags &= ~PF_EVTRET;
        __ipipe_dispatch_event(IPIPE_EVENT_RETURN, regs);
    }

    if (!__ipipe_root_domain_p)
        ret = -1;
    else {
        p = ipipe_root_cpudom_ptr();
        if (__ipipe_ipending_p(p))
            __ipipe_sync_pipeline();
    }

    hard_local_irq_enable();

    return -ret;
}
Example #3
0
asmlinkage int __ipipe_handle_exception(int vector, struct pt_regs *regs, long error_code)
{
	if (!__ipipe_event_monitored_p(vector) ||
	    __ipipe_dispatch_event(vector,regs) == 0) {
		__ipipe_exptr handler = __ipipe_std_extable[vector];
		handler(regs,error_code);
		__fixup_if(regs);
		return 0;
	}

	return 1;
}
Example #4
0
int __ipipe_syscall_root(struct pt_regs *regs)
{
	unsigned long flags;
	int ret;

	/*
	 * This routine either returns:
	 * 0 -- if the syscall is to be passed to Linux;
	 * >0 -- if the syscall should not be passed to Linux, and no
	 * tail work should be performed;
	 * <0 -- if the syscall should not be passed to Linux but the
	 * tail work has to be performed (for handling signals etc).
	 */

	if (!__ipipe_syscall_watched_p(current, regs->orig_ax) ||
	    !__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL))
		return 0;

	ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs);

	local_irq_save_hw(flags);

	if (current->ipipe_flags & PF_EVTRET) {
		current->ipipe_flags &= ~PF_EVTRET;
		__ipipe_dispatch_event(IPIPE_EVENT_RETURN, regs);
	}

	if (!ipipe_root_domain_p)
		return 1;

	/*
	 * If allowed, sync pending VIRQs before _TIF_NEED_RESCHED is
	 * tested.
	 */
	if (__ipipe_ipending_p(ipipe_root_cpudom_ptr()))
		__ipipe_sync_pipeline();

	if (!ret)
		local_irq_restore_hw(flags);

	return -ret;
}
Example #5
0
asmlinkage int __ipipe_syscall_root(struct pt_regs regs)
{
	ipipe_declare_cpuid;
	unsigned long flags;

	__fixup_if(&regs);

	/* This routine either returns:
	    0 -- if the syscall is to be passed to Linux;
	   >0 -- if the syscall should not be passed to Linux, and no
	   tail work should be performed;
	   <0 -- if the syscall should not be passed to Linux but the
	   tail work has to be performed (for handling signals etc). */

	if (__ipipe_syscall_watched_p(current, regs.orig_eax) &&
	    __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
	    __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL,&regs) > 0) {
		/* We might enter here over a non-root domain and exit
		 * over the root one as a result of the syscall
		 * (i.e. by recycling the register set of the current
		 * context across the migration), so we need to fixup
		 * the interrupt flag upon return too, so that
		 * __ipipe_unstall_iret_root() resets the correct
		 * stall bit on exit. */
		__fixup_if(&regs);

		if (ipipe_current_domain == ipipe_root_domain) {
			/* Sync pending VIRQs before _TIF_NEED_RESCHED
			 * is tested. */
			ipipe_lock_cpu(flags);
			if ((ipipe_root_domain->cpudata[cpuid].irq_pending_hi & IPIPE_IRQMASK_VIRT) != 0)
				__ipipe_sync_stage(IPIPE_IRQMASK_VIRT);
			ipipe_unlock_cpu(flags);
			return -1;
		}
		return 1;
	}

    return 0;
}