void evtchn_2l_init(struct domain *d)
{
d->evtchn_port_ops = &evtchn_port_ops_2l;
- d->max_evtchns = BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
}
/*
int evtchn_allocate_port(struct domain *d, evtchn_port_t port)
{
- if ( port > d->max_evtchn_port || port >= d->max_evtchns )
+ if ( port > d->max_evtchn_port || port >= max_evtchns(d) )
return -ENOSPC;
if ( port_is_valid(d, port) )
spin_lock(&d->event_lock);
- for ( port = 1; port < d->max_evtchns; ++port )
+ for ( port = 1; port_is_valid(d, port); ++port )
{
const struct evtchn *chn;
char *ssid;
- if ( !port_is_valid(d, port) )
- continue;
chn = evtchn_from_port(d, port);
if ( chn->state == ECS_FREE )
continue;
d->evtchn_fifo = NULL;
}
-static void setup_ports(struct domain *d)
+static void setup_ports(struct domain *d, unsigned int prev_evtchns)
{
unsigned int port;
* - save its pending state.
* - set default priority.
*/
- for ( port = 1; port < d->max_evtchns; port++ )
+ for ( port = 1; port < prev_evtchns; port++ )
{
struct evtchn *evtchn;
if ( !d->evtchn_fifo )
{
struct vcpu *vcb;
+ /* Latch the value before it changes during setup_event_array(). */
+ unsigned int prev_evtchns = max_evtchns(d);
for_each_vcpu ( d, vcb ) {
rc = setup_control_block(vcb);
goto error;
d->evtchn_port_ops = &evtchn_port_ops_fifo;
- d->max_evtchns = EVTCHN_FIFO_NR_CHANNELS;
- setup_ports(d);
+ setup_ports(d, prev_evtchns);
}
else
rc = map_control_block(v, gfn, offset);
goto out;
rc = -EINVAL;
- if ( port >= d->max_evtchns )
+ if ( !port_is_valid(d, port) )
goto out;
rc = 0;
#define bucket_from_port(d, p) \
((group_from_port(d, p))[((p) % EVTCHNS_PER_GROUP) / EVTCHNS_PER_BUCKET])
+static inline unsigned int max_evtchns(const struct domain *d)
+{
+ return d->evtchn_fifo ? EVTCHN_FIFO_NR_CHANNELS
+ : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
+}
+
static inline bool_t port_is_valid(struct domain *d, unsigned int p)
{
if ( p >= read_atomic(&d->valid_evtchns) )
/* Event channel information. */
struct evtchn *evtchn; /* first bucket only */
struct evtchn **evtchn_group[NR_EVTCHN_GROUPS]; /* all other buckets */
- unsigned int max_evtchns; /* number supported by ABI */
unsigned int max_evtchn_port; /* max permitted port number */
unsigned int valid_evtchns; /* number of allocated event channels */
spinlock_t event_lock;