hyperv.h revision 296083
1285101Semaste/*- 2285101Semaste * Copyright (c) 2009-2012 Microsoft Corp. 3285101Semaste * Copyright (c) 2012 NetApp Inc. 4285101Semaste * Copyright (c) 2012 Citrix Inc. 5285101Semaste * All rights reserved. 6285101Semaste * 7285101Semaste * Redistribution and use in source and binary forms, with or without 8285101Semaste * modification, are permitted provided that the following conditions 9285101Semaste * are met: 10314564Sdim * 1. Redistributions of source code must retain the above copyright 11285101Semaste * notice unmodified, this list of conditions, and the following 12314564Sdim * disclaimer. 13285101Semaste * 2. Redistributions in binary form must reproduce the above copyright 14285101Semaste * notice, this list of conditions and the following disclaimer in the 15285101Semaste * documentation and/or other materials provided with the distribution. 16285101Semaste * 17285101Semaste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18314564Sdim * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19285101Semaste * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20314564Sdim * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21285101Semaste * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22314564Sdim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23285101Semaste * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24314564Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25314564Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26314564Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27314564Sdim * 28314564Sdim * $FreeBSD: head/sys/dev/hyperv/include/hyperv.h 296083 2016-02-26 09:17:31Z sephe $ 29314564Sdim */ 30314564Sdim 31285101Semaste/** 32285101Semaste * HyperV definitions for messages that are sent between instances of the 33285101Semaste * Channel Management Library in separate partitions, or in some cases, 34314564Sdim * back to itself. 35285101Semaste */ 36314564Sdim 37314564Sdim#ifndef __HYPERV_H__ 38314564Sdim#define __HYPERV_H__ 39314564Sdim 40314564Sdim#include <sys/param.h> 41314564Sdim#include <sys/mbuf.h> 42314564Sdim#include <sys/queue.h> 43285101Semaste#include <sys/malloc.h> 44285101Semaste#include <sys/kthread.h> 45314564Sdim#include <sys/taskqueue.h> 46314564Sdim#include <sys/systm.h> 47314564Sdim#include <sys/lock.h> 48314564Sdim#include <sys/sema.h> 49314564Sdim#include <sys/smp.h> 50314564Sdim#include <sys/mutex.h> 51285101Semaste#include <sys/bus.h> 52314564Sdim#include <vm/vm.h> 53285101Semaste#include <vm/vm_param.h> 54285101Semaste#include <vm/pmap.h> 55314564Sdim 56314564Sdim#include <amd64/include/xen/synch_bitops.h> 57314564Sdim#include <amd64/include/atomic.h> 58314564Sdim 59314564Sdimtypedef uint8_t hv_bool_uint8_t; 60314564Sdim 61314564Sdim#define HV_S_OK 0x00000000 62285101Semaste#define HV_E_FAIL 0x80004005 63314564Sdim#define HV_ERROR_NOT_SUPPORTED 0x80070032 64285101Semaste#define HV_ERROR_MACHINE_LOCKED 0x800704F7 65285101Semaste 66314564Sdim/* 67314564Sdim * VMBUS version is 32 bit, upper 16 bit for major_number and lower 68314564Sdim * 16 bit for minor_number. 69314564Sdim * 70314564Sdim * 0.13 -- Windows Server 2008 71314564Sdim * 1.1 -- Windows 7 72314564Sdim * 2.4 -- Windows 8 73314564Sdim * 3.0 -- Windows 8.1 74314564Sdim */ 75314564Sdim#define HV_VMBUS_VERSION_WS2008 ((0 << 16) | (13)) 76285101Semaste#define HV_VMBUS_VERSION_WIN7 ((1 << 16) | (1)) 77314564Sdim#define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4)) 78285101Semaste#define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) 79314564Sdim 80285101Semaste#define HV_VMBUS_VERSION_INVALID -1 81285101Semaste 82314564Sdim#define HV_VMBUS_VERSION_CURRENT HV_VMBUS_VERSION_WIN8_1 83285101Semaste 84314564Sdim/* 85314564Sdim * Make maximum size of pipe payload of 16K 86314564Sdim */ 87285101Semaste 88314564Sdim#define HV_MAX_PIPE_DATA_PAYLOAD (sizeof(BYTE) * 16384) 89285101Semaste 90285101Semaste/* 91285101Semaste * Define pipe_mode values 92314564Sdim */ 93285101Semaste 94314564Sdim#define HV_VMBUS_PIPE_TYPE_BYTE 0x00000000 95285101Semaste#define HV_VMBUS_PIPE_TYPE_MESSAGE 0x00000004 96314564Sdim 97285101Semaste/* 98314564Sdim * The size of the user defined data buffer for non-pipe offers 99285101Semaste */ 100314564Sdim 101285101Semaste#define HV_MAX_USER_DEFINED_BYTES 120 102314564Sdim 103314564Sdim/* 104314564Sdim * The size of the user defined data buffer for pipe offers 105314564Sdim */ 106314564Sdim 107314564Sdim#define HV_MAX_PIPE_USER_DEFINED_BYTES 116 108285101Semaste 109314564Sdim 110285101Semaste#define HV_MAX_PAGE_BUFFER_COUNT 32 111285101Semaste#define HV_MAX_MULTIPAGE_BUFFER_COUNT 32 112285101Semaste 113314564Sdim#define HV_ALIGN_UP(value, align) \ 114314564Sdim (((value) & (align-1)) ? \ 115314564Sdim (((value) + (align-1)) & ~(align-1) ) : (value)) 116314564Sdim 117314564Sdim#define HV_ALIGN_DOWN(value, align) ( (value) & ~(align-1) ) 118314564Sdim 119285101Semaste#define HV_NUM_PAGES_SPANNED(addr, len) \ 120314564Sdim ((HV_ALIGN_UP(addr+len, PAGE_SIZE) - \ 121285101Semaste HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT ) 122285101Semaste 123285101Semastetypedef struct hv_guid { 124314564Sdim unsigned char data[16]; 125314564Sdim} __packed hv_guid; 126285101Semaste 127314564Sdim#define HV_NIC_GUID \ 128314564Sdim .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, \ 129314564Sdim 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E} 130314564Sdim 131285101Semaste#define HV_IDE_GUID \ 132314564Sdim .data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \ 133285101Semaste 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5} 134285101Semaste 135285101Semaste#define HV_SCSI_GUID \ 136314564Sdim .data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \ 137314564Sdim 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f} 138314564Sdim 139314564Sdim/* 140285101Semaste * At the center of the Channel Management library is 141314564Sdim * the Channel Offer. This struct contains the 142314564Sdim * fundamental information about an offer. 143314564Sdim */ 144314564Sdim 145285101Semastetypedef struct hv_vmbus_channel_offer { 146314564Sdim hv_guid interface_type; 147285101Semaste hv_guid interface_instance; 148314564Sdim uint64_t interrupt_latency_in_100ns_units; 149314564Sdim uint32_t interface_revision; 150314564Sdim uint32_t server_context_area_size; /* in bytes */ 151314564Sdim uint16_t channel_flags; 152285101Semaste uint16_t mmio_megabytes; /* in bytes * 1024 * 1024 */ 153285101Semaste union 154341825Sdim { 155341825Sdim /* 156341825Sdim * Non-pipes: The user has HV_MAX_USER_DEFINED_BYTES bytes. 157341825Sdim */ 158341825Sdim struct { 159341825Sdim uint8_t user_defined[HV_MAX_USER_DEFINED_BYTES]; 160341825Sdim } __packed standard; 161341825Sdim 162341825Sdim /* 163341825Sdim * Pipes: The following structure is an integrated pipe protocol, which 164341825Sdim * is implemented on top of standard user-defined data. pipe 165341825Sdim * clients have HV_MAX_PIPE_USER_DEFINED_BYTES left for their 166314564Sdim * own use. 167314564Sdim */ 168314564Sdim struct { 169314564Sdim uint32_t pipe_mode; 170285101Semaste uint8_t user_defined[HV_MAX_PIPE_USER_DEFINED_BYTES]; 171285101Semaste } __packed pipe; 172285101Semaste } u; 173314564Sdim 174314564Sdim /* 175314564Sdim * Sub_channel_index, newly added in Win8. 176314564Sdim */ 177314564Sdim uint16_t sub_channel_index; 178285101Semaste uint16_t padding; 179285101Semaste 180285101Semaste} __packed hv_vmbus_channel_offer; 181314564Sdim 182314564Sdimtypedef uint32_t hv_gpadl_handle; 183314564Sdim 184314564Sdimtypedef struct { 185314564Sdim uint16_t type; 186314564Sdim uint16_t data_offset8; 187285101Semaste uint16_t length8; 188285101Semaste uint16_t flags; 189285101Semaste uint64_t transaction_id; 190314564Sdim} __packed hv_vm_packet_descriptor; 191314564Sdim 192285101Semastetypedef uint32_t hv_previous_packet_offset; 193314564Sdim 194314564Sdimtypedef struct { 195314564Sdim hv_previous_packet_offset previous_packet_start_offset; 196314564Sdim hv_vm_packet_descriptor descriptor; 197314564Sdim} __packed hv_vm_packet_header; 198314564Sdim 199314564Sdimtypedef struct { 200314564Sdim uint32_t byte_count; 201314564Sdim uint32_t byte_offset; 202314564Sdim} __packed hv_vm_transfer_page; 203314564Sdim 204344779Sdimtypedef struct { 205314564Sdim hv_vm_packet_descriptor d; 206285101Semaste uint16_t transfer_page_set_id; 207314564Sdim hv_bool_uint8_t sender_owns_set; 208285101Semaste uint8_t reserved; 209314564Sdim uint32_t range_count; 210285101Semaste hv_vm_transfer_page ranges[1]; 211285101Semaste} __packed hv_vm_transfer_page_packet_header; 212285101Semaste 213314564Sdimtypedef struct { 214314564Sdim hv_vm_packet_descriptor d; 215285101Semaste uint32_t gpadl; 216314564Sdim uint32_t reserved; 217314564Sdim} __packed hv_vm_gpadl_packet_header; 218314564Sdim 219344779Sdimtypedef struct { 220314564Sdim hv_vm_packet_descriptor d; 221285101Semaste uint32_t gpadl; 222314564Sdim uint16_t transfer_page_set_id; 223285101Semaste uint16_t reserved; 224285101Semaste} __packed hv_vm_add_remove_transfer_page_set; 225285101Semaste 226314564Sdim/* 227314564Sdim * This structure defines a range in guest 228314564Sdim * physical space that can be made 229314564Sdim * to look virtually contiguous. 230314564Sdim */ 231314564Sdim 232314564Sdimtypedef struct { 233314564Sdim uint32_t byte_count; 234314564Sdim uint32_t byte_offset; 235314564Sdim uint64_t pfn_array[0]; 236344779Sdim} __packed hv_gpa_range; 237314564Sdim 238285101Semaste/* 239314564Sdim * This is the format for an Establish Gpadl packet, which contains a handle 240285101Semaste * by which this GPADL will be known and a set of GPA ranges associated with 241285101Semaste * it. This can be converted to a MDL by the guest OS. If there are multiple 242285101Semaste * GPA ranges, then the resulting MDL will be "chained," representing multiple 243314564Sdim * VA ranges. 244314564Sdim */ 245314564Sdim 246314564Sdimtypedef struct { 247314564Sdim hv_vm_packet_descriptor d; 248314564Sdim uint32_t gpadl; 249314564Sdim uint32_t range_count; 250314564Sdim hv_gpa_range range[1]; 251314564Sdim} __packed hv_vm_establish_gpadl; 252314564Sdim 253314564Sdim/* 254341825Sdim * This is the format for a Teardown Gpadl packet, which indicates that the 255341825Sdim * GPADL handle in the Establish Gpadl packet will never be referenced again. 256314564Sdim */ 257314564Sdim 258314564Sdimtypedef struct { 259314564Sdim hv_vm_packet_descriptor d; 260314564Sdim uint32_t gpadl; 261314564Sdim /* for alignment to a 8-byte boundary */ 262314564Sdim uint32_t reserved; 263314564Sdim} __packed hv_vm_teardown_gpadl; 264314564Sdim 265344779Sdim/* 266314564Sdim * This is the format for a GPA-Direct packet, which contains a set of GPA 267285101Semaste * ranges, in addition to commands and/or data. 268314564Sdim */ 269285101Semaste 270285101Semastetypedef struct { 271285101Semaste hv_vm_packet_descriptor d; 272314564Sdim uint32_t reserved; 273314564Sdim uint32_t range_count; 274314564Sdim hv_gpa_range range[1]; 275314564Sdim} __packed hv_vm_data_gpa_direct; 276314564Sdim 277314564Sdim/* 278285101Semaste * This is the format for a Additional data Packet. 279314564Sdim */ 280285101Semastetypedef struct { 281285101Semaste hv_vm_packet_descriptor d; 282314564Sdim uint64_t total_bytes; 283314564Sdim uint32_t byte_offset; 284314564Sdim uint32_t byte_count; 285314564Sdim uint8_t data[1]; 286314564Sdim} __packed hv_vm_additional_data; 287314564Sdim 288314564Sdimtypedef union { 289314564Sdim hv_vm_packet_descriptor simple_header; 290314564Sdim hv_vm_transfer_page_packet_header transfer_page_header; 291314564Sdim hv_vm_gpadl_packet_header gpadl_header; 292314564Sdim hv_vm_add_remove_transfer_page_set add_remove_transfer_page_header; 293314564Sdim hv_vm_establish_gpadl establish_gpadl_header; 294285101Semaste hv_vm_teardown_gpadl teardown_gpadl_header; 295314564Sdim hv_vm_data_gpa_direct data_gpa_direct_header; 296285101Semaste} __packed hv_vm_packet_largest_possible_header; 297314564Sdim 298314564Sdimtypedef enum { 299285101Semaste HV_VMBUS_PACKET_TYPE_INVALID = 0x0, 300314564Sdim HV_VMBUS_PACKET_TYPES_SYNCH = 0x1, 301285101Semaste HV_VMBUS_PACKET_TYPE_ADD_TRANSFER_PAGE_SET = 0x2, 302285101Semaste HV_VMBUS_PACKET_TYPE_REMOVE_TRANSFER_PAGE_SET = 0x3, 303314564Sdim HV_VMBUS_PACKET_TYPE_ESTABLISH_GPADL = 0x4, 304314564Sdim HV_VMBUS_PACKET_TYPE_TEAR_DOWN_GPADL = 0x5, 305314564Sdim HV_VMBUS_PACKET_TYPE_DATA_IN_BAND = 0x6, 306314564Sdim HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES = 0x7, 307314564Sdim HV_VMBUS_PACKET_TYPE_DATA_USING_GPADL = 0x8, 308314564Sdim HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT = 0x9, 309314564Sdim HV_VMBUS_PACKET_TYPE_CANCEL_REQUEST = 0xa, 310314564Sdim HV_VMBUS_PACKET_TYPE_COMPLETION = 0xb, 311314564Sdim HV_VMBUS_PACKET_TYPE_DATA_USING_ADDITIONAL_PACKETS = 0xc, 312285101Semaste HV_VMBUS_PACKET_TYPE_ADDITIONAL_DATA = 0xd 313314564Sdim} hv_vmbus_packet_type; 314314564Sdim 315314564Sdim#define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 316285101Semaste 317285101Semaste/* 318314564Sdim * Version 1 messages 319314564Sdim */ 320314564Sdimtypedef enum { 321314564Sdim HV_CHANNEL_MESSAGE_INVALID = 0, 322314564Sdim HV_CHANNEL_MESSAGE_OFFER_CHANNEL = 1, 323314564Sdim HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER = 2, 324314564Sdim HV_CHANNEL_MESSAGE_REQUEST_OFFERS = 3, 325314564Sdim HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED = 4, 326285101Semaste HV_CHANNEL_MESSAGE_OPEN_CHANNEL = 5, 327314564Sdim HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT = 6, 328285101Semaste HV_CHANNEL_MESSAGE_CLOSE_CHANNEL = 7, 329314564Sdim HV_CHANNEL_MESSAGEL_GPADL_HEADER = 8, 330314564Sdim HV_CHANNEL_MESSAGE_GPADL_BODY = 9, 331314564Sdim HV_CHANNEL_MESSAGE_GPADL_CREATED = 10, 332285101Semaste HV_CHANNEL_MESSAGE_GPADL_TEARDOWN = 11, 333285101Semaste HV_CHANNEL_MESSAGE_GPADL_TORNDOWN = 12, 334314564Sdim HV_CHANNEL_MESSAGE_REL_ID_RELEASED = 13, 335314564Sdim HV_CHANNEL_MESSAGE_INITIATED_CONTACT = 14, 336285101Semaste HV_CHANNEL_MESSAGE_VERSION_RESPONSE = 15, 337314564Sdim HV_CHANNEL_MESSAGE_UNLOAD = 16, 338314564Sdim HV_CHANNEL_MESSAGE_COUNT 339314564Sdim} hv_vmbus_channel_msg_type; 340314564Sdim 341314564Sdimtypedef struct { 342314564Sdim hv_vmbus_channel_msg_type message_type; 343314564Sdim uint32_t padding; 344285101Semaste} __packed hv_vmbus_channel_msg_header; 345314564Sdim 346285101Semaste/* 347285101Semaste * Query VMBus Version parameters 348314564Sdim */ 349314564Sdimtypedef struct { 350285101Semaste hv_vmbus_channel_msg_header header; 351314564Sdim uint32_t version; 352314564Sdim} __packed hv_vmbus_channel_query_vmbus_version; 353327952Sdim 354285101Semaste/* 355285101Semaste * VMBus Version Supported parameters 356285101Semaste */ 357314564Sdimtypedef struct { 358285101Semaste hv_vmbus_channel_msg_header header; 359285101Semaste hv_bool_uint8_t version_supported; 360314564Sdim} __packed hv_vmbus_channel_version_supported; 361285101Semaste 362285101Semaste/* 363314564Sdim * Channel Offer parameters 364285101Semaste */ 365314564Sdimtypedef struct { 366314564Sdim hv_vmbus_channel_msg_header header; 367314564Sdim hv_vmbus_channel_offer offer; 368314564Sdim uint32_t child_rel_id; 369285101Semaste uint8_t monitor_id; 370314564Sdim /* 371285101Semaste * This field has been split into a bit field on Win7 372285101Semaste * and higher. 373314564Sdim */ 374314564Sdim uint8_t monitor_allocated:1; 375285101Semaste uint8_t reserved:7; 376314564Sdim /* 377314564Sdim * Following fields were added in win7 and higher. 378314564Sdim * Make sure to check the version before accessing these fields. 379314564Sdim * 380314564Sdim * If "is_dedicated_interrupt" is set, we must not set the 381314564Sdim * associated bit in the channel bitmap while sending the 382314564Sdim * interrupt to the host. 383314564Sdim * 384314564Sdim * connection_id is used in signaling the host. 385285101Semaste */ 386314564Sdim uint16_t is_dedicated_interrupt:1; 387285101Semaste uint16_t reserved1:15; 388285101Semaste uint32_t connection_id; 389314564Sdim} __packed hv_vmbus_channel_offer_channel; 390285101Semaste 391285101Semaste/* 392314564Sdim * Rescind Offer parameters 393285101Semaste */ 394314564Sdimtypedef struct 395285101Semaste{ 396314564Sdim hv_vmbus_channel_msg_header header; 397314564Sdim uint32_t child_rel_id; 398314564Sdim} __packed hv_vmbus_channel_rescind_offer; 399285101Semaste 400285101Semaste 401314564Sdim/* 402285101Semaste * Request Offer -- no parameters, SynIC message contains the partition ID 403314564Sdim * 404314564Sdim * Set Snoop -- no parameters, SynIC message contains the partition ID 405285101Semaste * 406285101Semaste * Clear Snoop -- no parameters, SynIC message contains the partition ID 407314564Sdim * 408314564Sdim * All Offers Delivered -- no parameters, SynIC message contains the 409314564Sdim * partition ID 410314564Sdim * 411314564Sdim * Flush Client -- no parameters, SynIC message contains the partition ID 412314564Sdim */ 413314564Sdim 414314564Sdim 415314564Sdim/* 416314564Sdim * Open Channel parameters 417314564Sdim */ 418314564Sdimtypedef struct 419314564Sdim{ 420285101Semaste hv_vmbus_channel_msg_header header; 421285101Semaste 422314564Sdim /* 423285101Semaste * Identifies the specific VMBus channel that is being opened. 424314564Sdim */ 425314564Sdim uint32_t child_rel_id; 426314564Sdim 427314564Sdim /* 428314564Sdim * ID making a particular open request at a channel offer unique. 429314564Sdim */ 430285101Semaste uint32_t open_id; 431285101Semaste 432314564Sdim /* 433314564Sdim * GPADL for the channel's ring buffer. 434314564Sdim */ 435285101Semaste hv_gpadl_handle ring_buffer_gpadl_handle; 436314564Sdim 437314564Sdim /* 438314564Sdim * Before win8, all incoming channel interrupts are only 439314564Sdim * delivered on cpu 0. Setting this value to 0 would 440314564Sdim * preserve the earlier behavior. 441344779Sdim */ 442314564Sdim uint32_t target_vcpu; 443314564Sdim 444314564Sdim /* 445314564Sdim * The upstream ring buffer begins at offset zero in the memory described 446285101Semaste * by ring_buffer_gpadl_handle. The downstream ring buffer follows it at 447314564Sdim * this offset (in pages). 448314564Sdim */ 449285101Semaste uint32_t downstream_ring_buffer_page_offset; 450314564Sdim 451285101Semaste /* 452314564Sdim * User-specific data to be passed along to the server endpoint. 453285101Semaste */ 454285101Semaste uint8_t user_data[HV_MAX_USER_DEFINED_BYTES]; 455314564Sdim 456314564Sdim} __packed hv_vmbus_channel_open_channel; 457314564Sdim 458314564Sdimtypedef uint32_t hv_nt_status; 459314564Sdim 460314564Sdim/* 461314564Sdim * Open Channel Result parameters 462314564Sdim */ 463314564Sdimtypedef struct 464314564Sdim{ 465314564Sdim hv_vmbus_channel_msg_header header; 466314564Sdim uint32_t child_rel_id; 467314564Sdim uint32_t open_id; 468314564Sdim hv_nt_status status; 469314564Sdim} __packed hv_vmbus_channel_open_result; 470285101Semaste 471314564Sdim/* 472285101Semaste * Close channel parameters 473285101Semaste */ 474314564Sdimtypedef struct 475285101Semaste{ 476285101Semaste hv_vmbus_channel_msg_header header; 477285101Semaste uint32_t child_rel_id; 478314564Sdim} __packed hv_vmbus_channel_close_channel; 479314564Sdim 480314564Sdim/* 481314564Sdim * Channel Message GPADL 482314564Sdim */ 483314564Sdim#define HV_GPADL_TYPE_RING_BUFFER 1 484314564Sdim#define HV_GPADL_TYPE_SERVER_SAVE_AREA 2 485314564Sdim#define HV_GPADL_TYPE_TRANSACTION 8 486314564Sdim 487314564Sdim/* 488314564Sdim * The number of PFNs in a GPADL message is defined by the number of pages 489314564Sdim * that would be spanned by byte_count and byte_offset. If the implied number 490314564Sdim * of PFNs won't fit in this packet, there will be a follow-up packet that 491314564Sdim * contains more 492314564Sdim */ 493314564Sdim 494314564Sdimtypedef struct { 495314564Sdim hv_vmbus_channel_msg_header header; 496314564Sdim uint32_t child_rel_id; 497314564Sdim uint32_t gpadl; 498314564Sdim uint16_t range_buf_len; 499314564Sdim uint16_t range_count; 500314564Sdim hv_gpa_range range[0]; 501314564Sdim} __packed hv_vmbus_channel_gpadl_header; 502314564Sdim 503314564Sdim/* 504314564Sdim * This is the follow-up packet that contains more PFNs 505314564Sdim */ 506314564Sdimtypedef struct { 507314564Sdim hv_vmbus_channel_msg_header header; 508314564Sdim uint32_t message_number; 509314564Sdim uint32_t gpadl; 510314564Sdim uint64_t pfn[0]; 511314564Sdim} __packed hv_vmbus_channel_gpadl_body; 512314564Sdim 513314564Sdimtypedef struct { 514314564Sdim hv_vmbus_channel_msg_header header; 515314564Sdim uint32_t child_rel_id; 516314564Sdim uint32_t gpadl; 517314564Sdim uint32_t creation_status; 518314564Sdim} __packed hv_vmbus_channel_gpadl_created; 519314564Sdim 520314564Sdimtypedef struct { 521314564Sdim hv_vmbus_channel_msg_header header; 522314564Sdim uint32_t child_rel_id; 523314564Sdim uint32_t gpadl; 524314564Sdim} __packed hv_vmbus_channel_gpadl_teardown; 525314564Sdim 526314564Sdimtypedef struct { 527314564Sdim hv_vmbus_channel_msg_header header; 528314564Sdim uint32_t gpadl; 529314564Sdim} __packed hv_vmbus_channel_gpadl_torndown; 530285101Semaste 531314564Sdimtypedef struct { 532285101Semaste hv_vmbus_channel_msg_header header; 533285101Semaste uint32_t child_rel_id; 534314564Sdim} __packed hv_vmbus_channel_relid_released; 535314564Sdim 536314564Sdimtypedef struct { 537314564Sdim hv_vmbus_channel_msg_header header; 538314564Sdim uint32_t vmbus_version_requested; 539314564Sdim uint32_t padding2; 540285101Semaste uint64_t interrupt_page; 541314564Sdim uint64_t monitor_page_1; 542285101Semaste 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 taskqueue * rxq; 757 struct task channel_task; 758 hv_vmbus_pfn_channel_callback on_channel_callback; 759 void* channel_callback_context; 760 761 /* 762 * If batched_reading is set to "true", mask the interrupt 763 * and read until the channel is empty. 764 * If batched_reading is set to "false", the channel is not 765 * going to perform batched reading. 766 * 767 * Batched reading is enabled by default; specific 768 * drivers that don't want this behavior can turn it off. 769 */ 770 boolean_t batched_reading; 771 772 boolean_t is_dedicated_interrupt; 773 774 /* 775 * Used as an input param for HV_CALL_SIGNAL_EVENT hypercall. 776 */ 777 hv_vmbus_input_signal_event_buffer signal_event_buffer; 778 /* 779 * 8-bytes aligned of the buffer above 780 */ 781 hv_vmbus_input_signal_event *signal_event_param; 782 783 /* 784 * From Win8, this field specifies the target virtual process 785 * on which to deliver the interupt from the host to guest. 786 * Before Win8, all channel interrupts would only be 787 * delivered on cpu 0. Setting this value to 0 would preserve 788 * the earlier behavior. 789 */ 790 uint32_t target_vcpu; 791 /* The corresponding CPUID in the guest */ 792 uint32_t target_cpu; 793 794 /* 795 * Support for multi-channels. 796 * The initial offer is considered the primary channel and this 797 * offer message will indicate if the host supports multi-channels. 798 * The guest is free to ask for multi-channels to be offerred and can 799 * open these multi-channels as a normal "primary" channel. However, 800 * all multi-channels will have the same type and instance guids as the 801 * primary channel. Requests sent on a given channel will result in a 802 * response on the same channel. 803 */ 804 805 /* 806 * Multi-channel creation callback. This callback will be called in 807 * process context when a Multi-channel offer is received from the host. 808 * The guest can open the Multi-channel in the context of this callback. 809 */ 810 hv_vmbus_sc_creation_callback sc_creation_callback; 811 812 struct mtx sc_lock; 813 814 /* 815 * Link list of all the multi-channels if this is a primary channel 816 */ 817 TAILQ_HEAD(, hv_vmbus_channel) sc_list_anchor; 818 TAILQ_ENTRY(hv_vmbus_channel) sc_list_entry; 819 820 /* 821 * The primary channel this sub-channle belongs to. 822 * This will be NULL for the primary channel. 823 */ 824 struct hv_vmbus_channel *primary_channel; 825 /* 826 * Support per channel state for use by vmbus drivers. 827 */ 828 void *per_channel_state; 829} hv_vmbus_channel; 830 831static inline void 832hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t state) 833{ 834 channel->batched_reading = state; 835} 836 837typedef struct hv_device { 838 hv_guid class_id; 839 hv_guid device_id; 840 device_t device; 841 hv_vmbus_channel* channel; 842} hv_device; 843 844 845 846int hv_vmbus_channel_recv_packet( 847 hv_vmbus_channel* channel, 848 void* buffer, 849 uint32_t buffer_len, 850 uint32_t* buffer_actual_len, 851 uint64_t* request_id); 852 853int hv_vmbus_channel_recv_packet_raw( 854 hv_vmbus_channel* channel, 855 void* buffer, 856 uint32_t buffer_len, 857 uint32_t* buffer_actual_len, 858 uint64_t* request_id); 859 860int hv_vmbus_channel_open( 861 hv_vmbus_channel* channel, 862 uint32_t send_ring_buffer_size, 863 uint32_t recv_ring_buffer_size, 864 void* user_data, 865 uint32_t user_data_len, 866 hv_vmbus_pfn_channel_callback 867 pfn_on_channel_callback, 868 void* context); 869 870void hv_vmbus_channel_close(hv_vmbus_channel *channel); 871 872int hv_vmbus_channel_send_packet( 873 hv_vmbus_channel* channel, 874 void* buffer, 875 uint32_t buffer_len, 876 uint64_t request_id, 877 hv_vmbus_packet_type type, 878 uint32_t flags); 879 880int hv_vmbus_channel_send_packet_pagebuffer( 881 hv_vmbus_channel* channel, 882 hv_vmbus_page_buffer page_buffers[], 883 uint32_t page_count, 884 void* buffer, 885 uint32_t buffer_len, 886 uint64_t request_id); 887 888int hv_vmbus_channel_send_packet_multipagebuffer( 889 hv_vmbus_channel* channel, 890 hv_vmbus_multipage_buffer* multi_page_buffer, 891 void* buffer, 892 uint32_t buffer_len, 893 uint64_t request_id); 894 895int hv_vmbus_channel_establish_gpadl( 896 hv_vmbus_channel* channel, 897 /* must be phys and virt contiguous */ 898 void* contig_buffer, 899 /* page-size multiple */ 900 uint32_t size, 901 uint32_t* gpadl_handle); 902 903int hv_vmbus_channel_teardown_gpdal( 904 hv_vmbus_channel* channel, 905 uint32_t gpadl_handle); 906 907struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary); 908 909/** 910 * @brief Get physical address from virtual 911 */ 912static inline unsigned long 913hv_get_phys_addr(void *virt) 914{ 915 unsigned long ret; 916 ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK)); 917 return (ret); 918} 919 920extern uint32_t hv_vmbus_protocal_version; 921#endif /* __HYPERV_H__ */ 922