xen/intr: xen_intr_bind_isrc() always set handle
Previously the upper layer handle was being set before the last potential error condition. The reasoning appears to have been it was assumed invalid in case of an error being returned. Now ensure it is invalid until just before a successful return. Fixes:76acc41fb7
("Implement vector callback for PVHVM and unify event channel implementations") Fixes:6d54cab1fe
("xen: allow to register event channels without handlers") Reviewed by: royger
This commit is contained in:
parent
9903bf34f0
commit
054073c283
@ -410,7 +410,7 @@ static int
|
|||||||
xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
|
xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
|
||||||
enum evtchn_type type, const char *intr_owner, driver_filter_t filter,
|
enum evtchn_type type, const char *intr_owner, driver_filter_t filter,
|
||||||
driver_intr_t handler, void *arg, enum intr_type flags,
|
driver_intr_t handler, void *arg, enum intr_type flags,
|
||||||
xen_intr_handle_t *port_handlep)
|
xen_intr_handle_t *const port_handlep)
|
||||||
{
|
{
|
||||||
struct xenisrc *isrc;
|
struct xenisrc *isrc;
|
||||||
int error;
|
int error;
|
||||||
@ -420,6 +420,7 @@ xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
|
|||||||
printf("%s: %s: Bad event handle\n", intr_owner, __func__);
|
printf("%s: %s: Bad event handle\n", intr_owner, __func__);
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
*port_handlep = NULL;
|
||||||
|
|
||||||
mtx_lock(&xen_intr_isrc_lock);
|
mtx_lock(&xen_intr_isrc_lock);
|
||||||
isrc = xen_intr_find_unused_isrc(type);
|
isrc = xen_intr_find_unused_isrc(type);
|
||||||
@ -436,9 +437,6 @@ xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
|
|||||||
refcount_init(&isrc->xi_refcount, 1);
|
refcount_init(&isrc->xi_refcount, 1);
|
||||||
mtx_unlock(&xen_intr_isrc_lock);
|
mtx_unlock(&xen_intr_isrc_lock);
|
||||||
|
|
||||||
/* Assign the opaque handler */
|
|
||||||
*port_handlep = xen_intr_handle_from_isrc(isrc);
|
|
||||||
|
|
||||||
#ifdef SMP
|
#ifdef SMP
|
||||||
if (type == EVTCHN_TYPE_PORT) {
|
if (type == EVTCHN_TYPE_PORT) {
|
||||||
/*
|
/*
|
||||||
@ -450,23 +448,23 @@ xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (filter == NULL && handler == NULL) {
|
/*
|
||||||
/*
|
* If a filter or handler function is provided, add it to the event.
|
||||||
* No filter/handler provided, leave the event channel
|
* Otherwise the event channel is left masked and without a handler,
|
||||||
* masked and without a valid handler, the caller is
|
* the caller is in charge of setting that up.
|
||||||
* in charge of setting that up.
|
*/
|
||||||
*/
|
if (filter != NULL || handler != NULL) {
|
||||||
*isrcp = isrc;
|
error = xen_intr_add_handler(intr_owner, filter, handler, arg,
|
||||||
return (0);
|
flags, xen_intr_handle_from_isrc(isrc));
|
||||||
|
if (error != 0) {
|
||||||
|
xen_intr_release_isrc(isrc);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error = xen_intr_add_handler(intr_owner, filter, handler, arg, flags,
|
|
||||||
*port_handlep);
|
|
||||||
if (error != 0) {
|
|
||||||
xen_intr_release_isrc(isrc);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
*isrcp = isrc;
|
*isrcp = isrc;
|
||||||
|
/* Assign the opaque handler */
|
||||||
|
*port_handlep = xen_intr_handle_from_isrc(isrc);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user