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$ 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/mutex.h> 50 #include <sys/bus.h> 51 #include <vm/vm.h> 52 #include <vm/vm_param.h> 53 #include <vm/pmap.h> 54 55 #include <amd64/include/xen/synch_bitops.h> 56 #include <amd64/include/atomic.h> 57 58 typedef uint8_t hv_bool_uint8_t; 59 60 #define HV_S_OK 0x00000000 61 #define HV_E_FAIL 0x80004005 62 #define HV_ERROR_NOT_SUPPORTED 0x80070032 63 #define HV_ERROR_MACHINE_LOCKED 0x800704F7 64 65 /* 66 * A revision number of vmbus that is used for ensuring both ends on a 67 * partition are using compatible versions. 68 */ 69 70 #define HV_VMBUS_REVISION_NUMBER 13 71 72 /* 73 * Make maximum size of pipe payload of 16K 74 */ 75 76 #define HV_MAX_PIPE_DATA_PAYLOAD (sizeof(BYTE) * 16384) 77 78 /* 79 * Define pipe_mode values 80 */ 81 82 #define HV_VMBUS_PIPE_TYPE_BYTE 0x00000000 83 #define HV_VMBUS_PIPE_TYPE_MESSAGE 0x00000004 84 85 /* 86 * The size of the user defined data buffer for non-pipe offers 87 */ 88 89 #define HV_MAX_USER_DEFINED_BYTES 120 90 91 /* 92 * The size of the user defined data buffer for pipe offers 93 */ 94 95 #define HV_MAX_PIPE_USER_DEFINED_BYTES 116 96 97 98 #define HV_MAX_PAGE_BUFFER_COUNT 16 99 #define HV_MAX_MULTIPAGE_BUFFER_COUNT 32 100 101 #define HV_ALIGN_UP(value, align) \ 102 (((value) & (align-1)) ? \ 103 (((value) + (align-1)) & ~(align-1) ) : (value)) 104 105 #define HV_ALIGN_DOWN(value, align) ( (value) & ~(align-1) ) 106 107 #define HV_NUM_PAGES_SPANNED(addr, len) \ 108 ((HV_ALIGN_UP(addr+len, PAGE_SIZE) - \ 109 HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT ) 110 111 typedef struct hv_guid { 112 unsigned char data[16]; 113 } __packed hv_guid; 114 115 /* 116 * At the center of the Channel Management library is 117 * the Channel Offer. This struct contains the 118 * fundamental information about an offer. 119 */ 120 121 typedef struct hv_vmbus_channel_offer { 122 hv_guid interface_type; 123 hv_guid interface_instance; 124 uint64_t interrupt_latency_in_100ns_units; 125 uint32_t interface_revision; 126 uint32_t server_context_area_size; /* in bytes */ 127 uint16_t channel_flags; 128 uint16_t mmio_megabytes; /* in bytes * 1024 * 1024 */ 129 union 130 { 131 /* 132 * Non-pipes: The user has HV_MAX_USER_DEFINED_BYTES bytes. 133 */ 134 struct { 135 uint8_t user_defined[HV_MAX_USER_DEFINED_BYTES]; 136 } __packed standard; 137 138 /* 139 * Pipes: The following structure is an integrated pipe protocol, which 140 * is implemented on top of standard user-defined data. pipe 141 * clients have HV_MAX_PIPE_USER_DEFINED_BYTES left for their 142 * own use. 143 */ 144 struct { 145 uint32_t pipe_mode; 146 uint8_t user_defined[HV_MAX_PIPE_USER_DEFINED_BYTES]; 147 } __packed pipe; 148 } u; 149 150 uint32_t padding; 151 152 } __packed hv_vmbus_channel_offer; 153 154 typedef uint32_t hv_gpadl_handle; 155 156 typedef struct { 157 uint16_t type; 158 uint16_t data_offset8; 159 uint16_t length8; 160 uint16_t flags; 161 uint64_t transaction_id; 162 } __packed hv_vm_packet_descriptor; 163 164 typedef uint32_t hv_previous_packet_offset; 165 166 typedef struct { 167 hv_previous_packet_offset previous_packet_start_offset; 168 hv_vm_packet_descriptor descriptor; 169 } __packed hv_vm_packet_header; 170 171 typedef struct { 172 uint32_t byte_count; 173 uint32_t byte_offset; 174 } __packed hv_vm_transfer_page; 175 176 typedef struct { 177 hv_vm_packet_descriptor d; 178 uint16_t transfer_page_set_id; 179 hv_bool_uint8_t sender_owns_set; 180 uint8_t reserved; 181 uint32_t range_count; 182 hv_vm_transfer_page ranges[1]; 183 } __packed hv_vm_transfer_page_packet_header; 184 185 typedef struct { 186 hv_vm_packet_descriptor d; 187 uint32_t gpadl; 188 uint32_t reserved; 189 } __packed hv_vm_gpadl_packet_header; 190 191 typedef struct { 192 hv_vm_packet_descriptor d; 193 uint32_t gpadl; 194 uint16_t transfer_page_set_id; 195 uint16_t reserved; 196 } __packed hv_vm_add_remove_transfer_page_set; 197 198 /* 199 * This structure defines a range in guest 200 * physical space that can be made 201 * to look virtually contiguous. 202 */ 203 204 typedef struct { 205 uint32_t byte_count; 206 uint32_t byte_offset; 207 uint64_t pfn_array[0]; 208 } __packed hv_gpa_range; 209 210 /* 211 * This is the format for an Establish Gpadl packet, which contains a handle 212 * by which this GPADL will be known and a set of GPA ranges associated with 213 * it. This can be converted to a MDL by the guest OS. If there are multiple 214 * GPA ranges, then the resulting MDL will be "chained," representing multiple 215 * VA ranges. 216 */ 217 218 typedef struct { 219 hv_vm_packet_descriptor d; 220 uint32_t gpadl; 221 uint32_t range_count; 222 hv_gpa_range range[1]; 223 } __packed hv_vm_establish_gpadl; 224 225 /* 226 * This is the format for a Teardown Gpadl packet, which indicates that the 227 * GPADL handle in the Establish Gpadl packet will never be referenced again. 228 */ 229 230 typedef struct { 231 hv_vm_packet_descriptor d; 232 uint32_t gpadl; 233 /* for alignment to a 8-byte boundary */ 234 uint32_t reserved; 235 } __packed hv_vm_teardown_gpadl; 236 237 /* 238 * This is the format for a GPA-Direct packet, which contains a set of GPA 239 * ranges, in addition to commands and/or data. 240 */ 241 242 typedef struct { 243 hv_vm_packet_descriptor d; 244 uint32_t reserved; 245 uint32_t range_count; 246 hv_gpa_range range[1]; 247 } __packed hv_vm_data_gpa_direct; 248 249 /* 250 * This is the format for a Additional data Packet. 251 */ 252 typedef struct { 253 hv_vm_packet_descriptor d; 254 uint64_t total_bytes; 255 uint32_t byte_offset; 256 uint32_t byte_count; 257 uint8_t data[1]; 258 } __packed hv_vm_additional_data; 259 260 typedef union { 261 hv_vm_packet_descriptor simple_header; 262 hv_vm_transfer_page_packet_header transfer_page_header; 263 hv_vm_gpadl_packet_header gpadl_header; 264 hv_vm_add_remove_transfer_page_set add_remove_transfer_page_header; 265 hv_vm_establish_gpadl establish_gpadl_header; 266 hv_vm_teardown_gpadl teardown_gpadl_header; 267 hv_vm_data_gpa_direct data_gpa_direct_header; 268 } __packed hv_vm_packet_largest_possible_header; 269 270 typedef enum { 271 HV_VMBUS_PACKET_TYPE_INVALID = 0x0, 272 HV_VMBUS_PACKET_TYPES_SYNCH = 0x1, 273 HV_VMBUS_PACKET_TYPE_ADD_TRANSFER_PAGE_SET = 0x2, 274 HV_VMBUS_PACKET_TYPE_REMOVE_TRANSFER_PAGE_SET = 0x3, 275 HV_VMBUS_PACKET_TYPE_ESTABLISH_GPADL = 0x4, 276 HV_VMBUS_PACKET_TYPE_TEAR_DOWN_GPADL = 0x5, 277 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND = 0x6, 278 HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES = 0x7, 279 HV_VMBUS_PACKET_TYPE_DATA_USING_GPADL = 0x8, 280 HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT = 0x9, 281 HV_VMBUS_PACKET_TYPE_CANCEL_REQUEST = 0xa, 282 HV_VMBUS_PACKET_TYPE_COMPLETION = 0xb, 283 HV_VMBUS_PACKET_TYPE_DATA_USING_ADDITIONAL_PACKETS = 0xc, 284 HV_VMBUS_PACKET_TYPE_ADDITIONAL_DATA = 0xd 285 } hv_vmbus_packet_type; 286 287 #define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 288 289 /* 290 * Version 1 messages 291 */ 292 typedef enum { 293 HV_CHANNEL_MESSAGE_INVALID = 0, 294 HV_CHANNEL_MESSAGE_OFFER_CHANNEL = 1, 295 HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER = 2, 296 HV_CHANNEL_MESSAGE_REQUEST_OFFERS = 3, 297 HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED = 4, 298 HV_CHANNEL_MESSAGE_OPEN_CHANNEL = 5, 299 HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT = 6, 300 HV_CHANNEL_MESSAGE_CLOSE_CHANNEL = 7, 301 HV_CHANNEL_MESSAGEL_GPADL_HEADER = 8, 302 HV_CHANNEL_MESSAGE_GPADL_BODY = 9, 303 HV_CHANNEL_MESSAGE_GPADL_CREATED = 10, 304 HV_CHANNEL_MESSAGE_GPADL_TEARDOWN = 11, 305 HV_CHANNEL_MESSAGE_GPADL_TORNDOWN = 12, 306 HV_CHANNEL_MESSAGE_REL_ID_RELEASED = 13, 307 HV_CHANNEL_MESSAGE_INITIATED_CONTACT = 14, 308 HV_CHANNEL_MESSAGE_VERSION_RESPONSE = 15, 309 HV_CHANNEL_MESSAGE_UNLOAD = 16, 310 311 #ifdef HV_VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD 312 HV_CHANNEL_MESSAGE_VIEW_RANGE_ADD = 17, 313 HV_CHANNEL_MESSAGE_VIEW_RANGE_REMOVE = 18, 314 #endif 315 HV_CHANNEL_MESSAGE_COUNT 316 } hv_vmbus_channel_msg_type; 317 318 typedef struct { 319 hv_vmbus_channel_msg_type message_type; 320 uint32_t padding; 321 } __packed hv_vmbus_channel_msg_header; 322 323 /* 324 * Query VMBus Version parameters 325 */ 326 typedef struct { 327 hv_vmbus_channel_msg_header header; 328 uint32_t version; 329 } __packed hv_vmbus_channel_query_vmbus_version; 330 331 /* 332 * VMBus Version Supported parameters 333 */ 334 typedef struct { 335 hv_vmbus_channel_msg_header header; 336 hv_bool_uint8_t version_supported; 337 } __packed hv_vmbus_channel_version_supported; 338 339 /* 340 * Channel Offer parameters 341 */ 342 typedef struct { 343 hv_vmbus_channel_msg_header header; 344 hv_vmbus_channel_offer offer; 345 uint32_t child_rel_id; 346 uint8_t monitor_id; 347 hv_bool_uint8_t monitor_allocated; 348 } __packed hv_vmbus_channel_offer_channel; 349 350 /* 351 * Rescind Offer parameters 352 */ 353 typedef struct 354 { 355 hv_vmbus_channel_msg_header header; 356 uint32_t child_rel_id; 357 } __packed hv_vmbus_channel_rescind_offer; 358 359 360 /* 361 * Request Offer -- no parameters, SynIC message contains the partition ID 362 * 363 * Set Snoop -- no parameters, SynIC message contains the partition ID 364 * 365 * Clear Snoop -- no parameters, SynIC message contains the partition ID 366 * 367 * All Offers Delivered -- no parameters, SynIC message contains the 368 * partition ID 369 * 370 * Flush Client -- no parameters, SynIC message contains the partition ID 371 */ 372 373 374 /* 375 * Open Channel parameters 376 */ 377 typedef struct 378 { 379 hv_vmbus_channel_msg_header header; 380 381 /* 382 * Identifies the specific VMBus channel that is being opened. 383 */ 384 uint32_t child_rel_id; 385 386 /* 387 * ID making a particular open request at a channel offer unique. 388 */ 389 uint32_t open_id; 390 391 /* 392 * GPADL for the channel's ring buffer. 393 */ 394 hv_gpadl_handle ring_buffer_gpadl_handle; 395 396 /* 397 * GPADL for the channel's server context save area. 398 */ 399 hv_gpadl_handle server_context_area_gpadl_handle; 400 401 /* 402 * The upstream ring buffer begins at offset zero in the memory described 403 * by ring_buffer_gpadl_handle. The downstream ring buffer follows it at 404 * this offset (in pages). 405 */ 406 uint32_t downstream_ring_buffer_page_offset; 407 408 /* 409 * User-specific data to be passed along to the server endpoint. 410 */ 411 uint8_t user_data[HV_MAX_USER_DEFINED_BYTES]; 412 413 } __packed hv_vmbus_channel_open_channel; 414 415 typedef uint32_t hv_nt_status; 416 417 /* 418 * Open Channel Result parameters 419 */ 420 typedef struct 421 { 422 hv_vmbus_channel_msg_header header; 423 uint32_t child_rel_id; 424 uint32_t open_id; 425 hv_nt_status status; 426 } __packed hv_vmbus_channel_open_result; 427 428 /* 429 * Close channel parameters 430 */ 431 typedef struct 432 { 433 hv_vmbus_channel_msg_header header; 434 uint32_t child_rel_id; 435 } __packed hv_vmbus_channel_close_channel; 436 437 /* 438 * Channel Message GPADL 439 */ 440 #define HV_GPADL_TYPE_RING_BUFFER 1 441 #define HV_GPADL_TYPE_SERVER_SAVE_AREA 2 442 #define HV_GPADL_TYPE_TRANSACTION 8 443 444 /* 445 * The number of PFNs in a GPADL message is defined by the number of pages 446 * that would be spanned by byte_count and byte_offset. If the implied number 447 * of PFNs won't fit in this packet, there will be a follow-up packet that 448 * contains more 449 */ 450 451 typedef struct { 452 hv_vmbus_channel_msg_header header; 453 uint32_t child_rel_id; 454 uint32_t gpadl; 455 uint16_t range_buf_len; 456 uint16_t range_count; 457 hv_gpa_range range[0]; 458 } __packed hv_vmbus_channel_gpadl_header; 459 460 /* 461 * This is the follow-up packet that contains more PFNs 462 */ 463 typedef struct { 464 hv_vmbus_channel_msg_header header; 465 uint32_t message_number; 466 uint32_t gpadl; 467 uint64_t pfn[0]; 468 } __packed hv_vmbus_channel_gpadl_body; 469 470 typedef struct { 471 hv_vmbus_channel_msg_header header; 472 uint32_t child_rel_id; 473 uint32_t gpadl; 474 uint32_t creation_status; 475 } __packed hv_vmbus_channel_gpadl_created; 476 477 typedef struct { 478 hv_vmbus_channel_msg_header header; 479 uint32_t child_rel_id; 480 uint32_t gpadl; 481 } __packed hv_vmbus_channel_gpadl_teardown; 482 483 typedef struct { 484 hv_vmbus_channel_msg_header header; 485 uint32_t gpadl; 486 } __packed hv_vmbus_channel_gpadl_torndown; 487 488 typedef struct { 489 hv_vmbus_channel_msg_header header; 490 uint32_t child_rel_id; 491 } __packed hv_vmbus_channel_relid_released; 492 493 typedef struct { 494 hv_vmbus_channel_msg_header header; 495 uint32_t vmbus_version_requested; 496 uint32_t padding2; 497 uint64_t interrupt_page; 498 uint64_t monitor_page_1; 499 uint64_t monitor_page_2; 500 } __packed hv_vmbus_channel_initiate_contact; 501 502 typedef struct { 503 hv_vmbus_channel_msg_header header; 504 hv_bool_uint8_t version_supported; 505 } __packed hv_vmbus_channel_version_response; 506 507 typedef hv_vmbus_channel_msg_header hv_vmbus_channel_unload; 508 509 #define HW_MACADDR_LEN 6 510 511 /* 512 * Fixme: Added to quiet "typeof" errors involving hv_vmbus.h when 513 * the including C file was compiled with "-std=c99". 514 */ 515 #ifndef typeof 516 #define typeof __typeof 517 #endif 518 519 #ifndef NULL 520 #define NULL (void *)0 521 #endif 522 523 typedef void *hv_vmbus_handle; 524 525 #ifndef CONTAINING_RECORD 526 #define CONTAINING_RECORD(address, type, field) ((type *)( \ 527 (uint8_t *)(address) - \ 528 (uint8_t *)(&((type *)0)->field))) 529 #endif /* CONTAINING_RECORD */ 530 531 532 #define container_of(ptr, type, member) ({ \ 533 __typeof__( ((type *)0)->member ) *__mptr = (ptr); \ 534 (type *)( (char *)__mptr - offsetof(type,member) );}) 535 536 enum { 537 HV_VMBUS_IVAR_TYPE, 538 HV_VMBUS_IVAR_INSTANCE, 539 HV_VMBUS_IVAR_NODE, 540 HV_VMBUS_IVAR_DEVCTX 541 }; 542 543 #define HV_VMBUS_ACCESSOR(var, ivar, type) \ 544 __BUS_ACCESSOR(vmbus, var, HV_VMBUS, ivar, type) 545 546 HV_VMBUS_ACCESSOR(type, TYPE, const char *) 547 HV_VMBUS_ACCESSOR(devctx, DEVCTX, struct hv_device *) 548 549 550 /* 551 * Common defines for Hyper-V ICs 552 */ 553 #define HV_ICMSGTYPE_NEGOTIATE 0 554 #define HV_ICMSGTYPE_HEARTBEAT 1 555 #define HV_ICMSGTYPE_KVPEXCHANGE 2 556 #define HV_ICMSGTYPE_SHUTDOWN 3 557 #define HV_ICMSGTYPE_TIMESYNC 4 558 #define HV_ICMSGTYPE_VSS 5 559 560 #define HV_ICMSGHDRFLAG_TRANSACTION 1 561 #define HV_ICMSGHDRFLAG_REQUEST 2 562 #define HV_ICMSGHDRFLAG_RESPONSE 4 563 564 typedef struct hv_vmbus_pipe_hdr { 565 uint32_t flags; 566 uint32_t msgsize; 567 } __packed hv_vmbus_pipe_hdr; 568 569 typedef struct hv_vmbus_ic_version { 570 uint16_t major; 571 uint16_t minor; 572 } __packed hv_vmbus_ic_version; 573 574 typedef struct hv_vmbus_icmsg_hdr { 575 hv_vmbus_ic_version icverframe; 576 uint16_t icmsgtype; 577 hv_vmbus_ic_version icvermsg; 578 uint16_t icmsgsize; 579 uint32_t status; 580 uint8_t ictransaction_id; 581 uint8_t icflags; 582 uint8_t reserved[2]; 583 } __packed hv_vmbus_icmsg_hdr; 584 585 typedef struct hv_vmbus_icmsg_negotiate { 586 uint16_t icframe_vercnt; 587 uint16_t icmsg_vercnt; 588 uint32_t reserved; 589 hv_vmbus_ic_version icversion_data[1]; /* any size array */ 590 } __packed hv_vmbus_icmsg_negotiate; 591 592 typedef struct hv_vmbus_shutdown_msg_data { 593 uint32_t reason_code; 594 uint32_t timeout_seconds; 595 uint32_t flags; 596 uint8_t display_message[2048]; 597 } __packed hv_vmbus_shutdown_msg_data; 598 599 typedef struct hv_vmbus_heartbeat_msg_data { 600 uint64_t seq_num; 601 uint32_t reserved[8]; 602 } __packed hv_vmbus_heartbeat_msg_data; 603 604 typedef struct { 605 /* 606 * offset in bytes from the start of ring data below 607 */ 608 volatile uint32_t write_index; 609 /* 610 * offset in bytes from the start of ring data below 611 */ 612 volatile uint32_t read_index; 613 /* 614 * NOTE: The interrupt_mask field is used only for channels, but 615 * vmbus connection also uses this data structure 616 */ 617 volatile uint32_t interrupt_mask; 618 /* pad it to PAGE_SIZE so that data starts on a page */ 619 uint8_t reserved[4084]; 620 621 /* 622 * WARNING: Ring data starts here + ring_data_start_offset 623 * !!! DO NOT place any fields below this !!! 624 */ 625 uint8_t buffer[0]; /* doubles as interrupt mask */ 626 } __packed hv_vmbus_ring_buffer; 627 628 typedef struct { 629 int length; 630 int offset; 631 uint64_t pfn; 632 } __packed hv_vmbus_page_buffer; 633 634 typedef struct { 635 int length; 636 int offset; 637 uint64_t pfn_array[HV_MAX_MULTIPAGE_BUFFER_COUNT]; 638 } __packed hv_vmbus_multipage_buffer; 639 640 typedef struct { 641 hv_vmbus_ring_buffer* ring_buffer; 642 uint32_t ring_size; /* Include the shared header */ 643 struct mtx ring_lock; 644 uint32_t ring_data_size; /* ring_size */ 645 uint32_t ring_data_start_offset; 646 } hv_vmbus_ring_buffer_info; 647 648 typedef void (*hv_vmbus_pfn_channel_callback)(void *context); 649 650 typedef enum { 651 HV_CHANNEL_OFFER_STATE, 652 HV_CHANNEL_OPENING_STATE, 653 HV_CHANNEL_OPEN_STATE, 654 HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE, 655 } hv_vmbus_channel_state; 656 657 typedef struct hv_vmbus_channel { 658 TAILQ_ENTRY(hv_vmbus_channel) list_entry; 659 struct hv_device* device; 660 hv_vmbus_channel_state state; 661 hv_vmbus_channel_offer_channel offer_msg; 662 /* 663 * These are based on the offer_msg.monitor_id. 664 * Save it here for easy access. 665 */ 666 uint8_t monitor_group; 667 uint8_t monitor_bit; 668 669 uint32_t ring_buffer_gpadl_handle; 670 /* 671 * Allocated memory for ring buffer 672 */ 673 void* ring_buffer_pages; 674 unsigned long ring_buffer_size; 675 uint32_t ring_buffer_page_count; 676 /* 677 * send to parent 678 */ 679 hv_vmbus_ring_buffer_info outbound; 680 /* 681 * receive from parent 682 */ 683 hv_vmbus_ring_buffer_info inbound; 684 685 struct mtx inbound_lock; 686 hv_vmbus_handle control_work_queue; 687 688 hv_vmbus_pfn_channel_callback on_channel_callback; 689 void* channel_callback_context; 690 691 } hv_vmbus_channel; 692 693 typedef struct hv_device { 694 hv_guid class_id; 695 hv_guid device_id; 696 device_t device; 697 hv_vmbus_channel* channel; 698 } hv_device; 699 700 701 702 int hv_vmbus_channel_recv_packet( 703 hv_vmbus_channel* channel, 704 void* buffer, 705 uint32_t buffer_len, 706 uint32_t* buffer_actual_len, 707 uint64_t* request_id); 708 709 int hv_vmbus_channel_recv_packet_raw( 710 hv_vmbus_channel* channel, 711 void* buffer, 712 uint32_t buffer_len, 713 uint32_t* buffer_actual_len, 714 uint64_t* request_id); 715 716 int hv_vmbus_channel_open( 717 hv_vmbus_channel* channel, 718 uint32_t send_ring_buffer_size, 719 uint32_t recv_ring_buffer_size, 720 void* user_data, 721 uint32_t user_data_len, 722 hv_vmbus_pfn_channel_callback 723 pfn_on_channel_callback, 724 void* context); 725 726 void hv_vmbus_channel_close(hv_vmbus_channel *channel); 727 728 int hv_vmbus_channel_send_packet( 729 hv_vmbus_channel* channel, 730 void* buffer, 731 uint32_t buffer_len, 732 uint64_t request_id, 733 hv_vmbus_packet_type type, 734 uint32_t flags); 735 736 int hv_vmbus_channel_send_packet_pagebuffer( 737 hv_vmbus_channel* channel, 738 hv_vmbus_page_buffer page_buffers[], 739 uint32_t page_count, 740 void* buffer, 741 uint32_t buffer_len, 742 uint64_t request_id); 743 744 int hv_vmbus_channel_send_packet_multipagebuffer( 745 hv_vmbus_channel* channel, 746 hv_vmbus_multipage_buffer* multi_page_buffer, 747 void* buffer, 748 uint32_t buffer_len, 749 uint64_t request_id); 750 751 int hv_vmbus_channel_establish_gpadl( 752 hv_vmbus_channel* channel, 753 /* must be phys and virt contiguous */ 754 void* contig_buffer, 755 /* page-size multiple */ 756 uint32_t size, 757 uint32_t* gpadl_handle); 758 759 int hv_vmbus_channel_teardown_gpdal( 760 hv_vmbus_channel* channel, 761 uint32_t gpadl_handle); 762 763 /* 764 * Work abstraction defines 765 */ 766 typedef struct hv_work_queue { 767 struct taskqueue* queue; 768 struct proc* proc; 769 struct sema* work_sema; 770 } hv_work_queue; 771 772 typedef struct hv_work_item { 773 struct task work; 774 void (*callback)(void *); 775 void* context; 776 hv_work_queue* wq; 777 } hv_work_item; 778 779 struct hv_work_queue* hv_work_queue_create(char* name); 780 781 void hv_work_queue_close(struct hv_work_queue* wq); 782 783 int hv_queue_work_item( 784 hv_work_queue* wq, 785 void (*callback)(void *), 786 void* context); 787 /** 788 * @brief Get physical address from virtual 789 */ 790 static inline unsigned long 791 hv_get_phys_addr(void *virt) 792 { 793 unsigned long ret; 794 ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK)); 795 return (ret); 796 } 797 798 799 /** 800 * KVP related structures 801 * 802 */ 803 typedef struct hv_vmbus_service { 804 hv_guid guid; /* Hyper-V GUID */ 805 char *name; /* name of service */ 806 boolean_t enabled; /* service enabled */ 807 hv_work_queue *work_queue; /* background work queue */ 808 809 /* 810 * function to initialize service 811 */ 812 int (*init)(struct hv_vmbus_service *); 813 814 /* 815 * function to process Hyper-V messages 816 */ 817 void (*callback)(void *); 818 } hv_vmbus_service; 819 820 extern uint8_t* receive_buffer[]; 821 extern hv_vmbus_service service_table[]; 822 823 void hv_kvp_callback(void *context); 824 int hv_kvp_init(hv_vmbus_service *serv); 825 void hv_kvp_deinit(void); 826 827 #endif /* __HYPERV_H__ */ 828 829