aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2005-10-30 12:50:04 -0500
committerRoland Dreier <rolandd@cisco.com>2005-10-31 10:10:32 -0500
commit7162a3e0db34e914a8bc5bf74bbae0b386310cf8 (patch)
treeffd7eba03f29dd2932dd32ac4adc2921bde7644b
parenta20583a7c2e35d80b1dfc1f60c9729498838725e (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.h1
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c1
-rw-r--r--drivers/infiniband/core/uverbs_main.c9
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
114struct ib_ucq_object { 114struct 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
443void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) 443void 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