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; }
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; }
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; }
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; }
asmlinkage int __ipipe_syscall_root(struct pt_regs regs) { ipipe_declare_cpuid; unsigned long flags; __fixup_if(®s); /* 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,®s) > 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(®s); 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; }