Staging: hv: netvsc: Fix a dereferencing issue
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / hv / channel.c
index 455f47a891f17980a71d13b7f82ec00f89f27ae4..b6f3d38a6dbb5c8fbf6b424d185dd84e9d01328d 100644 (file)
@@ -76,15 +76,14 @@ void vmbus_get_debug_info(struct vmbus_channel *channel,
        struct hv_monitor_page *monitorpage;
        u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
        u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
-       /* u32 monitorBit       = 1 << monitorOffset; */
 
        debuginfo->relid = channel->offermsg.child_relid;
        debuginfo->state = channel->state;
        memcpy(&debuginfo->interfacetype,
-              &channel->offermsg.offer.if_type, sizeof(struct hv_guid));
+              &channel->offermsg.offer.if_type, sizeof(uuid_le));
        memcpy(&debuginfo->interface_instance,
               &channel->offermsg.offer.if_instance,
-              sizeof(struct hv_guid));
+              sizeof(uuid_le));
 
        monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
 
@@ -119,8 +118,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
                     u32 recv_ringbuffer_size, void *userdata, u32 userdatalen,
                     void (*onchannelcallback)(void *context), void *context)
 {
-       struct vmbus_channel_open_channel *openMsg;
-       struct vmbus_channel_msginfo *openInfo = NULL;
+       struct vmbus_channel_open_channel *open_msg;
+       struct vmbus_channel_msginfo *open_info = NULL;
        void *in, *out;
        unsigned long flags;
        int ret, t, err = 0;
@@ -173,24 +172,24 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
        }
 
        /* Create and init the channel open message */
-       openInfo = kmalloc(sizeof(*openInfo) +
+       open_info = kmalloc(sizeof(*open_info) +
                           sizeof(struct vmbus_channel_open_channel),
                           GFP_KERNEL);
-       if (!openInfo) {
+       if (!open_info) {
                err = -ENOMEM;
                goto errorout;
        }
 
-       init_completion(&openInfo->waitevent);
+       init_completion(&open_info->waitevent);
 
-       openMsg = (struct vmbus_channel_open_channel *)openInfo->msg;
-       openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL;
-       openMsg->openid = newchannel->offermsg.child_relid;
-       openMsg->child_relid = newchannel->offermsg.child_relid;
-       openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
-       openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
+       open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
+       open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
+       open_msg->openid = newchannel->offermsg.child_relid;
+       open_msg->child_relid = newchannel->offermsg.child_relid;
+       open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
+       open_msg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
                                                  PAGE_SHIFT;
-       openMsg->server_contextarea_gpadlhandle = 0;
+       open_msg->server_contextarea_gpadlhandle = 0;
 
        if (userdatalen > MAX_USER_DEFINED_BYTES) {
                err = -EINVAL;
@@ -198,35 +197,35 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
        }
 
        if (userdatalen)
-               memcpy(openMsg->userdata, userdata, userdatalen);
+               memcpy(open_msg->userdata, userdata, userdatalen);
 
        spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
-       list_add_tail(&openInfo->msglistentry,
+       list_add_tail(&open_info->msglistentry,
                      &vmbus_connection.chn_msg_list);
        spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
 
-       ret = vmbus_post_msg(openMsg,
+       ret = vmbus_post_msg(open_msg,
                               sizeof(struct vmbus_channel_open_channel));
 
        if (ret != 0)
                goto cleanup;
 
-       t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ);
+       t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
        if (t == 0) {
                err = -ETIMEDOUT;
                goto errorout;
        }
 
 
-       if (openInfo->response.open_result.status)
-               err = openInfo->response.open_result.status;
+       if (open_info->response.open_result.status)
+               err = open_info->response.open_result.status;
 
 cleanup:
        spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
-       list_del(&openInfo->msglistentry);
+       list_del(&open_info->msglistentry);
        spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
 
-       kfree(openInfo);
+       kfree(open_info);
        return err;
 
 errorout:
@@ -234,56 +233,11 @@ errorout:
        hv_ringbuffer_cleanup(&newchannel->inbound);
        free_pages((unsigned long)out,
                get_order(send_ringbuffer_size + recv_ringbuffer_size));
-       kfree(openInfo);
+       kfree(open_info);
        return err;
 }
 EXPORT_SYMBOL_GPL(vmbus_open);
 
-/*
- * dump_gpadl_body - Dump the gpadl body message to the console for
- * debugging purposes.
- */
-static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len)
-{
-       int i;
-       int pfncount;
-
-       pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) /
-                  sizeof(u64);
-
-       DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount);
-
-       for (i = 0; i < pfncount; i++)
-               DPRINT_DBG(VMBUS, "gpadl body  - %d) pfn %llu",
-                          i, gpadl->pfn[i]);
-}
-
-/*
- * dump_gpadl_header - Dump the gpadl header message to the console for
- * debugging purposes.
- */
-static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl)
-{
-       int i, j;
-       int pagecount;
-
-       DPRINT_DBG(VMBUS,
-                  "gpadl header - relid %d, range count %d, range buflen %d",
-                  gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen);
-       for (i = 0; i < gpadl->rangecount; i++) {
-               pagecount = gpadl->range[i].byte_count >> PAGE_SHIFT;
-               pagecount = (pagecount > 26) ? 26 : pagecount;
-
-               DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d "
-                          "page count %d", i, gpadl->range[i].byte_count,
-                          gpadl->range[i].byte_offset, pagecount);
-
-               for (j = 0; j < pagecount; j++)
-                       DPRINT_DBG(VMBUS, "%d) pfn %llu", j,
-                                  gpadl->range[i].pfn_array[j]);
-       }
-}
-
 /*
  * create_gpadl_header - Creates a gpadl for the specified buffer
  */
