diff --git a/xen/common/event_2l.c b/xen/common/event_2l.c index e1dbb860f4..a229d35271 100644 --- a/xen/common/event_2l.c +++ b/xen/common/event_2l.c @@ -103,7 +103,6 @@ static const struct evtchn_port_ops evtchn_port_ops_2l = 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); } /* diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 53c17bd354..08ffe0f063 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -151,7 +151,7 @@ static void free_evtchn_bucket(struct domain *d, struct evtchn *bucket) 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) ) @@ -1396,13 +1396,11 @@ static void domain_dump_evtchn_info(struct domain *d) 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; diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c index 230f440f14..2f13d92128 100644 --- a/xen/common/event_fifo.c +++ b/xen/common/event_fifo.c @@ -478,7 +478,7 @@ static void cleanup_event_array(struct domain *d) 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; @@ -488,7 +488,7 @@ static void setup_ports(struct domain *d) * - 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; @@ -546,6 +546,8 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control) 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); @@ -562,8 +564,7 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control) 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); diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c index cb49a8bc02..ab94d2ec3a 100644 --- a/xen/common/sched/core.c +++ b/xen/common/sched/core.c @@ -1428,7 +1428,7 @@ static long do_poll(struct sched_poll *sched_poll) goto out; rc = -EINVAL; - if ( port >= d->max_evtchns ) + if ( !port_is_valid(d, port) ) goto out; rc = 0; diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index c35f4b23b6..e1b299e8df 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -105,6 +105,12 @@ void notify_via_xen_event_channel(struct domain *ld, int lport); #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) ) diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index e9ce43cc9a..33d716ef77 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -359,7 +359,6 @@ struct domain /* 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;