{
if ( port > d->max_evtchn_port )
return -ENOSPC;
- if ( evtchn_from_port(d, port)->state == ECS_FREE )
+ if ( evtchn_from_port(d, port)->state == ECS_FREE
+ && !evtchn_port_is_busy(d, port) )
return port;
}
return test_bit(EVTCHN_FIFO_MASKED, word);
}
+static bool_t evtchn_fifo_is_busy(struct domain *d, evtchn_port_t port)
+{
+ event_word_t *word;
+
+ word = evtchn_fifo_word_from_port(d, port);
+ if ( unlikely(!word) )
+ return 0;
+
+ return test_bit(EVTCHN_FIFO_LINKED, word);
+}
+
static int evtchn_fifo_set_priority(struct domain *d, struct evtchn *evtchn,
unsigned int priority)
{
.unmask = evtchn_fifo_unmask,
.is_pending = evtchn_fifo_is_pending,
.is_masked = evtchn_fifo_is_masked,
+ .is_busy = evtchn_fifo_is_busy,
.set_priority = evtchn_fifo_set_priority,
.print_state = evtchn_fifo_print_state,
};
void (*unmask)(struct domain *d, struct evtchn *evtchn);
bool_t (*is_pending)(struct domain *d, const struct evtchn *evtchn);
bool_t (*is_masked)(struct domain *d, const struct evtchn *evtchn);
+ /*
+ * Is the port unavailable because it's still being cleaned up
+ * after being closed?
+ */
+ bool_t (*is_busy)(struct domain *d, evtchn_port_t port);
int (*set_priority)(struct domain *d, struct evtchn *evtchn,
unsigned int priority);
void (*print_state)(struct domain *d, const struct evtchn *evtchn);
return d->evtchn_port_ops->is_masked(d, evtchn);
}
+static inline bool_t evtchn_port_is_busy(struct domain *d, evtchn_port_t port)
+{
+ if ( d->evtchn_port_ops->is_busy )
+ return d->evtchn_port_ops->is_busy(d, port);
+ return 0;
+}
+
static inline int evtchn_port_set_priority(struct domain *d,
struct evtchn *evtchn,
unsigned int priority)