0001
0002
0003
0004
0005
0006
0007
0008
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010
0011 #include <linux/kernel.h>
0012 #include <linux/sched.h>
0013 #include <linux/wait.h>
0014 #include <linux/mm.h>
0015 #include <linux/slab.h>
0016 #include <linux/module.h>
0017 #include <linux/hyperv.h>
0018 #include <linux/uio.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/set_memory.h>
0021 #include <asm/page.h>
0022 #include <asm/mshyperv.h>
0023
0024 #include "hyperv_vmbus.h"
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 static inline u32 hv_gpadl_size(enum hv_gpadl_type type, u32 size)
0039 {
0040 switch (type) {
0041 case HV_GPADL_BUFFER:
0042 return size;
0043 case HV_GPADL_RING:
0044
0045 BUG_ON(size % PAGE_SIZE);
0046
0047
0048
0049
0050
0051
0052
0053
0054 return size - 2 * (PAGE_SIZE - HV_HYP_PAGE_SIZE);
0055 }
0056 BUG();
0057 return 0;
0058 }
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 static inline u32 hv_ring_gpadl_send_hvpgoffset(u32 offset)
0069 {
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 return (offset - (PAGE_SIZE - HV_HYP_PAGE_SIZE)) >> HV_HYP_PAGE_SHIFT;
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 static inline u64 hv_gpadl_hvpfn(enum hv_gpadl_type type, void *kbuffer,
0095 u32 size, u32 send_offset, int i)
0096 {
0097 int send_idx = hv_ring_gpadl_send_hvpgoffset(send_offset);
0098 unsigned long delta = 0UL;
0099
0100 switch (type) {
0101 case HV_GPADL_BUFFER:
0102 break;
0103 case HV_GPADL_RING:
0104 if (i == 0)
0105 delta = 0;
0106 else if (i <= send_idx)
0107 delta = PAGE_SIZE - HV_HYP_PAGE_SIZE;
0108 else
0109 delta = 2 * (PAGE_SIZE - HV_HYP_PAGE_SIZE);
0110 break;
0111 default:
0112 BUG();
0113 break;
0114 }
0115
0116 return virt_to_hvpfn(kbuffer + delta + (HV_HYP_PAGE_SIZE * i));
0117 }
0118
0119
0120
0121
0122
0123 void vmbus_setevent(struct vmbus_channel *channel)
0124 {
0125 struct hv_monitor_page *monitorpage;
0126
0127 trace_vmbus_setevent(channel);
0128
0129
0130
0131
0132
0133 if (channel->offermsg.monitor_allocated && !channel->low_latency) {
0134 vmbus_send_interrupt(channel->offermsg.child_relid);
0135
0136
0137 monitorpage = vmbus_connection.monitor_pages[1];
0138
0139 sync_set_bit(channel->monitor_bit,
0140 (unsigned long *)&monitorpage->trigger_group
0141 [channel->monitor_grp].pending);
0142
0143 } else {
0144 vmbus_set_event(channel);
0145 }
0146 }
0147 EXPORT_SYMBOL_GPL(vmbus_setevent);
0148
0149
0150 void vmbus_free_ring(struct vmbus_channel *channel)
0151 {
0152 hv_ringbuffer_cleanup(&channel->outbound);
0153 hv_ringbuffer_cleanup(&channel->inbound);
0154
0155 if (channel->ringbuffer_page) {
0156 __free_pages(channel->ringbuffer_page,
0157 get_order(channel->ringbuffer_pagecount
0158 << PAGE_SHIFT));
0159 channel->ringbuffer_page = NULL;
0160 }
0161 }
0162 EXPORT_SYMBOL_GPL(vmbus_free_ring);
0163
0164
0165 int vmbus_alloc_ring(struct vmbus_channel *newchannel,
0166 u32 send_size, u32 recv_size)
0167 {
0168 struct page *page;
0169 int order;
0170
0171 if (send_size % PAGE_SIZE || recv_size % PAGE_SIZE)
0172 return -EINVAL;
0173
0174
0175 order = get_order(send_size + recv_size);
0176 page = alloc_pages_node(cpu_to_node(newchannel->target_cpu),
0177 GFP_KERNEL|__GFP_ZERO, order);
0178
0179 if (!page)
0180 page = alloc_pages(GFP_KERNEL|__GFP_ZERO, order);
0181
0182 if (!page)
0183 return -ENOMEM;
0184
0185 newchannel->ringbuffer_page = page;
0186 newchannel->ringbuffer_pagecount = (send_size + recv_size) >> PAGE_SHIFT;
0187 newchannel->ringbuffer_send_offset = send_size >> PAGE_SHIFT;
0188
0189 return 0;
0190 }
0191 EXPORT_SYMBOL_GPL(vmbus_alloc_ring);
0192
0193
0194 int vmbus_send_tl_connect_request(const guid_t *shv_guest_servie_id,
0195 const guid_t *shv_host_servie_id)
0196 {
0197 struct vmbus_channel_tl_connect_request conn_msg;
0198 int ret;
0199
0200 memset(&conn_msg, 0, sizeof(conn_msg));
0201 conn_msg.header.msgtype = CHANNELMSG_TL_CONNECT_REQUEST;
0202 conn_msg.guest_endpoint_id = *shv_guest_servie_id;
0203 conn_msg.host_service_id = *shv_host_servie_id;
0204
0205 ret = vmbus_post_msg(&conn_msg, sizeof(conn_msg), true);
0206
0207 trace_vmbus_send_tl_connect_request(&conn_msg, ret);
0208
0209 return ret;
0210 }
0211 EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
0212
0213 static int send_modifychannel_without_ack(struct vmbus_channel *channel, u32 target_vp)
0214 {
0215 struct vmbus_channel_modifychannel msg;
0216 int ret;
0217
0218 memset(&msg, 0, sizeof(msg));
0219 msg.header.msgtype = CHANNELMSG_MODIFYCHANNEL;
0220 msg.child_relid = channel->offermsg.child_relid;
0221 msg.target_vp = target_vp;
0222
0223 ret = vmbus_post_msg(&msg, sizeof(msg), true);
0224 trace_vmbus_send_modifychannel(&msg, ret);
0225
0226 return ret;
0227 }
0228
0229 static int send_modifychannel_with_ack(struct vmbus_channel *channel, u32 target_vp)
0230 {
0231 struct vmbus_channel_modifychannel *msg;
0232 struct vmbus_channel_msginfo *info;
0233 unsigned long flags;
0234 int ret;
0235
0236 info = kzalloc(sizeof(struct vmbus_channel_msginfo) +
0237 sizeof(struct vmbus_channel_modifychannel),
0238 GFP_KERNEL);
0239 if (!info)
0240 return -ENOMEM;
0241
0242 init_completion(&info->waitevent);
0243 info->waiting_channel = channel;
0244
0245 msg = (struct vmbus_channel_modifychannel *)info->msg;
0246 msg->header.msgtype = CHANNELMSG_MODIFYCHANNEL;
0247 msg->child_relid = channel->offermsg.child_relid;
0248 msg->target_vp = target_vp;
0249
0250 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0251 list_add_tail(&info->msglistentry, &vmbus_connection.chn_msg_list);
0252 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0253
0254 ret = vmbus_post_msg(msg, sizeof(*msg), true);
0255 trace_vmbus_send_modifychannel(msg, ret);
0256 if (ret != 0) {
0257 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0258 list_del(&info->msglistentry);
0259 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0260 goto free_info;
0261 }
0262
0263
0264
0265
0266
0267
0268
0269
0270 mutex_unlock(&vmbus_connection.channel_mutex);
0271 wait_for_completion(&info->waitevent);
0272 mutex_lock(&vmbus_connection.channel_mutex);
0273
0274 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0275 list_del(&info->msglistentry);
0276 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0277
0278 if (info->response.modify_response.status)
0279 ret = -EAGAIN;
0280
0281 free_info:
0282 kfree(info);
0283 return ret;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298 int vmbus_send_modifychannel(struct vmbus_channel *channel, u32 target_vp)
0299 {
0300 if (vmbus_proto_version >= VERSION_WIN10_V5_3)
0301 return send_modifychannel_with_ack(channel, target_vp);
0302 return send_modifychannel_without_ack(channel, target_vp);
0303 }
0304 EXPORT_SYMBOL_GPL(vmbus_send_modifychannel);
0305
0306
0307
0308
0309 static int create_gpadl_header(enum hv_gpadl_type type, void *kbuffer,
0310 u32 size, u32 send_offset,
0311 struct vmbus_channel_msginfo **msginfo)
0312 {
0313 int i;
0314 int pagecount;
0315 struct vmbus_channel_gpadl_header *gpadl_header;
0316 struct vmbus_channel_gpadl_body *gpadl_body;
0317 struct vmbus_channel_msginfo *msgheader;
0318 struct vmbus_channel_msginfo *msgbody = NULL;
0319 u32 msgsize;
0320
0321 int pfnsum, pfncount, pfnleft, pfncurr, pfnsize;
0322
0323 pagecount = hv_gpadl_size(type, size) >> HV_HYP_PAGE_SHIFT;
0324
0325
0326 pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
0327 sizeof(struct vmbus_channel_gpadl_header) -
0328 sizeof(struct gpa_range);
0329 pfncount = pfnsize / sizeof(u64);
0330
0331 if (pagecount > pfncount) {
0332
0333
0334 msgsize = sizeof(struct vmbus_channel_msginfo) +
0335 sizeof(struct vmbus_channel_gpadl_header) +
0336 sizeof(struct gpa_range) + pfncount * sizeof(u64);
0337 msgheader = kzalloc(msgsize, GFP_KERNEL);
0338 if (!msgheader)
0339 goto nomem;
0340
0341 INIT_LIST_HEAD(&msgheader->submsglist);
0342 msgheader->msgsize = msgsize;
0343
0344 gpadl_header = (struct vmbus_channel_gpadl_header *)
0345 msgheader->msg;
0346 gpadl_header->rangecount = 1;
0347 gpadl_header->range_buflen = sizeof(struct gpa_range) +
0348 pagecount * sizeof(u64);
0349 gpadl_header->range[0].byte_offset = 0;
0350 gpadl_header->range[0].byte_count = hv_gpadl_size(type, size);
0351 for (i = 0; i < pfncount; i++)
0352 gpadl_header->range[0].pfn_array[i] = hv_gpadl_hvpfn(
0353 type, kbuffer, size, send_offset, i);
0354 *msginfo = msgheader;
0355
0356 pfnsum = pfncount;
0357 pfnleft = pagecount - pfncount;
0358
0359
0360 pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
0361 sizeof(struct vmbus_channel_gpadl_body);
0362 pfncount = pfnsize / sizeof(u64);
0363
0364
0365 while (pfnleft) {
0366 if (pfnleft > pfncount)
0367 pfncurr = pfncount;
0368 else
0369 pfncurr = pfnleft;
0370
0371 msgsize = sizeof(struct vmbus_channel_msginfo) +
0372 sizeof(struct vmbus_channel_gpadl_body) +
0373 pfncurr * sizeof(u64);
0374 msgbody = kzalloc(msgsize, GFP_KERNEL);
0375
0376 if (!msgbody) {
0377 struct vmbus_channel_msginfo *pos = NULL;
0378 struct vmbus_channel_msginfo *tmp = NULL;
0379
0380
0381
0382 list_for_each_entry_safe(pos, tmp,
0383 &msgheader->submsglist,
0384 msglistentry) {
0385
0386 list_del(&pos->msglistentry);
0387 kfree(pos);
0388 }
0389
0390 goto nomem;
0391 }
0392
0393 msgbody->msgsize = msgsize;
0394 gpadl_body =
0395 (struct vmbus_channel_gpadl_body *)msgbody->msg;
0396
0397
0398
0399
0400
0401
0402
0403 for (i = 0; i < pfncurr; i++)
0404 gpadl_body->pfn[i] = hv_gpadl_hvpfn(type,
0405 kbuffer, size, send_offset, pfnsum + i);
0406
0407
0408 list_add_tail(&msgbody->msglistentry,
0409 &msgheader->submsglist);
0410 pfnsum += pfncurr;
0411 pfnleft -= pfncurr;
0412 }
0413 } else {
0414
0415 msgsize = sizeof(struct vmbus_channel_msginfo) +
0416 sizeof(struct vmbus_channel_gpadl_header) +
0417 sizeof(struct gpa_range) + pagecount * sizeof(u64);
0418 msgheader = kzalloc(msgsize, GFP_KERNEL);
0419 if (msgheader == NULL)
0420 goto nomem;
0421
0422 INIT_LIST_HEAD(&msgheader->submsglist);
0423 msgheader->msgsize = msgsize;
0424
0425 gpadl_header = (struct vmbus_channel_gpadl_header *)
0426 msgheader->msg;
0427 gpadl_header->rangecount = 1;
0428 gpadl_header->range_buflen = sizeof(struct gpa_range) +
0429 pagecount * sizeof(u64);
0430 gpadl_header->range[0].byte_offset = 0;
0431 gpadl_header->range[0].byte_count = hv_gpadl_size(type, size);
0432 for (i = 0; i < pagecount; i++)
0433 gpadl_header->range[0].pfn_array[i] = hv_gpadl_hvpfn(
0434 type, kbuffer, size, send_offset, i);
0435
0436 *msginfo = msgheader;
0437 }
0438
0439 return 0;
0440 nomem:
0441 kfree(msgheader);
0442 kfree(msgbody);
0443 return -ENOMEM;
0444 }
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457 static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
0458 enum hv_gpadl_type type, void *kbuffer,
0459 u32 size, u32 send_offset,
0460 struct vmbus_gpadl *gpadl)
0461 {
0462 struct vmbus_channel_gpadl_header *gpadlmsg;
0463 struct vmbus_channel_gpadl_body *gpadl_body;
0464 struct vmbus_channel_msginfo *msginfo = NULL;
0465 struct vmbus_channel_msginfo *submsginfo, *tmp;
0466 struct list_head *curr;
0467 u32 next_gpadl_handle;
0468 unsigned long flags;
0469 int ret = 0;
0470
0471 next_gpadl_handle =
0472 (atomic_inc_return(&vmbus_connection.next_gpadl_handle) - 1);
0473
0474 ret = create_gpadl_header(type, kbuffer, size, send_offset, &msginfo);
0475 if (ret)
0476 return ret;
0477
0478 ret = set_memory_decrypted((unsigned long)kbuffer,
0479 PFN_UP(size));
0480 if (ret) {
0481 dev_warn(&channel->device_obj->device,
0482 "Failed to set host visibility for new GPADL %d.\n",
0483 ret);
0484 return ret;
0485 }
0486
0487 init_completion(&msginfo->waitevent);
0488 msginfo->waiting_channel = channel;
0489
0490 gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg;
0491 gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER;
0492 gpadlmsg->child_relid = channel->offermsg.child_relid;
0493 gpadlmsg->gpadl = next_gpadl_handle;
0494
0495
0496 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0497 list_add_tail(&msginfo->msglistentry,
0498 &vmbus_connection.chn_msg_list);
0499
0500 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0501
0502 if (channel->rescind) {
0503 ret = -ENODEV;
0504 goto cleanup;
0505 }
0506
0507 ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
0508 sizeof(*msginfo), true);
0509
0510 trace_vmbus_establish_gpadl_header(gpadlmsg, ret);
0511
0512 if (ret != 0)
0513 goto cleanup;
0514
0515 list_for_each(curr, &msginfo->submsglist) {
0516 submsginfo = (struct vmbus_channel_msginfo *)curr;
0517 gpadl_body =
0518 (struct vmbus_channel_gpadl_body *)submsginfo->msg;
0519
0520 gpadl_body->header.msgtype =
0521 CHANNELMSG_GPADL_BODY;
0522 gpadl_body->gpadl = next_gpadl_handle;
0523
0524 ret = vmbus_post_msg(gpadl_body,
0525 submsginfo->msgsize - sizeof(*submsginfo),
0526 true);
0527
0528 trace_vmbus_establish_gpadl_body(gpadl_body, ret);
0529
0530 if (ret != 0)
0531 goto cleanup;
0532
0533 }
0534 wait_for_completion(&msginfo->waitevent);
0535
0536 if (msginfo->response.gpadl_created.creation_status != 0) {
0537 pr_err("Failed to establish GPADL: err = 0x%x\n",
0538 msginfo->response.gpadl_created.creation_status);
0539
0540 ret = -EDQUOT;
0541 goto cleanup;
0542 }
0543
0544 if (channel->rescind) {
0545 ret = -ENODEV;
0546 goto cleanup;
0547 }
0548
0549
0550 gpadl->gpadl_handle = gpadlmsg->gpadl;
0551 gpadl->buffer = kbuffer;
0552 gpadl->size = size;
0553
0554
0555 cleanup:
0556 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0557 list_del(&msginfo->msglistentry);
0558 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0559 list_for_each_entry_safe(submsginfo, tmp, &msginfo->submsglist,
0560 msglistentry) {
0561 kfree(submsginfo);
0562 }
0563
0564 kfree(msginfo);
0565
0566 if (ret)
0567 set_memory_encrypted((unsigned long)kbuffer,
0568 PFN_UP(size));
0569
0570 return ret;
0571 }
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581 int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
0582 u32 size, struct vmbus_gpadl *gpadl)
0583 {
0584 return __vmbus_establish_gpadl(channel, HV_GPADL_BUFFER, kbuffer, size,
0585 0U, gpadl);
0586 }
0587 EXPORT_SYMBOL_GPL(vmbus_establish_gpadl);
0588
0589
0590
0591
0592
0593
0594
0595
0596 static u64 *request_arr_init(u32 size)
0597 {
0598 int i;
0599 u64 *req_arr;
0600
0601 req_arr = kcalloc(size, sizeof(u64), GFP_KERNEL);
0602 if (!req_arr)
0603 return NULL;
0604
0605 for (i = 0; i < size - 1; i++)
0606 req_arr[i] = i + 1;
0607
0608
0609 req_arr[i] = U64_MAX;
0610
0611 return req_arr;
0612 }
0613
0614
0615
0616
0617
0618
0619 static int vmbus_alloc_requestor(struct vmbus_requestor *rqstor, u32 size)
0620 {
0621 u64 *rqst_arr;
0622 unsigned long *bitmap;
0623
0624 rqst_arr = request_arr_init(size);
0625 if (!rqst_arr)
0626 return -ENOMEM;
0627
0628 bitmap = bitmap_zalloc(size, GFP_KERNEL);
0629 if (!bitmap) {
0630 kfree(rqst_arr);
0631 return -ENOMEM;
0632 }
0633
0634 rqstor->req_arr = rqst_arr;
0635 rqstor->req_bitmap = bitmap;
0636 rqstor->size = size;
0637 rqstor->next_request_id = 0;
0638 spin_lock_init(&rqstor->req_lock);
0639
0640 return 0;
0641 }
0642
0643
0644
0645
0646
0647 static void vmbus_free_requestor(struct vmbus_requestor *rqstor)
0648 {
0649 kfree(rqstor->req_arr);
0650 bitmap_free(rqstor->req_bitmap);
0651 }
0652
0653 static int __vmbus_open(struct vmbus_channel *newchannel,
0654 void *userdata, u32 userdatalen,
0655 void (*onchannelcallback)(void *context), void *context)
0656 {
0657 struct vmbus_channel_open_channel *open_msg;
0658 struct vmbus_channel_msginfo *open_info = NULL;
0659 struct page *page = newchannel->ringbuffer_page;
0660 u32 send_pages, recv_pages;
0661 unsigned long flags;
0662 int err;
0663
0664 if (userdatalen > MAX_USER_DEFINED_BYTES)
0665 return -EINVAL;
0666
0667 send_pages = newchannel->ringbuffer_send_offset;
0668 recv_pages = newchannel->ringbuffer_pagecount - send_pages;
0669
0670 if (newchannel->state != CHANNEL_OPEN_STATE)
0671 return -EINVAL;
0672
0673
0674 if (newchannel->rqstor_size) {
0675 if (vmbus_alloc_requestor(&newchannel->requestor, newchannel->rqstor_size))
0676 return -ENOMEM;
0677 }
0678
0679 newchannel->state = CHANNEL_OPENING_STATE;
0680 newchannel->onchannel_callback = onchannelcallback;
0681 newchannel->channel_callback_context = context;
0682
0683 if (!newchannel->max_pkt_size)
0684 newchannel->max_pkt_size = VMBUS_DEFAULT_MAX_PKT_SIZE;
0685
0686
0687 newchannel->ringbuffer_gpadlhandle.gpadl_handle = 0;
0688
0689 err = __vmbus_establish_gpadl(newchannel, HV_GPADL_RING,
0690 page_address(newchannel->ringbuffer_page),
0691 (send_pages + recv_pages) << PAGE_SHIFT,
0692 newchannel->ringbuffer_send_offset << PAGE_SHIFT,
0693 &newchannel->ringbuffer_gpadlhandle);
0694 if (err)
0695 goto error_clean_ring;
0696
0697 err = hv_ringbuffer_init(&newchannel->outbound,
0698 page, send_pages, 0);
0699 if (err)
0700 goto error_free_gpadl;
0701
0702 err = hv_ringbuffer_init(&newchannel->inbound, &page[send_pages],
0703 recv_pages, newchannel->max_pkt_size);
0704 if (err)
0705 goto error_free_gpadl;
0706
0707
0708 open_info = kzalloc(sizeof(*open_info) +
0709 sizeof(struct vmbus_channel_open_channel),
0710 GFP_KERNEL);
0711 if (!open_info) {
0712 err = -ENOMEM;
0713 goto error_free_gpadl;
0714 }
0715
0716 init_completion(&open_info->waitevent);
0717 open_info->waiting_channel = newchannel;
0718
0719 open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
0720 open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
0721 open_msg->openid = newchannel->offermsg.child_relid;
0722 open_msg->child_relid = newchannel->offermsg.child_relid;
0723 open_msg->ringbuffer_gpadlhandle
0724 = newchannel->ringbuffer_gpadlhandle.gpadl_handle;
0725
0726
0727
0728
0729
0730 open_msg->downstream_ringbuffer_pageoffset =
0731 hv_ring_gpadl_send_hvpgoffset(send_pages << PAGE_SHIFT);
0732 open_msg->target_vp = hv_cpu_number_to_vp_number(newchannel->target_cpu);
0733
0734 if (userdatalen)
0735 memcpy(open_msg->userdata, userdata, userdatalen);
0736
0737 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0738 list_add_tail(&open_info->msglistentry,
0739 &vmbus_connection.chn_msg_list);
0740 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0741
0742 if (newchannel->rescind) {
0743 err = -ENODEV;
0744 goto error_clean_msglist;
0745 }
0746
0747 err = vmbus_post_msg(open_msg,
0748 sizeof(struct vmbus_channel_open_channel), true);
0749
0750 trace_vmbus_open(open_msg, err);
0751
0752 if (err != 0)
0753 goto error_clean_msglist;
0754
0755 wait_for_completion(&open_info->waitevent);
0756
0757 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0758 list_del(&open_info->msglistentry);
0759 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0760
0761 if (newchannel->rescind) {
0762 err = -ENODEV;
0763 goto error_free_info;
0764 }
0765
0766 if (open_info->response.open_result.status) {
0767 err = -EAGAIN;
0768 goto error_free_info;
0769 }
0770
0771 newchannel->state = CHANNEL_OPENED_STATE;
0772 kfree(open_info);
0773 return 0;
0774
0775 error_clean_msglist:
0776 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0777 list_del(&open_info->msglistentry);
0778 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0779 error_free_info:
0780 kfree(open_info);
0781 error_free_gpadl:
0782 vmbus_teardown_gpadl(newchannel, &newchannel->ringbuffer_gpadlhandle);
0783 error_clean_ring:
0784 hv_ringbuffer_cleanup(&newchannel->outbound);
0785 hv_ringbuffer_cleanup(&newchannel->inbound);
0786 vmbus_free_requestor(&newchannel->requestor);
0787 newchannel->state = CHANNEL_OPEN_STATE;
0788 return err;
0789 }
0790
0791
0792
0793
0794 int vmbus_connect_ring(struct vmbus_channel *newchannel,
0795 void (*onchannelcallback)(void *context), void *context)
0796 {
0797 return __vmbus_open(newchannel, NULL, 0, onchannelcallback, context);
0798 }
0799 EXPORT_SYMBOL_GPL(vmbus_connect_ring);
0800
0801
0802
0803
0804 int vmbus_open(struct vmbus_channel *newchannel,
0805 u32 send_ringbuffer_size, u32 recv_ringbuffer_size,
0806 void *userdata, u32 userdatalen,
0807 void (*onchannelcallback)(void *context), void *context)
0808 {
0809 int err;
0810
0811 err = vmbus_alloc_ring(newchannel, send_ringbuffer_size,
0812 recv_ringbuffer_size);
0813 if (err)
0814 return err;
0815
0816 err = __vmbus_open(newchannel, userdata, userdatalen,
0817 onchannelcallback, context);
0818 if (err)
0819 vmbus_free_ring(newchannel);
0820
0821 return err;
0822 }
0823 EXPORT_SYMBOL_GPL(vmbus_open);
0824
0825
0826
0827
0828 int vmbus_teardown_gpadl(struct vmbus_channel *channel, struct vmbus_gpadl *gpadl)
0829 {
0830 struct vmbus_channel_gpadl_teardown *msg;
0831 struct vmbus_channel_msginfo *info;
0832 unsigned long flags;
0833 int ret;
0834
0835 info = kzalloc(sizeof(*info) +
0836 sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
0837 if (!info)
0838 return -ENOMEM;
0839
0840 init_completion(&info->waitevent);
0841 info->waiting_channel = channel;
0842
0843 msg = (struct vmbus_channel_gpadl_teardown *)info->msg;
0844
0845 msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN;
0846 msg->child_relid = channel->offermsg.child_relid;
0847 msg->gpadl = gpadl->gpadl_handle;
0848
0849 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0850 list_add_tail(&info->msglistentry,
0851 &vmbus_connection.chn_msg_list);
0852 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0853
0854 if (channel->rescind)
0855 goto post_msg_err;
0856
0857 ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_gpadl_teardown),
0858 true);
0859
0860 trace_vmbus_teardown_gpadl(msg, ret);
0861
0862 if (ret)
0863 goto post_msg_err;
0864
0865 wait_for_completion(&info->waitevent);
0866
0867 gpadl->gpadl_handle = 0;
0868
0869 post_msg_err:
0870
0871
0872
0873
0874
0875 if (channel->rescind)
0876 ret = 0;
0877
0878 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
0879 list_del(&info->msglistentry);
0880 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
0881
0882 kfree(info);
0883
0884 ret = set_memory_encrypted((unsigned long)gpadl->buffer,
0885 PFN_UP(gpadl->size));
0886 if (ret)
0887 pr_warn("Fail to set mem host visibility in GPADL teardown %d.\n", ret);
0888
0889 return ret;
0890 }
0891 EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
0892
0893 void vmbus_reset_channel_cb(struct vmbus_channel *channel)
0894 {
0895 unsigned long flags;
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910 tasklet_disable(&channel->callback_event);
0911
0912
0913 spin_lock_irqsave(&channel->sched_lock, flags);
0914 channel->onchannel_callback = NULL;
0915 spin_unlock_irqrestore(&channel->sched_lock, flags);
0916
0917 channel->sc_creation_callback = NULL;
0918
0919
0920 tasklet_enable(&channel->callback_event);
0921 }
0922
0923 static int vmbus_close_internal(struct vmbus_channel *channel)
0924 {
0925 struct vmbus_channel_close_channel *msg;
0926 int ret;
0927
0928 vmbus_reset_channel_cb(channel);
0929
0930
0931
0932
0933
0934
0935
0936
0937 if (channel->state != CHANNEL_OPENED_STATE)
0938 return -EINVAL;
0939
0940 channel->state = CHANNEL_OPEN_STATE;
0941
0942
0943
0944 msg = &channel->close_msg.msg;
0945
0946 msg->header.msgtype = CHANNELMSG_CLOSECHANNEL;
0947 msg->child_relid = channel->offermsg.child_relid;
0948
0949 ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel),
0950 true);
0951
0952 trace_vmbus_close_internal(msg, ret);
0953
0954 if (ret) {
0955 pr_err("Close failed: close post msg return is %d\n", ret);
0956
0957
0958
0959
0960 }
0961
0962
0963 else if (channel->ringbuffer_gpadlhandle.gpadl_handle) {
0964 ret = vmbus_teardown_gpadl(channel, &channel->ringbuffer_gpadlhandle);
0965 if (ret) {
0966 pr_err("Close failed: teardown gpadl return %d\n", ret);
0967
0968
0969
0970
0971 }
0972 }
0973
0974 if (!ret)
0975 vmbus_free_requestor(&channel->requestor);
0976
0977 return ret;
0978 }
0979
0980
0981 int vmbus_disconnect_ring(struct vmbus_channel *channel)
0982 {
0983 struct vmbus_channel *cur_channel, *tmp;
0984 int ret;
0985
0986 if (channel->primary_channel != NULL)
0987 return -EINVAL;
0988
0989 list_for_each_entry_safe(cur_channel, tmp, &channel->sc_list, sc_list) {
0990 if (cur_channel->rescind)
0991 wait_for_completion(&cur_channel->rescind_event);
0992
0993 mutex_lock(&vmbus_connection.channel_mutex);
0994 if (vmbus_close_internal(cur_channel) == 0) {
0995 vmbus_free_ring(cur_channel);
0996
0997 if (cur_channel->rescind)
0998 hv_process_channel_removal(cur_channel);
0999 }
1000 mutex_unlock(&vmbus_connection.channel_mutex);
1001 }
1002
1003
1004
1005
1006 mutex_lock(&vmbus_connection.channel_mutex);
1007 ret = vmbus_close_internal(channel);
1008 mutex_unlock(&vmbus_connection.channel_mutex);
1009
1010 return ret;
1011 }
1012 EXPORT_SYMBOL_GPL(vmbus_disconnect_ring);
1013
1014
1015
1016
1017 void vmbus_close(struct vmbus_channel *channel)
1018 {
1019 if (vmbus_disconnect_ring(channel) == 0)
1020 vmbus_free_ring(channel);
1021 }
1022 EXPORT_SYMBOL_GPL(vmbus_close);
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041 int vmbus_sendpacket_getid(struct vmbus_channel *channel, void *buffer,
1042 u32 bufferlen, u64 requestid, u64 *trans_id,
1043 enum vmbus_packet_type type, u32 flags)
1044 {
1045 struct vmpacket_descriptor desc;
1046 u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
1047 u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
1048 struct kvec bufferlist[3];
1049 u64 aligned_data = 0;
1050 int num_vecs = ((bufferlen != 0) ? 3 : 1);
1051
1052
1053
1054 desc.type = type;
1055 desc.flags = flags;
1056
1057 desc.offset8 = sizeof(struct vmpacket_descriptor) >> 3;
1058 desc.len8 = (u16)(packetlen_aligned >> 3);
1059 desc.trans_id = VMBUS_RQST_ERROR;
1060
1061 bufferlist[0].iov_base = &desc;
1062 bufferlist[0].iov_len = sizeof(struct vmpacket_descriptor);
1063 bufferlist[1].iov_base = buffer;
1064 bufferlist[1].iov_len = bufferlen;
1065 bufferlist[2].iov_base = &aligned_data;
1066 bufferlist[2].iov_len = (packetlen_aligned - packetlen);
1067
1068 return hv_ringbuffer_write(channel, bufferlist, num_vecs, requestid, trans_id);
1069 }
1070 EXPORT_SYMBOL(vmbus_sendpacket_getid);
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
1088 u32 bufferlen, u64 requestid,
1089 enum vmbus_packet_type type, u32 flags)
1090 {
1091 return vmbus_sendpacket_getid(channel, buffer, bufferlen,
1092 requestid, NULL, type, flags);
1093 }
1094 EXPORT_SYMBOL(vmbus_sendpacket);
1095
1096
1097
1098
1099
1100
1101
1102
1103 int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
1104 struct hv_page_buffer pagebuffers[],
1105 u32 pagecount, void *buffer, u32 bufferlen,
1106 u64 requestid)
1107 {
1108 int i;
1109 struct vmbus_channel_packet_page_buffer desc;
1110 u32 descsize;
1111 u32 packetlen;
1112 u32 packetlen_aligned;
1113 struct kvec bufferlist[3];
1114 u64 aligned_data = 0;
1115
1116 if (pagecount > MAX_PAGE_BUFFER_COUNT)
1117 return -EINVAL;
1118
1119
1120
1121
1122
1123 descsize = sizeof(struct vmbus_channel_packet_page_buffer) -
1124 ((MAX_PAGE_BUFFER_COUNT - pagecount) *
1125 sizeof(struct hv_page_buffer));
1126 packetlen = descsize + bufferlen;
1127 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
1128
1129
1130 desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
1131 desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
1132 desc.dataoffset8 = descsize >> 3;
1133 desc.length8 = (u16)(packetlen_aligned >> 3);
1134 desc.transactionid = VMBUS_RQST_ERROR;
1135 desc.reserved = 0;
1136 desc.rangecount = pagecount;
1137
1138 for (i = 0; i < pagecount; i++) {
1139 desc.range[i].len = pagebuffers[i].len;
1140 desc.range[i].offset = pagebuffers[i].offset;
1141 desc.range[i].pfn = pagebuffers[i].pfn;
1142 }
1143
1144 bufferlist[0].iov_base = &desc;
1145 bufferlist[0].iov_len = descsize;
1146 bufferlist[1].iov_base = buffer;
1147 bufferlist[1].iov_len = bufferlen;
1148 bufferlist[2].iov_base = &aligned_data;
1149 bufferlist[2].iov_len = (packetlen_aligned - packetlen);
1150
1151 return hv_ringbuffer_write(channel, bufferlist, 3, requestid, NULL);
1152 }
1153 EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
1154
1155
1156
1157
1158
1159
1160 int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
1161 struct vmbus_packet_mpb_array *desc,
1162 u32 desc_size,
1163 void *buffer, u32 bufferlen, u64 requestid)
1164 {
1165 u32 packetlen;
1166 u32 packetlen_aligned;
1167 struct kvec bufferlist[3];
1168 u64 aligned_data = 0;
1169
1170 packetlen = desc_size + bufferlen;
1171 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
1172
1173
1174 desc->type = VM_PKT_DATA_USING_GPA_DIRECT;
1175 desc->flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
1176 desc->dataoffset8 = desc_size >> 3;
1177 desc->length8 = (u16)(packetlen_aligned >> 3);
1178 desc->transactionid = VMBUS_RQST_ERROR;
1179 desc->reserved = 0;
1180 desc->rangecount = 1;
1181
1182 bufferlist[0].iov_base = desc;
1183 bufferlist[0].iov_len = desc_size;
1184 bufferlist[1].iov_base = buffer;
1185 bufferlist[1].iov_len = bufferlen;
1186 bufferlist[2].iov_base = &aligned_data;
1187 bufferlist[2].iov_len = (packetlen_aligned - packetlen);
1188
1189 return hv_ringbuffer_write(channel, bufferlist, 3, requestid, NULL);
1190 }
1191 EXPORT_SYMBOL_GPL(vmbus_sendpacket_mpb_desc);
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207 static inline int
1208 __vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
1209 u32 bufferlen, u32 *buffer_actual_len, u64 *requestid,
1210 bool raw)
1211 {
1212 return hv_ringbuffer_read(channel, buffer, bufferlen,
1213 buffer_actual_len, requestid, raw);
1214
1215 }
1216
1217 int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
1218 u32 bufferlen, u32 *buffer_actual_len,
1219 u64 *requestid)
1220 {
1221 return __vmbus_recvpacket(channel, buffer, bufferlen,
1222 buffer_actual_len, requestid, false);
1223 }
1224 EXPORT_SYMBOL(vmbus_recvpacket);
1225
1226
1227
1228
1229 int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
1230 u32 bufferlen, u32 *buffer_actual_len,
1231 u64 *requestid)
1232 {
1233 return __vmbus_recvpacket(channel, buffer, bufferlen,
1234 buffer_actual_len, requestid, true);
1235 }
1236 EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
1237
1238
1239
1240
1241
1242
1243
1244
1245 u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr)
1246 {
1247 struct vmbus_requestor *rqstor = &channel->requestor;
1248 unsigned long flags;
1249 u64 current_id;
1250
1251
1252 if (!channel->rqstor_size)
1253 return VMBUS_NO_RQSTOR;
1254
1255 lock_requestor(channel, flags);
1256 current_id = rqstor->next_request_id;
1257
1258
1259 if (current_id >= rqstor->size) {
1260 unlock_requestor(channel, flags);
1261 return VMBUS_RQST_ERROR;
1262 }
1263
1264 rqstor->next_request_id = rqstor->req_arr[current_id];
1265 rqstor->req_arr[current_id] = rqst_addr;
1266
1267
1268 bitmap_set(rqstor->req_bitmap, current_id, 1);
1269
1270 unlock_requestor(channel, flags);
1271
1272
1273
1274
1275
1276
1277
1278 return current_id + 1;
1279 }
1280 EXPORT_SYMBOL_GPL(vmbus_next_request_id);
1281
1282
1283 u64 __vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id,
1284 u64 rqst_addr)
1285 {
1286 struct vmbus_requestor *rqstor = &channel->requestor;
1287 u64 req_addr;
1288
1289
1290 if (!channel->rqstor_size)
1291 return VMBUS_NO_RQSTOR;
1292
1293
1294 if (!trans_id)
1295 return VMBUS_RQST_ERROR;
1296
1297
1298 trans_id--;
1299
1300
1301 if (trans_id >= rqstor->size || !test_bit(trans_id, rqstor->req_bitmap))
1302 return VMBUS_RQST_ERROR;
1303
1304 req_addr = rqstor->req_arr[trans_id];
1305 if (rqst_addr == VMBUS_RQST_ADDR_ANY || req_addr == rqst_addr) {
1306 rqstor->req_arr[trans_id] = rqstor->next_request_id;
1307 rqstor->next_request_id = trans_id;
1308
1309
1310 bitmap_clear(rqstor->req_bitmap, trans_id, 1);
1311 }
1312
1313 return req_addr;
1314 }
1315 EXPORT_SYMBOL_GPL(__vmbus_request_addr_match);
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327 u64 vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id,
1328 u64 rqst_addr)
1329 {
1330 unsigned long flags;
1331 u64 req_addr;
1332
1333 lock_requestor(channel, flags);
1334 req_addr = __vmbus_request_addr_match(channel, trans_id, rqst_addr);
1335 unlock_requestor(channel, flags);
1336
1337 return req_addr;
1338 }
1339 EXPORT_SYMBOL_GPL(vmbus_request_addr_match);
1340
1341
1342
1343
1344
1345
1346
1347
1348 u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id)
1349 {
1350 return vmbus_request_addr_match(channel, trans_id, VMBUS_RQST_ADDR_ANY);
1351 }
1352 EXPORT_SYMBOL_GPL(vmbus_request_addr);