diff options
author | Roland Dreier <rolandd@cisco.com> | 2005-10-30 12:50:04 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2005-10-31 10:10:32 -0500 |
commit | 7162a3e0db34e914a8bc5bf74bbae0b386310cf8 (patch) | |
tree | ffd7eba03f29dd2932dd32ac4adc2921bde7644b | |
parent | a20583a7c2e35d80b1dfc1f60c9729498838725e (diff) |
[IB] uverbs: Avoid NULL pointer deref on CQ async event
Userspace CQs that have no completion event channel attached end up
with their cq_context set to NULL. However, asynchronous events like
"CQ overrun" can still occur on such CQs, so add a uverbs_file member
to struct ib_ucq_object that we can follow to deliver these events.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 9 |
3 files changed, 5 insertions, 6 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 031cdf3c066d..ecb830127865 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -113,6 +113,7 @@ struct ib_uevent_object { | |||
113 | 113 | ||
114 | struct ib_ucq_object { | 114 | struct ib_ucq_object { |
115 | struct ib_uobject uobject; | 115 | struct ib_uobject uobject; |
116 | struct ib_uverbs_file *uverbs_file; | ||
116 | struct list_head comp_list; | 117 | struct list_head comp_list; |
117 | struct list_head async_list; | 118 | struct list_head async_list; |
118 | u32 comp_events_reported; | 119 | u32 comp_events_reported; |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 8c89abc8c764..63a74151c60b 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -602,6 +602,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, | |||
602 | 602 | ||
603 | uobj->uobject.user_handle = cmd.user_handle; | 603 | uobj->uobject.user_handle = cmd.user_handle; |
604 | uobj->uobject.context = file->ucontext; | 604 | uobj->uobject.context = file->ucontext; |
605 | uobj->uverbs_file = file; | ||
605 | uobj->comp_events_reported = 0; | 606 | uobj->comp_events_reported = 0; |
606 | uobj->async_events_reported = 0; | 607 | uobj->async_events_reported = 0; |
607 | INIT_LIST_HEAD(&uobj->comp_list); | 608 | INIT_LIST_HEAD(&uobj->comp_list); |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 0eb38f479b39..e58a7b278a00 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -442,13 +442,10 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, | |||
442 | 442 | ||
443 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) | 443 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) |
444 | { | 444 | { |
445 | struct ib_uverbs_event_file *ev_file = context_ptr; | 445 | struct ib_ucq_object *uobj = container_of(event->element.cq->uobject, |
446 | struct ib_ucq_object *uobj; | 446 | struct ib_ucq_object, uobject); |
447 | 447 | ||
448 | uobj = container_of(event->element.cq->uobject, | 448 | ib_uverbs_async_handler(uobj->uverbs_file, uobj->uobject.user_handle, |
449 | struct ib_ucq_object, uobject); | ||
450 | |||
451 | ib_uverbs_async_handler(ev_file->uverbs_file, uobj->uobject.user_handle, | ||
452 | event->event, &uobj->async_list, | 449 | event->event, &uobj->async_list, |
453 | &uobj->async_events_reported); | 450 | &uobj->async_events_reported); |
454 | 451 | ||