1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 *   Haiyang Zhang <haiyangz@microsoft.com>
19 *   Hank Janssen  <hjanssen@microsoft.com>
20 */
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/wait.h>
26#include <linux/mm.h>
27#include <linux/slab.h>
28#include <linux/module.h>
29#include <linux/hyperv.h>
30
31#include "hyperv_vmbus.h"
32
33#define NUM_PAGES_SPANNED(addr, len) \
34((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT))
35
36/* Internal routines */
37static int create_gpadl_header(
38	void *kbuffer,	/* must be phys and virt contiguous */
39	u32 size,	/* page-size multiple */
40	struct vmbus_channel_msginfo **msginfo,
41	u32 *messagecount);
42static void vmbus_setevent(struct vmbus_channel *channel);
43
44/*
45 * vmbus_setevent- Trigger an event notification on the specified
46 * channel.
47 */
48static void vmbus_setevent(struct vmbus_channel *channel)
49{
50	struct hv_monitor_page *monitorpage;
51
52	if (channel->offermsg.monitor_allocated) {
53		/* Each u32 represents 32 channels */
54		sync_set_bit(channel->offermsg.child_relid & 31,
55			(unsigned long *) vmbus_connection.send_int_page +
56			(channel->offermsg.child_relid >> 5));
57
58		monitorpage = vmbus_connection.monitor_pages;
59		monitorpage++; /* Get the child to parent monitor page */
60
61		sync_set_bit(channel->monitor_bit,
62			(unsigned long *)&monitorpage->trigger_group
63					[channel->monitor_grp].pending);
64
65	} else {
66		vmbus_set_event(channel->offermsg.child_relid);
67	}
68}
69
70/*
71 * vmbus_get_debug_info -Retrieve various channel debug info
72 */
73void vmbus_get_debug_info(struct vmbus_channel *channel,
74			      struct vmbus_channel_debug_info *debuginfo)
75{
76	struct hv_monitor_page *monitorpage;
77	u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
78	u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
79
80	debuginfo->relid = channel->offermsg.child_relid;
81	debuginfo->state = channel->state;
82	memcpy(&debuginfo->interfacetype,
83	       &channel->offermsg.offer.if_type, sizeof(uuid_le));
84	memcpy(&debuginfo->interface_instance,
85	       &channel->offermsg.offer.if_instance,
86	       sizeof(uuid_le));
87
88	monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
89
90	debuginfo->monitorid = channel->offermsg.monitorid;
91
92	debuginfo->servermonitor_pending =
93			monitorpage->trigger_group[monitor_group].pending;
94	debuginfo->servermonitor_latency =
95			monitorpage->latency[monitor_group][monitor_offset];
96	debuginfo->servermonitor_connectionid =
97			monitorpage->parameter[monitor_group]
98					[monitor_offset].connectionid.u.id;
99
100	monitorpage++;
101
102	debuginfo->clientmonitor_pending =
103			monitorpage->trigger_group[monitor_group].pending;
104	debuginfo->clientmonitor_latency =
105			monitorpage->latency[monitor_group][monitor_offset];
106	debuginfo->clientmonitor_connectionid =
107			monitorpage->parameter[monitor_group]
108					[monitor_offset].connectionid.u.id;
109
110	hv_ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
111	hv_ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
112}
113
114/*
115 * vmbus_open - Open the specified channel.
116 */
117int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
118		     u32 recv_ringbuffer_size, void *userdata, u32 userdatalen,
119		     void (*onchannelcallback)(void *context), void *context)
120{
121	struct vmbus_channel_open_channel *open_msg;
122	struct vmbus_channel_msginfo *open_info = NULL;
123	void *in, *out;
124	unsigned long flags;
125	int ret, t, err = 0;
126
127	newchannel->onchannel_callback = onchannelcallback;
128	newchannel->channel_callback_context = context;
129
130	/* Allocate the ring buffer */
131	out = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
132		get_order(send_ringbuffer_size + recv_ringbuffer_size));
133
134	if (!out)
135		return -ENOMEM;
136
137
138	in = (void *)((unsigned long)out + send_ringbuffer_size);
139
140	newchannel->ringbuffer_pages = out;
141	newchannel->ringbuffer_pagecount = (send_ringbuffer_size +
142					   recv_ringbuffer_size) >> PAGE_SHIFT;
143
144	ret = hv_ringbuffer_init(
145		&newchannel->outbound, out, send_ringbuffer_size);
146
147	if (ret != 0) {
148		err = ret;
149		goto errorout;
150	}
151
152	ret = hv_ringbuffer_init(
153		&newchannel->inbound, in, recv_ringbuffer_size);
154	if (ret != 0) {
155		err = ret;
156		goto errorout;
157	}
158
159
160	/* Establish the gpadl for the ring buffer */
161	newchannel->ringbuffer_gpadlhandle = 0;
162
163	ret = vmbus_establish_gpadl(newchannel,
164					 newchannel->outbound.ring_buffer,
165					 send_ringbuffer_size +
166					 recv_ringbuffer_size,
167					 &newchannel->ringbuffer_gpadlhandle);
168
169	if (ret != 0) {
170		err = ret;
171		goto errorout;
172	}
173
174	/* Create and init the channel open message */
175	open_info = kmalloc(sizeof(*open_info) +
176			   sizeof(struct vmbus_channel_open_channel),
177			   GFP_KERNEL);
178	if (!open_info) {
179		err = -ENOMEM;
180		goto errorout;
181	}
182
183	init_completion(&open_info->waitevent);
184
185	open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
186	open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
187	open_msg->openid = newchannel->offermsg.child_relid;
188	open_msg->child_relid = newchannel->offermsg.child_relid;
189	open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
190	open_msg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
191						  PAGE_SHIFT;
192	open_msg->server_contextarea_gpadlhandle = 0;
193
194	if (userdatalen > MAX_USER_DEFINED_BYTES) {
195		err = -EINVAL;
196		goto errorout;
197	}
198
199	if (userdatalen)
200		memcpy(open_msg->userdata, userdata, userdatalen);
201
202	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
203	list_add_tail(&open_info->msglistentry,
204		      &vmbus_connection.chn_msg_list);
205	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
206
207	ret = vmbus_post_msg(open_msg,
208			       sizeof(struct vmbus_channel_open_channel));
209
210	if (ret != 0)
211		goto cleanup;
212
213	t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
214	if (t == 0) {
215		err = -ETIMEDOUT;
216		goto errorout;
217	}
218
219
220	if (open_info->response.open_result.status)
221		err = open_info->response.open_result.status;
222
223cleanup:
224	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
225	list_del(&open_info->msglistentry);
226	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
227
228	kfree(open_info);
229	return err;
230
231errorout:
232	hv_ringbuffer_cleanup(&newchannel->outbound);
233	hv_ringbuffer_cleanup(&newchannel->inbound);
234	free_pages((unsigned long)out,
235		get_order(send_ringbuffer_size + recv_ringbuffer_size));
236	kfree(open_info);
237	return err;
238}
239EXPORT_SYMBOL_GPL(vmbus_open);
240
241/*
242 * create_gpadl_header - Creates a gpadl for the specified buffer
243 */
244static int create_gpadl_header(void *kbuffer, u32 size,
245					 struct vmbus_channel_msginfo **msginfo,
246					 u32 *messagecount)
247{
248	int i;
249	int pagecount;
250	unsigned long long pfn;
251	struct vmbus_channel_gpadl_header *gpadl_header;
252	struct vmbus_channel_gpadl_body *gpadl_body;
253	struct vmbus_channel_msginfo *msgheader;
254	struct vmbus_channel_msginfo *msgbody = NULL;
255	u32 msgsize;
256
257	int pfnsum, pfncount, pfnleft, pfncurr, pfnsize;
258
259	pagecount = size >> PAGE_SHIFT;
260	pfn = virt_to_phys(kbuffer) >> PAGE_SHIFT;
261
262	/* do we need a gpadl body msg */
263	pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
264		  sizeof(struct vmbus_channel_gpadl_header) -
265		  sizeof(struct gpa_range);
266	pfncount = pfnsize / sizeof(u64);
267
268	if (pagecount > pfncount) {
269		/* we need a gpadl body */
270		/* fill in the header */
271		msgsize = sizeof(struct vmbus_channel_msginfo) +
272			  sizeof(struct vmbus_channel_gpadl_header) +
273			  sizeof(struct gpa_range) + pfncount * sizeof(u64);
274		msgheader =  kzalloc(msgsize, GFP_KERNEL);
275		if (!msgheader)
276			goto nomem;
277
278		INIT_LIST_HEAD(&msgheader->submsglist);
279		msgheader->msgsize = msgsize;
280
281		gpadl_header = (struct vmbus_channel_gpadl_header *)
282			msgheader->msg;
283		gpadl_header->rangecount = 1;
284		gpadl_header->range_buflen = sizeof(struct gpa_range) +
285					 pagecount * sizeof(u64);
286		gpadl_header->range[0].byte_offset = 0;
287		gpadl_header->range[0].byte_count = size;
288		for (i = 0; i < pfncount; i++)
289			gpadl_header->range[0].pfn_array[i] = pfn+i;
290		*msginfo = msgheader;
291		*messagecount = 1;
292
293		pfnsum = pfncount;
294		pfnleft = pagecount - pfncount;
295
296		/* how many pfns can we fit */
297		pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
298			  sizeof(struct vmbus_channel_gpadl_body);
299		pfncount = pfnsize / sizeof(u64);
300
301		/* fill in the body */
302		while (pfnleft) {
303			if (pfnleft > pfncount)
304				pfncurr = pfncount;
305			else
306				pfncurr = pfnleft;
307
308			msgsize = sizeof(struct vmbus_channel_msginfo) +
309				  sizeof(struct vmbus_channel_gpadl_body) +
310				  pfncurr * sizeof(u64);
311			msgbody = kzalloc(msgsize, GFP_KERNEL);
312
313			if (!msgbody) {
314				struct vmbus_channel_msginfo *pos = NULL;
315				struct vmbus_channel_msginfo *tmp = NULL;
316				/*
317				 * Free up all the allocated messages.
318				 */
319				list_for_each_entry_safe(pos, tmp,
320					&msgheader->submsglist,
321					msglistentry) {
322
323					list_del(&pos->msglistentry);
324					kfree(pos);
325				}
326
327				goto nomem;
328			}
329
330			msgbody->msgsize = msgsize;
331			(*messagecount)++;
332			gpadl_body =
333				(struct vmbus_channel_gpadl_body *)msgbody->msg;
334
335			/*
336			 * Gpadl is u32 and we are using a pointer which could
337			 * be 64-bit
338			 * This is governed by the guest/host protocol and
339			 * so the hypervisor gurantees that this is ok.
340			 */
341			for (i = 0; i < pfncurr; i++)
342				gpadl_body->pfn[i] = pfn + pfnsum + i;
343
344			/* add to msg header */
345			list_add_tail(&msgbody->msglistentry,
346				      &msgheader->submsglist);
347			pfnsum += pfncurr;
348			pfnleft -= pfncurr;
349		}
350	} else {
351		/* everything fits in a header */
352		msgsize = sizeof(struct vmbus_channel_msginfo) +
353			  sizeof(struct vmbus_channel_gpadl_header) +
354			  sizeof(struct gpa_range) + pagecount * sizeof(u64);
355		msgheader = kzalloc(msgsize, GFP_KERNEL);
356		if (msgheader == NULL)
357			goto nomem;
358		msgheader->msgsize = msgsize;
359
360		gpadl_header = (struct vmbus_channel_gpadl_header *)
361			msgheader->msg;
362		gpadl_header->rangecount = 1;
363		gpadl_header->range_buflen = sizeof(struct gpa_range) +
364					 pagecount * sizeof(u64);
365		gpadl_header->range[0].byte_offset = 0;
366		gpadl_header->range[0].byte_count = size;
367		for (i = 0; i < pagecount; i++)
368			gpadl_header->range[0].pfn_array[i] = pfn+i;
369
370		*msginfo = msgheader;
371		*messagecount = 1;
372	}
373
374	return 0;
375nomem:
376	kfree(msgheader);
377	kfree(msgbody);
378	return -ENOMEM;
379}
380
381/*
382 * vmbus_establish_gpadl - Estabish a GPADL for the specified buffer
383 *
384 * @channel: a channel
385 * @kbuffer: from kmalloc
386 * @size: page-size multiple
387 * @gpadl_handle: some funky thing
388 */
389int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
390			       u32 size, u32 *gpadl_handle)
391{
392	struct vmbus_channel_gpadl_header *gpadlmsg;
393	struct vmbus_channel_gpadl_body *gpadl_body;
394	struct vmbus_channel_msginfo *msginfo = NULL;
395	struct vmbus_channel_msginfo *submsginfo;
396	u32 msgcount;
397	struct list_head *curr;
398	u32 next_gpadl_handle;
399	unsigned long flags;
400	int ret = 0;
401	int t;
402
403	next_gpadl_handle = atomic_read(&vmbus_connection.next_gpadl_handle);
404	atomic_inc(&vmbus_connection.next_gpadl_handle);
405
406	ret = create_gpadl_header(kbuffer, size, &msginfo, &msgcount);
407	if (ret)
408		return ret;
409
410	init_completion(&msginfo->waitevent);
411
412	gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg;
413	gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER;
414	gpadlmsg->child_relid = channel->offermsg.child_relid;
415	gpadlmsg->gpadl = next_gpadl_handle;
416
417
418	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
419	list_add_tail(&msginfo->msglistentry,
420		      &vmbus_connection.chn_msg_list);
421
422	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
423
424	ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
425			       sizeof(*msginfo));
426	if (ret != 0)
427		goto cleanup;
428
429	if (msgcount > 1) {
430		list_for_each(curr, &msginfo->submsglist) {
431
432			submsginfo = (struct vmbus_channel_msginfo *)curr;
433			gpadl_body =
434			     (struct vmbus_channel_gpadl_body *)submsginfo->msg;
435
436			gpadl_body->header.msgtype =
437				CHANNELMSG_GPADL_BODY;
438			gpadl_body->gpadl = next_gpadl_handle;
439
440			ret = vmbus_post_msg(gpadl_body,
441					       submsginfo->msgsize -
442					       sizeof(*submsginfo));
443			if (ret != 0)
444				goto cleanup;
445
446		}
447	}
448	t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
449	BUG_ON(t == 0);
450
451
452	/* At this point, we received the gpadl created msg */
453	*gpadl_handle = gpadlmsg->gpadl;
454
455cleanup:
456	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
457	list_del(&msginfo->msglistentry);
458	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
459
460	kfree(msginfo);
461	return ret;
462}
463EXPORT_SYMBOL_GPL(vmbus_establish_gpadl);
464
465/*
466 * vmbus_teardown_gpadl -Teardown the specified GPADL handle
467 */
468int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
469{
470	struct vmbus_channel_gpadl_teardown *msg;
471	struct vmbus_channel_msginfo *info;
472	unsigned long flags;
473	int ret, t;
474
475	info = kmalloc(sizeof(*info) +
476		       sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
477	if (!info)
478		return -ENOMEM;
479
480	init_completion(&info->waitevent);
481
482	msg = (struct vmbus_channel_gpadl_teardown *)info->msg;
483
484	msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN;
485	msg->child_relid = channel->offermsg.child_relid;
486	msg->gpadl = gpadl_handle;
487
488	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
489	list_add_tail(&info->msglistentry,
490		      &vmbus_connection.chn_msg_list);
491	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
492	ret = vmbus_post_msg(msg,
493			       sizeof(struct vmbus_channel_gpadl_teardown));
494
495	BUG_ON(ret != 0);
496	t = wait_for_completion_timeout(&info->waitevent, 5*HZ);
497	BUG_ON(t == 0);
498
499	/* Received a torndown response */
500	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
501	list_del(&info->msglistentry);
502	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
503
504	kfree(info);
505	return ret;
506}
507EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
508
509/*
510 * vmbus_close - Close the specified channel
511 */
512void vmbus_close(struct vmbus_channel *channel)
513{
514	struct vmbus_channel_close_channel *msg;
515	int ret;
516	unsigned long flags;
517
518	/* Stop callback and cancel the timer asap */
519	spin_lock_irqsave(&channel->inbound_lock, flags);
520	channel->onchannel_callback = NULL;
521	spin_unlock_irqrestore(&channel->inbound_lock, flags);
522
523	/* Send a closing message */
524
525	msg = &channel->close_msg.msg;
526
527	msg->header.msgtype = CHANNELMSG_CLOSECHANNEL;
528	msg->child_relid = channel->offermsg.child_relid;
529
530	ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel));
531
532	BUG_ON(ret != 0);
533	/* Tear down the gpadl for the channel's ring buffer */
534	if (channel->ringbuffer_gpadlhandle)
535		vmbus_teardown_gpadl(channel,
536					  channel->ringbuffer_gpadlhandle);
537
538	/* Cleanup the ring buffers for this channel */
539	hv_ringbuffer_cleanup(&channel->outbound);
540	hv_ringbuffer_cleanup(&channel->inbound);
541
542	free_pages((unsigned long)channel->ringbuffer_pages,
543		get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
544
545
546}
547EXPORT_SYMBOL_GPL(vmbus_close);
548
549/**
550 * vmbus_sendpacket() - Send the specified buffer on the given channel
551 * @channel: Pointer to vmbus_channel structure.
552 * @buffer: Pointer to the buffer you want to receive the data into.
553 * @bufferlen: Maximum size of what the the buffer will hold
554 * @requestid: Identifier of the request
555 * @type: Type of packet that is being send e.g. negotiate, time
556 * packet etc.
557 *
558 * Sends data in @buffer directly to hyper-v via the vmbus
559 * This will send the data unparsed to hyper-v.
560 *
561 * Mainly used by Hyper-V drivers.
562 */
563int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer,
564			   u32 bufferlen, u64 requestid,
565			   enum vmbus_packet_type type, u32 flags)
566{
567	struct vmpacket_descriptor desc;
568	u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
569	u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
570	struct scatterlist bufferlist[3];
571	u64 aligned_data = 0;
572	int ret;
573
574
575	/* Setup the descriptor */
576	desc.type = type; /* VmbusPacketTypeDataInBand; */
577	desc.flags = flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
578	/* in 8-bytes granularity */
579	desc.offset8 = sizeof(struct vmpacket_descriptor) >> 3;
580	desc.len8 = (u16)(packetlen_aligned >> 3);
581	desc.trans_id = requestid;
582
583	sg_init_table(bufferlist, 3);
584	sg_set_buf(&bufferlist[0], &desc, sizeof(struct vmpacket_descriptor));
585	sg_set_buf(&bufferlist[1], buffer, bufferlen);
586	sg_set_buf(&bufferlist[2], &aligned_data,
587		   packetlen_aligned - packetlen);
588
589	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
590
591	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
592		vmbus_setevent(channel);
593
594	return ret;
595}
596EXPORT_SYMBOL(vmbus_sendpacket);
597
598/*
599 * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
600 * packets using a GPADL Direct packet type.
601 */
602int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
603				     struct hv_page_buffer pagebuffers[],
604				     u32 pagecount, void *buffer, u32 bufferlen,
605				     u64 requestid)
606{
607	int ret;
608	int i;
609	struct vmbus_channel_packet_page_buffer desc;
610	u32 descsize;
611	u32 packetlen;
612	u32 packetlen_aligned;
613	struct scatterlist bufferlist[3];
614	u64 aligned_data = 0;
615
616	if (pagecount > MAX_PAGE_BUFFER_COUNT)
617		return -EINVAL;
618
619
620	/*
621	 * Adjust the size down since vmbus_channel_packet_page_buffer is the
622	 * largest size we support
623	 */
624	descsize = sizeof(struct vmbus_channel_packet_page_buffer) -
625			  ((MAX_PAGE_BUFFER_COUNT - pagecount) *
626			  sizeof(struct hv_page_buffer));
627	packetlen = descsize + bufferlen;
628	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
629
630	/* Setup the descriptor */
631	desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
632	desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
633	desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
634	desc.length8 = (u16)(packetlen_aligned >> 3);
635	desc.transactionid = requestid;
636	desc.rangecount = pagecount;
637
638	for (i = 0; i < pagecount; i++) {
639		desc.range[i].len = pagebuffers[i].len;
640		desc.range[i].offset = pagebuffers[i].offset;
641		desc.range[i].pfn	 = pagebuffers[i].pfn;
642	}
643
644	sg_init_table(bufferlist, 3);
645	sg_set_buf(&bufferlist[0], &desc, descsize);
646	sg_set_buf(&bufferlist[1], buffer, bufferlen);
647	sg_set_buf(&bufferlist[2], &aligned_data,
648		packetlen_aligned - packetlen);
649
650	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
651
652	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
653		vmbus_setevent(channel);
654
655	return ret;
656}
657EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
658
659/*
660 * vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
661 * using a GPADL Direct packet type.
662 */
663int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
664				struct hv_multipage_buffer *multi_pagebuffer,
665				void *buffer, u32 bufferlen, u64 requestid)
666{
667	int ret;
668	struct vmbus_channel_packet_multipage_buffer desc;
669	u32 descsize;
670	u32 packetlen;
671	u32 packetlen_aligned;
672	struct scatterlist bufferlist[3];
673	u64 aligned_data = 0;
674	u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
675					 multi_pagebuffer->len);
676
677
678	if ((pfncount < 0) || (pfncount > MAX_MULTIPAGE_BUFFER_COUNT))
679		return -EINVAL;
680
681	/*
682	 * Adjust the size down since vmbus_channel_packet_multipage_buffer is
683	 * the largest size we support
684	 */
685	descsize = sizeof(struct vmbus_channel_packet_multipage_buffer) -
686			  ((MAX_MULTIPAGE_BUFFER_COUNT - pfncount) *
687			  sizeof(u64));
688	packetlen = descsize + bufferlen;
689	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
690
691
692	/* Setup the descriptor */
693	desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
694	desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
695	desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
696	desc.length8 = (u16)(packetlen_aligned >> 3);
697	desc.transactionid = requestid;
698	desc.rangecount = 1;
699
700	desc.range.len = multi_pagebuffer->len;
701	desc.range.offset = multi_pagebuffer->offset;
702
703	memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array,
704	       pfncount * sizeof(u64));
705
706	sg_init_table(bufferlist, 3);
707	sg_set_buf(&bufferlist[0], &desc, descsize);
708	sg_set_buf(&bufferlist[1], buffer, bufferlen);
709	sg_set_buf(&bufferlist[2], &aligned_data,
710		packetlen_aligned - packetlen);
711
712	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
713
714	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
715		vmbus_setevent(channel);
716
717	return ret;
718}
719EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
720
721/**
722 * vmbus_recvpacket() - Retrieve the user packet on the specified channel
723 * @channel: Pointer to vmbus_channel structure.
724 * @buffer: Pointer to the buffer you want to receive the data into.
725 * @bufferlen: Maximum size of what the the buffer will hold
726 * @buffer_actual_len: The actual size of the data after it was received
727 * @requestid: Identifier of the request
728 *
729 * Receives directly from the hyper-v vmbus and puts the data it received
730 * into Buffer. This will receive the data unparsed from hyper-v.
731 *
732 * Mainly used by Hyper-V drivers.
733 */
734int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
735			u32 bufferlen, u32 *buffer_actual_len, u64 *requestid)
736{
737	struct vmpacket_descriptor desc;
738	u32 packetlen;
739	u32 userlen;
740	int ret;
741
742	*buffer_actual_len = 0;
743	*requestid = 0;
744
745
746	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
747			     sizeof(struct vmpacket_descriptor));
748	if (ret != 0)
749		return 0;
750
751	packetlen = desc.len8 << 3;
752	userlen = packetlen - (desc.offset8 << 3);
753
754	*buffer_actual_len = userlen;
755
756	if (userlen > bufferlen) {
757
758		pr_err("Buffer too small - got %d needs %d\n",
759			   bufferlen, userlen);
760		return -ETOOSMALL;
761	}
762
763	*requestid = desc.trans_id;
764
765	/* Copy over the packet to the user buffer */
766	ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
767			     (desc.offset8 << 3));
768
769
770	return 0;
771}
772EXPORT_SYMBOL(vmbus_recvpacket);
773
774/*
775 * vmbus_recvpacket_raw - Retrieve the raw packet on the specified channel
776 */
777int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
778			      u32 bufferlen, u32 *buffer_actual_len,
779			      u64 *requestid)
780{
781	struct vmpacket_descriptor desc;
782	u32 packetlen;
783	u32 userlen;
784	int ret;
785
786	*buffer_actual_len = 0;
787	*requestid = 0;
788
789
790	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
791			     sizeof(struct vmpacket_descriptor));
792	if (ret != 0)
793		return 0;
794
795
796	packetlen = desc.len8 << 3;
797	userlen = packetlen - (desc.offset8 << 3);
798
799	*buffer_actual_len = packetlen;
800
801	if (packetlen > bufferlen) {
802		pr_err("Buffer too small - needed %d bytes but "
803			"got space for only %d bytes\n",
804			packetlen, bufferlen);
805		return -ENOBUFS;
806	}
807
808	*requestid = desc.trans_id;
809
810	/* Copy over the entire packet to the user buffer */
811	ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
812
813	return 0;
814}
815EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
816