Deleted Added
sdiff udiff text old ( 293871 ) new ( 294886 )
full compact
1/*-
2 * Copyright (c) 2009-2012 Microsoft Corp.
3 * Copyright (c) 2012 NetApp Inc.
4 * Copyright (c) 2012 Citrix Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice unmodified, this list of conditions, and the following
12 * disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/dev/hyperv/include/hyperv.h 294886 2016-01-27 03:53:30Z sephe $
29 */
30
31/**
32 * HyperV definitions for messages that are sent between instances of the
33 * Channel Management Library in separate partitions, or in some cases,
34 * back to itself.
35 */
36
37#ifndef __HYPERV_H__
38#define __HYPERV_H__
39
40#include <sys/param.h>
41#include <sys/mbuf.h>
42#include <sys/queue.h>
43#include <sys/malloc.h>
44#include <sys/kthread.h>
45#include <sys/taskqueue.h>
46#include <sys/systm.h>
47#include <sys/lock.h>
48#include <sys/sema.h>
49#include <sys/smp.h>
50#include <sys/mutex.h>
51#include <sys/bus.h>
52#include <vm/vm.h>
53#include <vm/vm_param.h>
54#include <vm/pmap.h>
55
56#include <amd64/include/xen/synch_bitops.h>
57#include <amd64/include/atomic.h>
58
59typedef uint8_t hv_bool_uint8_t;
60
61#define HV_S_OK 0x00000000
62#define HV_E_FAIL 0x80004005
63#define HV_ERROR_NOT_SUPPORTED 0x80070032
64#define HV_ERROR_MACHINE_LOCKED 0x800704F7
65
66/*
67 * VMBUS version is 32 bit, upper 16 bit for major_number and lower
68 * 16 bit for minor_number.
69 *
70 * 0.13 -- Windows Server 2008
71 * 1.1 -- Windows 7
72 * 2.4 -- Windows 8
73 * 3.0 -- Windows 8.1
74 */
75#define HV_VMBUS_VERSION_WS2008 ((0 << 16) | (13))
76#define HV_VMBUS_VERSION_WIN7 ((1 << 16) | (1))
77#define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4))
78#define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0))
79
80#define HV_VMBUS_VERSION_INVALID -1
81
82#define HV_VMBUS_VERSION_CURRENT HV_VMBUS_VERSION_WIN8_1
83
84/*
85 * Make maximum size of pipe payload of 16K
86 */
87
88#define HV_MAX_PIPE_DATA_PAYLOAD (sizeof(BYTE) * 16384)
89
90/*
91 * Define pipe_mode values
92 */
93
94#define HV_VMBUS_PIPE_TYPE_BYTE 0x00000000
95#define HV_VMBUS_PIPE_TYPE_MESSAGE 0x00000004
96
97/*
98 * The size of the user defined data buffer for non-pipe offers
99 */
100
101#define HV_MAX_USER_DEFINED_BYTES 120
102
103/*
104 * The size of the user defined data buffer for pipe offers
105 */
106
107#define HV_MAX_PIPE_USER_DEFINED_BYTES 116
108
109
110#define HV_MAX_PAGE_BUFFER_COUNT 32
111#define HV_MAX_MULTIPAGE_BUFFER_COUNT 32
112
113#define HV_ALIGN_UP(value, align) \
114 (((value) & (align-1)) ? \
115 (((value) + (align-1)) & ~(align-1) ) : (value))
116
117#define HV_ALIGN_DOWN(value, align) ( (value) & ~(align-1) )
118
119#define HV_NUM_PAGES_SPANNED(addr, len) \
120 ((HV_ALIGN_UP(addr+len, PAGE_SIZE) - \
121 HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT )
122
123typedef struct hv_guid {
124 unsigned char data[16];
125} __packed hv_guid;
126
127#define HV_NIC_GUID \
128 .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, \
129 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
130
131#define HV_IDE_GUID \
132 .data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \
133 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5}
134
135#define HV_SCSI_GUID \
136 .data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \
137 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f}
138
139/*
140 * At the center of the Channel Management library is
141 * the Channel Offer. This struct contains the
142 * fundamental information about an offer.
143 */
144
145typedef struct hv_vmbus_channel_offer {
146 hv_guid interface_type;
147 hv_guid interface_instance;
148 uint64_t interrupt_latency_in_100ns_units;
149 uint32_t interface_revision;
150 uint32_t server_context_area_size; /* in bytes */
151 uint16_t channel_flags;
152 uint16_t mmio_megabytes; /* in bytes * 1024 * 1024 */
153 union
154 {
155 /*
156 * Non-pipes: The user has HV_MAX_USER_DEFINED_BYTES bytes.
157 */
158 struct {
159 uint8_t user_defined[HV_MAX_USER_DEFINED_BYTES];
160 } __packed standard;
161
162 /*
163 * Pipes: The following structure is an integrated pipe protocol, which
164 * is implemented on top of standard user-defined data. pipe
165 * clients have HV_MAX_PIPE_USER_DEFINED_BYTES left for their
166 * own use.
167 */
168 struct {
169 uint32_t pipe_mode;
170 uint8_t user_defined[HV_MAX_PIPE_USER_DEFINED_BYTES];
171 } __packed pipe;
172 } u;
173
174 /*
175 * Sub_channel_index, newly added in Win8.
176 */
177 uint16_t sub_channel_index;
178 uint16_t padding;
179
180} __packed hv_vmbus_channel_offer;
181
182typedef uint32_t hv_gpadl_handle;
183
184typedef struct {
185 uint16_t type;
186 uint16_t data_offset8;
187 uint16_t length8;
188 uint16_t flags;
189 uint64_t transaction_id;
190} __packed hv_vm_packet_descriptor;
191
192typedef uint32_t hv_previous_packet_offset;
193
194typedef struct {
195 hv_previous_packet_offset previous_packet_start_offset;
196 hv_vm_packet_descriptor descriptor;
197} __packed hv_vm_packet_header;
198
199typedef struct {
200 uint32_t byte_count;
201 uint32_t byte_offset;
202} __packed hv_vm_transfer_page;
203
204typedef struct {
205 hv_vm_packet_descriptor d;
206 uint16_t transfer_page_set_id;
207 hv_bool_uint8_t sender_owns_set;
208 uint8_t reserved;
209 uint32_t range_count;
210 hv_vm_transfer_page ranges[1];
211} __packed hv_vm_transfer_page_packet_header;
212
213typedef struct {
214 hv_vm_packet_descriptor d;
215 uint32_t gpadl;
216 uint32_t reserved;
217} __packed hv_vm_gpadl_packet_header;
218
219typedef struct {
220 hv_vm_packet_descriptor d;
221 uint32_t gpadl;
222 uint16_t transfer_page_set_id;
223 uint16_t reserved;
224} __packed hv_vm_add_remove_transfer_page_set;
225
226/*
227 * This structure defines a range in guest
228 * physical space that can be made
229 * to look virtually contiguous.
230 */
231
232typedef struct {
233 uint32_t byte_count;
234 uint32_t byte_offset;
235 uint64_t pfn_array[0];
236} __packed hv_gpa_range;
237
238/*
239 * This is the format for an Establish Gpadl packet, which contains a handle
240 * by which this GPADL will be known and a set of GPA ranges associated with
241 * it. This can be converted to a MDL by the guest OS. If there are multiple
242 * GPA ranges, then the resulting MDL will be "chained," representing multiple
243 * VA ranges.
244 */
245
246typedef struct {
247 hv_vm_packet_descriptor d;
248 uint32_t gpadl;
249 uint32_t range_count;
250 hv_gpa_range range[1];
251} __packed hv_vm_establish_gpadl;
252
253/*
254 * This is the format for a Teardown Gpadl packet, which indicates that the
255 * GPADL handle in the Establish Gpadl packet will never be referenced again.
256 */
257
258typedef struct {
259 hv_vm_packet_descriptor d;
260 uint32_t gpadl;
261 /* for alignment to a 8-byte boundary */
262 uint32_t reserved;
263} __packed hv_vm_teardown_gpadl;
264
265/*
266 * This is the format for a GPA-Direct packet, which contains a set of GPA
267 * ranges, in addition to commands and/or data.
268 */
269
270typedef struct {
271 hv_vm_packet_descriptor d;
272 uint32_t reserved;
273 uint32_t range_count;
274 hv_gpa_range range[1];
275} __packed hv_vm_data_gpa_direct;
276
277/*
278 * This is the format for a Additional data Packet.
279 */
280typedef struct {
281 hv_vm_packet_descriptor d;
282 uint64_t total_bytes;
283 uint32_t byte_offset;
284 uint32_t byte_count;
285 uint8_t data[1];
286} __packed hv_vm_additional_data;
287
288typedef union {
289 hv_vm_packet_descriptor simple_header;
290 hv_vm_transfer_page_packet_header transfer_page_header;
291 hv_vm_gpadl_packet_header gpadl_header;
292 hv_vm_add_remove_transfer_page_set add_remove_transfer_page_header;
293 hv_vm_establish_gpadl establish_gpadl_header;
294 hv_vm_teardown_gpadl teardown_gpadl_header;
295 hv_vm_data_gpa_direct data_gpa_direct_header;
296} __packed hv_vm_packet_largest_possible_header;
297
298typedef enum {
299 HV_VMBUS_PACKET_TYPE_INVALID = 0x0,
300 HV_VMBUS_PACKET_TYPES_SYNCH = 0x1,
301 HV_VMBUS_PACKET_TYPE_ADD_TRANSFER_PAGE_SET = 0x2,
302 HV_VMBUS_PACKET_TYPE_REMOVE_TRANSFER_PAGE_SET = 0x3,
303 HV_VMBUS_PACKET_TYPE_ESTABLISH_GPADL = 0x4,
304 HV_VMBUS_PACKET_TYPE_TEAR_DOWN_GPADL = 0x5,
305 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND = 0x6,
306 HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES = 0x7,
307 HV_VMBUS_PACKET_TYPE_DATA_USING_GPADL = 0x8,
308 HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT = 0x9,
309 HV_VMBUS_PACKET_TYPE_CANCEL_REQUEST = 0xa,
310 HV_VMBUS_PACKET_TYPE_COMPLETION = 0xb,
311 HV_VMBUS_PACKET_TYPE_DATA_USING_ADDITIONAL_PACKETS = 0xc,
312 HV_VMBUS_PACKET_TYPE_ADDITIONAL_DATA = 0xd
313} hv_vmbus_packet_type;
314
315#define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1
316
317/*
318 * Version 1 messages
319 */
320typedef enum {
321 HV_CHANNEL_MESSAGE_INVALID = 0,
322 HV_CHANNEL_MESSAGE_OFFER_CHANNEL = 1,
323 HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER = 2,
324 HV_CHANNEL_MESSAGE_REQUEST_OFFERS = 3,
325 HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED = 4,
326 HV_CHANNEL_MESSAGE_OPEN_CHANNEL = 5,
327 HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT = 6,
328 HV_CHANNEL_MESSAGE_CLOSE_CHANNEL = 7,
329 HV_CHANNEL_MESSAGEL_GPADL_HEADER = 8,
330 HV_CHANNEL_MESSAGE_GPADL_BODY = 9,
331 HV_CHANNEL_MESSAGE_GPADL_CREATED = 10,
332 HV_CHANNEL_MESSAGE_GPADL_TEARDOWN = 11,
333 HV_CHANNEL_MESSAGE_GPADL_TORNDOWN = 12,
334 HV_CHANNEL_MESSAGE_REL_ID_RELEASED = 13,
335 HV_CHANNEL_MESSAGE_INITIATED_CONTACT = 14,
336 HV_CHANNEL_MESSAGE_VERSION_RESPONSE = 15,
337 HV_CHANNEL_MESSAGE_UNLOAD = 16,
338 HV_CHANNEL_MESSAGE_COUNT
339} hv_vmbus_channel_msg_type;
340
341typedef struct {
342 hv_vmbus_channel_msg_type message_type;
343 uint32_t padding;
344} __packed hv_vmbus_channel_msg_header;
345
346/*
347 * Query VMBus Version parameters
348 */
349typedef struct {
350 hv_vmbus_channel_msg_header header;
351 uint32_t version;
352} __packed hv_vmbus_channel_query_vmbus_version;
353
354/*
355 * VMBus Version Supported parameters
356 */
357typedef struct {
358 hv_vmbus_channel_msg_header header;
359 hv_bool_uint8_t version_supported;
360} __packed hv_vmbus_channel_version_supported;
361
362/*
363 * Channel Offer parameters
364 */
365typedef struct {
366 hv_vmbus_channel_msg_header header;
367 hv_vmbus_channel_offer offer;
368 uint32_t child_rel_id;
369 uint8_t monitor_id;
370 /*
371 * This field has been split into a bit field on Win7
372 * and higher.
373 */
374 uint8_t monitor_allocated:1;
375 uint8_t reserved:7;
376 /*
377 * Following fields were added in win7 and higher.
378 * Make sure to check the version before accessing these fields.
379 *
380 * If "is_dedicated_interrupt" is set, we must not set the
381 * associated bit in the channel bitmap while sending the
382 * interrupt to the host.
383 *
384 * connection_id is used in signaling the host.
385 */
386 uint16_t is_dedicated_interrupt:1;
387 uint16_t reserved1:15;
388 uint32_t connection_id;
389} __packed hv_vmbus_channel_offer_channel;
390
391/*
392 * Rescind Offer parameters
393 */
394typedef struct
395{
396 hv_vmbus_channel_msg_header header;
397 uint32_t child_rel_id;
398} __packed hv_vmbus_channel_rescind_offer;
399
400
401/*
402 * Request Offer -- no parameters, SynIC message contains the partition ID
403 *
404 * Set Snoop -- no parameters, SynIC message contains the partition ID
405 *
406 * Clear Snoop -- no parameters, SynIC message contains the partition ID
407 *
408 * All Offers Delivered -- no parameters, SynIC message contains the
409 * partition ID
410 *
411 * Flush Client -- no parameters, SynIC message contains the partition ID
412 */
413
414
415/*
416 * Open Channel parameters
417 */
418typedef struct
419{
420 hv_vmbus_channel_msg_header header;
421
422 /*
423 * Identifies the specific VMBus channel that is being opened.
424 */
425 uint32_t child_rel_id;
426
427 /*
428 * ID making a particular open request at a channel offer unique.
429 */
430 uint32_t open_id;
431
432 /*
433 * GPADL for the channel's ring buffer.
434 */
435 hv_gpadl_handle ring_buffer_gpadl_handle;
436
437 /*
438 * Before win8, all incoming channel interrupts are only
439 * delivered on cpu 0. Setting this value to 0 would
440 * preserve the earlier behavior.
441 */
442 uint32_t target_vcpu;
443
444 /*
445 * The upstream ring buffer begins at offset zero in the memory described
446 * by ring_buffer_gpadl_handle. The downstream ring buffer follows it at
447 * this offset (in pages).
448 */
449 uint32_t downstream_ring_buffer_page_offset;
450
451 /*
452 * User-specific data to be passed along to the server endpoint.
453 */
454 uint8_t user_data[HV_MAX_USER_DEFINED_BYTES];
455
456} __packed hv_vmbus_channel_open_channel;
457
458typedef uint32_t hv_nt_status;
459
460/*
461 * Open Channel Result parameters
462 */
463typedef struct
464{
465 hv_vmbus_channel_msg_header header;
466 uint32_t child_rel_id;
467 uint32_t open_id;
468 hv_nt_status status;
469} __packed hv_vmbus_channel_open_result;
470
471/*
472 * Close channel parameters
473 */
474typedef struct
475{
476 hv_vmbus_channel_msg_header header;
477 uint32_t child_rel_id;
478} __packed hv_vmbus_channel_close_channel;
479
480/*
481 * Channel Message GPADL
482 */
483#define HV_GPADL_TYPE_RING_BUFFER 1
484#define HV_GPADL_TYPE_SERVER_SAVE_AREA 2
485#define HV_GPADL_TYPE_TRANSACTION 8
486
487/*
488 * The number of PFNs in a GPADL message is defined by the number of pages
489 * that would be spanned by byte_count and byte_offset. If the implied number
490 * of PFNs won't fit in this packet, there will be a follow-up packet that
491 * contains more
492 */
493
494typedef struct {
495 hv_vmbus_channel_msg_header header;
496 uint32_t child_rel_id;
497 uint32_t gpadl;
498 uint16_t range_buf_len;
499 uint16_t range_count;
500 hv_gpa_range range[0];
501} __packed hv_vmbus_channel_gpadl_header;
502
503/*
504 * This is the follow-up packet that contains more PFNs
505 */
506typedef struct {
507 hv_vmbus_channel_msg_header header;
508 uint32_t message_number;
509 uint32_t gpadl;
510 uint64_t pfn[0];
511} __packed hv_vmbus_channel_gpadl_body;
512
513typedef struct {
514 hv_vmbus_channel_msg_header header;
515 uint32_t child_rel_id;
516 uint32_t gpadl;
517 uint32_t creation_status;
518} __packed hv_vmbus_channel_gpadl_created;
519
520typedef struct {
521 hv_vmbus_channel_msg_header header;
522 uint32_t child_rel_id;
523 uint32_t gpadl;
524} __packed hv_vmbus_channel_gpadl_teardown;
525
526typedef struct {
527 hv_vmbus_channel_msg_header header;
528 uint32_t gpadl;
529} __packed hv_vmbus_channel_gpadl_torndown;
530
531typedef struct {
532 hv_vmbus_channel_msg_header header;
533 uint32_t child_rel_id;
534} __packed hv_vmbus_channel_relid_released;
535
536typedef struct {
537 hv_vmbus_channel_msg_header header;
538 uint32_t vmbus_version_requested;
539 uint32_t padding2;
540 uint64_t interrupt_page;
541 uint64_t monitor_page_1;
542 uint64_t monitor_page_2;
543} __packed hv_vmbus_channel_initiate_contact;
544
545typedef struct {
546 hv_vmbus_channel_msg_header header;
547 hv_bool_uint8_t version_supported;
548} __packed hv_vmbus_channel_version_response;
549
550typedef hv_vmbus_channel_msg_header hv_vmbus_channel_unload;
551
552#define HW_MACADDR_LEN 6
553
554/*
555 * Fixme: Added to quiet "typeof" errors involving hv_vmbus.h when
556 * the including C file was compiled with "-std=c99".
557 */
558#ifndef typeof
559#define typeof __typeof
560#endif
561
562#ifndef NULL
563#define NULL (void *)0
564#endif
565
566typedef void *hv_vmbus_handle;
567
568#ifndef CONTAINING_RECORD
569#define CONTAINING_RECORD(address, type, field) ((type *)( \
570 (uint8_t *)(address) - \
571 (uint8_t *)(&((type *)0)->field)))
572#endif /* CONTAINING_RECORD */
573
574
575#define container_of(ptr, type, member) ({ \
576 __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
577 (type *)( (char *)__mptr - offsetof(type,member) );})
578
579enum {
580 HV_VMBUS_IVAR_TYPE,
581 HV_VMBUS_IVAR_INSTANCE,
582 HV_VMBUS_IVAR_NODE,
583 HV_VMBUS_IVAR_DEVCTX
584};
585
586#define HV_VMBUS_ACCESSOR(var, ivar, type) \
587 __BUS_ACCESSOR(vmbus, var, HV_VMBUS, ivar, type)
588
589HV_VMBUS_ACCESSOR(type, TYPE, const char *)
590HV_VMBUS_ACCESSOR(devctx, DEVCTX, struct hv_device *)
591
592
593/*
594 * Common defines for Hyper-V ICs
595 */
596#define HV_ICMSGTYPE_NEGOTIATE 0
597#define HV_ICMSGTYPE_HEARTBEAT 1
598#define HV_ICMSGTYPE_KVPEXCHANGE 2
599#define HV_ICMSGTYPE_SHUTDOWN 3
600#define HV_ICMSGTYPE_TIMESYNC 4
601#define HV_ICMSGTYPE_VSS 5
602
603#define HV_ICMSGHDRFLAG_TRANSACTION 1
604#define HV_ICMSGHDRFLAG_REQUEST 2
605#define HV_ICMSGHDRFLAG_RESPONSE 4
606
607typedef struct hv_vmbus_pipe_hdr {
608 uint32_t flags;
609 uint32_t msgsize;
610} __packed hv_vmbus_pipe_hdr;
611
612typedef struct hv_vmbus_ic_version {
613 uint16_t major;
614 uint16_t minor;
615} __packed hv_vmbus_ic_version;
616
617typedef struct hv_vmbus_icmsg_hdr {
618 hv_vmbus_ic_version icverframe;
619 uint16_t icmsgtype;
620 hv_vmbus_ic_version icvermsg;
621 uint16_t icmsgsize;
622 uint32_t status;
623 uint8_t ictransaction_id;
624 uint8_t icflags;
625 uint8_t reserved[2];
626} __packed hv_vmbus_icmsg_hdr;
627
628typedef struct hv_vmbus_icmsg_negotiate {
629 uint16_t icframe_vercnt;
630 uint16_t icmsg_vercnt;
631 uint32_t reserved;
632 hv_vmbus_ic_version icversion_data[1]; /* any size array */
633} __packed hv_vmbus_icmsg_negotiate;
634
635typedef struct hv_vmbus_shutdown_msg_data {
636 uint32_t reason_code;
637 uint32_t timeout_seconds;
638 uint32_t flags;
639 uint8_t display_message[2048];
640} __packed hv_vmbus_shutdown_msg_data;
641
642typedef struct hv_vmbus_heartbeat_msg_data {
643 uint64_t seq_num;
644 uint32_t reserved[8];
645} __packed hv_vmbus_heartbeat_msg_data;
646
647typedef struct {
648 /*
649 * offset in bytes from the start of ring data below
650 */
651 volatile uint32_t write_index;
652 /*
653 * offset in bytes from the start of ring data below
654 */
655 volatile uint32_t read_index;
656 /*
657 * NOTE: The interrupt_mask field is used only for channels, but
658 * vmbus connection also uses this data structure
659 */
660 volatile uint32_t interrupt_mask;
661 /* pad it to PAGE_SIZE so that data starts on a page */
662 uint8_t reserved[4084];
663
664 /*
665 * WARNING: Ring data starts here + ring_data_start_offset
666 * !!! DO NOT place any fields below this !!!
667 */
668 uint8_t buffer[0]; /* doubles as interrupt mask */
669} __packed hv_vmbus_ring_buffer;
670
671typedef struct {
672 int length;
673 int offset;
674 uint64_t pfn;
675} __packed hv_vmbus_page_buffer;
676
677typedef struct {
678 int length;
679 int offset;
680 uint64_t pfn_array[HV_MAX_MULTIPAGE_BUFFER_COUNT];
681} __packed hv_vmbus_multipage_buffer;
682
683typedef struct {
684 hv_vmbus_ring_buffer* ring_buffer;
685 uint32_t ring_size; /* Include the shared header */
686 struct mtx ring_lock;
687 uint32_t ring_data_size; /* ring_size */
688 uint32_t ring_data_start_offset;
689} hv_vmbus_ring_buffer_info;
690
691typedef void (*hv_vmbus_pfn_channel_callback)(void *context);
692typedef void (*hv_vmbus_sc_creation_callback)(void *context);
693
694typedef enum {
695 HV_CHANNEL_OFFER_STATE,
696 HV_CHANNEL_OPENING_STATE,
697 HV_CHANNEL_OPEN_STATE,
698 HV_CHANNEL_OPENED_STATE,
699 HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE,
700} hv_vmbus_channel_state;
701
702/*
703 * Connection identifier type
704 */
705typedef union {
706 uint32_t as_uint32_t;
707 struct {
708 uint32_t id:24;
709 uint32_t reserved:8;
710 } u;
711
712} __packed hv_vmbus_connection_id;
713
714/*
715 * Definition of the hv_vmbus_signal_event hypercall input structure
716 */
717typedef struct {
718 hv_vmbus_connection_id connection_id;
719 uint16_t flag_number;
720 uint16_t rsvd_z;
721} __packed hv_vmbus_input_signal_event;
722
723typedef struct {
724 uint64_t align8;
725 hv_vmbus_input_signal_event event;
726} __packed hv_vmbus_input_signal_event_buffer;
727
728typedef struct hv_vmbus_channel {
729 TAILQ_ENTRY(hv_vmbus_channel) list_entry;
730 struct hv_device* device;
731 hv_vmbus_channel_state state;
732 hv_vmbus_channel_offer_channel offer_msg;
733 /*
734 * These are based on the offer_msg.monitor_id.
735 * Save it here for easy access.
736 */
737 uint8_t monitor_group;
738 uint8_t monitor_bit;
739
740 uint32_t ring_buffer_gpadl_handle;
741 /*
742 * Allocated memory for ring buffer
743 */
744 void* ring_buffer_pages;
745 unsigned long ring_buffer_size;
746 uint32_t ring_buffer_page_count;
747 /*
748 * send to parent
749 */
750 hv_vmbus_ring_buffer_info outbound;
751 /*
752 * receive from parent
753 */
754 hv_vmbus_ring_buffer_info inbound;
755
756 struct mtx inbound_lock;
757
758 struct taskqueue * rxq;
759 struct task channel_task;
760 hv_vmbus_pfn_channel_callback on_channel_callback;
761 void* channel_callback_context;
762
763 /*
764 * If batched_reading is set to "true", mask the interrupt
765 * and read until the channel is empty.
766 * If batched_reading is set to "false", the channel is not
767 * going to perform batched reading.
768 *
769 * Batched reading is enabled by default; specific
770 * drivers that don't want this behavior can turn it off.
771 */
772 boolean_t batched_reading;
773
774 boolean_t is_dedicated_interrupt;
775
776 /*
777 * Used as an input param for HV_CALL_SIGNAL_EVENT hypercall.
778 */
779 hv_vmbus_input_signal_event_buffer signal_event_buffer;
780 /*
781 * 8-bytes aligned of the buffer above
782 */
783 hv_vmbus_input_signal_event *signal_event_param;
784
785 /*
786 * From Win8, this field specifies the target virtual process
787 * on which to deliver the interupt from the host to guest.
788 * Before Win8, all channel interrupts would only be
789 * delivered on cpu 0. Setting this value to 0 would preserve
790 * the earlier behavior.
791 */
792 uint32_t target_vcpu;
793 /* The corresponding CPUID in the guest */
794 uint32_t target_cpu;
795
796 /*
797 * Support for multi-channels.
798 * The initial offer is considered the primary channel and this
799 * offer message will indicate if the host supports multi-channels.
800 * The guest is free to ask for multi-channels to be offerred and can
801 * open these multi-channels as a normal "primary" channel. However,
802 * all multi-channels will have the same type and instance guids as the
803 * primary channel. Requests sent on a given channel will result in a
804 * response on the same channel.
805 */
806
807 /*
808 * Multi-channel creation callback. This callback will be called in
809 * process context when a Multi-channel offer is received from the host.
810 * The guest can open the Multi-channel in the context of this callback.
811 */
812 hv_vmbus_sc_creation_callback sc_creation_callback;
813
814 struct mtx sc_lock;
815
816 /*
817 * Link list of all the multi-channels if this is a primary channel
818 */
819 TAILQ_HEAD(, hv_vmbus_channel) sc_list_anchor;
820 TAILQ_ENTRY(hv_vmbus_channel) sc_list_entry;
821
822 /*
823 * The primary channel this sub-channle belongs to.
824 * This will be NULL for the primary channel.
825 */
826 struct hv_vmbus_channel *primary_channel;
827 /*
828 * Support per channel state for use by vmbus drivers.
829 */
830 void *per_channel_state;
831} hv_vmbus_channel;
832
833static inline void
834hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t state)
835{
836 channel->batched_reading = state;
837}
838
839typedef struct hv_device {
840 hv_guid class_id;
841 hv_guid device_id;
842 device_t device;
843 hv_vmbus_channel* channel;
844} hv_device;
845
846
847
848int hv_vmbus_channel_recv_packet(
849 hv_vmbus_channel* channel,
850 void* buffer,
851 uint32_t buffer_len,
852 uint32_t* buffer_actual_len,
853 uint64_t* request_id);
854
855int hv_vmbus_channel_recv_packet_raw(
856 hv_vmbus_channel* channel,
857 void* buffer,
858 uint32_t buffer_len,
859 uint32_t* buffer_actual_len,
860 uint64_t* request_id);
861
862int hv_vmbus_channel_open(
863 hv_vmbus_channel* channel,
864 uint32_t send_ring_buffer_size,
865 uint32_t recv_ring_buffer_size,
866 void* user_data,
867 uint32_t user_data_len,
868 hv_vmbus_pfn_channel_callback
869 pfn_on_channel_callback,
870 void* context);
871
872void hv_vmbus_channel_close(hv_vmbus_channel *channel);
873
874int hv_vmbus_channel_send_packet(
875 hv_vmbus_channel* channel,
876 void* buffer,
877 uint32_t buffer_len,
878 uint64_t request_id,
879 hv_vmbus_packet_type type,
880 uint32_t flags);
881
882int hv_vmbus_channel_send_packet_pagebuffer(
883 hv_vmbus_channel* channel,
884 hv_vmbus_page_buffer page_buffers[],
885 uint32_t page_count,
886 void* buffer,
887 uint32_t buffer_len,
888 uint64_t request_id);
889
890int hv_vmbus_channel_send_packet_multipagebuffer(
891 hv_vmbus_channel* channel,
892 hv_vmbus_multipage_buffer* multi_page_buffer,
893 void* buffer,
894 uint32_t buffer_len,
895 uint64_t request_id);
896
897int hv_vmbus_channel_establish_gpadl(
898 hv_vmbus_channel* channel,
899 /* must be phys and virt contiguous */
900 void* contig_buffer,
901 /* page-size multiple */
902 uint32_t size,
903 uint32_t* gpadl_handle);
904
905int hv_vmbus_channel_teardown_gpdal(
906 hv_vmbus_channel* channel,
907 uint32_t gpadl_handle);
908
909struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary);
910
911/*
912 * Work abstraction defines
913 */
914typedef struct hv_work_queue {
915 struct taskqueue* queue;
916 struct proc* proc;
917 struct sema* work_sema;
918} hv_work_queue;
919
920typedef struct hv_work_item {
921 struct task work;
922 void (*callback)(void *);
923 void* context;
924 hv_work_queue* wq;
925} hv_work_item;
926
927struct hv_work_queue* hv_work_queue_create(char* name);
928
929void hv_work_queue_close(struct hv_work_queue* wq);
930
931int hv_queue_work_item(
932 hv_work_queue* wq,
933 void (*callback)(void *),
934 void* context);
935/**
936 * @brief Get physical address from virtual
937 */
938static inline unsigned long
939hv_get_phys_addr(void *virt)
940{
941 unsigned long ret;
942 ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK));
943 return (ret);
944}
945
946
947/**
948 * KVP related structures
949 *
950 */
951typedef struct hv_vmbus_service {
952 hv_guid guid; /* Hyper-V GUID */
953 char *name; /* name of service */
954 boolean_t enabled; /* service enabled */
955 hv_work_queue *work_queue; /* background work queue */
956
957 /*
958 * function to initialize service
959 */
960 int (*init)(struct hv_vmbus_service *);
961
962 /*
963 * function to process Hyper-V messages
964 */
965 void (*callback)(void *);
966} hv_vmbus_service;
967
968extern uint8_t* receive_buffer[];
969extern hv_vmbus_service service_table[];
970extern uint32_t hv_vmbus_protocal_version;
971
972void hv_kvp_callback(void *context);
973int hv_kvp_init(hv_vmbus_service *serv);
974void hv_kvp_deinit(void);
975
976#endif /* __HYPERV_H__ */
977