Lines Matching +full:close +full:- +full:range

1 // SPDX-License-Identifier: GPL-2.0-only
26 * hv_gpadl_size - Return the real size of a gpadl, the size that Hyper-V uses
28 * For BUFFER gpadl, Hyper-V uses the exact same size as the guest does.
33 * (PAGE_SIZE - HV_HYP_PAGE_SIZE) gap. And since there are two rings in a
34 * ringbuffer, the total size for a RING gpadl that Hyper-V uses is the
43 /* The size of a ringbuffer must be page-aligned */ in hv_gpadl_size()
49 * the first guest-size page of each of the two ring buffers. in hv_gpadl_size()
50 * So we effectively subtract out two guest-size pages, and add in hv_gpadl_size()
51 * back two Hyper-V size pages. in hv_gpadl_size()
53 return size - 2 * (PAGE_SIZE - HV_HYP_PAGE_SIZE); in hv_gpadl_size()
60 * hv_ring_gpadl_send_hvpgoffset - Calculate the send offset (in unit of
74 * therefore leaving a (PAGE_SIZE - HV_HYP_PAGE_SIZE) gap. in hv_ring_gpadl_send_hvpgoffset()
79 return (offset - (PAGE_SIZE - HV_HYP_PAGE_SIZE)) >> HV_HYP_PAGE_SHIFT; in hv_ring_gpadl_send_hvpgoffset()
83 * hv_gpadl_hvpfn - Return the Hyper-V page PFN of the @i th Hyper-V page in
106 delta = PAGE_SIZE - HV_HYP_PAGE_SIZE; in hv_gpadl_hvpfn()
108 delta = 2 * (PAGE_SIZE - HV_HYP_PAGE_SIZE); in hv_gpadl_hvpfn()
119 * vmbus_setevent- Trigger an event notification on the specified
132 if (channel->offermsg.monitor_allocated && !channel->low_latency) { in vmbus_setevent()
133 vmbus_send_interrupt(channel->offermsg.child_relid); in vmbus_setevent()
138 sync_set_bit(channel->monitor_bit, in vmbus_setevent()
139 (unsigned long *)&monitorpage->trigger_group in vmbus_setevent()
140 [channel->monitor_grp].pending); in vmbus_setevent()
148 /* vmbus_free_ring - drop mapping of ring buffer */
151 hv_ringbuffer_cleanup(&channel->outbound); in vmbus_free_ring()
152 hv_ringbuffer_cleanup(&channel->inbound); in vmbus_free_ring()
154 if (channel->ringbuffer_page) { in vmbus_free_ring()
155 __free_pages(channel->ringbuffer_page, in vmbus_free_ring()
156 get_order(channel->ringbuffer_pagecount in vmbus_free_ring()
158 channel->ringbuffer_page = NULL; in vmbus_free_ring()
163 /* vmbus_alloc_ring - allocate and map pages for ring buffer */
171 return -EINVAL; in vmbus_alloc_ring()
175 page = alloc_pages_node(cpu_to_node(newchannel->target_cpu), in vmbus_alloc_ring()
182 return -ENOMEM; in vmbus_alloc_ring()
184 newchannel->ringbuffer_page = page; in vmbus_alloc_ring()
185 newchannel->ringbuffer_pagecount = (send_size + recv_size) >> PAGE_SHIFT; in vmbus_alloc_ring()
186 newchannel->ringbuffer_send_offset = send_size >> PAGE_SHIFT; in vmbus_alloc_ring()
192 /* Used for Hyper-V Socket: a guest client's connect() to the host */
219 msg.child_relid = channel->offermsg.child_relid; in send_modifychannel_without_ack()
239 return -ENOMEM; in send_modifychannel_with_ack()
241 init_completion(&info->waitevent); in send_modifychannel_with_ack()
242 info->waiting_channel = channel; in send_modifychannel_with_ack()
244 msg = (struct vmbus_channel_modifychannel *)info->msg; in send_modifychannel_with_ack()
245 msg->header.msgtype = CHANNELMSG_MODIFYCHANNEL; in send_modifychannel_with_ack()
246 msg->child_relid = channel->offermsg.child_relid; in send_modifychannel_with_ack()
247 msg->target_vp = target_vp; in send_modifychannel_with_ack()
250 list_add_tail(&info->msglistentry, &vmbus_connection.chn_msg_list); in send_modifychannel_with_ack()
257 list_del(&info->msglistentry); in send_modifychannel_with_ack()
270 wait_for_completion(&info->waitevent); in send_modifychannel_with_ack()
274 list_del(&info->msglistentry); in send_modifychannel_with_ack()
277 if (info->response.modify_response.status) in send_modifychannel_with_ack()
278 ret = -EAGAIN; in send_modifychannel_with_ack()
289 * or later is negotiated, Hyper-V always sends an ACK in response to such a
290 * message. For VMbus version 5.2 and earlier, it never sends an ACK. With-
306 * create_gpadl_header - Creates a gpadl for the specified buffer
325 pfnsize = MAX_SIZE_CHANNEL_MESSAGE - in create_gpadl_header()
326 sizeof(struct vmbus_channel_gpadl_header) - in create_gpadl_header()
340 INIT_LIST_HEAD(&msgheader->submsglist); in create_gpadl_header()
341 msgheader->msgsize = msgsize; in create_gpadl_header()
344 msgheader->msg; in create_gpadl_header()
345 gpadl_header->rangecount = 1; in create_gpadl_header()
346 gpadl_header->range_buflen = sizeof(struct gpa_range) + in create_gpadl_header()
348 gpadl_header->range[0].byte_offset = 0; in create_gpadl_header()
349 gpadl_header->range[0].byte_count = hv_gpadl_size(type, size); in create_gpadl_header()
351 gpadl_header->range[0].pfn_array[i] = hv_gpadl_hvpfn( in create_gpadl_header()
356 pfnleft = pagecount - pfncount; in create_gpadl_header()
359 pfnsize = MAX_SIZE_CHANNEL_MESSAGE - in create_gpadl_header()
382 &msgheader->submsglist, in create_gpadl_header()
385 list_del(&pos->msglistentry); in create_gpadl_header()
392 msgbody->msgsize = msgsize; in create_gpadl_header()
394 (struct vmbus_channel_gpadl_body *)msgbody->msg; in create_gpadl_header()
398 * be 64-bit in create_gpadl_header()
403 gpadl_body->pfn[i] = hv_gpadl_hvpfn(type, in create_gpadl_header()
407 list_add_tail(&msgbody->msglistentry, in create_gpadl_header()
408 &msgheader->submsglist); in create_gpadl_header()
410 pfnleft -= pfncurr; in create_gpadl_header()
421 INIT_LIST_HEAD(&msgheader->submsglist); in create_gpadl_header()
422 msgheader->msgsize = msgsize; in create_gpadl_header()
425 msgheader->msg; in create_gpadl_header()
426 gpadl_header->rangecount = 1; in create_gpadl_header()
427 gpadl_header->range_buflen = sizeof(struct gpa_range) + in create_gpadl_header()
429 gpadl_header->range[0].byte_offset = 0; in create_gpadl_header()
430 gpadl_header->range[0].byte_count = hv_gpadl_size(type, size); in create_gpadl_header()
432 gpadl_header->range[0].pfn_array[i] = hv_gpadl_hvpfn( in create_gpadl_header()
442 return -ENOMEM; in create_gpadl_header()
446 * __vmbus_establish_gpadl - Establish a GPADL for a buffer or ringbuffer
451 * @size: page-size multiple
471 (atomic_inc_return(&vmbus_connection.next_gpadl_handle) - 1); in __vmbus_establish_gpadl()
477 init_completion(&msginfo->waitevent); in __vmbus_establish_gpadl()
478 msginfo->waiting_channel = channel; in __vmbus_establish_gpadl()
480 gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg; in __vmbus_establish_gpadl()
481 gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER; in __vmbus_establish_gpadl()
482 gpadlmsg->child_relid = channel->offermsg.child_relid; in __vmbus_establish_gpadl()
483 gpadlmsg->gpadl = next_gpadl_handle; in __vmbus_establish_gpadl()
487 list_add_tail(&msginfo->msglistentry, in __vmbus_establish_gpadl()
492 if (channel->rescind) { in __vmbus_establish_gpadl()
493 ret = -ENODEV; in __vmbus_establish_gpadl()
497 ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize - in __vmbus_establish_gpadl()
505 list_for_each(curr, &msginfo->submsglist) { in __vmbus_establish_gpadl()
508 (struct vmbus_channel_gpadl_body *)submsginfo->msg; in __vmbus_establish_gpadl()
510 gpadl_body->header.msgtype = in __vmbus_establish_gpadl()
512 gpadl_body->gpadl = next_gpadl_handle; in __vmbus_establish_gpadl()
515 submsginfo->msgsize - sizeof(*submsginfo), in __vmbus_establish_gpadl()
524 wait_for_completion(&msginfo->waitevent); in __vmbus_establish_gpadl()
526 if (msginfo->response.gpadl_created.creation_status != 0) { in __vmbus_establish_gpadl()
528 msginfo->response.gpadl_created.creation_status); in __vmbus_establish_gpadl()
530 ret = -EDQUOT; in __vmbus_establish_gpadl()
534 if (channel->rescind) { in __vmbus_establish_gpadl()
535 ret = -ENODEV; in __vmbus_establish_gpadl()
540 *gpadl_handle = gpadlmsg->gpadl; in __vmbus_establish_gpadl()
544 list_del(&msginfo->msglistentry); in __vmbus_establish_gpadl()
546 list_for_each_entry_safe(submsginfo, tmp, &msginfo->submsglist, in __vmbus_establish_gpadl()
556 * vmbus_establish_gpadl - Establish a GPADL for the specified buffer
560 * @size: page-size multiple
572 * request_arr_init - Allocates memory for the requestor array. Each slot
587 for (i = 0; i < size - 1; i++) in request_arr_init()
597 * vmbus_alloc_requestor - Initializes @rqstor's fields.
608 return -ENOMEM; in vmbus_alloc_requestor()
613 return -ENOMEM; in vmbus_alloc_requestor()
616 rqstor->req_arr = rqst_arr; in vmbus_alloc_requestor()
617 rqstor->req_bitmap = bitmap; in vmbus_alloc_requestor()
618 rqstor->size = size; in vmbus_alloc_requestor()
619 rqstor->next_request_id = 0; in vmbus_alloc_requestor()
620 spin_lock_init(&rqstor->req_lock); in vmbus_alloc_requestor()
626 * vmbus_free_requestor - Frees memory allocated for @rqstor
631 kfree(rqstor->req_arr); in vmbus_free_requestor()
632 bitmap_free(rqstor->req_bitmap); in vmbus_free_requestor()
641 struct page *page = newchannel->ringbuffer_page; in __vmbus_open()
647 return -EINVAL; in __vmbus_open()
649 send_pages = newchannel->ringbuffer_send_offset; in __vmbus_open()
650 recv_pages = newchannel->ringbuffer_pagecount - send_pages; in __vmbus_open()
652 if (newchannel->state != CHANNEL_OPEN_STATE) in __vmbus_open()
653 return -EINVAL; in __vmbus_open()
656 if (newchannel->rqstor_size) { in __vmbus_open()
657 if (vmbus_alloc_requestor(&newchannel->requestor, newchannel->rqstor_size)) in __vmbus_open()
658 return -ENOMEM; in __vmbus_open()
661 newchannel->state = CHANNEL_OPENING_STATE; in __vmbus_open()
662 newchannel->onchannel_callback = onchannelcallback; in __vmbus_open()
663 newchannel->channel_callback_context = context; in __vmbus_open()
665 if (!newchannel->max_pkt_size) in __vmbus_open()
666 newchannel->max_pkt_size = VMBUS_DEFAULT_MAX_PKT_SIZE; in __vmbus_open()
668 err = hv_ringbuffer_init(&newchannel->outbound, page, send_pages, 0); in __vmbus_open()
672 err = hv_ringbuffer_init(&newchannel->inbound, &page[send_pages], in __vmbus_open()
673 recv_pages, newchannel->max_pkt_size); in __vmbus_open()
678 newchannel->ringbuffer_gpadlhandle = 0; in __vmbus_open()
681 page_address(newchannel->ringbuffer_page), in __vmbus_open()
683 newchannel->ringbuffer_send_offset << PAGE_SHIFT, in __vmbus_open()
684 &newchannel->ringbuffer_gpadlhandle); in __vmbus_open()
693 err = -ENOMEM; in __vmbus_open()
697 init_completion(&open_info->waitevent); in __vmbus_open()
698 open_info->waiting_channel = newchannel; in __vmbus_open()
700 open_msg = (struct vmbus_channel_open_channel *)open_info->msg; in __vmbus_open()
701 open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL; in __vmbus_open()
702 open_msg->openid = newchannel->offermsg.child_relid; in __vmbus_open()
703 open_msg->child_relid = newchannel->offermsg.child_relid; in __vmbus_open()
704 open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; in __vmbus_open()
706 * The unit of ->downstream_ringbuffer_pageoffset is HV_HYP_PAGE and in __vmbus_open()
707 * the unit of ->ringbuffer_send_offset (i.e. send_pages) is PAGE, so in __vmbus_open()
710 open_msg->downstream_ringbuffer_pageoffset = in __vmbus_open()
712 open_msg->target_vp = hv_cpu_number_to_vp_number(newchannel->target_cpu); in __vmbus_open()
715 memcpy(open_msg->userdata, userdata, userdatalen); in __vmbus_open()
718 list_add_tail(&open_info->msglistentry, in __vmbus_open()
722 if (newchannel->rescind) { in __vmbus_open()
723 err = -ENODEV; in __vmbus_open()
735 wait_for_completion(&open_info->waitevent); in __vmbus_open()
738 list_del(&open_info->msglistentry); in __vmbus_open()
741 if (newchannel->rescind) { in __vmbus_open()
742 err = -ENODEV; in __vmbus_open()
746 if (open_info->response.open_result.status) { in __vmbus_open()
747 err = -EAGAIN; in __vmbus_open()
751 newchannel->state = CHANNEL_OPENED_STATE; in __vmbus_open()
757 list_del(&open_info->msglistentry); in __vmbus_open()
762 vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle); in __vmbus_open()
763 newchannel->ringbuffer_gpadlhandle = 0; in __vmbus_open()
765 hv_ringbuffer_cleanup(&newchannel->outbound); in __vmbus_open()
766 hv_ringbuffer_cleanup(&newchannel->inbound); in __vmbus_open()
767 vmbus_free_requestor(&newchannel->requestor); in __vmbus_open()
768 newchannel->state = CHANNEL_OPEN_STATE; in __vmbus_open()
773 * vmbus_connect_ring - Open the channel but reuse ring buffer
783 * vmbus_open - Open the specified channel.
807 * vmbus_teardown_gpadl -Teardown the specified GPADL handle
819 return -ENOMEM; in vmbus_teardown_gpadl()
821 init_completion(&info->waitevent); in vmbus_teardown_gpadl()
822 info->waiting_channel = channel; in vmbus_teardown_gpadl()
824 msg = (struct vmbus_channel_gpadl_teardown *)info->msg; in vmbus_teardown_gpadl()
826 msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN; in vmbus_teardown_gpadl()
827 msg->child_relid = channel->offermsg.child_relid; in vmbus_teardown_gpadl()
828 msg->gpadl = gpadl_handle; in vmbus_teardown_gpadl()
831 list_add_tail(&info->msglistentry, in vmbus_teardown_gpadl()
835 if (channel->rescind) in vmbus_teardown_gpadl()
846 wait_for_completion(&info->waitevent); in vmbus_teardown_gpadl()
854 if (channel->rescind) in vmbus_teardown_gpadl()
858 list_del(&info->msglistentry); in vmbus_teardown_gpadl()
871 * vmbus_on_event(), running in the per-channel tasklet, can race in vmbus_reset_channel_cb()
873 * the former is accessing channel->inbound.ring_buffer, the latter in vmbus_reset_channel_cb()
883 tasklet_disable(&channel->callback_event); in vmbus_reset_channel_cb()
886 spin_lock_irqsave(&channel->sched_lock, flags); in vmbus_reset_channel_cb()
887 channel->onchannel_callback = NULL; in vmbus_reset_channel_cb()
888 spin_unlock_irqrestore(&channel->sched_lock, flags); in vmbus_reset_channel_cb()
890 channel->sc_creation_callback = NULL; in vmbus_reset_channel_cb()
892 /* Re-enable tasklet for use on re-open */ in vmbus_reset_channel_cb()
893 tasklet_enable(&channel->callback_event); in vmbus_reset_channel_cb()
905 * util_probe() -> vmbus_open() returns -ENOMEM) and the device is in vmbus_close_internal()
907 * in Hyper-V Manager), the driver's remove() invokes vmbus_close(): in vmbus_close_internal()
910 if (channel->state != CHANNEL_OPENED_STATE) in vmbus_close_internal()
911 return -EINVAL; in vmbus_close_internal()
913 channel->state = CHANNEL_OPEN_STATE; in vmbus_close_internal()
917 msg = &channel->close_msg.msg; in vmbus_close_internal()
919 msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; in vmbus_close_internal()
920 msg->child_relid = channel->offermsg.child_relid; in vmbus_close_internal()
928 pr_err("Close failed: close post msg return is %d\n", ret); in vmbus_close_internal()
930 * If we failed to post the close msg, in vmbus_close_internal()
936 else if (channel->ringbuffer_gpadlhandle) { in vmbus_close_internal()
938 channel->ringbuffer_gpadlhandle); in vmbus_close_internal()
940 pr_err("Close failed: teardown gpadl return %d\n", ret); in vmbus_close_internal()
947 channel->ringbuffer_gpadlhandle = 0; in vmbus_close_internal()
951 vmbus_free_requestor(&channel->requestor); in vmbus_close_internal()
956 /* disconnect ring - close all channels */
962 if (channel->primary_channel != NULL) in vmbus_disconnect_ring()
963 return -EINVAL; in vmbus_disconnect_ring()
965 list_for_each_entry_safe(cur_channel, tmp, &channel->sc_list, sc_list) { in vmbus_disconnect_ring()
966 if (cur_channel->rescind) in vmbus_disconnect_ring()
967 wait_for_completion(&cur_channel->rescind_event); in vmbus_disconnect_ring()
973 if (cur_channel->rescind) in vmbus_disconnect_ring()
980 * Now close the primary. in vmbus_disconnect_ring()
991 * vmbus_close - Close the specified channel
1001 * vmbus_sendpacket() - Send the specified buffer on the given channel
1010 * Sends data in @buffer directly to Hyper-V via the vmbus.
1011 * This will send the data unparsed to Hyper-V.
1013 * Mainly used by Hyper-V drivers.
1030 /* in 8-bytes granularity */ in vmbus_sendpacket()
1040 bufferlist[2].iov_len = (packetlen_aligned - packetlen); in vmbus_sendpacket()
1047 * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
1067 return -EINVAL; in vmbus_sendpacket_pagebuffer()
1073 descsize = sizeof(struct vmbus_channel_packet_page_buffer) - in vmbus_sendpacket_pagebuffer()
1074 ((MAX_PAGE_BUFFER_COUNT - pagecount) * in vmbus_sendpacket_pagebuffer()
1082 desc.dataoffset8 = descsize >> 3; /* in 8-bytes granularity */ in vmbus_sendpacket_pagebuffer()
1089 desc.range[i].len = pagebuffers[i].len; in vmbus_sendpacket_pagebuffer()
1090 desc.range[i].offset = pagebuffers[i].offset; in vmbus_sendpacket_pagebuffer()
1091 desc.range[i].pfn = pagebuffers[i].pfn; in vmbus_sendpacket_pagebuffer()
1099 bufferlist[2].iov_len = (packetlen_aligned - packetlen); in vmbus_sendpacket_pagebuffer()
1106 * vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
1124 desc->type = VM_PKT_DATA_USING_GPA_DIRECT; in vmbus_sendpacket_mpb_desc()
1125 desc->flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; in vmbus_sendpacket_mpb_desc()
1126 desc->dataoffset8 = desc_size >> 3; /* in 8-bytes granularity */ in vmbus_sendpacket_mpb_desc()
1127 desc->length8 = (u16)(packetlen_aligned >> 3); in vmbus_sendpacket_mpb_desc()
1128 desc->transactionid = VMBUS_RQST_ERROR; /* will be updated in hv_ringbuffer_write() */ in vmbus_sendpacket_mpb_desc()
1129 desc->reserved = 0; in vmbus_sendpacket_mpb_desc()
1130 desc->rangecount = 1; in vmbus_sendpacket_mpb_desc()
1137 bufferlist[2].iov_len = (packetlen_aligned - packetlen); in vmbus_sendpacket_mpb_desc()
1144 * __vmbus_recvpacket() - Retrieve the user packet on the specified channel
1152 * Receives directly from the hyper-v vmbus and puts the data it received
1153 * into Buffer. This will receive the data unparsed from hyper-v.
1155 * Mainly used by Hyper-V drivers.
1177 * vmbus_recvpacket_raw - Retrieve the raw packet on the specified channel
1189 * vmbus_next_request_id - Returns a new request id. It is also
1197 struct vmbus_requestor *rqstor = &channel->requestor; in vmbus_next_request_id()
1202 if (!channel->rqstor_size) in vmbus_next_request_id()
1205 spin_lock_irqsave(&rqstor->req_lock, flags); in vmbus_next_request_id()
1206 current_id = rqstor->next_request_id; in vmbus_next_request_id()
1209 if (current_id >= rqstor->size) { in vmbus_next_request_id()
1210 spin_unlock_irqrestore(&rqstor->req_lock, flags); in vmbus_next_request_id()
1214 rqstor->next_request_id = rqstor->req_arr[current_id]; in vmbus_next_request_id()
1215 rqstor->req_arr[current_id] = rqst_addr; in vmbus_next_request_id()
1218 bitmap_set(rqstor->req_bitmap, current_id, 1); in vmbus_next_request_id()
1220 spin_unlock_irqrestore(&rqstor->req_lock, flags); in vmbus_next_request_id()
1224 * message from Hyper-V. in vmbus_next_request_id()
1231 * vmbus_request_addr - Returns the memory address stored at @trans_id
1234 * @trans_id: Request id sent back from Hyper-V. Becomes the requestor's
1239 struct vmbus_requestor *rqstor = &channel->requestor; in vmbus_request_addr()
1244 if (!channel->rqstor_size) in vmbus_request_addr()
1247 /* Hyper-V can send an unsolicited message with ID of 0 */ in vmbus_request_addr()
1251 spin_lock_irqsave(&rqstor->req_lock, flags); in vmbus_request_addr()
1253 /* Data corresponding to trans_id is stored at trans_id - 1 */ in vmbus_request_addr()
1254 trans_id--; in vmbus_request_addr()
1257 if (trans_id >= rqstor->size || !test_bit(trans_id, rqstor->req_bitmap)) { in vmbus_request_addr()
1258 spin_unlock_irqrestore(&rqstor->req_lock, flags); in vmbus_request_addr()
1262 req_addr = rqstor->req_arr[trans_id]; in vmbus_request_addr()
1263 rqstor->req_arr[trans_id] = rqstor->next_request_id; in vmbus_request_addr()
1264 rqstor->next_request_id = trans_id; in vmbus_request_addr()
1267 bitmap_clear(rqstor->req_bitmap, trans_id, 1); in vmbus_request_addr()
1269 spin_unlock_irqrestore(&rqstor->req_lock, flags); in vmbus_request_addr()