static int get_free_port(struct domain *d) { struct evtchn *chn; int port; int i, j; if ( d->is_dying ) return -EINVAL; for ( port = 0; port_is_valid(d, port); port++ ) if ( evtchn_from_port(d, port)->state == ECS_FREE ) return port; if ( port == MAX_EVTCHNS(d) ) return -ENOSPC; chn = xzalloc_array(struct evtchn, EVTCHNS_PER_BUCKET); if ( unlikely(chn == NULL) ) return -ENOMEM; bucket_from_port(d, port) = chn; for ( i = 0; i < EVTCHNS_PER_BUCKET; i++ ) { if ( xsm_alloc_security_evtchn(&chn[i]) ) { for ( j = 0; j < i; j++ ) xsm_free_security_evtchn(&chn[j]); xfree(chn); return -ENOMEM; } } return port; }
static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port) { struct evtchn *chn; unsigned int i; chn = xzalloc_array(struct evtchn, EVTCHNS_PER_BUCKET); if ( !chn ) return NULL; for ( i = 0; i < EVTCHNS_PER_BUCKET; i++ ) { if ( xsm_alloc_security_evtchn(&chn[i]) ) { while ( i-- ) xsm_free_security_evtchn(&chn[i]); xfree(chn); return NULL; } chn[i].port = port + i; } return chn; }