aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-10-04 15:29:52 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-11 00:52:55 -0400
commit46a971913611a23478283931460a95be962ce329 (patch)
tree7452d0f07ee9f1f5270a8da6c1387f35c439843d /drivers/hv
parent715a4801e734ea9c8e528265ce3ff6aead85bce1 (diff)
Staging: hv: move hyperv code out of staging directory
After many years wandering the desert, it is finally time for the Microsoft HyperV code to move out of the staging directory. Or at least the core hyperv bus code, and the utility driver, the rest still have some review to get through by the various subsystem maintainers. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/Kconfig14
-rw-r--r--drivers/hv/Makefile7
-rw-r--r--drivers/hv/channel.c815
-rw-r--r--drivers/hv/channel_mgmt.c647
-rw-r--r--drivers/hv/connection.c318
-rw-r--r--drivers/hv/hv.c429
-rw-r--r--drivers/hv/hv_kvp.c339
-rw-r--r--drivers/hv/hv_kvp.h184
-rw-r--r--drivers/hv/hv_util.c354
-rw-r--r--drivers/hv/hyperv_vmbus.h628
-rw-r--r--drivers/hv/ring_buffer.c527
-rw-r--r--drivers/hv/vmbus_drv.c772
12 files changed, 5034 insertions, 0 deletions
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
new file mode 100644
index 000000000000..9fa09ac000ad
--- /dev/null
+++ b/drivers/hv/Kconfig
@@ -0,0 +1,14 @@
1config HYPERV
2 tristate "Microsoft Hyper-V client drivers"
3 depends on X86 && ACPI && PCI
4 help
5 Select this option to run Linux as a Hyper-V client operating
6 system.
7
8config HYPERV_UTILS
9 tristate "Microsoft Hyper-V Utilities driver"
10 depends on HYPERV && CONNECTOR && NLS
11 help
12 Select this option to enable the Hyper-V Utilities.
13
14
diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
new file mode 100644
index 000000000000..a23938b991c9
--- /dev/null
+++ b/drivers/hv/Makefile
@@ -0,0 +1,7 @@
1obj-$(CONFIG_HYPERV) += hv_vmbus.o
2obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
3
4hv_vmbus-y := vmbus_drv.o \
5 hv.o connection.o channel.o \
6 channel_mgmt.o ring_buffer.o
7hv_utils-y := hv_util.o hv_kvp.o
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
new file mode 100644
index 000000000000..406537420fff
--- /dev/null
+++ b/drivers/hv/channel.c
@@ -0,0 +1,815 @@
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);
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
new file mode 100644
index 000000000000..41bf287baa1c
--- /dev/null
+++ b/drivers/hv/channel_mgmt.c
@@ -0,0 +1,647 @@
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/list.h>
29#include <linux/module.h>
30#include <linux/completion.h>
31#include <linux/hyperv.h>
32
33#include "hyperv_vmbus.h"
34
35struct vmbus_channel_message_table_entry {
36 enum vmbus_channel_message_type message_type;
37 void (*message_handler)(struct vmbus_channel_message_header *msg);
38};
39
40#define MAX_MSG_TYPES 4
41#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8
42
43static const uuid_le
44 supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
45 /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
46 /* Storage - SCSI */
47 {
48 .b = {
49 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
50 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
51 }
52 },
53
54 /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
55 /* Network */
56 {
57 .b = {
58 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
59 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
60 }
61 },
62
63 /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
64 /* Input */
65 {
66 .b = {
67 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
68 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
69 }
70 },
71
72 /* {32412632-86cb-44a2-9b5c-50d1417354f5} */
73 /* IDE */
74 {
75 .b = {
76 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
77 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
78 }
79 },
80 /* 0E0B6031-5213-4934-818B-38D90CED39DB */
81 /* Shutdown */
82 {
83 .b = {
84 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
85 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
86 }
87 },
88 /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
89 /* TimeSync */
90 {
91 .b = {
92 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
93 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
94 }
95 },
96 /* {57164f39-9115-4e78-ab55-382f3bd5422d} */
97 /* Heartbeat */
98 {
99 .b = {
100 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
101 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
102 }
103 },
104 /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
105 /* KVP */
106 {
107 .b = {
108 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
109 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
110 }
111 },
112
113};
114
115
116/**
117 * prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
118 * @icmsghdrp: Pointer to msg header structure
119 * @icmsg_negotiate: Pointer to negotiate message structure
120 * @buf: Raw buffer channel data
121 *
122 * @icmsghdrp is of type &struct icmsg_hdr.
123 * @negop is of type &struct icmsg_negotiate.
124 * Set up and fill in default negotiate response message. This response can
125 * come from both the vmbus driver and the hv_utils driver. The current api
126 * will respond properly to both Windows 2008 and Windows 2008-R2 operating
127 * systems.
128 *
129 * Mainly used by Hyper-V drivers.
130 */
131void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
132 struct icmsg_negotiate *negop,
133 u8 *buf)
134{
135 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
136 icmsghdrp->icmsgsize = 0x10;
137
138 negop = (struct icmsg_negotiate *)&buf[
139 sizeof(struct vmbuspipe_hdr) +
140 sizeof(struct icmsg_hdr)];
141
142 if (negop->icframe_vercnt == 2 &&
143 negop->icversion_data[1].major == 3) {
144 negop->icversion_data[0].major = 3;
145 negop->icversion_data[0].minor = 0;
146 negop->icversion_data[1].major = 3;
147 negop->icversion_data[1].minor = 0;
148 } else {
149 negop->icversion_data[0].major = 1;
150 negop->icversion_data[0].minor = 0;
151 negop->icversion_data[1].major = 1;
152 negop->icversion_data[1].minor = 0;
153 }
154
155 negop->icframe_vercnt = 1;
156 negop->icmsg_vercnt = 1;
157 }
158}
159EXPORT_SYMBOL(prep_negotiate_resp);
160
161/*
162 * alloc_channel - Allocate and initialize a vmbus channel object
163 */
164static struct vmbus_channel *alloc_channel(void)
165{
166 struct vmbus_channel *channel;
167
168 channel = kzalloc(sizeof(*channel), GFP_ATOMIC);
169 if (!channel)
170 return NULL;
171
172 spin_lock_init(&channel->inbound_lock);
173
174 channel->controlwq = create_workqueue("hv_vmbus_ctl");
175 if (!channel->controlwq) {
176 kfree(channel);
177 return NULL;
178 }
179
180 return channel;
181}
182
183/*
184 * release_hannel - Release the vmbus channel object itself
185 */
186static void release_channel(struct work_struct *work)
187{
188 struct vmbus_channel *channel = container_of(work,
189 struct vmbus_channel,
190 work);
191
192 destroy_workqueue(channel->controlwq);
193
194 kfree(channel);
195}
196
197/*
198 * free_channel - Release the resources used by the vmbus channel object
199 */
200void free_channel(struct vmbus_channel *channel)
201{
202
203 /*
204 * We have to release the channel's workqueue/thread in the vmbus's
205 * workqueue/thread context
206 * ie we can't destroy ourselves.
207 */
208 INIT_WORK(&channel->work, release_channel);
209 queue_work(vmbus_connection.work_queue, &channel->work);
210}
211
212
213
214/*
215 * vmbus_process_rescind_offer -
216 * Rescind the offer by initiating a device removal
217 */
218static void vmbus_process_rescind_offer(struct work_struct *work)
219{
220 struct vmbus_channel *channel = container_of(work,
221 struct vmbus_channel,
222 work);
223
224 vmbus_device_unregister(channel->device_obj);
225}
226
227/*
228 * vmbus_process_offer - Process the offer by creating a channel/device
229 * associated with this offer
230 */
231static void vmbus_process_offer(struct work_struct *work)
232{
233 struct vmbus_channel *newchannel = container_of(work,
234 struct vmbus_channel,
235 work);
236 struct vmbus_channel *channel;
237 bool fnew = true;
238 int ret;
239 unsigned long flags;
240
241 /* The next possible work is rescind handling */
242 INIT_WORK(&newchannel->work, vmbus_process_rescind_offer);
243
244 /* Make sure this is a new offer */
245 spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
246
247 list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
248 if (!uuid_le_cmp(channel->offermsg.offer.if_type,
249 newchannel->offermsg.offer.if_type) &&
250 !uuid_le_cmp(channel->offermsg.offer.if_instance,
251 newchannel->offermsg.offer.if_instance)) {
252 fnew = false;
253 break;
254 }
255 }
256
257 if (fnew)
258 list_add_tail(&newchannel->listentry,
259 &vmbus_connection.chn_list);
260
261 spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
262
263 if (!fnew) {
264 free_channel(newchannel);
265 return;
266 }
267
268 /*
269 * Start the process of binding this offer to the driver
270 * We need to set the DeviceObject field before calling
271 * vmbus_child_dev_add()
272 */
273 newchannel->device_obj = vmbus_device_create(
274 &newchannel->offermsg.offer.if_type,
275 &newchannel->offermsg.offer.if_instance,
276 newchannel);
277
278 /*
279 * Add the new device to the bus. This will kick off device-driver
280 * binding which eventually invokes the device driver's AddDevice()
281 * method.
282 */
283 ret = vmbus_device_register(newchannel->device_obj);
284 if (ret != 0) {
285 pr_err("unable to add child device object (relid %d)\n",
286 newchannel->offermsg.child_relid);
287
288 spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
289 list_del(&newchannel->listentry);
290 spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
291
292 free_channel(newchannel);
293 } else {
294 /*
295 * This state is used to indicate a successful open
296 * so that when we do close the channel normally, we
297 * can cleanup properly
298 */
299 newchannel->state = CHANNEL_OPEN_STATE;
300 }
301}
302
303/*
304 * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
305 *
306 */
307static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
308{
309 struct vmbus_channel_offer_channel *offer;
310 struct vmbus_channel *newchannel;
311 uuid_le *guidtype;
312 uuid_le *guidinstance;
313 int i;
314 int fsupported = 0;
315
316 offer = (struct vmbus_channel_offer_channel *)hdr;
317 for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
318 if (!uuid_le_cmp(offer->offer.if_type,
319 supported_device_classes[i])) {
320 fsupported = 1;
321 break;
322 }
323 }
324
325 if (!fsupported)
326 return;
327
328 guidtype = &offer->offer.if_type;
329 guidinstance = &offer->offer.if_instance;
330
331 /* Allocate the channel object and save this offer. */
332 newchannel = alloc_channel();
333 if (!newchannel) {
334 pr_err("Unable to allocate channel object\n");
335 return;
336 }
337
338 memcpy(&newchannel->offermsg, offer,
339 sizeof(struct vmbus_channel_offer_channel));
340 newchannel->monitor_grp = (u8)offer->monitorid / 32;
341 newchannel->monitor_bit = (u8)offer->monitorid % 32;
342
343 INIT_WORK(&newchannel->work, vmbus_process_offer);
344 queue_work(newchannel->controlwq, &newchannel->work);
345}
346
347/*
348 * vmbus_onoffer_rescind - Rescind offer handler.
349 *
350 * We queue a work item to process this offer synchronously
351 */
352static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
353{
354 struct vmbus_channel_rescind_offer *rescind;
355 struct vmbus_channel *channel;
356
357 rescind = (struct vmbus_channel_rescind_offer *)hdr;
358 channel = relid2channel(rescind->child_relid);
359
360 if (channel == NULL)
361 /* Just return here, no channel found */
362 return;
363
364 /* work is initialized for vmbus_process_rescind_offer() from
365 * vmbus_process_offer() where the channel got created */
366 queue_work(channel->controlwq, &channel->work);
367}
368
369/*
370 * vmbus_onoffers_delivered -
371 * This is invoked when all offers have been delivered.
372 *
373 * Nothing to do here.
374 */
375static void vmbus_onoffers_delivered(
376 struct vmbus_channel_message_header *hdr)
377{
378}
379
380/*
381 * vmbus_onopen_result - Open result handler.
382 *
383 * This is invoked when we received a response to our channel open request.
384 * Find the matching request, copy the response and signal the requesting
385 * thread.
386 */
387static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr)
388{
389 struct vmbus_channel_open_result *result;
390 struct vmbus_channel_msginfo *msginfo;
391 struct vmbus_channel_message_header *requestheader;
392 struct vmbus_channel_open_channel *openmsg;
393 unsigned long flags;
394
395 result = (struct vmbus_channel_open_result *)hdr;
396
397 /*
398 * Find the open msg, copy the result and signal/unblock the wait event
399 */
400 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
401
402 list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
403 msglistentry) {
404 requestheader =
405 (struct vmbus_channel_message_header *)msginfo->msg;
406
407 if (requestheader->msgtype == CHANNELMSG_OPENCHANNEL) {
408 openmsg =
409 (struct vmbus_channel_open_channel *)msginfo->msg;
410 if (openmsg->child_relid == result->child_relid &&
411 openmsg->openid == result->openid) {
412 memcpy(&msginfo->response.open_result,
413 result,
414 sizeof(
415 struct vmbus_channel_open_result));
416 complete(&msginfo->waitevent);
417 break;
418 }
419 }
420 }
421 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
422}
423
424/*
425 * vmbus_ongpadl_created - GPADL created handler.
426 *
427 * This is invoked when we received a response to our gpadl create request.
428 * Find the matching request, copy the response and signal the requesting
429 * thread.
430 */
431static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr)
432{
433 struct vmbus_channel_gpadl_created *gpadlcreated;
434 struct vmbus_channel_msginfo *msginfo;
435 struct vmbus_channel_message_header *requestheader;
436 struct vmbus_channel_gpadl_header *gpadlheader;
437 unsigned long flags;
438
439 gpadlcreated = (struct vmbus_channel_gpadl_created *)hdr;
440
441 /*
442 * Find the establish msg, copy the result and signal/unblock the wait
443 * event
444 */
445 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
446
447 list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
448 msglistentry) {
449 requestheader =
450 (struct vmbus_channel_message_header *)msginfo->msg;
451
452 if (requestheader->msgtype == CHANNELMSG_GPADL_HEADER) {
453 gpadlheader =
454 (struct vmbus_channel_gpadl_header *)requestheader;
455
456 if ((gpadlcreated->child_relid ==
457 gpadlheader->child_relid) &&
458 (gpadlcreated->gpadl == gpadlheader->gpadl)) {
459 memcpy(&msginfo->response.gpadl_created,
460 gpadlcreated,
461 sizeof(
462 struct vmbus_channel_gpadl_created));
463 complete(&msginfo->waitevent);
464 break;
465 }
466 }
467 }
468 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
469}
470
471/*
472 * vmbus_ongpadl_torndown - GPADL torndown handler.
473 *
474 * This is invoked when we received a response to our gpadl teardown request.
475 * Find the matching request, copy the response and signal the requesting
476 * thread.
477 */
478static void vmbus_ongpadl_torndown(
479 struct vmbus_channel_message_header *hdr)
480{
481 struct vmbus_channel_gpadl_torndown *gpadl_torndown;
482 struct vmbus_channel_msginfo *msginfo;
483 struct vmbus_channel_message_header *requestheader;
484 struct vmbus_channel_gpadl_teardown *gpadl_teardown;
485 unsigned long flags;
486
487 gpadl_torndown = (struct vmbus_channel_gpadl_torndown *)hdr;
488
489 /*
490 * Find the open msg, copy the result and signal/unblock the wait event
491 */
492 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
493
494 list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
495 msglistentry) {
496 requestheader =
497 (struct vmbus_channel_message_header *)msginfo->msg;
498
499 if (requestheader->msgtype == CHANNELMSG_GPADL_TEARDOWN) {
500 gpadl_teardown =
501 (struct vmbus_channel_gpadl_teardown *)requestheader;
502
503 if (gpadl_torndown->gpadl == gpadl_teardown->gpadl) {
504 memcpy(&msginfo->response.gpadl_torndown,
505 gpadl_torndown,
506 sizeof(
507 struct vmbus_channel_gpadl_torndown));
508 complete(&msginfo->waitevent);
509 break;
510 }
511 }
512 }
513 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
514}
515
516/*
517 * vmbus_onversion_response - Version response handler
518 *
519 * This is invoked when we received a response to our initiate contact request.
520 * Find the matching request, copy the response and signal the requesting
521 * thread.
522 */
523static void vmbus_onversion_response(
524 struct vmbus_channel_message_header *hdr)
525{
526 struct vmbus_channel_msginfo *msginfo;
527 struct vmbus_channel_message_header *requestheader;
528 struct vmbus_channel_initiate_contact *initiate;
529 struct vmbus_channel_version_response *version_response;
530 unsigned long flags;
531
532 version_response = (struct vmbus_channel_version_response *)hdr;
533 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
534
535 list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
536 msglistentry) {
537 requestheader =
538 (struct vmbus_channel_message_header *)msginfo->msg;
539
540 if (requestheader->msgtype ==
541 CHANNELMSG_INITIATE_CONTACT) {
542 initiate =
543 (struct vmbus_channel_initiate_contact *)requestheader;
544 memcpy(&msginfo->response.version_response,
545 version_response,
546 sizeof(struct vmbus_channel_version_response));
547 complete(&msginfo->waitevent);
548 }
549 }
550 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
551}
552
553/* Channel message dispatch table */
554static struct vmbus_channel_message_table_entry
555 channel_message_table[CHANNELMSG_COUNT] = {
556 {CHANNELMSG_INVALID, NULL},
557 {CHANNELMSG_OFFERCHANNEL, vmbus_onoffer},
558 {CHANNELMSG_RESCIND_CHANNELOFFER, vmbus_onoffer_rescind},
559 {CHANNELMSG_REQUESTOFFERS, NULL},
560 {CHANNELMSG_ALLOFFERS_DELIVERED, vmbus_onoffers_delivered},
561 {CHANNELMSG_OPENCHANNEL, NULL},
562 {CHANNELMSG_OPENCHANNEL_RESULT, vmbus_onopen_result},
563 {CHANNELMSG_CLOSECHANNEL, NULL},
564 {CHANNELMSG_GPADL_HEADER, NULL},
565 {CHANNELMSG_GPADL_BODY, NULL},
566 {CHANNELMSG_GPADL_CREATED, vmbus_ongpadl_created},
567 {CHANNELMSG_GPADL_TEARDOWN, NULL},
568 {CHANNELMSG_GPADL_TORNDOWN, vmbus_ongpadl_torndown},
569 {CHANNELMSG_RELID_RELEASED, NULL},
570 {CHANNELMSG_INITIATE_CONTACT, NULL},
571 {CHANNELMSG_VERSION_RESPONSE, vmbus_onversion_response},
572 {CHANNELMSG_UNLOAD, NULL},
573};
574
575/*
576 * vmbus_onmessage - Handler for channel protocol messages.
577 *
578 * This is invoked in the vmbus worker thread context.
579 */
580void vmbus_onmessage(void *context)
581{
582 struct hv_message *msg = context;
583 struct vmbus_channel_message_header *hdr;
584 int size;
585
586 hdr = (struct vmbus_channel_message_header *)msg->u.payload;
587 size = msg->header.payload_size;
588
589 if (hdr->msgtype >= CHANNELMSG_COUNT) {
590 pr_err("Received invalid channel message type %d size %d\n",
591 hdr->msgtype, size);
592 print_hex_dump_bytes("", DUMP_PREFIX_NONE,
593 (unsigned char *)msg->u.payload, size);
594 return;
595 }
596
597 if (channel_message_table[hdr->msgtype].message_handler)
598 channel_message_table[hdr->msgtype].message_handler(hdr);
599 else
600 pr_err("Unhandled channel message type %d\n", hdr->msgtype);
601}
602
603/*
604 * vmbus_request_offers - Send a request to get all our pending offers.
605 */
606int vmbus_request_offers(void)
607{
608 struct vmbus_channel_message_header *msg;
609 struct vmbus_channel_msginfo *msginfo;
610 int ret, t;
611
612 msginfo = kmalloc(sizeof(*msginfo) +
613 sizeof(struct vmbus_channel_message_header),
614 GFP_KERNEL);
615 if (!msginfo)
616 return -ENOMEM;
617
618 init_completion(&msginfo->waitevent);
619
620 msg = (struct vmbus_channel_message_header *)msginfo->msg;
621
622 msg->msgtype = CHANNELMSG_REQUESTOFFERS;
623
624
625 ret = vmbus_post_msg(msg,
626 sizeof(struct vmbus_channel_message_header));
627 if (ret != 0) {
628 pr_err("Unable to request offers - %d\n", ret);
629
630 goto cleanup;
631 }
632
633 t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
634 if (t == 0) {
635 ret = -ETIMEDOUT;
636 goto cleanup;
637 }
638
639
640
641cleanup:
642 kfree(msginfo);
643
644 return ret;
645}
646
647/* eof */
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
new file mode 100644
index 000000000000..5f438b650068
--- /dev/null
+++ b/drivers/hv/connection.c
@@ -0,0 +1,318 @@
1/*
2 *
3 * Copyright (c) 2009, Microsoft Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 * Authors:
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
21 *
22 */
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/wait.h>
28#include <linux/delay.h>
29#include <linux/mm.h>
30#include <linux/slab.h>
31#include <linux/vmalloc.h>
32#include <linux/hyperv.h>
33
34#include "hyperv_vmbus.h"
35
36
37struct vmbus_connection vmbus_connection = {
38 .conn_state = DISCONNECTED,
39 .next_gpadl_handle = ATOMIC_INIT(0xE1E10),
40};
41
42/*
43 * vmbus_connect - Sends a connect request on the partition service connection
44 */
45int vmbus_connect(void)
46{
47 int ret = 0;
48 int t;
49 struct vmbus_channel_msginfo *msginfo = NULL;
50 struct vmbus_channel_initiate_contact *msg;
51 unsigned long flags;
52
53 /* Initialize the vmbus connection */
54 vmbus_connection.conn_state = CONNECTING;
55 vmbus_connection.work_queue = create_workqueue("hv_vmbus_con");
56 if (!vmbus_connection.work_queue) {
57 ret = -ENOMEM;
58 goto cleanup;
59 }
60
61 INIT_LIST_HEAD(&vmbus_connection.chn_msg_list);
62 spin_lock_init(&vmbus_connection.channelmsg_lock);
63
64 INIT_LIST_HEAD(&vmbus_connection.chn_list);
65 spin_lock_init(&vmbus_connection.channel_lock);
66
67 /*
68 * Setup the vmbus event connection for channel interrupt
69 * abstraction stuff
70 */
71 vmbus_connection.int_page =
72 (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0);
73 if (vmbus_connection.int_page == NULL) {
74 ret = -ENOMEM;
75 goto cleanup;
76 }
77
78 vmbus_connection.recv_int_page = vmbus_connection.int_page;
79 vmbus_connection.send_int_page =
80 (void *)((unsigned long)vmbus_connection.int_page +
81 (PAGE_SIZE >> 1));
82
83 /*
84 * Setup the monitor notification facility. The 1st page for
85 * parent->child and the 2nd page for child->parent
86 */
87 vmbus_connection.monitor_pages =
88 (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1);
89 if (vmbus_connection.monitor_pages == NULL) {
90 ret = -ENOMEM;
91 goto cleanup;
92 }
93
94 msginfo = kzalloc(sizeof(*msginfo) +
95 sizeof(struct vmbus_channel_initiate_contact),
96 GFP_KERNEL);
97 if (msginfo == NULL) {
98 ret = -ENOMEM;
99 goto cleanup;
100 }
101
102 init_completion(&msginfo->waitevent);
103
104 msg = (struct vmbus_channel_initiate_contact *)msginfo->msg;
105
106 msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT;
107 msg->vmbus_version_requested = VMBUS_REVISION_NUMBER;
108 msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
109 msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages);
110 msg->monitor_page2 = virt_to_phys(
111 (void *)((unsigned long)vmbus_connection.monitor_pages +
112 PAGE_SIZE));
113
114 /*
115 * Add to list before we send the request since we may
116 * receive the response before returning from this routine
117 */
118 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
119 list_add_tail(&msginfo->msglistentry,
120 &vmbus_connection.chn_msg_list);
121
122 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
123
124 ret = vmbus_post_msg(msg,
125 sizeof(struct vmbus_channel_initiate_contact));
126 if (ret != 0) {
127 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
128 list_del(&msginfo->msglistentry);
129 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock,
130 flags);
131 goto cleanup;
132 }
133
134 /* Wait for the connection response */
135 t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
136 if (t == 0) {
137 spin_lock_irqsave(&vmbus_connection.channelmsg_lock,
138 flags);
139 list_del(&msginfo->msglistentry);
140 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock,
141 flags);
142 ret = -ETIMEDOUT;
143 goto cleanup;
144 }
145
146 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
147 list_del(&msginfo->msglistentry);
148 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
149
150 /* Check if successful */
151 if (msginfo->response.version_response.version_supported) {
152 vmbus_connection.conn_state = CONNECTED;
153 } else {
154 pr_err("Unable to connect, "
155 "Version %d not supported by Hyper-V\n",
156 VMBUS_REVISION_NUMBER);
157 ret = -ECONNREFUSED;
158 goto cleanup;
159 }
160
161 kfree(msginfo);
162 return 0;
163
164cleanup:
165 vmbus_connection.conn_state = DISCONNECTED;
166
167 if (vmbus_connection.work_queue)
168 destroy_workqueue(vmbus_connection.work_queue);
169
170 if (vmbus_connection.int_page) {
171 free_pages((unsigned long)vmbus_connection.int_page, 0);
172 vmbus_connection.int_page = NULL;
173 }
174
175 if (vmbus_connection.monitor_pages) {
176 free_pages((unsigned long)vmbus_connection.monitor_pages, 1);
177 vmbus_connection.monitor_pages = NULL;
178 }
179
180 kfree(msginfo);
181
182 return ret;
183}
184
185
186/*
187 * relid2channel - Get the channel object given its
188 * child relative id (ie channel id)
189 */
190struct vmbus_channel *relid2channel(u32 relid)
191{
192 struct vmbus_channel *channel;
193 struct vmbus_channel *found_channel = NULL;
194 unsigned long flags;
195
196 spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
197 list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
198 if (channel->offermsg.child_relid == relid) {
199 found_channel = channel;
200 break;
201 }
202 }
203 spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
204
205 return found_channel;
206}
207
208/*
209 * process_chn_event - Process a channel event notification
210 */
211static void process_chn_event(u32 relid)
212{
213 struct vmbus_channel *channel;
214 unsigned long flags;
215
216 /*
217 * Find the channel based on this relid and invokes the
218 * channel callback to process the event
219 */
220 channel = relid2channel(relid);
221
222 if (!channel) {
223 pr_err("channel not found for relid - %u\n", relid);
224 return;
225 }
226
227 /*
228 * A channel once created is persistent even when there
229 * is no driver handling the device. An unloading driver
230 * sets the onchannel_callback to NULL under the
231 * protection of the channel inbound_lock. Thus, checking
232 * and invoking the driver specific callback takes care of
233 * orderly unloading of the driver.
234 */
235
236 spin_lock_irqsave(&channel->inbound_lock, flags);
237 if (channel->onchannel_callback != NULL)
238 channel->onchannel_callback(channel->channel_callback_context);
239 else
240 pr_err("no channel callback for relid - %u\n", relid);
241
242 spin_unlock_irqrestore(&channel->inbound_lock, flags);
243}
244
245/*
246 * vmbus_on_event - Handler for events
247 */
248void vmbus_on_event(unsigned long data)
249{
250 u32 dword;
251 u32 maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
252 int bit;
253 u32 relid;
254 u32 *recv_int_page = vmbus_connection.recv_int_page;
255
256 /* Check events */
257 if (!recv_int_page)
258 return;
259 for (dword = 0; dword < maxdword; dword++) {
260 if (!recv_int_page[dword])
261 continue;
262 for (bit = 0; bit < 32; bit++) {
263 if (sync_test_and_clear_bit(bit,
264 (unsigned long *)&recv_int_page[dword])) {
265 relid = (dword << 5) + bit;
266
267 if (relid == 0)
268 /*
269 * Special case - vmbus
270 * channel protocol msg
271 */
272 continue;
273
274 process_chn_event(relid);
275 }
276 }
277 }
278}
279
280/*
281 * vmbus_post_msg - Send a msg on the vmbus's message connection
282 */
283int vmbus_post_msg(void *buffer, size_t buflen)
284{
285 union hv_connection_id conn_id;
286 int ret = 0;
287 int retries = 0;
288
289 conn_id.asu32 = 0;
290 conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
291
292 /*
293 * hv_post_message() can have transient failures because of
294 * insufficient resources. Retry the operation a couple of
295 * times before giving up.
296 */
297 while (retries < 3) {
298 ret = hv_post_message(conn_id, 1, buffer, buflen);
299 if (ret != HV_STATUS_INSUFFICIENT_BUFFERS)
300 return ret;
301 retries++;
302 msleep(100);
303 }
304 return ret;
305}
306
307/*
308 * vmbus_set_event - Send an event notification to the parent
309 */
310int vmbus_set_event(u32 child_relid)
311{
312 /* Each u32 represents 32 channels */
313 sync_set_bit(child_relid & 31,
314 (unsigned long *)vmbus_connection.send_int_page +
315 (child_relid >> 5));
316
317 return hv_signal_event();
318}
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
new file mode 100644
index 000000000000..931b7b030784
--- /dev/null
+++ b/drivers/hv/hv.c
@@ -0,0 +1,429 @@
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 */
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24#include <linux/kernel.h>
25#include <linux/mm.h>
26#include <linux/slab.h>
27#include <linux/vmalloc.h>
28#include <linux/hyperv.h>
29
30#include "hyperv_vmbus.h"
31
32/* The one and only */
33struct hv_context hv_context = {
34 .synic_initialized = false,
35 .hypercall_page = NULL,
36 .signal_event_param = NULL,
37 .signal_event_buffer = NULL,
38};
39
40/*
41 * query_hypervisor_presence
42 * - Query the cpuid for presence of windows hypervisor
43 */
44static int query_hypervisor_presence(void)
45{
46 unsigned int eax;
47 unsigned int ebx;
48 unsigned int ecx;
49 unsigned int edx;
50 unsigned int op;
51
52 eax = 0;
53 ebx = 0;
54 ecx = 0;
55 edx = 0;
56 op = HVCPUID_VERSION_FEATURES;
57 cpuid(op, &eax, &ebx, &ecx, &edx);
58
59 return ecx & HV_PRESENT_BIT;
60}
61
62/*
63 * query_hypervisor_info - Get version info of the windows hypervisor
64 */
65static int query_hypervisor_info(void)
66{
67 unsigned int eax;
68 unsigned int ebx;
69 unsigned int ecx;
70 unsigned int edx;
71 unsigned int max_leaf;
72 unsigned int op;
73
74 /*
75 * Its assumed that this is called after confirming that Viridian
76 * is present. Query id and revision.
77 */
78 eax = 0;
79 ebx = 0;
80 ecx = 0;
81 edx = 0;
82 op = HVCPUID_VENDOR_MAXFUNCTION;
83 cpuid(op, &eax, &ebx, &ecx, &edx);
84
85 max_leaf = eax;
86
87 if (max_leaf >= HVCPUID_VERSION) {
88 eax = 0;
89 ebx = 0;
90 ecx = 0;
91 edx = 0;
92 op = HVCPUID_VERSION;
93 cpuid(op, &eax, &ebx, &ecx, &edx);
94 pr_info("Hyper-V Host OS Build:%d-%d.%d-%d-%d.%d\n",
95 eax,
96 ebx >> 16,
97 ebx & 0xFFFF,
98 ecx,
99 edx >> 24,
100 edx & 0xFFFFFF);
101 }
102 return max_leaf;
103}
104
105/*
106 * do_hypercall- Invoke the specified hypercall
107 */
108static u64 do_hypercall(u64 control, void *input, void *output)
109{
110#ifdef CONFIG_X86_64
111 u64 hv_status = 0;
112 u64 input_address = (input) ? virt_to_phys(input) : 0;
113 u64 output_address = (output) ? virt_to_phys(output) : 0;
114 void *hypercall_page = hv_context.hypercall_page;
115
116 __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
117 __asm__ __volatile__("call *%3" : "=a" (hv_status) :
118 "c" (control), "d" (input_address),
119 "m" (hypercall_page));
120
121 return hv_status;
122
123#else
124
125 u32 control_hi = control >> 32;
126 u32 control_lo = control & 0xFFFFFFFF;
127 u32 hv_status_hi = 1;
128 u32 hv_status_lo = 1;
129 u64 input_address = (input) ? virt_to_phys(input) : 0;
130 u32 input_address_hi = input_address >> 32;
131 u32 input_address_lo = input_address & 0xFFFFFFFF;
132 u64 output_address = (output) ? virt_to_phys(output) : 0;
133 u32 output_address_hi = output_address >> 32;
134 u32 output_address_lo = output_address & 0xFFFFFFFF;
135 void *hypercall_page = hv_context.hypercall_page;
136
137 __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
138 "=a"(hv_status_lo) : "d" (control_hi),
139 "a" (control_lo), "b" (input_address_hi),
140 "c" (input_address_lo), "D"(output_address_hi),
141 "S"(output_address_lo), "m" (hypercall_page));
142
143 return hv_status_lo | ((u64)hv_status_hi << 32);
144#endif /* !x86_64 */
145}
146
147/*
148 * hv_init - Main initialization routine.
149 *
150 * This routine must be called before any other routines in here are called
151 */
152int hv_init(void)
153{
154 int max_leaf;
155 union hv_x64_msr_hypercall_contents hypercall_msr;
156 void *virtaddr = NULL;
157
158 memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS);
159 memset(hv_context.synic_message_page, 0,
160 sizeof(void *) * MAX_NUM_CPUS);
161
162 if (!query_hypervisor_presence())
163 goto cleanup;
164
165 max_leaf = query_hypervisor_info();
166
167 rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);
168
169 if (hv_context.guestid != 0)
170 goto cleanup;
171
172 /* Write our OS info */
173 wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
174 hv_context.guestid = HV_LINUX_GUEST_ID;
175
176 /* See if the hypercall page is already set */
177 rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
178
179 virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC);
180
181 if (!virtaddr)
182 goto cleanup;
183
184 hypercall_msr.enable = 1;
185
186 hypercall_msr.guest_physical_address = vmalloc_to_pfn(virtaddr);
187 wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
188
189 /* Confirm that hypercall page did get setup. */
190 hypercall_msr.as_uint64 = 0;
191 rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
192
193 if (!hypercall_msr.enable)
194 goto cleanup;
195
196 hv_context.hypercall_page = virtaddr;
197
198 /* Setup the global signal event param for the signal event hypercall */
199 hv_context.signal_event_buffer =
200 kmalloc(sizeof(struct hv_input_signal_event_buffer),
201 GFP_KERNEL);
202 if (!hv_context.signal_event_buffer)
203 goto cleanup;
204
205 hv_context.signal_event_param =
206 (struct hv_input_signal_event *)
207 (ALIGN((unsigned long)
208 hv_context.signal_event_buffer,
209 HV_HYPERCALL_PARAM_ALIGN));
210 hv_context.signal_event_param->connectionid.asu32 = 0;
211 hv_context.signal_event_param->connectionid.u.id =
212 VMBUS_EVENT_CONNECTION_ID;
213 hv_context.signal_event_param->flag_number = 0;
214 hv_context.signal_event_param->rsvdz = 0;
215
216 return 0;
217
218cleanup:
219 if (virtaddr) {
220 if (hypercall_msr.enable) {
221 hypercall_msr.as_uint64 = 0;
222 wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
223 }
224
225 vfree(virtaddr);
226 }
227
228 return -ENOTSUPP;
229}
230
231/*
232 * hv_cleanup - Cleanup routine.
233 *
234 * This routine is called normally during driver unloading or exiting.
235 */
236void hv_cleanup(void)
237{
238 union hv_x64_msr_hypercall_contents hypercall_msr;
239
240 kfree(hv_context.signal_event_buffer);
241 hv_context.signal_event_buffer = NULL;
242 hv_context.signal_event_param = NULL;
243
244 if (hv_context.hypercall_page) {
245 hypercall_msr.as_uint64 = 0;
246 wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
247 vfree(hv_context.hypercall_page);
248 hv_context.hypercall_page = NULL;
249 }
250}
251
252/*
253 * hv_post_message - Post a message using the hypervisor message IPC.
254 *
255 * This involves a hypercall.
256 */
257u16 hv_post_message(union hv_connection_id connection_id,
258 enum hv_message_type message_type,
259 void *payload, size_t payload_size)
260{
261 struct aligned_input {
262 u64 alignment8;
263 struct hv_input_post_message msg;
264 };
265
266 struct hv_input_post_message *aligned_msg;
267 u16 status;
268 unsigned long addr;
269
270 if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
271 return -EMSGSIZE;
272
273 addr = (unsigned long)kmalloc(sizeof(struct aligned_input), GFP_ATOMIC);
274 if (!addr)
275 return -ENOMEM;
276
277 aligned_msg = (struct hv_input_post_message *)
278 (ALIGN(addr, HV_HYPERCALL_PARAM_ALIGN));
279
280 aligned_msg->connectionid = connection_id;
281 aligned_msg->message_type = message_type;
282 aligned_msg->payload_size = payload_size;
283 memcpy((void *)aligned_msg->payload, payload, payload_size);
284
285 status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
286 & 0xFFFF;
287
288 kfree((void *)addr);
289
290 return status;
291}
292
293
294/*
295 * hv_signal_event -
296 * Signal an event on the specified connection using the hypervisor event IPC.
297 *
298 * This involves a hypercall.
299 */
300u16 hv_signal_event(void)
301{
302 u16 status;
303
304 status = do_hypercall(HVCALL_SIGNAL_EVENT,
305 hv_context.signal_event_param,
306 NULL) & 0xFFFF;
307 return status;
308}
309
310/*
311 * hv_synic_init - Initialize the Synthethic Interrupt Controller.
312 *
313 * If it is already initialized by another entity (ie x2v shim), we need to
314 * retrieve the initialized message and event pages. Otherwise, we create and
315 * initialize the message and event pages.
316 */
317void hv_synic_init(void *irqarg)
318{
319 u64 version;
320 union hv_synic_simp simp;
321 union hv_synic_siefp siefp;
322 union hv_synic_sint shared_sint;
323 union hv_synic_scontrol sctrl;
324
325 u32 irq_vector = *((u32 *)(irqarg));
326 int cpu = smp_processor_id();
327
328 if (!hv_context.hypercall_page)
329 return;
330
331 /* Check the version */
332 rdmsrl(HV_X64_MSR_SVERSION, version);
333
334 hv_context.synic_message_page[cpu] =
335 (void *)get_zeroed_page(GFP_ATOMIC);
336
337 if (hv_context.synic_message_page[cpu] == NULL) {
338 pr_err("Unable to allocate SYNIC message page\n");
339 goto cleanup;
340 }
341
342 hv_context.synic_event_page[cpu] =
343 (void *)get_zeroed_page(GFP_ATOMIC);
344
345 if (hv_context.synic_event_page[cpu] == NULL) {
346 pr_err("Unable to allocate SYNIC event page\n");
347 goto cleanup;
348 }
349
350 /* Setup the Synic's message page */
351 rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
352 simp.simp_enabled = 1;
353 simp.base_simp_gpa = virt_to_phys(hv_context.synic_message_page[cpu])
354 >> PAGE_SHIFT;
355
356 wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
357
358 /* Setup the Synic's event page */
359 rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
360 siefp.siefp_enabled = 1;
361 siefp.base_siefp_gpa = virt_to_phys(hv_context.synic_event_page[cpu])
362 >> PAGE_SHIFT;
363
364 wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
365
366 /* Setup the shared SINT. */
367 rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
368
369 shared_sint.as_uint64 = 0;
370 shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
371 shared_sint.masked = false;
372 shared_sint.auto_eoi = false;
373
374 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
375
376 /* Enable the global synic bit */
377 rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
378 sctrl.enable = 1;
379
380 wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
381
382 hv_context.synic_initialized = true;
383 return;
384
385cleanup:
386 if (hv_context.synic_event_page[cpu])
387 free_page((unsigned long)hv_context.synic_event_page[cpu]);
388
389 if (hv_context.synic_message_page[cpu])
390 free_page((unsigned long)hv_context.synic_message_page[cpu]);
391 return;
392}
393
394/*
395 * hv_synic_cleanup - Cleanup routine for hv_synic_init().
396 */
397void hv_synic_cleanup(void *arg)
398{
399 union hv_synic_sint shared_sint;
400 union hv_synic_simp simp;
401 union hv_synic_siefp siefp;
402 int cpu = smp_processor_id();
403
404 if (!hv_context.synic_initialized)
405 return;
406
407 rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
408
409 shared_sint.masked = 1;
410
411 /* Need to correctly cleanup in the case of SMP!!! */
412 /* Disable the interrupt */
413 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
414
415 rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
416 simp.simp_enabled = 0;
417 simp.base_simp_gpa = 0;
418
419 wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
420
421 rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
422 siefp.siefp_enabled = 0;
423 siefp.base_siefp_gpa = 0;
424
425 wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
426
427 free_page((unsigned long)hv_context.synic_message_page[cpu]);
428 free_page((unsigned long)hv_context.synic_event_page[cpu]);
429}
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
new file mode 100644
index 000000000000..69c4c985daeb
--- /dev/null
+++ b/drivers/hv/hv_kvp.c
@@ -0,0 +1,339 @@
1/*
2 * An implementation of key value pair (KVP) functionality for Linux.
3 *
4 *
5 * Copyright (C) 2010, Novell, Inc.
6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/net.h>
26#include <linux/nls.h>
27#include <linux/connector.h>
28#include <linux/workqueue.h>
29#include <linux/hyperv.h>
30
31#include "hv_kvp.h"
32
33
34
35/*
36 * Global state maintained for transaction that is being processed.
37 * Note that only one transaction can be active at any point in time.
38 *
39 * This state is set when we receive a request from the host; we
40 * cleanup this state when the transaction is completed - when we respond
41 * to the host with the key value.
42 */
43
44static struct {
45 bool active; /* transaction status - active or not */
46 int recv_len; /* number of bytes received. */
47 int index; /* current index */
48 struct vmbus_channel *recv_channel; /* chn we got the request */
49 u64 recv_req_id; /* request ID. */
50} kvp_transaction;
51
52static void kvp_send_key(struct work_struct *dummy);
53
54#define TIMEOUT_FIRED 1
55
56static void kvp_respond_to_host(char *key, char *value, int error);
57static void kvp_work_func(struct work_struct *dummy);
58static void kvp_register(void);
59
60static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func);
61static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
62
63static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL };
64static const char kvp_name[] = "kvp_kernel_module";
65static u8 *recv_buffer;
66/*
67 * Register the kernel component with the user-level daemon.
68 * As part of this registration, pass the LIC version number.
69 */
70
71static void
72kvp_register(void)
73{
74
75 struct cn_msg *msg;
76
77 msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC);
78
79 if (msg) {
80 msg->id.idx = CN_KVP_IDX;
81 msg->id.val = CN_KVP_VAL;
82 msg->seq = KVP_REGISTER;
83 strcpy(msg->data, HV_DRV_VERSION);
84 msg->len = strlen(HV_DRV_VERSION) + 1;
85 cn_netlink_send(msg, 0, GFP_ATOMIC);
86 kfree(msg);
87 }
88}
89static void
90kvp_work_func(struct work_struct *dummy)
91{
92 /*
93 * If the timer fires, the user-mode component has not responded;
94 * process the pending transaction.
95 */
96 kvp_respond_to_host("Unknown key", "Guest timed out", TIMEOUT_FIRED);
97}
98
99/*
100 * Callback when data is received from user mode.
101 */
102
103static void
104kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
105{
106 struct hv_ku_msg *message;
107
108 message = (struct hv_ku_msg *)msg->data;
109 if (msg->seq == KVP_REGISTER) {
110 pr_info("KVP: user-mode registering done.\n");
111 kvp_register();
112 }
113
114 if (msg->seq == KVP_USER_SET) {
115 /*
116 * Complete the transaction by forwarding the key value
117 * to the host. But first, cancel the timeout.
118 */
119 if (cancel_delayed_work_sync(&kvp_work))
120 kvp_respond_to_host(message->kvp_key,
121 message->kvp_value,
122 !strlen(message->kvp_key));
123 }
124}
125
126static void
127kvp_send_key(struct work_struct *dummy)
128{
129 struct cn_msg *msg;
130 int index = kvp_transaction.index;
131
132 msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
133
134 if (msg) {
135 msg->id.idx = CN_KVP_IDX;
136 msg->id.val = CN_KVP_VAL;
137 msg->seq = KVP_KERNEL_GET;
138 ((struct hv_ku_msg *)msg->data)->kvp_index = index;
139 msg->len = sizeof(struct hv_ku_msg);
140 cn_netlink_send(msg, 0, GFP_ATOMIC);
141 kfree(msg);
142 }
143 return;
144}
145
146/*
147 * Send a response back to the host.
148 */
149
150static void
151kvp_respond_to_host(char *key, char *value, int error)
152{
153 struct hv_kvp_msg *kvp_msg;
154 struct hv_kvp_msg_enumerate *kvp_data;
155 char *key_name;
156 struct icmsg_hdr *icmsghdrp;
157 int keylen, valuelen;
158 u32 buf_len;
159 struct vmbus_channel *channel;
160 u64 req_id;
161
162 /*
163 * If a transaction is not active; log and return.
164 */
165
166 if (!kvp_transaction.active) {
167 /*
168 * This is a spurious call!
169 */
170 pr_warn("KVP: Transaction not active\n");
171 return;
172 }
173 /*
174 * Copy the global state for completing the transaction. Note that
175 * only one transaction can be active at a time.
176 */
177
178 buf_len = kvp_transaction.recv_len;
179 channel = kvp_transaction.recv_channel;
180 req_id = kvp_transaction.recv_req_id;
181
182 kvp_transaction.active = false;
183
184 if (channel->onchannel_callback == NULL)
185 /*
186 * We have raced with util driver being unloaded;
187 * silently return.
188 */
189 return;
190
191 icmsghdrp = (struct icmsg_hdr *)
192 &recv_buffer[sizeof(struct vmbuspipe_hdr)];
193 kvp_msg = (struct hv_kvp_msg *)
194 &recv_buffer[sizeof(struct vmbuspipe_hdr) +
195 sizeof(struct icmsg_hdr)];
196 kvp_data = &kvp_msg->kvp_data;
197 key_name = key;
198
199 /*
200 * If the error parameter is set, terminate the host's enumeration.
201 */
202 if (error) {
203 /*
204 * We don't support this index or the we have timedout;
205 * terminate the host-side iteration by returning an error.
206 */
207 icmsghdrp->status = HV_E_FAIL;
208 goto response_done;
209 }
210
211 /*
212 * The windows host expects the key/value pair to be encoded
213 * in utf16.
214 */
215 keylen = utf8s_to_utf16s(key_name, strlen(key_name),
216 (wchar_t *)kvp_data->data.key);
217 kvp_data->data.key_size = 2*(keylen + 1); /* utf16 encoding */
218 valuelen = utf8s_to_utf16s(value, strlen(value),
219 (wchar_t *)kvp_data->data.value);
220 kvp_data->data.value_size = 2*(valuelen + 1); /* utf16 encoding */
221
222 kvp_data->data.value_type = REG_SZ; /* all our values are strings */
223 icmsghdrp->status = HV_S_OK;
224
225response_done:
226 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
227
228 vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
229 VM_PKT_DATA_INBAND, 0);
230
231}
232
233/*
234 * This callback is invoked when we get a KVP message from the host.
235 * The host ensures that only one KVP transaction can be active at a time.
236 * KVP implementation in Linux needs to forward the key to a user-mde
237 * component to retrive the corresponding value. Consequently, we cannot
238 * respond to the host in the conext of this callback. Since the host
239 * guarantees that at most only one transaction can be active at a time,
240 * we stash away the transaction state in a set of global variables.
241 */
242
243void hv_kvp_onchannelcallback(void *context)
244{
245 struct vmbus_channel *channel = context;
246 u32 recvlen;
247 u64 requestid;
248
249 struct hv_kvp_msg *kvp_msg;
250 struct hv_kvp_msg_enumerate *kvp_data;
251
252 struct icmsg_hdr *icmsghdrp;
253 struct icmsg_negotiate *negop = NULL;
254
255
256 vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid);
257
258 if (recvlen > 0) {
259 icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
260 sizeof(struct vmbuspipe_hdr)];
261
262 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
263 prep_negotiate_resp(icmsghdrp, negop, recv_buffer);
264 } else {
265 kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
266 sizeof(struct vmbuspipe_hdr) +
267 sizeof(struct icmsg_hdr)];
268
269 kvp_data = &kvp_msg->kvp_data;
270
271 /*
272 * We only support the "get" operation on
273 * "KVP_POOL_AUTO" pool.
274 */
275
276 if ((kvp_msg->kvp_hdr.pool != KVP_POOL_AUTO) ||
277 (kvp_msg->kvp_hdr.operation !=
278 KVP_OP_ENUMERATE)) {
279 icmsghdrp->status = HV_E_FAIL;
280 goto callback_done;
281 }
282
283 /*
284 * Stash away this global state for completing the
285 * transaction; note transactions are serialized.
286 */
287 kvp_transaction.recv_len = recvlen;
288 kvp_transaction.recv_channel = channel;
289 kvp_transaction.recv_req_id = requestid;
290 kvp_transaction.active = true;
291 kvp_transaction.index = kvp_data->index;
292
293 /*
294 * Get the information from the
295 * user-mode component.
296 * component. This transaction will be
297 * completed when we get the value from
298 * the user-mode component.
299 * Set a timeout to deal with
300 * user-mode not responding.
301 */
302 schedule_work(&kvp_sendkey_work);
303 schedule_delayed_work(&kvp_work, 5*HZ);
304
305 return;
306
307 }
308
309callback_done:
310
311 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
312 | ICMSGHDRFLAG_RESPONSE;
313
314 vmbus_sendpacket(channel, recv_buffer,
315 recvlen, requestid,
316 VM_PKT_DATA_INBAND, 0);
317 }
318
319}
320
321int
322hv_kvp_init(struct hv_util_service *srv)
323{
324 int err;
325
326 err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback);
327 if (err)
328 return err;
329 recv_buffer = srv->recv_buffer;
330
331 return 0;
332}
333
334void hv_kvp_deinit(void)
335{
336 cn_del_callback(&kvp_id);
337 cancel_delayed_work_sync(&kvp_work);
338 cancel_work_sync(&kvp_sendkey_work);
339}
diff --git a/drivers/hv/hv_kvp.h b/drivers/hv/hv_kvp.h
new file mode 100644
index 000000000000..9b765d7df838
--- /dev/null
+++ b/drivers/hv/hv_kvp.h
@@ -0,0 +1,184 @@
1/*
2 * An implementation of HyperV key value pair (KVP) functionality for Linux.
3 *
4 *
5 * Copyright (C) 2010, Novell, Inc.
6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23#ifndef _KVP_H
24#define _KVP_H_
25
26/*
27 * Maximum value size - used for both key names and value data, and includes
28 * any applicable NULL terminators.
29 *
30 * Note: This limit is somewhat arbitrary, but falls easily within what is
31 * supported for all native guests (back to Win 2000) and what is reasonable
32 * for the IC KVP exchange functionality. Note that Windows Me/98/95 are
33 * limited to 255 character key names.
34 *
35 * MSDN recommends not storing data values larger than 2048 bytes in the
36 * registry.
37 *
38 * Note: This value is used in defining the KVP exchange message - this value
39 * cannot be modified without affecting the message size and compatibility.
40 */
41
42/*
43 * bytes, including any null terminators
44 */
45#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048)
46
47
48/*
49 * Maximum key size - the registry limit for the length of an entry name
50 * is 256 characters, including the null terminator
51 */
52
53#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512)
54
55/*
56 * In Linux, we implement the KVP functionality in two components:
57 * 1) The kernel component which is packaged as part of the hv_utils driver
58 * is responsible for communicating with the host and responsible for
59 * implementing the host/guest protocol. 2) A user level daemon that is
60 * responsible for data gathering.
61 *
62 * Host/Guest Protocol: The host iterates over an index and expects the guest
63 * to assign a key name to the index and also return the value corresponding to
64 * the key. The host will have atmost one KVP transaction outstanding at any
65 * given point in time. The host side iteration stops when the guest returns
66 * an error. Microsoft has specified the following mapping of key names to
67 * host specified index:
68 *
69 * Index Key Name
70 * 0 FullyQualifiedDomainName
71 * 1 IntegrationServicesVersion
72 * 2 NetworkAddressIPv4
73 * 3 NetworkAddressIPv6
74 * 4 OSBuildNumber
75 * 5 OSName
76 * 6 OSMajorVersion
77 * 7 OSMinorVersion
78 * 8 OSVersion
79 * 9 ProcessorArchitecture
80 *
81 * The Windows host expects the Key Name and Key Value to be encoded in utf16.
82 *
83 * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the
84 * data gathering functionality in a user mode daemon. The user level daemon
85 * is also responsible for binding the key name to the index as well. The
86 * kernel and user-level daemon communicate using a connector channel.
87 *
88 * The user mode component first registers with the
89 * the kernel component. Subsequently, the kernel component requests, data
90 * for the specified keys. In response to this message the user mode component
91 * fills in the value corresponding to the specified key. We overload the
92 * sequence field in the cn_msg header to define our KVP message types.
93 *
94 *
95 * The kernel component simply acts as a conduit for communication between the
96 * Windows host and the user-level daemon. The kernel component passes up the
97 * index received from the Host to the user-level daemon. If the index is
98 * valid (supported), the corresponding key as well as its
99 * value (both are strings) is returned. If the index is invalid
100 * (not supported), a NULL key string is returned.
101 */
102
103/*
104 *
105 * The following definitions are shared with the user-mode component; do not
106 * change any of this without making the corresponding changes in
107 * the KVP user-mode component.
108 */
109
110#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */
111#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */
112
113enum hv_ku_op {
114 KVP_REGISTER = 0, /* Register the user mode component */
115 KVP_KERNEL_GET, /* Kernel is requesting the value */
116 KVP_KERNEL_SET, /* Kernel is providing the value */
117 KVP_USER_GET, /* User is requesting the value */
118 KVP_USER_SET /* User is providing the value */
119};
120
121struct hv_ku_msg {
122 __u32 kvp_index; /* Key index */
123 __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */
124 __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */
125};
126
127
128
129
130#ifdef __KERNEL__
131
132/*
133 * Registry value types.
134 */
135
136#define REG_SZ 1
137
138enum hv_kvp_exchg_op {
139 KVP_OP_GET = 0,
140 KVP_OP_SET,
141 KVP_OP_DELETE,
142 KVP_OP_ENUMERATE,
143 KVP_OP_COUNT /* Number of operations, must be last. */
144};
145
146enum hv_kvp_exchg_pool {
147 KVP_POOL_EXTERNAL = 0,
148 KVP_POOL_GUEST,
149 KVP_POOL_AUTO,
150 KVP_POOL_AUTO_EXTERNAL,
151 KVP_POOL_AUTO_INTERNAL,
152 KVP_POOL_COUNT /* Number of pools, must be last. */
153};
154
155struct hv_kvp_hdr {
156 u8 operation;
157 u8 pool;
158};
159
160struct hv_kvp_exchg_msg_value {
161 u32 value_type;
162 u32 key_size;
163 u32 value_size;
164 u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
165 u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
166};
167
168struct hv_kvp_msg_enumerate {
169 u32 index;
170 struct hv_kvp_exchg_msg_value data;
171};
172
173struct hv_kvp_msg {
174 struct hv_kvp_hdr kvp_hdr;
175 struct hv_kvp_msg_enumerate kvp_data;
176};
177
178int hv_kvp_init(struct hv_util_service *);
179void hv_kvp_deinit(void);
180void hv_kvp_onchannelcallback(void *);
181
182#endif /* __KERNEL__ */
183#endif /* _KVP_H */
184
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
new file mode 100644
index 000000000000..e0e3a6d0244d
--- /dev/null
+++ b/drivers/hv/hv_util.c
@@ -0,0 +1,354 @@
1/*
2 * Copyright (c) 2010, 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/init.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/sysctl.h>
28#include <linux/reboot.h>
29#include <linux/hyperv.h>
30
31#include "hv_kvp.h"
32
33
34static void shutdown_onchannelcallback(void *context);
35static struct hv_util_service util_shutdown = {
36 .util_cb = shutdown_onchannelcallback,
37};
38
39static void timesync_onchannelcallback(void *context);
40static struct hv_util_service util_timesynch = {
41 .util_cb = timesync_onchannelcallback,
42};
43
44static void heartbeat_onchannelcallback(void *context);
45static struct hv_util_service util_heartbeat = {
46 .util_cb = heartbeat_onchannelcallback,
47};
48
49static struct hv_util_service util_kvp = {
50 .util_cb = hv_kvp_onchannelcallback,
51 .util_init = hv_kvp_init,
52 .util_deinit = hv_kvp_deinit,
53};
54
55static void shutdown_onchannelcallback(void *context)
56{
57 struct vmbus_channel *channel = context;
58 u32 recvlen;
59 u64 requestid;
60 u8 execute_shutdown = false;
61 u8 *shut_txf_buf = util_shutdown.recv_buffer;
62
63 struct shutdown_msg_data *shutdown_msg;
64
65 struct icmsg_hdr *icmsghdrp;
66 struct icmsg_negotiate *negop = NULL;
67
68 vmbus_recvpacket(channel, shut_txf_buf,
69 PAGE_SIZE, &recvlen, &requestid);
70
71 if (recvlen > 0) {
72 icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[
73 sizeof(struct vmbuspipe_hdr)];
74
75 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
76 prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf);
77 } else {
78 shutdown_msg =
79 (struct shutdown_msg_data *)&shut_txf_buf[
80 sizeof(struct vmbuspipe_hdr) +
81 sizeof(struct icmsg_hdr)];
82
83 switch (shutdown_msg->flags) {
84 case 0:
85 case 1:
86 icmsghdrp->status = HV_S_OK;
87 execute_shutdown = true;
88
89 pr_info("Shutdown request received -"
90 " graceful shutdown initiated\n");
91 break;
92 default:
93 icmsghdrp->status = HV_E_FAIL;
94 execute_shutdown = false;
95
96 pr_info("Shutdown request received -"
97 " Invalid request\n");
98 break;
99 }
100 }
101
102 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
103 | ICMSGHDRFLAG_RESPONSE;
104
105 vmbus_sendpacket(channel, shut_txf_buf,
106 recvlen, requestid,
107 VM_PKT_DATA_INBAND, 0);
108 }
109
110 if (execute_shutdown == true)
111 orderly_poweroff(true);
112}
113
114/*
115 * Set guest time to host UTC time.
116 */
117static inline void do_adj_guesttime(u64 hosttime)
118{
119 s64 host_tns;
120 struct timespec host_ts;
121
122 host_tns = (hosttime - WLTIMEDELTA) * 100;
123 host_ts = ns_to_timespec(host_tns);
124
125 do_settimeofday(&host_ts);
126}
127
128/*
129 * Set the host time in a process context.
130 */
131
132struct adj_time_work {
133 struct work_struct work;
134 u64 host_time;
135};
136
137static void hv_set_host_time(struct work_struct *work)
138{
139 struct adj_time_work *wrk;
140
141 wrk = container_of(work, struct adj_time_work, work);
142 do_adj_guesttime(wrk->host_time);
143 kfree(wrk);
144}
145
146/*
147 * Synchronize time with host after reboot, restore, etc.
148 *
149 * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM.
150 * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time
151 * message after the timesync channel is opened. Since the hv_utils module is
152 * loaded after hv_vmbus, the first message is usually missed. The other
153 * thing is, systime is automatically set to emulated hardware clock which may
154 * not be UTC time or in the same time zone. So, to override these effects, we
155 * use the first 50 time samples for initial system time setting.
156 */
157static inline void adj_guesttime(u64 hosttime, u8 flags)
158{
159 struct adj_time_work *wrk;
160 static s32 scnt = 50;
161
162 wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC);
163 if (wrk == NULL)
164 return;
165
166 wrk->host_time = hosttime;
167 if ((flags & ICTIMESYNCFLAG_SYNC) != 0) {
168 INIT_WORK(&wrk->work, hv_set_host_time);
169 schedule_work(&wrk->work);
170 return;
171 }
172
173 if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) {
174 scnt--;
175 INIT_WORK(&wrk->work, hv_set_host_time);
176 schedule_work(&wrk->work);
177 } else
178 kfree(wrk);
179}
180
181/*
182 * Time Sync Channel message handler.
183 */
184static void timesync_onchannelcallback(void *context)
185{
186 struct vmbus_channel *channel = context;
187 u32 recvlen;
188 u64 requestid;
189 struct icmsg_hdr *icmsghdrp;
190 struct ictimesync_data *timedatap;
191 u8 *time_txf_buf = util_timesynch.recv_buffer;
192
193 vmbus_recvpacket(channel, time_txf_buf,
194 PAGE_SIZE, &recvlen, &requestid);
195
196 if (recvlen > 0) {
197 icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
198 sizeof(struct vmbuspipe_hdr)];
199
200 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
201 prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf);
202 } else {
203 timedatap = (struct ictimesync_data *)&time_txf_buf[
204 sizeof(struct vmbuspipe_hdr) +
205 sizeof(struct icmsg_hdr)];
206 adj_guesttime(timedatap->parenttime, timedatap->flags);
207 }
208
209 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
210 | ICMSGHDRFLAG_RESPONSE;
211
212 vmbus_sendpacket(channel, time_txf_buf,
213 recvlen, requestid,
214 VM_PKT_DATA_INBAND, 0);
215 }
216}
217
218/*
219 * Heartbeat functionality.
220 * Every two seconds, Hyper-V send us a heartbeat request message.
221 * we respond to this message, and Hyper-V knows we are alive.
222 */
223static void heartbeat_onchannelcallback(void *context)
224{
225 struct vmbus_channel *channel = context;
226 u32 recvlen;
227 u64 requestid;
228 struct icmsg_hdr *icmsghdrp;
229 struct heartbeat_msg_data *heartbeat_msg;
230 u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
231
232 vmbus_recvpacket(channel, hbeat_txf_buf,
233 PAGE_SIZE, &recvlen, &requestid);
234
235 if (recvlen > 0) {
236 icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[
237 sizeof(struct vmbuspipe_hdr)];
238
239 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
240 prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf);
241 } else {
242 heartbeat_msg =
243 (struct heartbeat_msg_data *)&hbeat_txf_buf[
244 sizeof(struct vmbuspipe_hdr) +
245 sizeof(struct icmsg_hdr)];
246
247 heartbeat_msg->seq_num += 1;
248 }
249
250 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
251 | ICMSGHDRFLAG_RESPONSE;
252
253 vmbus_sendpacket(channel, hbeat_txf_buf,
254 recvlen, requestid,
255 VM_PKT_DATA_INBAND, 0);
256 }
257}
258
259static int util_probe(struct hv_device *dev,
260 const struct hv_vmbus_device_id *dev_id)
261{
262 struct hv_util_service *srv =
263 (struct hv_util_service *)dev_id->driver_data;
264 int ret;
265
266 srv->recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
267 if (!srv->recv_buffer)
268 return -ENOMEM;
269 if (srv->util_init) {
270 ret = srv->util_init(srv);
271 if (ret) {
272 ret = -ENODEV;
273 goto error1;
274 }
275 }
276
277 ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0,
278 srv->util_cb, dev->channel);
279 if (ret)
280 goto error;
281
282 hv_set_drvdata(dev, srv);
283 return 0;
284
285error:
286 if (srv->util_deinit)
287 srv->util_deinit();
288error1:
289 kfree(srv->recv_buffer);
290 return ret;
291}
292
293static int util_remove(struct hv_device *dev)
294{
295 struct hv_util_service *srv = hv_get_drvdata(dev);
296
297 vmbus_close(dev->channel);
298 if (srv->util_deinit)
299 srv->util_deinit();
300 kfree(srv->recv_buffer);
301
302 return 0;
303}
304
305static const struct hv_vmbus_device_id id_table[] = {
306 /* Shutdown guid */
307 { VMBUS_DEVICE(0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
308 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB)
309 .driver_data = (unsigned long)&util_shutdown },
310 /* Time synch guid */
311 { VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
312 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
313 .driver_data = (unsigned long)&util_timesynch },
314 /* Heartbeat guid */
315 { VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
316 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
317 .driver_data = (unsigned long)&util_heartbeat },
318 /* KVP guid */
319 { VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
320 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6)
321 .driver_data = (unsigned long)&util_kvp },
322 { },
323};
324
325MODULE_DEVICE_TABLE(vmbus, id_table);
326
327/* The one and only one */
328static struct hv_driver util_drv = {
329 .name = "hv_util",
330 .id_table = id_table,
331 .probe = util_probe,
332 .remove = util_remove,
333};
334
335static int __init init_hyperv_utils(void)
336{
337 pr_info("Registering HyperV Utility Driver\n");
338
339 return vmbus_driver_register(&util_drv);
340}
341
342static void exit_hyperv_utils(void)
343{
344 pr_info("De-Registered HyperV Utility Driver\n");
345
346 vmbus_driver_unregister(&util_drv);
347}
348
349module_init(init_hyperv_utils);
350module_exit(exit_hyperv_utils);
351
352MODULE_DESCRIPTION("Hyper-V Utilities");
353MODULE_VERSION(HV_DRV_VERSION);
354MODULE_LICENSE("GPL");
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
new file mode 100644
index 000000000000..8261cb64931b
--- /dev/null
+++ b/drivers/hv/hyperv_vmbus.h
@@ -0,0 +1,628 @@
1/*
2 *
3 * Copyright (c) 2011, Microsoft Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 * Authors:
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
21 * K. Y. Srinivasan <kys@microsoft.com>
22 *
23 */
24
25#ifndef _HYPERV_VMBUS_H
26#define _HYPERV_VMBUS_H
27
28#include <linux/list.h>
29#include <asm/sync_bitops.h>
30#include <linux/atomic.h>
31#include <linux/hyperv.h>
32
33/*
34 * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
35 * is set by CPUID(HVCPUID_VERSION_FEATURES).
36 */
37enum hv_cpuid_function {
38 HVCPUID_VERSION_FEATURES = 0x00000001,
39 HVCPUID_VENDOR_MAXFUNCTION = 0x40000000,
40 HVCPUID_INTERFACE = 0x40000001,
41
42 /*
43 * The remaining functions depend on the value of
44 * HVCPUID_INTERFACE
45 */
46 HVCPUID_VERSION = 0x40000002,
47 HVCPUID_FEATURES = 0x40000003,
48 HVCPUID_ENLIGHTENMENT_INFO = 0x40000004,
49 HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005,
50};
51
52/* Define version of the synthetic interrupt controller. */
53#define HV_SYNIC_VERSION (1)
54
55/* Define the expected SynIC version. */
56#define HV_SYNIC_VERSION_1 (0x1)
57
58/* Define synthetic interrupt controller message constants. */
59#define HV_MESSAGE_SIZE (256)
60#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
61#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
62#define HV_ANY_VP (0xFFFFFFFF)
63
64/* Define synthetic interrupt controller flag constants. */
65#define HV_EVENT_FLAGS_COUNT (256 * 8)
66#define HV_EVENT_FLAGS_BYTE_COUNT (256)
67#define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(u32))
68
69/* Define hypervisor message types. */
70enum hv_message_type {
71 HVMSG_NONE = 0x00000000,
72
73 /* Memory access messages. */
74 HVMSG_UNMAPPED_GPA = 0x80000000,
75 HVMSG_GPA_INTERCEPT = 0x80000001,
76
77 /* Timer notification messages. */
78 HVMSG_TIMER_EXPIRED = 0x80000010,
79
80 /* Error messages. */
81 HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
82 HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
83 HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
84
85 /* Trace buffer complete messages. */
86 HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
87
88 /* Platform-specific processor intercept messages. */
89 HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
90 HVMSG_X64_MSR_INTERCEPT = 0x80010001,
91 HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
92 HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
93 HVMSG_X64_APIC_EOI = 0x80010004,
94 HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
95};
96
97/* Define the number of synthetic interrupt sources. */
98#define HV_SYNIC_SINT_COUNT (16)
99#define HV_SYNIC_STIMER_COUNT (4)
100
101/* Define invalid partition identifier. */
102#define HV_PARTITION_ID_INVALID ((u64)0x0)
103
104/* Define connection identifier type. */
105union hv_connection_id {
106 u32 asu32;
107 struct {
108 u32 id:24;
109 u32 reserved:8;
110 } u;
111};
112
113/* Define port identifier type. */
114union hv_port_id {
115 u32 asu32;
116 struct {
117 u32 id:24;
118 u32 reserved:8;
119 } u ;
120};
121
122/* Define port type. */
123enum hv_port_type {
124 HVPORT_MSG = 1,
125 HVPORT_EVENT = 2,
126 HVPORT_MONITOR = 3
127};
128
129/* Define port information structure. */
130struct hv_port_info {
131 enum hv_port_type port_type;
132 u32 padding;
133 union {
134 struct {
135 u32 target_sint;
136 u32 target_vp;
137 u64 rsvdz;
138 } message_port_info;
139 struct {
140 u32 target_sint;
141 u32 target_vp;
142 u16 base_flag_bumber;
143 u16 flag_count;
144 u32 rsvdz;
145 } event_port_info;
146 struct {
147 u64 monitor_address;
148 u64 rsvdz;
149 } monitor_port_info;
150 };
151};
152
153struct hv_connection_info {
154 enum hv_port_type port_type;
155 u32 padding;
156 union {
157 struct {
158 u64 rsvdz;
159 } message_connection_info;
160 struct {
161 u64 rsvdz;
162 } event_connection_info;
163 struct {
164 u64 monitor_address;
165 } monitor_connection_info;
166 };
167};
168
169/* Define synthetic interrupt controller message flags. */
170union hv_message_flags {
171 u8 asu8;
172 struct {
173 u8 msg_pending:1;
174 u8 reserved:7;
175 };
176};
177
178/* Define synthetic interrupt controller message header. */
179struct hv_message_header {
180 enum hv_message_type message_type;
181 u8 payload_size;
182 union hv_message_flags message_flags;
183 u8 reserved[2];
184 union {
185 u64 sender;
186 union hv_port_id port;
187 };
188};
189
190/* Define timer message payload structure. */
191struct hv_timer_message_payload {
192 u32 timer_index;
193 u32 reserved;
194 u64 expiration_time; /* When the timer expired */
195 u64 delivery_time; /* When the message was delivered */
196};
197
198/* Define synthetic interrupt controller message format. */
199struct hv_message {
200 struct hv_message_header header;
201 union {
202 u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
203 } u ;
204};
205
206/* Define the number of message buffers associated with each port. */
207#define HV_PORT_MESSAGE_BUFFER_COUNT (16)
208
209/* Define the synthetic interrupt message page layout. */
210struct hv_message_page {
211 struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
212};
213
214/* Define the synthetic interrupt controller event flags format. */
215union hv_synic_event_flags {
216 u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
217 u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT];
218};
219
220/* Define the synthetic interrupt flags page layout. */
221struct hv_synic_event_flags_page {
222 union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT];
223};
224
225/* Define SynIC control register. */
226union hv_synic_scontrol {
227 u64 as_uint64;
228 struct {
229 u64 enable:1;
230 u64 reserved:63;
231 };
232};
233
234/* Define synthetic interrupt source. */
235union hv_synic_sint {
236 u64 as_uint64;
237 struct {
238 u64 vector:8;
239 u64 reserved1:8;
240 u64 masked:1;
241 u64 auto_eoi:1;
242 u64 reserved2:46;
243 };
244};
245
246/* Define the format of the SIMP register */
247union hv_synic_simp {
248 u64 as_uint64;
249 struct {
250 u64 simp_enabled:1;
251 u64 preserved:11;
252 u64 base_simp_gpa:52;
253 };
254};
255
256/* Define the format of the SIEFP register */
257union hv_synic_siefp {
258 u64 as_uint64;
259 struct {
260 u64 siefp_enabled:1;
261 u64 preserved:11;
262 u64 base_siefp_gpa:52;
263 };
264};
265
266/* Definitions for the monitored notification facility */
267union hv_monitor_trigger_group {
268 u64 as_uint64;
269 struct {
270 u32 pending;
271 u32 armed;
272 };
273};
274
275struct hv_monitor_parameter {
276 union hv_connection_id connectionid;
277 u16 flagnumber;
278 u16 rsvdz;
279};
280
281union hv_monitor_trigger_state {
282 u32 asu32;
283
284 struct {
285 u32 group_enable:4;
286 u32 rsvdz:28;
287 };
288};
289
290/* struct hv_monitor_page Layout */
291/* ------------------------------------------------------ */
292/* | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) | */
293/* | 8 | TriggerGroup[0] | */
294/* | 10 | TriggerGroup[1] | */
295/* | 18 | TriggerGroup[2] | */
296/* | 20 | TriggerGroup[3] | */
297/* | 28 | Rsvd2[0] | */
298/* | 30 | Rsvd2[1] | */
299/* | 38 | Rsvd2[2] | */
300/* | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] | */
301/* | ... | */
302/* | 240 | Latency[0][0..3] | */
303/* | 340 | Rsvz3[0] | */
304/* | 440 | Parameter[0][0] | */
305/* | 448 | Parameter[0][1] | */
306/* | ... | */
307/* | 840 | Rsvd4[0] | */
308/* ------------------------------------------------------ */
309struct hv_monitor_page {
310 union hv_monitor_trigger_state trigger_state;
311 u32 rsvdz1;
312
313 union hv_monitor_trigger_group trigger_group[4];
314 u64 rsvdz2[3];
315
316 s32 next_checktime[4][32];
317
318 u16 latency[4][32];
319 u64 rsvdz3[32];
320
321 struct hv_monitor_parameter parameter[4][32];
322
323 u8 rsvdz4[1984];
324};
325
326/* Declare the various hypercall operations. */
327enum hv_call_code {
328 HVCALL_POST_MESSAGE = 0x005c,
329 HVCALL_SIGNAL_EVENT = 0x005d,
330};
331
332/* Definition of the hv_post_message hypercall input structure. */
333struct hv_input_post_message {
334 union hv_connection_id connectionid;
335 u32 reserved;
336 enum hv_message_type message_type;
337 u32 payload_size;
338 u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
339};
340
341/* Definition of the hv_signal_event hypercall input structure. */
342struct hv_input_signal_event {
343 union hv_connection_id connectionid;
344 u16 flag_number;
345 u16 rsvdz;
346};
347
348/*
349 * Versioning definitions used for guests reporting themselves to the
350 * hypervisor, and visa versa.
351 */
352
353/* Version info reported by guest OS's */
354enum hv_guest_os_vendor {
355 HVGUESTOS_VENDOR_MICROSOFT = 0x0001
356};
357
358enum hv_guest_os_microsoft_ids {
359 HVGUESTOS_MICROSOFT_UNDEFINED = 0x00,
360 HVGUESTOS_MICROSOFT_MSDOS = 0x01,
361 HVGUESTOS_MICROSOFT_WINDOWS3X = 0x02,
362 HVGUESTOS_MICROSOFT_WINDOWS9X = 0x03,
363 HVGUESTOS_MICROSOFT_WINDOWSNT = 0x04,
364 HVGUESTOS_MICROSOFT_WINDOWSCE = 0x05
365};
366
367/*
368 * Declare the MSR used to identify the guest OS.
369 */
370#define HV_X64_MSR_GUEST_OS_ID 0x40000000
371
372union hv_x64_msr_guest_os_id_contents {
373 u64 as_uint64;
374 struct {
375 u64 build_number:16;
376 u64 service_version:8; /* Service Pack, etc. */
377 u64 minor_version:8;
378 u64 major_version:8;
379 u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
380 u64 vendor_id:16; /* enum hv_guest_os_vendor */
381 };
382};
383
384/*
385 * Declare the MSR used to setup pages used to communicate with the hypervisor.
386 */
387#define HV_X64_MSR_HYPERCALL 0x40000001
388
389union hv_x64_msr_hypercall_contents {
390 u64 as_uint64;
391 struct {
392 u64 enable:1;
393 u64 reserved:11;
394 u64 guest_physical_address:52;
395 };
396};
397
398
399enum {
400 VMBUS_MESSAGE_CONNECTION_ID = 1,
401 VMBUS_MESSAGE_PORT_ID = 1,
402 VMBUS_EVENT_CONNECTION_ID = 2,
403 VMBUS_EVENT_PORT_ID = 2,
404 VMBUS_MONITOR_CONNECTION_ID = 3,
405 VMBUS_MONITOR_PORT_ID = 3,
406 VMBUS_MESSAGE_SINT = 2,
407};
408
409/* #defines */
410
411#define HV_PRESENT_BIT 0x80000000
412
413#define HV_LINUX_GUEST_ID_LO 0x00000000
414#define HV_LINUX_GUEST_ID_HI 0xB16B00B5
415#define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \
416 HV_LINUX_GUEST_ID_LO)
417
418#define HV_CPU_POWER_MANAGEMENT (1 << 0)
419#define HV_RECOMMENDATIONS_MAX 4
420
421#define HV_X64_MAX 5
422#define HV_CAPS_MAX 8
423
424
425#define HV_HYPERCALL_PARAM_ALIGN sizeof(u64)
426
427
428/* Service definitions */
429
430#define HV_SERVICE_PARENT_PORT (0)
431#define HV_SERVICE_PARENT_CONNECTION (0)
432
433#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS (0)
434#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER (1)
435#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE (2)
436#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED (3)
437
438#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID (1)
439#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID (2)
440#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID (3)
441#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID (4)
442#define HV_SERVICE_MAX_MESSAGE_ID (4)
443
444#define HV_SERVICE_PROTOCOL_VERSION (0x0010)
445#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64
446
447/* #define VMBUS_REVISION_NUMBER 6 */
448
449/* Our local vmbus's port and connection id. Anything >0 is fine */
450/* #define VMBUS_PORT_ID 11 */
451
452/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
453static const uuid_le VMBUS_SERVICE_ID = {
454 .b = {
455 0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
456 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
457 },
458};
459
460#define MAX_NUM_CPUS 32
461
462
463struct hv_input_signal_event_buffer {
464 u64 align8;
465 struct hv_input_signal_event event;
466};
467
468struct hv_context {
469 /* We only support running on top of Hyper-V
470 * So at this point this really can only contain the Hyper-V ID
471 */
472 u64 guestid;
473
474 void *hypercall_page;
475
476 bool synic_initialized;
477
478 /*
479 * This is used as an input param to HvCallSignalEvent hypercall. The
480 * input param is immutable in our usage and must be dynamic mem (vs
481 * stack or global). */
482 struct hv_input_signal_event_buffer *signal_event_buffer;
483 /* 8-bytes aligned of the buffer above */
484 struct hv_input_signal_event *signal_event_param;
485
486 void *synic_message_page[MAX_NUM_CPUS];
487 void *synic_event_page[MAX_NUM_CPUS];
488};
489
490extern struct hv_context hv_context;
491
492
493/* Hv Interface */
494
495extern int hv_init(void);
496
497extern void hv_cleanup(void);
498
499extern u16 hv_post_message(union hv_connection_id connection_id,
500 enum hv_message_type message_type,
501 void *payload, size_t payload_size);
502
503extern u16 hv_signal_event(void);
504
505extern void hv_synic_init(void *irqarg);
506
507extern void hv_synic_cleanup(void *arg);
508
509
510/* Interface */
511
512
513int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer,
514 u32 buflen);
515
516void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
517
518int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info,
519 struct scatterlist *sglist,
520 u32 sgcount);
521
522int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer,
523 u32 buflen);
524
525int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info,
526 void *buffer,
527 u32 buflen,
528 u32 offset);
529
530u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
531
532void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix);
533
534void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
535 struct hv_ring_buffer_debug_info *debug_info);
536
537/*
538 * Maximum channels is determined by the size of the interrupt page
539 * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
540 * and the other is receive endpoint interrupt
541 */
542#define MAX_NUM_CHANNELS ((PAGE_SIZE >> 1) << 3) /* 16348 channels */
543
544/* The value here must be in multiple of 32 */
545/* TODO: Need to make this configurable */
546#define MAX_NUM_CHANNELS_SUPPORTED 256
547
548
549enum vmbus_connect_state {
550 DISCONNECTED,
551 CONNECTING,
552 CONNECTED,
553 DISCONNECTING
554};
555
556#define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT
557
558struct vmbus_connection {
559 enum vmbus_connect_state conn_state;
560
561 atomic_t next_gpadl_handle;
562
563 /*
564 * Represents channel interrupts. Each bit position represents a
565 * channel. When a channel sends an interrupt via VMBUS, it finds its
566 * bit in the sendInterruptPage, set it and calls Hv to generate a port
567 * event. The other end receives the port event and parse the
568 * recvInterruptPage to see which bit is set
569 */
570 void *int_page;
571 void *send_int_page;
572 void *recv_int_page;
573
574 /*
575 * 2 pages - 1st page for parent->child notification and 2nd
576 * is child->parent notification
577 */
578 void *monitor_pages;
579 struct list_head chn_msg_list;
580 spinlock_t channelmsg_lock;
581
582 /* List of channels */
583 struct list_head chn_list;
584 spinlock_t channel_lock;
585
586 struct workqueue_struct *work_queue;
587};
588
589
590struct vmbus_msginfo {
591 /* Bookkeeping stuff */
592 struct list_head msglist_entry;
593
594 /* The message itself */
595 unsigned char msg[0];
596};
597
598
599extern struct vmbus_connection vmbus_connection;
600
601/* General vmbus interface */
602
603struct hv_device *vmbus_device_create(uuid_le *type,
604 uuid_le *instance,
605 struct vmbus_channel *channel);
606
607int vmbus_device_register(struct hv_device *child_device_obj);
608void vmbus_device_unregister(struct hv_device *device_obj);
609
610/* static void */
611/* VmbusChildDeviceDestroy( */
612/* struct hv_device *); */
613
614struct vmbus_channel *relid2channel(u32 relid);
615
616
617/* Connection interface */
618
619int vmbus_connect(void);
620
621int vmbus_post_msg(void *buffer, size_t buflen);
622
623int vmbus_set_event(u32 child_relid);
624
625void vmbus_on_event(unsigned long data);
626
627
628#endif /* _HYPERV_VMBUS_H */
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
new file mode 100644
index 000000000000..f594ed09d7e0
--- /dev/null
+++ b/drivers/hv/ring_buffer.c
@@ -0,0 +1,527 @@
1/*
2 *
3 * Copyright (c) 2009, Microsoft Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 * Authors:
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
21 * K. Y. Srinivasan <kys@microsoft.com>
22 *
23 */
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26#include <linux/kernel.h>
27#include <linux/mm.h>
28#include <linux/hyperv.h>
29
30#include "hyperv_vmbus.h"
31
32
33/* #defines */
34
35
36/* Amount of space to write to */
37#define BYTES_AVAIL_TO_WRITE(r, w, z) \
38 ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
39
40
41/*
42 *
43 * hv_get_ringbuffer_availbytes()
44 *
45 * Get number of bytes available to read and to write to
46 * for the specified ring buffer
47 */
48static inline void
49hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
50 u32 *read, u32 *write)
51{
52 u32 read_loc, write_loc;
53
54 smp_read_barrier_depends();
55
56 /* Capture the read/write indices before they changed */
57 read_loc = rbi->ring_buffer->read_index;
58 write_loc = rbi->ring_buffer->write_index;
59
60 *write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->ring_datasize);
61 *read = rbi->ring_datasize - *write;
62}
63
64/*
65 * hv_get_next_write_location()
66 *
67 * Get the next write location for the specified ring buffer
68 *
69 */
70static inline u32
71hv_get_next_write_location(struct hv_ring_buffer_info *ring_info)
72{
73 u32 next = ring_info->ring_buffer->write_index;
74
75 return next;
76}
77
78/*
79 * hv_set_next_write_location()
80 *
81 * Set the next write location for the specified ring buffer
82 *
83 */
84static inline void
85hv_set_next_write_location(struct hv_ring_buffer_info *ring_info,
86 u32 next_write_location)
87{
88 ring_info->ring_buffer->write_index = next_write_location;
89}
90
91/*
92 * hv_get_next_read_location()
93 *
94 * Get the next read location for the specified ring buffer
95 */
96static inline u32
97hv_get_next_read_location(struct hv_ring_buffer_info *ring_info)
98{
99 u32 next = ring_info->ring_buffer->read_index;
100
101 return next;
102}
103
104/*
105 * hv_get_next_readlocation_withoffset()
106 *
107 * Get the next read location + offset for the specified ring buffer.
108 * This allows the caller to skip
109 */
110static inline u32
111hv_get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
112 u32 offset)
113{
114 u32 next = ring_info->ring_buffer->read_index;
115
116 next += offset;
117 next %= ring_info->ring_datasize;
118
119 return next;
120}
121
122/*
123 *
124 * hv_set_next_read_location()
125 *
126 * Set the next read location for the specified ring buffer
127 *
128 */
129static inline void
130hv_set_next_read_location(struct hv_ring_buffer_info *ring_info,
131 u32 next_read_location)
132{
133 ring_info->ring_buffer->read_index = next_read_location;
134}
135
136
137/*
138 *
139 * hv_get_ring_buffer()
140 *
141 * Get the start of the ring buffer
142 */
143static inline void *
144hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
145{
146 return (void *)ring_info->ring_buffer->buffer;
147}
148
149
150/*
151 *
152 * hv_get_ring_buffersize()
153 *
154 * Get the size of the ring buffer
155 */
156static inline u32
157hv_get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
158{
159 return ring_info->ring_datasize;
160}
161
162/*
163 *
164 * hv_get_ring_bufferindices()
165 *
166 * Get the read and write indices as u64 of the specified ring buffer
167 *
168 */
169static inline u64
170hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
171{
172 return (u64)ring_info->ring_buffer->write_index << 32;
173}
174
175
176/*
177 *
178 * hv_dump_ring_info()
179 *
180 * Dump out to console the ring buffer info
181 *
182 */
183void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
184{
185 u32 bytes_avail_towrite;
186 u32 bytes_avail_toread;
187
188 hv_get_ringbuffer_availbytes(ring_info,
189 &bytes_avail_toread,
190 &bytes_avail_towrite);
191
192 DPRINT(VMBUS,
193 DEBUG_RING_LVL,
194 "%s <<ringinfo %p buffer %p avail write %u "
195 "avail read %u read idx %u write idx %u>>",
196 prefix,
197 ring_info,
198 ring_info->ring_buffer->buffer,
199 bytes_avail_towrite,
200 bytes_avail_toread,
201 ring_info->ring_buffer->read_index,
202 ring_info->ring_buffer->write_index);
203}
204
205
206/*
207 *
208 * hv_copyfrom_ringbuffer()
209 *
210 * Helper routine to copy to source from ring buffer.
211 * Assume there is enough room. Handles wrap-around in src case only!!
212 *
213 */
214static u32 hv_copyfrom_ringbuffer(
215 struct hv_ring_buffer_info *ring_info,
216 void *dest,
217 u32 destlen,
218 u32 start_read_offset)
219{
220 void *ring_buffer = hv_get_ring_buffer(ring_info);
221 u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
222
223 u32 frag_len;
224
225 /* wrap-around detected at the src */
226 if (destlen > ring_buffer_size - start_read_offset) {
227 frag_len = ring_buffer_size - start_read_offset;
228
229 memcpy(dest, ring_buffer + start_read_offset, frag_len);
230 memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
231 } else
232
233 memcpy(dest, ring_buffer + start_read_offset, destlen);
234
235
236 start_read_offset += destlen;
237 start_read_offset %= ring_buffer_size;
238
239 return start_read_offset;
240}
241
242
243/*
244 *
245 * hv_copyto_ringbuffer()
246 *
247 * Helper routine to copy from source to ring buffer.
248 * Assume there is enough room. Handles wrap-around in dest case only!!
249 *
250 */
251static u32 hv_copyto_ringbuffer(
252 struct hv_ring_buffer_info *ring_info,
253 u32 start_write_offset,
254 void *src,
255 u32 srclen)
256{
257 void *ring_buffer = hv_get_ring_buffer(ring_info);
258 u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
259 u32 frag_len;
260
261 /* wrap-around detected! */
262 if (srclen > ring_buffer_size - start_write_offset) {
263 frag_len = ring_buffer_size - start_write_offset;
264 memcpy(ring_buffer + start_write_offset, src, frag_len);
265 memcpy(ring_buffer, src + frag_len, srclen - frag_len);
266 } else
267 memcpy(ring_buffer + start_write_offset, src, srclen);
268
269 start_write_offset += srclen;
270 start_write_offset %= ring_buffer_size;
271
272 return start_write_offset;
273}
274
275/*
276 *
277 * hv_ringbuffer_get_debuginfo()
278 *
279 * Get various debug metrics for the specified ring buffer
280 *
281 */
282void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
283 struct hv_ring_buffer_debug_info *debug_info)
284{
285 u32 bytes_avail_towrite;
286 u32 bytes_avail_toread;
287
288 if (ring_info->ring_buffer) {
289 hv_get_ringbuffer_availbytes(ring_info,
290 &bytes_avail_toread,
291 &bytes_avail_towrite);
292
293 debug_info->bytes_avail_toread = bytes_avail_toread;
294 debug_info->bytes_avail_towrite = bytes_avail_towrite;
295 debug_info->current_read_index =
296 ring_info->ring_buffer->read_index;
297 debug_info->current_write_index =
298 ring_info->ring_buffer->write_index;
299 debug_info->current_interrupt_mask =
300 ring_info->ring_buffer->interrupt_mask;
301 }
302}
303
304
305/*
306 *
307 * hv_get_ringbuffer_interrupt_mask()
308 *
309 * Get the interrupt mask for the specified ring buffer
310 *
311 */
312u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
313{
314 return rbi->ring_buffer->interrupt_mask;
315}
316
317/*
318 *
319 * hv_ringbuffer_init()
320 *
321 *Initialize the ring buffer
322 *
323 */
324int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
325 void *buffer, u32 buflen)
326{
327 if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
328 return -EINVAL;
329
330 memset(ring_info, 0, sizeof(struct hv_ring_buffer_info));
331
332 ring_info->ring_buffer = (struct hv_ring_buffer *)buffer;
333 ring_info->ring_buffer->read_index =
334 ring_info->ring_buffer->write_index = 0;
335
336 ring_info->ring_size = buflen;
337 ring_info->ring_datasize = buflen - sizeof(struct hv_ring_buffer);
338
339 spin_lock_init(&ring_info->ring_lock);
340
341 return 0;
342}
343
344/*
345 *
346 * hv_ringbuffer_cleanup()
347 *
348 * Cleanup the ring buffer
349 *
350 */
351void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
352{
353}
354
355/*
356 *
357 * hv_ringbuffer_write()
358 *
359 * Write to the ring buffer
360 *
361 */
362int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
363 struct scatterlist *sglist, u32 sgcount)
364{
365 int i = 0;
366 u32 bytes_avail_towrite;
367 u32 bytes_avail_toread;
368 u32 totalbytes_towrite = 0;
369
370 struct scatterlist *sg;
371 u32 next_write_location;
372 u64 prev_indices = 0;
373 unsigned long flags;
374
375 for_each_sg(sglist, sg, sgcount, i)
376 {
377 totalbytes_towrite += sg->length;
378 }
379
380 totalbytes_towrite += sizeof(u64);
381
382 spin_lock_irqsave(&outring_info->ring_lock, flags);
383
384 hv_get_ringbuffer_availbytes(outring_info,
385 &bytes_avail_toread,
386 &bytes_avail_towrite);
387
388
389 /* If there is only room for the packet, assume it is full. */
390 /* Otherwise, the next time around, we think the ring buffer */
391 /* is empty since the read index == write index */
392 if (bytes_avail_towrite <= totalbytes_towrite) {
393 spin_unlock_irqrestore(&outring_info->ring_lock, flags);
394 return -EAGAIN;
395 }
396
397 /* Write to the ring buffer */
398 next_write_location = hv_get_next_write_location(outring_info);
399
400 for_each_sg(sglist, sg, sgcount, i)
401 {
402 next_write_location = hv_copyto_ringbuffer(outring_info,
403 next_write_location,
404 sg_virt(sg),
405 sg->length);
406 }
407
408 /* Set previous packet start */
409 prev_indices = hv_get_ring_bufferindices(outring_info);
410
411 next_write_location = hv_copyto_ringbuffer(outring_info,
412 next_write_location,
413 &prev_indices,
414 sizeof(u64));
415
416 /* Make sure we flush all writes before updating the writeIndex */
417 smp_wmb();
418
419 /* Now, update the write location */
420 hv_set_next_write_location(outring_info, next_write_location);
421
422
423 spin_unlock_irqrestore(&outring_info->ring_lock, flags);
424 return 0;
425}
426
427
428/*
429 *
430 * hv_ringbuffer_peek()
431 *
432 * Read without advancing the read index
433 *
434 */
435int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
436 void *Buffer, u32 buflen)
437{
438 u32 bytes_avail_towrite;
439 u32 bytes_avail_toread;
440 u32 next_read_location = 0;
441 unsigned long flags;
442
443 spin_lock_irqsave(&Inring_info->ring_lock, flags);
444
445 hv_get_ringbuffer_availbytes(Inring_info,
446 &bytes_avail_toread,
447 &bytes_avail_towrite);
448
449 /* Make sure there is something to read */
450 if (bytes_avail_toread < buflen) {
451
452 spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
453
454 return -EAGAIN;
455 }
456
457 /* Convert to byte offset */
458 next_read_location = hv_get_next_read_location(Inring_info);
459
460 next_read_location = hv_copyfrom_ringbuffer(Inring_info,
461 Buffer,
462 buflen,
463 next_read_location);
464
465 spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
466
467 return 0;
468}
469
470
471/*
472 *
473 * hv_ringbuffer_read()
474 *
475 * Read and advance the read index
476 *
477 */
478int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
479 u32 buflen, u32 offset)
480{
481 u32 bytes_avail_towrite;
482 u32 bytes_avail_toread;
483 u32 next_read_location = 0;
484 u64 prev_indices = 0;
485 unsigned long flags;
486
487 if (buflen <= 0)
488 return -EINVAL;
489
490 spin_lock_irqsave(&inring_info->ring_lock, flags);
491
492 hv_get_ringbuffer_availbytes(inring_info,
493 &bytes_avail_toread,
494 &bytes_avail_towrite);
495
496 /* Make sure there is something to read */
497 if (bytes_avail_toread < buflen) {
498 spin_unlock_irqrestore(&inring_info->ring_lock, flags);
499
500 return -EAGAIN;
501 }
502
503 next_read_location =
504 hv_get_next_readlocation_withoffset(inring_info, offset);
505
506 next_read_location = hv_copyfrom_ringbuffer(inring_info,
507 buffer,
508 buflen,
509 next_read_location);
510
511 next_read_location = hv_copyfrom_ringbuffer(inring_info,
512 &prev_indices,
513 sizeof(u64),
514 next_read_location);
515
516 /* Make sure all reads are done before we update the read index since */
517 /* the writer may start writing to the read area once the read index */
518 /*is updated */
519 smp_mb();
520
521 /* Update the read index */
522 hv_set_next_read_location(inring_info, next_read_location);
523
524 spin_unlock_irqrestore(&inring_info->ring_lock, flags);
525
526 return 0;
527}
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
new file mode 100644
index 000000000000..b0d08f980de1
--- /dev/null
+++ b/drivers/hv/vmbus_drv.c
@@ -0,0 +1,772 @@
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 * K. Y. Srinivasan <kys@microsoft.com>
21 *
22 */
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/device.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h>
30#include <linux/sysctl.h>
31#include <linux/slab.h>
32#include <linux/acpi.h>
33#include <acpi/acpi_bus.h>
34#include <linux/completion.h>
35#include <linux/hyperv.h>
36
37#include "hyperv_vmbus.h"
38
39
40static struct acpi_device *hv_acpi_dev;
41
42static struct tasklet_struct msg_dpc;
43static struct tasklet_struct event_dpc;
44
45unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL);
46EXPORT_SYMBOL(vmbus_loglevel);
47
48static struct completion probe_event;
49static int irq;
50
51static void get_channel_info(struct hv_device *device,
52 struct hv_device_info *info)
53{
54 struct vmbus_channel_debug_info debug_info;
55
56 if (!device->channel)
57 return;
58
59 vmbus_get_debug_info(device->channel, &debug_info);
60
61 info->chn_id = debug_info.relid;
62 info->chn_state = debug_info.state;
63 memcpy(&info->chn_type, &debug_info.interfacetype,
64 sizeof(uuid_le));
65 memcpy(&info->chn_instance, &debug_info.interface_instance,
66 sizeof(uuid_le));
67
68 info->monitor_id = debug_info.monitorid;
69
70 info->server_monitor_pending = debug_info.servermonitor_pending;
71 info->server_monitor_latency = debug_info.servermonitor_latency;
72 info->server_monitor_conn_id = debug_info.servermonitor_connectionid;
73
74 info->client_monitor_pending = debug_info.clientmonitor_pending;
75 info->client_monitor_latency = debug_info.clientmonitor_latency;
76 info->client_monitor_conn_id = debug_info.clientmonitor_connectionid;
77
78 info->inbound.int_mask = debug_info.inbound.current_interrupt_mask;
79 info->inbound.read_idx = debug_info.inbound.current_read_index;
80 info->inbound.write_idx = debug_info.inbound.current_write_index;
81 info->inbound.bytes_avail_toread =
82 debug_info.inbound.bytes_avail_toread;
83 info->inbound.bytes_avail_towrite =
84 debug_info.inbound.bytes_avail_towrite;
85
86 info->outbound.int_mask =
87 debug_info.outbound.current_interrupt_mask;
88 info->outbound.read_idx = debug_info.outbound.current_read_index;
89 info->outbound.write_idx = debug_info.outbound.current_write_index;
90 info->outbound.bytes_avail_toread =
91 debug_info.outbound.bytes_avail_toread;
92 info->outbound.bytes_avail_towrite =
93 debug_info.outbound.bytes_avail_towrite;
94}
95
96#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
97static void print_alias_name(struct hv_device *hv_dev, char *alias_name)
98{
99 int i;
100 for (i = 0; i < VMBUS_ALIAS_LEN; i += 2)
101 sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]);
102}
103
104/*
105 * vmbus_show_device_attr - Show the device attribute in sysfs.
106 *
107 * This is invoked when user does a
108 * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
109 */
110static ssize_t vmbus_show_device_attr(struct device *dev,
111 struct device_attribute *dev_attr,
112 char *buf)
113{
114 struct hv_device *hv_dev = device_to_hv_device(dev);
115 struct hv_device_info *device_info;
116 char alias_name[VMBUS_ALIAS_LEN + 1];
117 int ret = 0;
118
119 device_info = kzalloc(sizeof(struct hv_device_info), GFP_KERNEL);
120 if (!device_info)
121 return ret;
122
123 get_channel_info(hv_dev, device_info);
124
125 if (!strcmp(dev_attr->attr.name, "class_id")) {
126 ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
127 "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
128 device_info->chn_type.b[3],
129 device_info->chn_type.b[2],
130 device_info->chn_type.b[1],
131 device_info->chn_type.b[0],
132 device_info->chn_type.b[5],
133 device_info->chn_type.b[4],
134 device_info->chn_type.b[7],
135 device_info->chn_type.b[6],
136 device_info->chn_type.b[8],
137 device_info->chn_type.b[9],
138 device_info->chn_type.b[10],
139 device_info->chn_type.b[11],
140 device_info->chn_type.b[12],
141 device_info->chn_type.b[13],
142 device_info->chn_type.b[14],
143 device_info->chn_type.b[15]);
144 } else if (!strcmp(dev_attr->attr.name, "device_id")) {
145 ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
146 "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
147 device_info->chn_instance.b[3],
148 device_info->chn_instance.b[2],
149 device_info->chn_instance.b[1],
150 device_info->chn_instance.b[0],
151 device_info->chn_instance.b[5],
152 device_info->chn_instance.b[4],
153 device_info->chn_instance.b[7],
154 device_info->chn_instance.b[6],
155 device_info->chn_instance.b[8],
156 device_info->chn_instance.b[9],
157 device_info->chn_instance.b[10],
158 device_info->chn_instance.b[11],
159 device_info->chn_instance.b[12],
160 device_info->chn_instance.b[13],
161 device_info->chn_instance.b[14],
162 device_info->chn_instance.b[15]);
163 } else if (!strcmp(dev_attr->attr.name, "modalias")) {
164 print_alias_name(hv_dev, alias_name);
165 ret = sprintf(buf, "vmbus:%s\n", alias_name);
166 } else if (!strcmp(dev_attr->attr.name, "state")) {
167 ret = sprintf(buf, "%d\n", device_info->chn_state);
168 } else if (!strcmp(dev_attr->attr.name, "id")) {
169 ret = sprintf(buf, "%d\n", device_info->chn_id);
170 } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
171 ret = sprintf(buf, "%d\n", device_info->outbound.int_mask);
172 } else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
173 ret = sprintf(buf, "%d\n", device_info->outbound.read_idx);
174 } else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
175 ret = sprintf(buf, "%d\n", device_info->outbound.write_idx);
176 } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
177 ret = sprintf(buf, "%d\n",
178 device_info->outbound.bytes_avail_toread);
179 } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
180 ret = sprintf(buf, "%d\n",
181 device_info->outbound.bytes_avail_towrite);
182 } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
183 ret = sprintf(buf, "%d\n", device_info->inbound.int_mask);
184 } else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
185 ret = sprintf(buf, "%d\n", device_info->inbound.read_idx);
186 } else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
187 ret = sprintf(buf, "%d\n", device_info->inbound.write_idx);
188 } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
189 ret = sprintf(buf, "%d\n",
190 device_info->inbound.bytes_avail_toread);
191 } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
192 ret = sprintf(buf, "%d\n",
193 device_info->inbound.bytes_avail_towrite);
194 } else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
195 ret = sprintf(buf, "%d\n", device_info->monitor_id);
196 } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
197 ret = sprintf(buf, "%d\n", device_info->server_monitor_pending);
198 } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
199 ret = sprintf(buf, "%d\n", device_info->server_monitor_latency);
200 } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
201 ret = sprintf(buf, "%d\n",
202 device_info->server_monitor_conn_id);
203 } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
204 ret = sprintf(buf, "%d\n", device_info->client_monitor_pending);
205 } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
206 ret = sprintf(buf, "%d\n", device_info->client_monitor_latency);
207 } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
208 ret = sprintf(buf, "%d\n",
209 device_info->client_monitor_conn_id);
210 }
211
212 kfree(device_info);
213 return ret;
214}
215
216/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
217static struct device_attribute vmbus_device_attrs[] = {
218 __ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
219 __ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
220 __ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
221 __ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
222 __ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
223 __ATTR(modalias, S_IRUGO, vmbus_show_device_attr, NULL),
224
225 __ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
226 __ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
227 __ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
228
229 __ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
230 __ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
231 __ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
232
233 __ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
234 __ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
235 __ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
236 __ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
237 __ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
238
239 __ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
240 __ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
241 __ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
242 __ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
243 __ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
244 __ATTR_NULL
245};
246
247
248/*
249 * vmbus_uevent - add uevent for our device
250 *
251 * This routine is invoked when a device is added or removed on the vmbus to
252 * generate a uevent to udev in the userspace. The udev will then look at its
253 * rule and the uevent generated here to load the appropriate driver
254 *
255 * The alias string will be of the form vmbus:guid where guid is the string
256 * representation of the device guid (each byte of the guid will be
257 * represented with two hex characters.
258 */
259static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
260{
261 struct hv_device *dev = device_to_hv_device(device);
262 int ret;
263 char alias_name[VMBUS_ALIAS_LEN + 1];
264
265 print_alias_name(dev, alias_name);
266 ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name);
267 return ret;
268}
269
270static uuid_le null_guid;
271
272static inline bool is_null_guid(const __u8 *guid)
273{
274 if (memcmp(guid, &null_guid, sizeof(uuid_le)))
275 return false;
276 return true;
277}
278
279/*
280 * Return a matching hv_vmbus_device_id pointer.
281 * If there is no match, return NULL.
282 */
283static const struct hv_vmbus_device_id *hv_vmbus_get_id(
284 const struct hv_vmbus_device_id *id,
285 __u8 *guid)
286{
287 for (; !is_null_guid(id->guid); id++)
288 if (!memcmp(&id->guid, guid, sizeof(uuid_le)))
289 return id;
290
291 return NULL;
292}
293
294
295
296/*
297 * vmbus_match - Attempt to match the specified device to the specified driver
298 */
299static int vmbus_match(struct device *device, struct device_driver *driver)
300{
301 struct hv_driver *drv = drv_to_hv_drv(driver);
302 struct hv_device *hv_dev = device_to_hv_device(device);
303
304 if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b))
305 return 1;
306
307 return 0;
308}
309
310/*
311 * vmbus_probe - Add the new vmbus's child device
312 */
313static int vmbus_probe(struct device *child_device)
314{
315 int ret = 0;
316 struct hv_driver *drv =
317 drv_to_hv_drv(child_device->driver);
318 struct hv_device *dev = device_to_hv_device(child_device);
319 const struct hv_vmbus_device_id *dev_id;
320
321 dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b);
322 if (drv->probe) {
323 ret = drv->probe(dev, dev_id);
324 if (ret != 0)
325 pr_err("probe failed for device %s (%d)\n",
326 dev_name(child_device), ret);
327
328 } else {
329 pr_err("probe not set for driver %s\n",
330 dev_name(child_device));
331 ret = -ENODEV;
332 }
333 return ret;
334}
335
336/*
337 * vmbus_remove - Remove a vmbus device
338 */
339static int vmbus_remove(struct device *child_device)
340{
341 struct hv_driver *drv = drv_to_hv_drv(child_device->driver);
342 struct hv_device *dev = device_to_hv_device(child_device);
343
344 if (drv->remove)
345 drv->remove(dev);
346 else
347 pr_err("remove not set for driver %s\n",
348 dev_name(child_device));
349
350 return 0;
351}
352
353
354/*
355 * vmbus_shutdown - Shutdown a vmbus device
356 */
357static void vmbus_shutdown(struct device *child_device)
358{
359 struct hv_driver *drv;
360 struct hv_device *dev = device_to_hv_device(child_device);
361
362
363 /* The device may not be attached yet */
364 if (!child_device->driver)
365 return;
366
367 drv = drv_to_hv_drv(child_device->driver);
368
369 if (drv->shutdown)
370 drv->shutdown(dev);
371
372 return;
373}
374
375
376/*
377 * vmbus_device_release - Final callback release of the vmbus child device
378 */
379static void vmbus_device_release(struct device *device)
380{
381 struct hv_device *hv_dev = device_to_hv_device(device);
382
383 kfree(hv_dev);
384
385}
386
387/* The one and only one */
388static struct bus_type hv_bus = {
389 .name = "vmbus",
390 .match = vmbus_match,
391 .shutdown = vmbus_shutdown,
392 .remove = vmbus_remove,
393 .probe = vmbus_probe,
394 .uevent = vmbus_uevent,
395 .dev_attrs = vmbus_device_attrs,
396};
397
398static const char *driver_name = "hyperv";
399
400
401struct onmessage_work_context {
402 struct work_struct work;
403 struct hv_message msg;
404};
405
406static void vmbus_onmessage_work(struct work_struct *work)
407{
408 struct onmessage_work_context *ctx;
409
410 ctx = container_of(work, struct onmessage_work_context,
411 work);
412 vmbus_onmessage(&ctx->msg);
413 kfree(ctx);
414}
415
416static void vmbus_on_msg_dpc(unsigned long data)
417{
418 int cpu = smp_processor_id();
419 void *page_addr = hv_context.synic_message_page[cpu];
420 struct hv_message *msg = (struct hv_message *)page_addr +
421 VMBUS_MESSAGE_SINT;
422 struct onmessage_work_context *ctx;
423
424 while (1) {
425 if (msg->header.message_type == HVMSG_NONE) {
426 /* no msg */
427 break;
428 } else {
429 ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
430 if (ctx == NULL)
431 continue;
432 INIT_WORK(&ctx->work, vmbus_onmessage_work);
433 memcpy(&ctx->msg, msg, sizeof(*msg));
434 queue_work(vmbus_connection.work_queue, &ctx->work);
435 }
436
437 msg->header.message_type = HVMSG_NONE;
438
439 /*
440 * Make sure the write to MessageType (ie set to
441 * HVMSG_NONE) happens before we read the
442 * MessagePending and EOMing. Otherwise, the EOMing
443 * will not deliver any more messages since there is
444 * no empty slot
445 */
446 smp_mb();
447
448 if (msg->header.message_flags.msg_pending) {
449 /*
450 * This will cause message queue rescan to
451 * possibly deliver another msg from the
452 * hypervisor
453 */
454 wrmsrl(HV_X64_MSR_EOM, 0);
455 }
456 }
457}
458
459static irqreturn_t vmbus_isr(int irq, void *dev_id)
460{
461 int cpu = smp_processor_id();
462 void *page_addr;
463 struct hv_message *msg;
464 union hv_synic_event_flags *event;
465 bool handled = false;
466
467 /*
468 * Check for events before checking for messages. This is the order
469 * in which events and messages are checked in Windows guests on
470 * Hyper-V, and the Windows team suggested we do the same.
471 */
472
473 page_addr = hv_context.synic_event_page[cpu];
474 event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
475
476 /* Since we are a child, we only need to check bit 0 */
477 if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) {
478 handled = true;
479 tasklet_schedule(&event_dpc);
480 }
481
482 page_addr = hv_context.synic_message_page[cpu];
483 msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
484
485 /* Check if there are actual msgs to be processed */
486 if (msg->header.message_type != HVMSG_NONE) {
487 handled = true;
488 tasklet_schedule(&msg_dpc);
489 }
490
491 if (handled)
492 return IRQ_HANDLED;
493 else
494 return IRQ_NONE;
495}
496
497/*
498 * vmbus_bus_init -Main vmbus driver initialization routine.
499 *
500 * Here, we
501 * - initialize the vmbus driver context
502 * - invoke the vmbus hv main init routine
503 * - get the irq resource
504 * - retrieve the channel offers
505 */
506static int vmbus_bus_init(int irq)
507{
508 int ret;
509 unsigned int vector;
510
511 /* Hypervisor initialization...setup hypercall page..etc */
512 ret = hv_init();
513 if (ret != 0) {
514 pr_err("Unable to initialize the hypervisor - 0x%x\n", ret);
515 return ret;
516 }
517
518 tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
519 tasklet_init(&event_dpc, vmbus_on_event, 0);
520
521 ret = bus_register(&hv_bus);
522 if (ret)
523 goto err_cleanup;
524
525 ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
526 driver_name, hv_acpi_dev);
527
528 if (ret != 0) {
529 pr_err("Unable to request IRQ %d\n",
530 irq);
531 goto err_unregister;
532 }
533
534 vector = IRQ0_VECTOR + irq;
535
536 /*
537 * Notify the hypervisor of our irq and
538 * connect to the host.
539 */
540 on_each_cpu(hv_synic_init, (void *)&vector, 1);
541 ret = vmbus_connect();
542 if (ret)
543 goto err_irq;
544
545 vmbus_request_offers();
546
547 return 0;
548
549err_irq:
550 free_irq(irq, hv_acpi_dev);
551
552err_unregister:
553 bus_unregister(&hv_bus);
554
555err_cleanup:
556 hv_cleanup();
557
558 return ret;
559}
560
561/**
562 * __vmbus_child_driver_register - Register a vmbus's driver
563 * @drv: Pointer to driver structure you want to register
564 * @owner: owner module of the drv
565 * @mod_name: module name string
566 *
567 * Registers the given driver with Linux through the 'driver_register()' call
568 * and sets up the hyper-v vmbus handling for this driver.
569 * It will return the state of the 'driver_register()' call.
570 *
571 */
572int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, const char *mod_name)
573{
574 int ret;
575
576 pr_info("registering driver %s\n", hv_driver->name);
577
578 hv_driver->driver.name = hv_driver->name;
579 hv_driver->driver.owner = owner;
580 hv_driver->driver.mod_name = mod_name;
581 hv_driver->driver.bus = &hv_bus;
582
583 ret = driver_register(&hv_driver->driver);
584
585 vmbus_request_offers();
586
587 return ret;
588}
589EXPORT_SYMBOL_GPL(__vmbus_driver_register);
590
591/**
592 * vmbus_driver_unregister() - Unregister a vmbus's driver
593 * @drv: Pointer to driver structure you want to un-register
594 *
595 * Un-register the given driver that was previous registered with a call to
596 * vmbus_driver_register()
597 */
598void vmbus_driver_unregister(struct hv_driver *hv_driver)
599{
600 pr_info("unregistering driver %s\n", hv_driver->name);
601
602 driver_unregister(&hv_driver->driver);
603
604}
605EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
606
607/*
608 * vmbus_device_create - Creates and registers a new child device
609 * on the vmbus.
610 */
611struct hv_device *vmbus_device_create(uuid_le *type,
612 uuid_le *instance,
613 struct vmbus_channel *channel)
614{
615 struct hv_device *child_device_obj;
616
617 child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL);
618 if (!child_device_obj) {
619 pr_err("Unable to allocate device object for child device\n");
620 return NULL;
621 }
622
623 child_device_obj->channel = channel;
624 memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
625 memcpy(&child_device_obj->dev_instance, instance,
626 sizeof(uuid_le));
627
628
629 return child_device_obj;
630}
631
632/*
633 * vmbus_device_register - Register the child device
634 */
635int vmbus_device_register(struct hv_device *child_device_obj)
636{
637 int ret = 0;
638
639 static atomic_t device_num = ATOMIC_INIT(0);
640
641 dev_set_name(&child_device_obj->device, "vmbus_0_%d",
642 atomic_inc_return(&device_num));
643
644 child_device_obj->device.bus = &hv_bus;
645 child_device_obj->device.parent = &hv_acpi_dev->dev;
646 child_device_obj->device.release = vmbus_device_release;
647
648 /*
649 * Register with the LDM. This will kick off the driver/device
650 * binding...which will eventually call vmbus_match() and vmbus_probe()
651 */
652 ret = device_register(&child_device_obj->device);
653
654 if (ret)
655 pr_err("Unable to register child device\n");
656 else
657 pr_info("child device %s registered\n",
658 dev_name(&child_device_obj->device));
659
660 return ret;
661}
662
663/*
664 * vmbus_device_unregister - Remove the specified child device
665 * from the vmbus.
666 */
667void vmbus_device_unregister(struct hv_device *device_obj)
668{
669 /*
670 * Kick off the process of unregistering the device.
671 * This will call vmbus_remove() and eventually vmbus_device_release()
672 */
673 device_unregister(&device_obj->device);
674
675 pr_info("child device %s unregistered\n",
676 dev_name(&device_obj->device));
677}
678
679
680/*
681 * VMBUS is an acpi enumerated device. Get the the IRQ information
682 * from DSDT.
683 */
684
685static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *irq)
686{
687
688 if (res->type == ACPI_RESOURCE_TYPE_IRQ) {
689 struct acpi_resource_irq *irqp;
690 irqp = &res->data.irq;
691
692 *((unsigned int *)irq) = irqp->interrupts[0];
693 }
694
695 return AE_OK;
696}
697
698static int vmbus_acpi_add(struct acpi_device *device)
699{
700 acpi_status result;
701
702 hv_acpi_dev = device;
703
704 result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
705 vmbus_walk_resources, &irq);
706
707 if (ACPI_FAILURE(result)) {
708 complete(&probe_event);
709 return -ENODEV;
710 }
711 complete(&probe_event);
712 return 0;
713}
714
715static const struct acpi_device_id vmbus_acpi_device_ids[] = {
716 {"VMBUS", 0},
717 {"VMBus", 0},
718 {"", 0},
719};
720MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
721
722static struct acpi_driver vmbus_acpi_driver = {
723 .name = "vmbus",
724 .ids = vmbus_acpi_device_ids,
725 .ops = {
726 .add = vmbus_acpi_add,
727 },
728};
729
730static int __init hv_acpi_init(void)
731{
732 int ret, t;
733
734 init_completion(&probe_event);
735
736 /*
737 * Get irq resources first.
738 */
739
740 ret = acpi_bus_register_driver(&vmbus_acpi_driver);
741
742 if (ret)
743 return ret;
744
745 t = wait_for_completion_timeout(&probe_event, 5*HZ);
746 if (t == 0) {
747 ret = -ETIMEDOUT;
748 goto cleanup;
749 }
750
751 if (irq <= 0) {
752 ret = -ENODEV;
753 goto cleanup;
754 }
755
756 ret = vmbus_bus_init(irq);
757 if (ret)
758 goto cleanup;
759
760 return 0;
761
762cleanup:
763 acpi_bus_unregister_driver(&vmbus_acpi_driver);
764 return ret;
765}
766
767
768MODULE_LICENSE("GPL");
769MODULE_VERSION(HV_DRV_VERSION);
770module_param(vmbus_loglevel, int, S_IRUGO|S_IWUSR);
771
772module_init(hv_acpi_init);