Page MenuHomeFreeBSD

D31188.id111709.diff
No OneTemporary

D31188.id111709.diff

diff --git a/sys/dev/xen/bus/xen_intr.c b/sys/dev/xen/bus/xen_intr.c
--- a/sys/dev/xen/bus/xen_intr.c
+++ b/sys/dev/xen/bus/xen_intr.c
@@ -232,14 +232,34 @@
return (0);
}
+/**
+ * Allocate a xenisrc structure and initialize it to default values.
+ *
+ * \returns A pointer to the Xen interrupt source object allocated
+ */
+static struct xenisrc *
+xen_intr_alloc_isrc(void)
+{
+ struct xenisrc *isrc;
+
+ isrc = xen_arch_intr_alloc();
+
+ if (isrc != NULL) {
+ isrc->xi_cookie = NULL;
+ isrc->xi_port = INVALID_EVTCHN;
+ isrc->xi_close = false;
+ isrc->xi_cpu = ~0U;
+ refcount_init(&isrc->xi_refcount, 1);
+ }
+
+ return (isrc);
+}
+
/**
* Associate an interrupt handler with an already allocated local Xen
* event channel port.
*
- * \param isrcp The returned Xen interrupt object associated with
- * the specified local port.
- * \param local_port The event channel to bind.
- * \param type The event channel type of local_port.
+ * \param isrc A pointer to an initialized interrupt source object.
* \param intr_owner The device making this bind request.
* \param handlep Pointer to an opaque handle used to manage this
* registration.
@@ -247,32 +267,33 @@
* \returns 0 on success, otherwise an errno.
*/
static int
-xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
- enum evtchn_type type, const char *intr_owner,
+xen_intr_bind_isrc(struct xenisrc *isrc, const char *intr_owner,
xen_intr_handle_t *const port_handlep)
{
- struct xenisrc *isrc;
- *isrcp = NULL;
KASSERT(port_handlep != NULL, ("%s: %s: Bad event handle\n", intr_owner,
__func__));
- isrc = xen_arch_intr_alloc();
- if (isrc == NULL)
- return (ENOSPC);
+ KASSERT(isrc != NULL, ("%s: NULL isrc passed in", __func__));
+
+ KASSERT(is_valid_evtchn(isrc->xi_port),
+ ("%s: Called with invalid event channel (%u)", __func__,
+ isrc->xi_port));
+
+ KASSERT((isrc->xi_type > EVTCHN_TYPE_UNBOUND) &&
+ (isrc->xi_type < EVTCHN_TYPE_COUNT),
+ ("%s: Called with invalid event channel type (%d)", __func__,
+ isrc->xi_type));
+
+ KASSERT(isrc->xi_cookie == NULL,
+ ("%s: Called with uninitialized cookie", __func__));
- isrc->xi_cookie = NULL;
- isrc->xi_type = type;
- isrc->xi_port = local_port;
- isrc->xi_close = false;
- isrc->xi_cpu = 0;
- refcount_init(&isrc->xi_refcount, 1);
mtx_lock(&xen_intr_isrc_lock);
xen_intr_port_to_isrc[isrc->xi_port] = isrc;
mtx_unlock(&xen_intr_isrc_lock);
#ifdef SMP
- if (type == EVTCHN_TYPE_PORT) {
+ if (isrc->xi_type == EVTCHN_TYPE_PORT) {
/*
* By default all interrupts are assigned to vCPU#0
* unless specified otherwise, so shuffle them to balance
@@ -282,7 +303,6 @@
}
#endif
- *isrcp = isrc;
/* Assign the opaque handler */
*port_handlep = xen_intr_handle_from_isrc(isrc);
return (0);
@@ -718,22 +738,20 @@
{
struct xenisrc *isrc;
const char *const name = device_get_nameunit(dev);
- int error;
KASSERT(port_handlep != NULL, ("%s: %s: Bad event handle\n", name,
__func__));
- error = xen_intr_bind_isrc(&isrc, local_port, EVTCHN_TYPE_PORT,
- name, port_handlep);
- if (error != 0)
- return (error);
+ if ((isrc = xen_intr_alloc_isrc()) == NULL)
+ return (ENOSPC);
+ isrc->xi_type = EVTCHN_TYPE_PORT;
+ isrc->xi_port = local_port;
/*
* The Event Channel API didn't open this port, so it is not
* responsible for closing it automatically on unbind.
*/
- isrc->xi_close = 0;
- return (0);
+ return (xen_intr_bind_isrc(isrc, name, port_handlep));
}
int
@@ -748,6 +766,11 @@
KASSERT(port_handlep != NULL, ("%s: %s: Bad event handle\n", name,
__func__));
+ if ((isrc = xen_intr_alloc_isrc()) == NULL)
+ return (ENOSPC);
+
+ isrc->xi_type = EVTCHN_TYPE_PORT;
+
alloc_unbound.dom = DOMID_SELF;
alloc_unbound.remote_dom = remote_domain;
error = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
@@ -757,11 +780,12 @@
* XXX Trap Hypercall error code Linuxisms in
* the HYPERCALL layer.
*/
+ xen_intr_release_isrc(isrc);
return (-error);
}
- error = xen_intr_bind_isrc(&isrc, alloc_unbound.port, EVTCHN_TYPE_PORT,
- name, port_handlep);
+ isrc->xi_port = alloc_unbound.port;
+ error = xen_intr_bind_isrc(isrc, name, port_handlep);
if (error != 0) {
evtchn_close_t close = { .port = alloc_unbound.port };
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
@@ -785,6 +809,11 @@
KASSERT(port_handlep != NULL, ("%s: %s: Bad event handle\n", name,
__func__));
+ if ((isrc = xen_intr_alloc_isrc()) == NULL)
+ return (ENOSPC);
+
+ isrc->xi_type = EVTCHN_TYPE_PORT;
+
bind_interdomain.remote_dom = remote_domain;
bind_interdomain.remote_port = remote_port;
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
@@ -794,11 +823,12 @@
* XXX Trap Hypercall error code Linuxisms in
* the HYPERCALL layer.
*/
+ xen_intr_release_isrc(isrc);
return (-error);
}
- error = xen_intr_bind_isrc(&isrc, bind_interdomain.local_port,
- EVTCHN_TYPE_PORT, name, port_handlep);
+ isrc->xi_port = bind_interdomain.local_port;
+ error = xen_intr_bind_isrc(isrc, name, port_handlep);
if (error) {
evtchn_close_t close = { .port = bind_interdomain.local_port };
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
@@ -827,18 +857,24 @@
KASSERT(port_handlep != NULL, ("%s: %s: Bad event handle\n", name,
__func__));
- isrc = NULL;
+ if ((isrc = xen_intr_alloc_isrc()) == NULL)
+ return (ENOSPC);
+
+ isrc->xi_type = EVTCHN_TYPE_VIRQ;
+ isrc->xi_virq = virq;
+
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &bind_virq);
if (error != 0) {
/*
* XXX Trap Hypercall error code Linuxisms in
* the HYPERCALL layer.
*/
+ xen_intr_release_isrc(isrc);
return (-error);
}
- error = xen_intr_bind_isrc(&isrc, bind_virq.port, EVTCHN_TYPE_VIRQ,
- name, port_handlep);
+ isrc->xi_port = bind_virq.port;
+ error = xen_intr_bind_isrc(isrc, name, port_handlep);
#ifdef SMP
if (error == 0)
@@ -871,7 +907,6 @@
* responsible for closing it automatically on unbind.
*/
isrc->xi_close = 1;
- isrc->xi_virq = virq;
return (0);
}
@@ -892,18 +927,23 @@
KASSERT(port_handlep != NULL, ("%s: %s: Bad event handle\n",
name, __func__));
- isrc = NULL;
+ if ((isrc = xen_intr_alloc_isrc()) == NULL)
+ return (ENOSPC);
+
+ isrc->xi_type = EVTCHN_TYPE_IPI;
+
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, &bind_ipi);
if (error != 0) {
/*
* XXX Trap Hypercall error code Linuxisms in
* the HYPERCALL layer.
*/
+ xen_intr_release_isrc(isrc);
return (-error);
}
- error = xen_intr_bind_isrc(&isrc, bind_ipi.port, EVTCHN_TYPE_IPI,
- name, port_handlep);
+ isrc->xi_port = bind_ipi.port;
+ error = xen_intr_bind_isrc(isrc, name, port_handlep);
if (error != 0) {
evtchn_close_t close = { .port = bind_ipi.port };

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 10, 9:53 PM (19 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31248362
Default Alt Text
D31188.id111709.diff (6 KB)

Event Timeline