chn->state = ECS_UNBOUND;
if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
chn->u.unbound.remote_domid = current->domain->domain_id;
+ evtchn_port_init(d, chn);
alloc->port = port;
lchn->u.interdomain.remote_dom = rd;
lchn->u.interdomain.remote_port = (u16)rport;
lchn->state = ECS_INTERDOMAIN;
+ evtchn_port_init(ld, lchn);
rchn->u.interdomain.remote_dom = ld;
rchn->u.interdomain.remote_port = (u16)lport;
chn->state = ECS_VIRQ;
chn->notify_vcpu_id = vcpu;
chn->u.virq = virq;
+ evtchn_port_init(d, chn);
v->virq_to_evtchn[virq] = bind->port = port;
chn = evtchn_from_port(d, port);
chn->state = ECS_IPI;
chn->notify_vcpu_id = vcpu;
+ evtchn_port_init(d, chn);
bind->port = port;
chn->state = ECS_PIRQ;
chn->u.pirq.irq = pirq;
link_pirq_port(port, chn, v);
+ evtchn_port_init(d, chn);
bind->port = port;
return d->evtchn_fifo->event_array[p] + w;
}
+static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
+{
+ event_word_t *word;
+
+ evtchn->priority = EVTCHN_FIFO_PRIORITY_DEFAULT;
+
+ /*
+ * If this event is still linked, the first event may be delivered
+ * on the wrong VCPU or with an unexpected priority.
+ */
+ word = evtchn_fifo_word_from_port(d, evtchn->port);
+ if ( word && test_bit(EVTCHN_FIFO_LINKED, word) )
+ gdprintk(XENLOG_WARNING, "domain %d, port %d already on a queue\n",
+ d->domain_id, evtchn->port);
+}
+
static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
{
event_word_t new, old;
static const struct evtchn_port_ops evtchn_port_ops_fifo =
{
+ .init = evtchn_fifo_init,
.set_pending = evtchn_fifo_set_pending,
.clear_pending = evtchn_fifo_clear_pending,
.unmask = evtchn_fifo_unmask,
* Low-level event channel port ops.
*/
struct evtchn_port_ops {
+ void (*init)(struct domain *d, struct evtchn *evtchn);
void (*set_pending)(struct vcpu *v, struct evtchn *evtchn);
void (*clear_pending)(struct domain *d, struct evtchn *evtchn);
void (*unmask)(struct domain *d, struct evtchn *evtchn);
void (*print_state)(struct domain *d, const struct evtchn *evtchn);
};
+static inline void evtchn_port_init(struct domain *d, struct evtchn *evtchn)
+{
+ if ( d->evtchn_port_ops->init )
+ d->evtchn_port_ops->init(d, evtchn);
+}
+
static inline void evtchn_port_set_pending(struct vcpu *v,
struct evtchn *evtchn)
{