@@ -437,7 +391,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
 {
        struct vmbus_channel_gpadl_header *gpadlmsg;
        struct vmbus_channel_gpadl_body *gpadl_body;
-       /* struct vmbus_channel_gpadl_created *gpadlCreated; */
        struct vmbus_channel_msginfo *msginfo = NULL;
        struct vmbus_channel_msginfo *submsginfo;
        u32 msgcount;
@@ -461,7 +414,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
        gpadlmsg->child_relid = channel->offermsg.child_relid;
        gpadlmsg->gpadl = next_gpadl_handle;
 
-       dump_gpadl_header(gpadlmsg);
 
        spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
        list_add_tail(&msginfo->msglistentry,
@@ -485,8 +437,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
                                CHANNELMSG_GPADL_BODY;
                        gpadl_body->gpadl = next_gpadl_handle;
 
-                       dump_gpadl_body(gpadl_body, submsginfo->msgsize -
-                                     sizeof(*submsginfo));
                        ret = vmbus_post_msg(gpadl_body,
                                               submsginfo->msgsize -
                                               sizeof(*submsginfo));
@@ -522,8 +472,6 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
        unsigned long flags;
        int ret, t;
 
-       /* ASSERT(gpadl_handle != 0); */
-
        info = kmalloc(sizeof(*info) +
                       sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
        if (!info)
@@ -565,9 +513,12 @@ void vmbus_close(struct vmbus_channel *channel)
 {
        struct vmbus_channel_close_channel *msg;
        int ret;
+       unsigned long flags;
 
        /* Stop callback and cancel the timer asap */
+       spin_lock_irqsave(&channel->inbound_lock, flags);
        channel->onchannel_callback = NULL;
+       spin_unlock_irqrestore(&channel->inbound_lock, flags);
 
        /* Send a closing message */
 
@@ -787,19 +738,15 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
        u32 packetlen;
        u32 userlen;
        int ret;
-       unsigned long flags;
 
        *buffer_actual_len = 0;
        *requestid = 0;
 
-       spin_lock_irqsave(&channel->inbound_lock, flags);
 
        ret = hv_ringbuffer_peek(&channel->inbound, &desc,
                             sizeof(struct vmpacket_descriptor));
-       if (ret != 0) {
-               spin_unlock_irqrestore(&channel->inbound_lock, flags);
+       if (ret != 0)
                return 0;
-       }
 
        packetlen = desc.len8 << 3;
        userlen = packetlen - (desc.offset8 << 3);
@@ -807,7 +754,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
        *buffer_actual_len = userlen;
 
        if (userlen > bufferlen) {
-               spin_unlock_irqrestore(&channel->inbound_lock, flags);
 
                pr_err("Buffer too small - got %d needs %d\n",
                           bufferlen, userlen);
@@ -820,7 +766,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
        ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
                             (desc.offset8 << 3));
 
-       spin_unlock_irqrestore(&channel->inbound_lock, flags);
 
        return 0;
 }
@@ -837,19 +782,15 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
        u32 packetlen;
        u32 userlen;
        int ret;
-       unsigned long flags;
 
        *buffer_actual_len = 0;
        *requestid = 0;
 
-       spin_lock_irqsave(&channel->inbound_lock, flags);
 
        ret = hv_ringbuffer_peek(&channel->inbound, &desc,
                             sizeof(struct vmpacket_descriptor));
-       if (ret != 0) {
-               spin_unlock_irqrestore(&channel->inbound_lock, flags);
+       if (ret != 0)
                return 0;
-       }
 
 
        packetlen = desc.len8 << 3;
@@ -858,12 +799,10 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
        *buffer_actual_len = packetlen;
 
        if (packetlen > bufferlen) {
-               spin_unlock_irqrestore(&channel->inbound_lock, flags);
-
                pr_err("Buffer too small - needed %d bytes but "
                        "got space for only %d bytes\n",
                        packetlen, bufferlen);
-               return -2;
+               return -ENOBUFS;
        }
 
        *requestid = desc.trans_id;
@@ -871,7 +810,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
        /* Copy over the entire packet to the user buffer */
        ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
 
-       spin_unlock_irqrestore(&channel->inbound_lock, flags);
        return 0;
 }
 EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);