static inline void evt_do_hypervisor_callback(unsigned int port, unsigned int l1i, unsigned int l2i, void *args) { KASSERT(args != NULL); struct cpu_info *ci = curcpu(); struct intrframe *regs = args; #ifdef PORT_DEBUG if (port == PORT_DEBUG) printf("do_hypervisor_callback event %d\n", port); #endif if (evtsource[port]) { ci->ci_idepth++; evtchn_do_event(port, regs); ci->ci_idepth--; } #ifdef DOM0OPS else { if (ci->ci_ilevel < IPL_HIGH) { /* fast path */ int oipl = ci->ci_ilevel; ci->ci_ilevel = IPL_HIGH; ci->ci_idepth++; xenevt_event(port); ci->ci_idepth--; ci->ci_ilevel = oipl; } else { /* set pending event */ xenevt_setipending(l1i, l2i); } } #endif }
/* process pending events */ static int xenevt_processevt(void *v) { long l1, l2; int l1i, l2i; int port; l1 = xen_atomic_xchg(&xenevt_ev1, 0); while ((l1i = xen_ffs(l1)) != 0) { l1i--; l1 &= ~(1UL << l1i); l2 = xen_atomic_xchg(&xenevt_ev2[l1i], 0); while ((l2i = xen_ffs(l2)) != 0) { l2i--; l2 &= ~(1UL << l2i); port = (l1i << LONG_SHIFT) + l2i; xenevt_event(port); } } return 0; }