146a97191SGreg Kroah-Hartman /* 246a97191SGreg Kroah-Hartman * 346a97191SGreg Kroah-Hartman * Copyright (c) 2011, Microsoft Corporation. 446a97191SGreg Kroah-Hartman * 546a97191SGreg Kroah-Hartman * This program is free software; you can redistribute it and/or modify it 646a97191SGreg Kroah-Hartman * under the terms and conditions of the GNU General Public License, 746a97191SGreg Kroah-Hartman * version 2, as published by the Free Software Foundation. 846a97191SGreg Kroah-Hartman * 946a97191SGreg Kroah-Hartman * This program is distributed in the hope it will be useful, but WITHOUT 1046a97191SGreg Kroah-Hartman * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1146a97191SGreg Kroah-Hartman * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 1246a97191SGreg Kroah-Hartman * more details. 1346a97191SGreg Kroah-Hartman * 1446a97191SGreg Kroah-Hartman * You should have received a copy of the GNU General Public License along with 1546a97191SGreg Kroah-Hartman * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 1646a97191SGreg Kroah-Hartman * Place - Suite 330, Boston, MA 02111-1307 USA. 1746a97191SGreg Kroah-Hartman * 1846a97191SGreg Kroah-Hartman * Authors: 1946a97191SGreg Kroah-Hartman * Haiyang Zhang <[email protected]> 2046a97191SGreg Kroah-Hartman * Hank Janssen <[email protected]> 2146a97191SGreg Kroah-Hartman * K. Y. Srinivasan <[email protected]> 2246a97191SGreg Kroah-Hartman * 2346a97191SGreg Kroah-Hartman */ 2446a97191SGreg Kroah-Hartman 2546a97191SGreg Kroah-Hartman #ifndef _HYPERV_H 2646a97191SGreg Kroah-Hartman #define _HYPERV_H 2746a97191SGreg Kroah-Hartman 285267cf02SBjarke Istrup Pedersen #include <uapi/linux/hyperv.h> 295267cf02SBjarke Istrup Pedersen 302939437cSK. Y. Srinivasan #include <linux/types.h> 3146a97191SGreg Kroah-Hartman #include <linux/scatterlist.h> 3246a97191SGreg Kroah-Hartman #include <linux/list.h> 3346a97191SGreg Kroah-Hartman #include <linux/timer.h> 3446a97191SGreg Kroah-Hartman #include <linux/workqueue.h> 3546a97191SGreg Kroah-Hartman #include <linux/completion.h> 3646a97191SGreg Kroah-Hartman #include <linux/device.h> 3746a97191SGreg Kroah-Hartman #include <linux/mod_devicetable.h> 3846a97191SGreg Kroah-Hartman 3946a97191SGreg Kroah-Hartman 407e5ec368SK. Y. Srinivasan #define MAX_PAGE_BUFFER_COUNT 32 4146a97191SGreg Kroah-Hartman #define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */ 4246a97191SGreg Kroah-Hartman 4346a97191SGreg Kroah-Hartman #pragma pack(push, 1) 4446a97191SGreg Kroah-Hartman 4546a97191SGreg Kroah-Hartman /* Single-page buffer */ 4646a97191SGreg Kroah-Hartman struct hv_page_buffer { 4746a97191SGreg Kroah-Hartman u32 len; 4846a97191SGreg Kroah-Hartman u32 offset; 4946a97191SGreg Kroah-Hartman u64 pfn; 5046a97191SGreg Kroah-Hartman }; 5146a97191SGreg Kroah-Hartman 5246a97191SGreg Kroah-Hartman /* Multiple-page buffer */ 5346a97191SGreg Kroah-Hartman struct hv_multipage_buffer { 5446a97191SGreg Kroah-Hartman /* Length and Offset determines the # of pfns in the array */ 5546a97191SGreg Kroah-Hartman u32 len; 5646a97191SGreg Kroah-Hartman u32 offset; 5746a97191SGreg Kroah-Hartman u64 pfn_array[MAX_MULTIPAGE_BUFFER_COUNT]; 5846a97191SGreg Kroah-Hartman }; 5946a97191SGreg Kroah-Hartman 6046a97191SGreg Kroah-Hartman /* 0x18 includes the proprietary packet header */ 6146a97191SGreg Kroah-Hartman #define MAX_PAGE_BUFFER_PACKET (0x18 + \ 6246a97191SGreg Kroah-Hartman (sizeof(struct hv_page_buffer) * \ 6346a97191SGreg Kroah-Hartman MAX_PAGE_BUFFER_COUNT)) 6446a97191SGreg Kroah-Hartman #define MAX_MULTIPAGE_BUFFER_PACKET (0x18 + \ 6546a97191SGreg Kroah-Hartman sizeof(struct hv_multipage_buffer)) 6646a97191SGreg Kroah-Hartman 6746a97191SGreg Kroah-Hartman 6846a97191SGreg Kroah-Hartman #pragma pack(pop) 6946a97191SGreg Kroah-Hartman 7046a97191SGreg Kroah-Hartman struct hv_ring_buffer { 7146a97191SGreg Kroah-Hartman /* Offset in bytes from the start of ring data below */ 7246a97191SGreg Kroah-Hartman u32 write_index; 7346a97191SGreg Kroah-Hartman 7446a97191SGreg Kroah-Hartman /* Offset in bytes from the start of ring data below */ 7546a97191SGreg Kroah-Hartman u32 read_index; 7646a97191SGreg Kroah-Hartman 7746a97191SGreg Kroah-Hartman u32 interrupt_mask; 7846a97191SGreg Kroah-Hartman 792416603eSK. Y. Srinivasan /* 802416603eSK. Y. Srinivasan * Win8 uses some of the reserved bits to implement 812416603eSK. Y. Srinivasan * interrupt driven flow management. On the send side 822416603eSK. Y. Srinivasan * we can request that the receiver interrupt the sender 832416603eSK. Y. Srinivasan * when the ring transitions from being full to being able 842416603eSK. Y. Srinivasan * to handle a message of size "pending_send_sz". 852416603eSK. Y. Srinivasan * 862416603eSK. Y. Srinivasan * Add necessary state for this enhancement. 8746a97191SGreg Kroah-Hartman */ 882416603eSK. Y. Srinivasan u32 pending_send_sz; 892416603eSK. Y. Srinivasan 902416603eSK. Y. Srinivasan u32 reserved1[12]; 912416603eSK. Y. Srinivasan 922416603eSK. Y. Srinivasan union { 932416603eSK. Y. Srinivasan struct { 942416603eSK. Y. Srinivasan u32 feat_pending_send_sz:1; 952416603eSK. Y. Srinivasan }; 962416603eSK. Y. Srinivasan u32 value; 972416603eSK. Y. Srinivasan } feature_bits; 982416603eSK. Y. Srinivasan 992416603eSK. Y. Srinivasan /* Pad it to PAGE_SIZE so that data starts on page boundary */ 1002416603eSK. Y. Srinivasan u8 reserved2[4028]; 10146a97191SGreg Kroah-Hartman 10246a97191SGreg Kroah-Hartman /* 10346a97191SGreg Kroah-Hartman * Ring data starts here + RingDataStartOffset 10446a97191SGreg Kroah-Hartman * !!! DO NOT place any fields below this !!! 10546a97191SGreg Kroah-Hartman */ 10646a97191SGreg Kroah-Hartman u8 buffer[0]; 10746a97191SGreg Kroah-Hartman } __packed; 10846a97191SGreg Kroah-Hartman 10946a97191SGreg Kroah-Hartman struct hv_ring_buffer_info { 11046a97191SGreg Kroah-Hartman struct hv_ring_buffer *ring_buffer; 11146a97191SGreg Kroah-Hartman u32 ring_size; /* Include the shared header */ 11246a97191SGreg Kroah-Hartman spinlock_t ring_lock; 11346a97191SGreg Kroah-Hartman 11446a97191SGreg Kroah-Hartman u32 ring_datasize; /* < ring_size */ 11546a97191SGreg Kroah-Hartman u32 ring_data_startoffset; 11646a97191SGreg Kroah-Hartman }; 11746a97191SGreg Kroah-Hartman 11833be96e4SHaiyang Zhang /* 11933be96e4SHaiyang Zhang * 12033be96e4SHaiyang Zhang * hv_get_ringbuffer_availbytes() 12133be96e4SHaiyang Zhang * 12233be96e4SHaiyang Zhang * Get number of bytes available to read and to write to 12333be96e4SHaiyang Zhang * for the specified ring buffer 12433be96e4SHaiyang Zhang */ 12533be96e4SHaiyang Zhang static inline void 12633be96e4SHaiyang Zhang hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, 12733be96e4SHaiyang Zhang u32 *read, u32 *write) 12833be96e4SHaiyang Zhang { 12933be96e4SHaiyang Zhang u32 read_loc, write_loc, dsize; 13033be96e4SHaiyang Zhang 13133be96e4SHaiyang Zhang smp_read_barrier_depends(); 13233be96e4SHaiyang Zhang 13333be96e4SHaiyang Zhang /* Capture the read/write indices before they changed */ 13433be96e4SHaiyang Zhang read_loc = rbi->ring_buffer->read_index; 13533be96e4SHaiyang Zhang write_loc = rbi->ring_buffer->write_index; 13633be96e4SHaiyang Zhang dsize = rbi->ring_datasize; 13733be96e4SHaiyang Zhang 13833be96e4SHaiyang Zhang *write = write_loc >= read_loc ? dsize - (write_loc - read_loc) : 13933be96e4SHaiyang Zhang read_loc - write_loc; 14033be96e4SHaiyang Zhang *read = dsize - *write; 14133be96e4SHaiyang Zhang } 14233be96e4SHaiyang Zhang 143eafa7072SK. Y. Srinivasan /* 144eafa7072SK. Y. Srinivasan * VMBUS version is 32 bit entity broken up into 145eafa7072SK. Y. Srinivasan * two 16 bit quantities: major_number. minor_number. 146eafa7072SK. Y. Srinivasan * 147eafa7072SK. Y. Srinivasan * 0 . 13 (Windows Server 2008) 148eafa7072SK. Y. Srinivasan * 1 . 1 (Windows 7) 149eafa7072SK. Y. Srinivasan * 2 . 4 (Windows 8) 15003367ef5SK. Y. Srinivasan * 3 . 0 (Windows 8 R2) 151eafa7072SK. Y. Srinivasan */ 152eafa7072SK. Y. Srinivasan 153eafa7072SK. Y. Srinivasan #define VERSION_WS2008 ((0 << 16) | (13)) 154eafa7072SK. Y. Srinivasan #define VERSION_WIN7 ((1 << 16) | (1)) 155eafa7072SK. Y. Srinivasan #define VERSION_WIN8 ((2 << 16) | (4)) 15603367ef5SK. Y. Srinivasan #define VERSION_WIN8_1 ((3 << 16) | (0)) 157eafa7072SK. Y. Srinivasan 158eafa7072SK. Y. Srinivasan #define VERSION_INVAL -1 159eafa7072SK. Y. Srinivasan 16003367ef5SK. Y. Srinivasan #define VERSION_CURRENT VERSION_WIN8_1 16146a97191SGreg Kroah-Hartman 16246a97191SGreg Kroah-Hartman /* Make maximum size of pipe payload of 16K */ 16346a97191SGreg Kroah-Hartman #define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384) 16446a97191SGreg Kroah-Hartman 16546a97191SGreg Kroah-Hartman /* Define PipeMode values. */ 16646a97191SGreg Kroah-Hartman #define VMBUS_PIPE_TYPE_BYTE 0x00000000 16746a97191SGreg Kroah-Hartman #define VMBUS_PIPE_TYPE_MESSAGE 0x00000004 16846a97191SGreg Kroah-Hartman 16946a97191SGreg Kroah-Hartman /* The size of the user defined data buffer for non-pipe offers. */ 17046a97191SGreg Kroah-Hartman #define MAX_USER_DEFINED_BYTES 120 17146a97191SGreg Kroah-Hartman 17246a97191SGreg Kroah-Hartman /* The size of the user defined data buffer for pipe offers. */ 17346a97191SGreg Kroah-Hartman #define MAX_PIPE_USER_DEFINED_BYTES 116 17446a97191SGreg Kroah-Hartman 17546a97191SGreg Kroah-Hartman /* 17646a97191SGreg Kroah-Hartman * At the center of the Channel Management library is the Channel Offer. This 17746a97191SGreg Kroah-Hartman * struct contains the fundamental information about an offer. 17846a97191SGreg Kroah-Hartman */ 17946a97191SGreg Kroah-Hartman struct vmbus_channel_offer { 18046a97191SGreg Kroah-Hartman uuid_le if_type; 18146a97191SGreg Kroah-Hartman uuid_le if_instance; 18229423b7eSK. Y. Srinivasan 18329423b7eSK. Y. Srinivasan /* 18429423b7eSK. Y. Srinivasan * These two fields are not currently used. 18529423b7eSK. Y. Srinivasan */ 18629423b7eSK. Y. Srinivasan u64 reserved1; 18729423b7eSK. Y. Srinivasan u64 reserved2; 18829423b7eSK. Y. Srinivasan 18946a97191SGreg Kroah-Hartman u16 chn_flags; 19046a97191SGreg Kroah-Hartman u16 mmio_megabytes; /* in bytes * 1024 * 1024 */ 19146a97191SGreg Kroah-Hartman 19246a97191SGreg Kroah-Hartman union { 19346a97191SGreg Kroah-Hartman /* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */ 19446a97191SGreg Kroah-Hartman struct { 19546a97191SGreg Kroah-Hartman unsigned char user_def[MAX_USER_DEFINED_BYTES]; 19646a97191SGreg Kroah-Hartman } std; 19746a97191SGreg Kroah-Hartman 19846a97191SGreg Kroah-Hartman /* 19946a97191SGreg Kroah-Hartman * Pipes: 20046a97191SGreg Kroah-Hartman * The following sructure is an integrated pipe protocol, which 20146a97191SGreg Kroah-Hartman * is implemented on top of standard user-defined data. Pipe 20246a97191SGreg Kroah-Hartman * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own 20346a97191SGreg Kroah-Hartman * use. 20446a97191SGreg Kroah-Hartman */ 20546a97191SGreg Kroah-Hartman struct { 20646a97191SGreg Kroah-Hartman u32 pipe_mode; 20746a97191SGreg Kroah-Hartman unsigned char user_def[MAX_PIPE_USER_DEFINED_BYTES]; 20846a97191SGreg Kroah-Hartman } pipe; 20946a97191SGreg Kroah-Hartman } u; 21029423b7eSK. Y. Srinivasan /* 21129423b7eSK. Y. Srinivasan * The sub_channel_index is defined in win8. 21229423b7eSK. Y. Srinivasan */ 21329423b7eSK. Y. Srinivasan u16 sub_channel_index; 21429423b7eSK. Y. Srinivasan u16 reserved3; 21546a97191SGreg Kroah-Hartman } __packed; 21646a97191SGreg Kroah-Hartman 21746a97191SGreg Kroah-Hartman /* Server Flags */ 21846a97191SGreg Kroah-Hartman #define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1 21946a97191SGreg Kroah-Hartman #define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES 2 22046a97191SGreg Kroah-Hartman #define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS 4 22146a97191SGreg Kroah-Hartman #define VMBUS_CHANNEL_NAMED_PIPE_MODE 0x10 22246a97191SGreg Kroah-Hartman #define VMBUS_CHANNEL_LOOPBACK_OFFER 0x100 22346a97191SGreg Kroah-Hartman #define VMBUS_CHANNEL_PARENT_OFFER 0x200 22446a97191SGreg Kroah-Hartman #define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400 22546a97191SGreg Kroah-Hartman 22646a97191SGreg Kroah-Hartman struct vmpacket_descriptor { 22746a97191SGreg Kroah-Hartman u16 type; 22846a97191SGreg Kroah-Hartman u16 offset8; 22946a97191SGreg Kroah-Hartman u16 len8; 23046a97191SGreg Kroah-Hartman u16 flags; 23146a97191SGreg Kroah-Hartman u64 trans_id; 23246a97191SGreg Kroah-Hartman } __packed; 23346a97191SGreg Kroah-Hartman 23446a97191SGreg Kroah-Hartman struct vmpacket_header { 23546a97191SGreg Kroah-Hartman u32 prev_pkt_start_offset; 23646a97191SGreg Kroah-Hartman struct vmpacket_descriptor descriptor; 23746a97191SGreg Kroah-Hartman } __packed; 23846a97191SGreg Kroah-Hartman 23946a97191SGreg Kroah-Hartman struct vmtransfer_page_range { 24046a97191SGreg Kroah-Hartman u32 byte_count; 24146a97191SGreg Kroah-Hartman u32 byte_offset; 24246a97191SGreg Kroah-Hartman } __packed; 24346a97191SGreg Kroah-Hartman 24446a97191SGreg Kroah-Hartman struct vmtransfer_page_packet_header { 24546a97191SGreg Kroah-Hartman struct vmpacket_descriptor d; 24646a97191SGreg Kroah-Hartman u16 xfer_pageset_id; 2471508d811SK. Y. Srinivasan u8 sender_owns_set; 24846a97191SGreg Kroah-Hartman u8 reserved; 24946a97191SGreg Kroah-Hartman u32 range_cnt; 25046a97191SGreg Kroah-Hartman struct vmtransfer_page_range ranges[1]; 25146a97191SGreg Kroah-Hartman } __packed; 25246a97191SGreg Kroah-Hartman 25346a97191SGreg Kroah-Hartman struct vmgpadl_packet_header { 25446a97191SGreg Kroah-Hartman struct vmpacket_descriptor d; 25546a97191SGreg Kroah-Hartman u32 gpadl; 25646a97191SGreg Kroah-Hartman u32 reserved; 25746a97191SGreg Kroah-Hartman } __packed; 25846a97191SGreg Kroah-Hartman 25946a97191SGreg Kroah-Hartman struct vmadd_remove_transfer_page_set { 26046a97191SGreg Kroah-Hartman struct vmpacket_descriptor d; 26146a97191SGreg Kroah-Hartman u32 gpadl; 26246a97191SGreg Kroah-Hartman u16 xfer_pageset_id; 26346a97191SGreg Kroah-Hartman u16 reserved; 26446a97191SGreg Kroah-Hartman } __packed; 26546a97191SGreg Kroah-Hartman 26646a97191SGreg Kroah-Hartman /* 26746a97191SGreg Kroah-Hartman * This structure defines a range in guest physical space that can be made to 26846a97191SGreg Kroah-Hartman * look virtually contiguous. 26946a97191SGreg Kroah-Hartman */ 27046a97191SGreg Kroah-Hartman struct gpa_range { 27146a97191SGreg Kroah-Hartman u32 byte_count; 27246a97191SGreg Kroah-Hartman u32 byte_offset; 27346a97191SGreg Kroah-Hartman u64 pfn_array[0]; 27446a97191SGreg Kroah-Hartman }; 27546a97191SGreg Kroah-Hartman 27646a97191SGreg Kroah-Hartman /* 27746a97191SGreg Kroah-Hartman * This is the format for an Establish Gpadl packet, which contains a handle by 27846a97191SGreg Kroah-Hartman * which this GPADL will be known and a set of GPA ranges associated with it. 27946a97191SGreg Kroah-Hartman * This can be converted to a MDL by the guest OS. If there are multiple GPA 28046a97191SGreg Kroah-Hartman * ranges, then the resulting MDL will be "chained," representing multiple VA 28146a97191SGreg Kroah-Hartman * ranges. 28246a97191SGreg Kroah-Hartman */ 28346a97191SGreg Kroah-Hartman struct vmestablish_gpadl { 28446a97191SGreg Kroah-Hartman struct vmpacket_descriptor d; 28546a97191SGreg Kroah-Hartman u32 gpadl; 28646a97191SGreg Kroah-Hartman u32 range_cnt; 28746a97191SGreg Kroah-Hartman struct gpa_range range[1]; 28846a97191SGreg Kroah-Hartman } __packed; 28946a97191SGreg Kroah-Hartman 29046a97191SGreg Kroah-Hartman /* 29146a97191SGreg Kroah-Hartman * This is the format for a Teardown Gpadl packet, which indicates that the 29246a97191SGreg Kroah-Hartman * GPADL handle in the Establish Gpadl packet will never be referenced again. 29346a97191SGreg Kroah-Hartman */ 29446a97191SGreg Kroah-Hartman struct vmteardown_gpadl { 29546a97191SGreg Kroah-Hartman struct vmpacket_descriptor d; 29646a97191SGreg Kroah-Hartman u32 gpadl; 29746a97191SGreg Kroah-Hartman u32 reserved; /* for alignment to a 8-byte boundary */ 29846a97191SGreg Kroah-Hartman } __packed; 29946a97191SGreg Kroah-Hartman 30046a97191SGreg Kroah-Hartman /* 30146a97191SGreg Kroah-Hartman * This is the format for a GPA-Direct packet, which contains a set of GPA 30246a97191SGreg Kroah-Hartman * ranges, in addition to commands and/or data. 30346a97191SGreg Kroah-Hartman */ 30446a97191SGreg Kroah-Hartman struct vmdata_gpa_direct { 30546a97191SGreg Kroah-Hartman struct vmpacket_descriptor d; 30646a97191SGreg Kroah-Hartman u32 reserved; 30746a97191SGreg Kroah-Hartman u32 range_cnt; 30846a97191SGreg Kroah-Hartman struct gpa_range range[1]; 30946a97191SGreg Kroah-Hartman } __packed; 31046a97191SGreg Kroah-Hartman 31146a97191SGreg Kroah-Hartman /* This is the format for a Additional Data Packet. */ 31246a97191SGreg Kroah-Hartman struct vmadditional_data { 31346a97191SGreg Kroah-Hartman struct vmpacket_descriptor d; 31446a97191SGreg Kroah-Hartman u64 total_bytes; 31546a97191SGreg Kroah-Hartman u32 offset; 31646a97191SGreg Kroah-Hartman u32 byte_cnt; 31746a97191SGreg Kroah-Hartman unsigned char data[1]; 31846a97191SGreg Kroah-Hartman } __packed; 31946a97191SGreg Kroah-Hartman 32046a97191SGreg Kroah-Hartman union vmpacket_largest_possible_header { 32146a97191SGreg Kroah-Hartman struct vmpacket_descriptor simple_hdr; 32246a97191SGreg Kroah-Hartman struct vmtransfer_page_packet_header xfer_page_hdr; 32346a97191SGreg Kroah-Hartman struct vmgpadl_packet_header gpadl_hdr; 32446a97191SGreg Kroah-Hartman struct vmadd_remove_transfer_page_set add_rm_xfer_page_hdr; 32546a97191SGreg Kroah-Hartman struct vmestablish_gpadl establish_gpadl_hdr; 32646a97191SGreg Kroah-Hartman struct vmteardown_gpadl teardown_gpadl_hdr; 32746a97191SGreg Kroah-Hartman struct vmdata_gpa_direct data_gpa_direct_hdr; 32846a97191SGreg Kroah-Hartman }; 32946a97191SGreg Kroah-Hartman 33046a97191SGreg Kroah-Hartman #define VMPACKET_DATA_START_ADDRESS(__packet) \ 33146a97191SGreg Kroah-Hartman (void *)(((unsigned char *)__packet) + \ 33246a97191SGreg Kroah-Hartman ((struct vmpacket_descriptor)__packet)->offset8 * 8) 33346a97191SGreg Kroah-Hartman 33446a97191SGreg Kroah-Hartman #define VMPACKET_DATA_LENGTH(__packet) \ 33546a97191SGreg Kroah-Hartman ((((struct vmpacket_descriptor)__packet)->len8 - \ 33646a97191SGreg Kroah-Hartman ((struct vmpacket_descriptor)__packet)->offset8) * 8) 33746a97191SGreg Kroah-Hartman 33846a97191SGreg Kroah-Hartman #define VMPACKET_TRANSFER_MODE(__packet) \ 33946a97191SGreg Kroah-Hartman (((struct IMPACT)__packet)->type) 34046a97191SGreg Kroah-Hartman 34146a97191SGreg Kroah-Hartman enum vmbus_packet_type { 34246a97191SGreg Kroah-Hartman VM_PKT_INVALID = 0x0, 34346a97191SGreg Kroah-Hartman VM_PKT_SYNCH = 0x1, 34446a97191SGreg Kroah-Hartman VM_PKT_ADD_XFER_PAGESET = 0x2, 34546a97191SGreg Kroah-Hartman VM_PKT_RM_XFER_PAGESET = 0x3, 34646a97191SGreg Kroah-Hartman VM_PKT_ESTABLISH_GPADL = 0x4, 34746a97191SGreg Kroah-Hartman VM_PKT_TEARDOWN_GPADL = 0x5, 34846a97191SGreg Kroah-Hartman VM_PKT_DATA_INBAND = 0x6, 34946a97191SGreg Kroah-Hartman VM_PKT_DATA_USING_XFER_PAGES = 0x7, 35046a97191SGreg Kroah-Hartman VM_PKT_DATA_USING_GPADL = 0x8, 35146a97191SGreg Kroah-Hartman VM_PKT_DATA_USING_GPA_DIRECT = 0x9, 35246a97191SGreg Kroah-Hartman VM_PKT_CANCEL_REQUEST = 0xa, 35346a97191SGreg Kroah-Hartman VM_PKT_COMP = 0xb, 35446a97191SGreg Kroah-Hartman VM_PKT_DATA_USING_ADDITIONAL_PKT = 0xc, 35546a97191SGreg Kroah-Hartman VM_PKT_ADDITIONAL_DATA = 0xd 35646a97191SGreg Kroah-Hartman }; 35746a97191SGreg Kroah-Hartman 35846a97191SGreg Kroah-Hartman #define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 35946a97191SGreg Kroah-Hartman 36046a97191SGreg Kroah-Hartman 36146a97191SGreg Kroah-Hartman /* Version 1 messages */ 36246a97191SGreg Kroah-Hartman enum vmbus_channel_message_type { 36346a97191SGreg Kroah-Hartman CHANNELMSG_INVALID = 0, 36446a97191SGreg Kroah-Hartman CHANNELMSG_OFFERCHANNEL = 1, 36546a97191SGreg Kroah-Hartman CHANNELMSG_RESCIND_CHANNELOFFER = 2, 36646a97191SGreg Kroah-Hartman CHANNELMSG_REQUESTOFFERS = 3, 36746a97191SGreg Kroah-Hartman CHANNELMSG_ALLOFFERS_DELIVERED = 4, 36846a97191SGreg Kroah-Hartman CHANNELMSG_OPENCHANNEL = 5, 36946a97191SGreg Kroah-Hartman CHANNELMSG_OPENCHANNEL_RESULT = 6, 37046a97191SGreg Kroah-Hartman CHANNELMSG_CLOSECHANNEL = 7, 37146a97191SGreg Kroah-Hartman CHANNELMSG_GPADL_HEADER = 8, 37246a97191SGreg Kroah-Hartman CHANNELMSG_GPADL_BODY = 9, 37346a97191SGreg Kroah-Hartman CHANNELMSG_GPADL_CREATED = 10, 37446a97191SGreg Kroah-Hartman CHANNELMSG_GPADL_TEARDOWN = 11, 37546a97191SGreg Kroah-Hartman CHANNELMSG_GPADL_TORNDOWN = 12, 37646a97191SGreg Kroah-Hartman CHANNELMSG_RELID_RELEASED = 13, 37746a97191SGreg Kroah-Hartman CHANNELMSG_INITIATE_CONTACT = 14, 37846a97191SGreg Kroah-Hartman CHANNELMSG_VERSION_RESPONSE = 15, 37946a97191SGreg Kroah-Hartman CHANNELMSG_UNLOAD = 16, 38046a97191SGreg Kroah-Hartman #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD 38146a97191SGreg Kroah-Hartman CHANNELMSG_VIEWRANGE_ADD = 17, 38246a97191SGreg Kroah-Hartman CHANNELMSG_VIEWRANGE_REMOVE = 18, 38346a97191SGreg Kroah-Hartman #endif 38446a97191SGreg Kroah-Hartman CHANNELMSG_COUNT 38546a97191SGreg Kroah-Hartman }; 38646a97191SGreg Kroah-Hartman 38746a97191SGreg Kroah-Hartman struct vmbus_channel_message_header { 38846a97191SGreg Kroah-Hartman enum vmbus_channel_message_type msgtype; 38946a97191SGreg Kroah-Hartman u32 padding; 39046a97191SGreg Kroah-Hartman } __packed; 39146a97191SGreg Kroah-Hartman 39246a97191SGreg Kroah-Hartman /* Query VMBus Version parameters */ 39346a97191SGreg Kroah-Hartman struct vmbus_channel_query_vmbus_version { 39446a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 39546a97191SGreg Kroah-Hartman u32 version; 39646a97191SGreg Kroah-Hartman } __packed; 39746a97191SGreg Kroah-Hartman 39846a97191SGreg Kroah-Hartman /* VMBus Version Supported parameters */ 39946a97191SGreg Kroah-Hartman struct vmbus_channel_version_supported { 40046a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 4011508d811SK. Y. Srinivasan u8 version_supported; 40246a97191SGreg Kroah-Hartman } __packed; 40346a97191SGreg Kroah-Hartman 40446a97191SGreg Kroah-Hartman /* Offer Channel parameters */ 40546a97191SGreg Kroah-Hartman struct vmbus_channel_offer_channel { 40646a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 40746a97191SGreg Kroah-Hartman struct vmbus_channel_offer offer; 40846a97191SGreg Kroah-Hartman u32 child_relid; 40946a97191SGreg Kroah-Hartman u8 monitorid; 41029423b7eSK. Y. Srinivasan /* 41129423b7eSK. Y. Srinivasan * win7 and beyond splits this field into a bit field. 41229423b7eSK. Y. Srinivasan */ 41329423b7eSK. Y. Srinivasan u8 monitor_allocated:1; 41429423b7eSK. Y. Srinivasan u8 reserved:7; 41529423b7eSK. Y. Srinivasan /* 41629423b7eSK. Y. Srinivasan * These are new fields added in win7 and later. 41729423b7eSK. Y. Srinivasan * Do not access these fields without checking the 41829423b7eSK. Y. Srinivasan * negotiated protocol. 41929423b7eSK. Y. Srinivasan * 42029423b7eSK. Y. Srinivasan * If "is_dedicated_interrupt" is set, we must not set the 42129423b7eSK. Y. Srinivasan * associated bit in the channel bitmap while sending the 42229423b7eSK. Y. Srinivasan * interrupt to the host. 42329423b7eSK. Y. Srinivasan * 42429423b7eSK. Y. Srinivasan * connection_id is to be used in signaling the host. 42529423b7eSK. Y. Srinivasan */ 42629423b7eSK. Y. Srinivasan u16 is_dedicated_interrupt:1; 42729423b7eSK. Y. Srinivasan u16 reserved1:15; 42829423b7eSK. Y. Srinivasan u32 connection_id; 42946a97191SGreg Kroah-Hartman } __packed; 43046a97191SGreg Kroah-Hartman 43146a97191SGreg Kroah-Hartman /* Rescind Offer parameters */ 43246a97191SGreg Kroah-Hartman struct vmbus_channel_rescind_offer { 43346a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 43446a97191SGreg Kroah-Hartman u32 child_relid; 43546a97191SGreg Kroah-Hartman } __packed; 43646a97191SGreg Kroah-Hartman 43746a97191SGreg Kroah-Hartman /* 43846a97191SGreg Kroah-Hartman * Request Offer -- no parameters, SynIC message contains the partition ID 43946a97191SGreg Kroah-Hartman * Set Snoop -- no parameters, SynIC message contains the partition ID 44046a97191SGreg Kroah-Hartman * Clear Snoop -- no parameters, SynIC message contains the partition ID 44146a97191SGreg Kroah-Hartman * All Offers Delivered -- no parameters, SynIC message contains the partition 44246a97191SGreg Kroah-Hartman * ID 44346a97191SGreg Kroah-Hartman * Flush Client -- no parameters, SynIC message contains the partition ID 44446a97191SGreg Kroah-Hartman */ 44546a97191SGreg Kroah-Hartman 44646a97191SGreg Kroah-Hartman /* Open Channel parameters */ 44746a97191SGreg Kroah-Hartman struct vmbus_channel_open_channel { 44846a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 44946a97191SGreg Kroah-Hartman 45046a97191SGreg Kroah-Hartman /* Identifies the specific VMBus channel that is being opened. */ 45146a97191SGreg Kroah-Hartman u32 child_relid; 45246a97191SGreg Kroah-Hartman 45346a97191SGreg Kroah-Hartman /* ID making a particular open request at a channel offer unique. */ 45446a97191SGreg Kroah-Hartman u32 openid; 45546a97191SGreg Kroah-Hartman 45646a97191SGreg Kroah-Hartman /* GPADL for the channel's ring buffer. */ 45746a97191SGreg Kroah-Hartman u32 ringbuffer_gpadlhandle; 45846a97191SGreg Kroah-Hartman 459abbf3b2aSK. Y. Srinivasan /* 460abbf3b2aSK. Y. Srinivasan * Starting with win8, this field will be used to specify 461abbf3b2aSK. Y. Srinivasan * the target virtual processor on which to deliver the interrupt for 462abbf3b2aSK. Y. Srinivasan * the host to guest communication. 463abbf3b2aSK. Y. Srinivasan * Prior to win8, incoming channel interrupts would only 464abbf3b2aSK. Y. Srinivasan * be delivered on cpu 0. Setting this value to 0 would 465abbf3b2aSK. Y. Srinivasan * preserve the earlier behavior. 466abbf3b2aSK. Y. Srinivasan */ 467abbf3b2aSK. Y. Srinivasan u32 target_vp; 46846a97191SGreg Kroah-Hartman 46946a97191SGreg Kroah-Hartman /* 47046a97191SGreg Kroah-Hartman * The upstream ring buffer begins at offset zero in the memory 47146a97191SGreg Kroah-Hartman * described by RingBufferGpadlHandle. The downstream ring buffer 47246a97191SGreg Kroah-Hartman * follows it at this offset (in pages). 47346a97191SGreg Kroah-Hartman */ 47446a97191SGreg Kroah-Hartman u32 downstream_ringbuffer_pageoffset; 47546a97191SGreg Kroah-Hartman 47646a97191SGreg Kroah-Hartman /* User-specific data to be passed along to the server endpoint. */ 47746a97191SGreg Kroah-Hartman unsigned char userdata[MAX_USER_DEFINED_BYTES]; 47846a97191SGreg Kroah-Hartman } __packed; 47946a97191SGreg Kroah-Hartman 48046a97191SGreg Kroah-Hartman /* Open Channel Result parameters */ 48146a97191SGreg Kroah-Hartman struct vmbus_channel_open_result { 48246a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 48346a97191SGreg Kroah-Hartman u32 child_relid; 48446a97191SGreg Kroah-Hartman u32 openid; 48546a97191SGreg Kroah-Hartman u32 status; 48646a97191SGreg Kroah-Hartman } __packed; 48746a97191SGreg Kroah-Hartman 48846a97191SGreg Kroah-Hartman /* Close channel parameters; */ 48946a97191SGreg Kroah-Hartman struct vmbus_channel_close_channel { 49046a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 49146a97191SGreg Kroah-Hartman u32 child_relid; 49246a97191SGreg Kroah-Hartman } __packed; 49346a97191SGreg Kroah-Hartman 49446a97191SGreg Kroah-Hartman /* Channel Message GPADL */ 49546a97191SGreg Kroah-Hartman #define GPADL_TYPE_RING_BUFFER 1 49646a97191SGreg Kroah-Hartman #define GPADL_TYPE_SERVER_SAVE_AREA 2 49746a97191SGreg Kroah-Hartman #define GPADL_TYPE_TRANSACTION 8 49846a97191SGreg Kroah-Hartman 49946a97191SGreg Kroah-Hartman /* 50046a97191SGreg Kroah-Hartman * The number of PFNs in a GPADL message is defined by the number of 50146a97191SGreg Kroah-Hartman * pages that would be spanned by ByteCount and ByteOffset. If the 50246a97191SGreg Kroah-Hartman * implied number of PFNs won't fit in this packet, there will be a 50346a97191SGreg Kroah-Hartman * follow-up packet that contains more. 50446a97191SGreg Kroah-Hartman */ 50546a97191SGreg Kroah-Hartman struct vmbus_channel_gpadl_header { 50646a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 50746a97191SGreg Kroah-Hartman u32 child_relid; 50846a97191SGreg Kroah-Hartman u32 gpadl; 50946a97191SGreg Kroah-Hartman u16 range_buflen; 51046a97191SGreg Kroah-Hartman u16 rangecount; 51146a97191SGreg Kroah-Hartman struct gpa_range range[0]; 51246a97191SGreg Kroah-Hartman } __packed; 51346a97191SGreg Kroah-Hartman 51446a97191SGreg Kroah-Hartman /* This is the followup packet that contains more PFNs. */ 51546a97191SGreg Kroah-Hartman struct vmbus_channel_gpadl_body { 51646a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 51746a97191SGreg Kroah-Hartman u32 msgnumber; 51846a97191SGreg Kroah-Hartman u32 gpadl; 51946a97191SGreg Kroah-Hartman u64 pfn[0]; 52046a97191SGreg Kroah-Hartman } __packed; 52146a97191SGreg Kroah-Hartman 52246a97191SGreg Kroah-Hartman struct vmbus_channel_gpadl_created { 52346a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 52446a97191SGreg Kroah-Hartman u32 child_relid; 52546a97191SGreg Kroah-Hartman u32 gpadl; 52646a97191SGreg Kroah-Hartman u32 creation_status; 52746a97191SGreg Kroah-Hartman } __packed; 52846a97191SGreg Kroah-Hartman 52946a97191SGreg Kroah-Hartman struct vmbus_channel_gpadl_teardown { 53046a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 53146a97191SGreg Kroah-Hartman u32 child_relid; 53246a97191SGreg Kroah-Hartman u32 gpadl; 53346a97191SGreg Kroah-Hartman } __packed; 53446a97191SGreg Kroah-Hartman 53546a97191SGreg Kroah-Hartman struct vmbus_channel_gpadl_torndown { 53646a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 53746a97191SGreg Kroah-Hartman u32 gpadl; 53846a97191SGreg Kroah-Hartman } __packed; 53946a97191SGreg Kroah-Hartman 54046a97191SGreg Kroah-Hartman #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD 54146a97191SGreg Kroah-Hartman struct vmbus_channel_view_range_add { 54246a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 54346a97191SGreg Kroah-Hartman PHYSICAL_ADDRESS viewrange_base; 54446a97191SGreg Kroah-Hartman u64 viewrange_length; 54546a97191SGreg Kroah-Hartman u32 child_relid; 54646a97191SGreg Kroah-Hartman } __packed; 54746a97191SGreg Kroah-Hartman 54846a97191SGreg Kroah-Hartman struct vmbus_channel_view_range_remove { 54946a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 55046a97191SGreg Kroah-Hartman PHYSICAL_ADDRESS viewrange_base; 55146a97191SGreg Kroah-Hartman u32 child_relid; 55246a97191SGreg Kroah-Hartman } __packed; 55346a97191SGreg Kroah-Hartman #endif 55446a97191SGreg Kroah-Hartman 55546a97191SGreg Kroah-Hartman struct vmbus_channel_relid_released { 55646a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 55746a97191SGreg Kroah-Hartman u32 child_relid; 55846a97191SGreg Kroah-Hartman } __packed; 55946a97191SGreg Kroah-Hartman 56046a97191SGreg Kroah-Hartman struct vmbus_channel_initiate_contact { 56146a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 56246a97191SGreg Kroah-Hartman u32 vmbus_version_requested; 563e28bab48SK. Y. Srinivasan u32 target_vcpu; /* The VCPU the host should respond to */ 56446a97191SGreg Kroah-Hartman u64 interrupt_page; 56546a97191SGreg Kroah-Hartman u64 monitor_page1; 56646a97191SGreg Kroah-Hartman u64 monitor_page2; 56746a97191SGreg Kroah-Hartman } __packed; 56846a97191SGreg Kroah-Hartman 56946a97191SGreg Kroah-Hartman struct vmbus_channel_version_response { 57046a97191SGreg Kroah-Hartman struct vmbus_channel_message_header header; 5711508d811SK. Y. Srinivasan u8 version_supported; 57246a97191SGreg Kroah-Hartman } __packed; 57346a97191SGreg Kroah-Hartman 57446a97191SGreg Kroah-Hartman enum vmbus_channel_state { 57546a97191SGreg Kroah-Hartman CHANNEL_OFFER_STATE, 57646a97191SGreg Kroah-Hartman CHANNEL_OPENING_STATE, 57746a97191SGreg Kroah-Hartman CHANNEL_OPEN_STATE, 578e68d2971SK. Y. Srinivasan CHANNEL_OPENED_STATE, 57946a97191SGreg Kroah-Hartman }; 58046a97191SGreg Kroah-Hartman 58146a97191SGreg Kroah-Hartman /* 58246a97191SGreg Kroah-Hartman * Represents each channel msg on the vmbus connection This is a 58346a97191SGreg Kroah-Hartman * variable-size data structure depending on the msg type itself 58446a97191SGreg Kroah-Hartman */ 58546a97191SGreg Kroah-Hartman struct vmbus_channel_msginfo { 58646a97191SGreg Kroah-Hartman /* Bookkeeping stuff */ 58746a97191SGreg Kroah-Hartman struct list_head msglistentry; 58846a97191SGreg Kroah-Hartman 58946a97191SGreg Kroah-Hartman /* So far, this is only used to handle gpadl body message */ 59046a97191SGreg Kroah-Hartman struct list_head submsglist; 59146a97191SGreg Kroah-Hartman 59246a97191SGreg Kroah-Hartman /* Synchronize the request/response if needed */ 59346a97191SGreg Kroah-Hartman struct completion waitevent; 59446a97191SGreg Kroah-Hartman union { 59546a97191SGreg Kroah-Hartman struct vmbus_channel_version_supported version_supported; 59646a97191SGreg Kroah-Hartman struct vmbus_channel_open_result open_result; 59746a97191SGreg Kroah-Hartman struct vmbus_channel_gpadl_torndown gpadl_torndown; 59846a97191SGreg Kroah-Hartman struct vmbus_channel_gpadl_created gpadl_created; 59946a97191SGreg Kroah-Hartman struct vmbus_channel_version_response version_response; 60046a97191SGreg Kroah-Hartman } response; 60146a97191SGreg Kroah-Hartman 60246a97191SGreg Kroah-Hartman u32 msgsize; 60346a97191SGreg Kroah-Hartman /* 60446a97191SGreg Kroah-Hartman * The channel message that goes out on the "wire". 60546a97191SGreg Kroah-Hartman * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header 60646a97191SGreg Kroah-Hartman */ 60746a97191SGreg Kroah-Hartman unsigned char msg[0]; 60846a97191SGreg Kroah-Hartman }; 60946a97191SGreg Kroah-Hartman 61046a97191SGreg Kroah-Hartman struct vmbus_close_msg { 61146a97191SGreg Kroah-Hartman struct vmbus_channel_msginfo info; 61246a97191SGreg Kroah-Hartman struct vmbus_channel_close_channel msg; 61346a97191SGreg Kroah-Hartman }; 61446a97191SGreg Kroah-Hartman 615b3bf60c7SK. Y. Srinivasan /* Define connection identifier type. */ 616b3bf60c7SK. Y. Srinivasan union hv_connection_id { 617b3bf60c7SK. Y. Srinivasan u32 asu32; 618b3bf60c7SK. Y. Srinivasan struct { 619b3bf60c7SK. Y. Srinivasan u32 id:24; 620b3bf60c7SK. Y. Srinivasan u32 reserved:8; 621b3bf60c7SK. Y. Srinivasan } u; 622b3bf60c7SK. Y. Srinivasan }; 623b3bf60c7SK. Y. Srinivasan 624b3bf60c7SK. Y. Srinivasan /* Definition of the hv_signal_event hypercall input structure. */ 625b3bf60c7SK. Y. Srinivasan struct hv_input_signal_event { 626b3bf60c7SK. Y. Srinivasan union hv_connection_id connectionid; 627b3bf60c7SK. Y. Srinivasan u16 flag_number; 628b3bf60c7SK. Y. Srinivasan u16 rsvdz; 629b3bf60c7SK. Y. Srinivasan }; 630b3bf60c7SK. Y. Srinivasan 631b3bf60c7SK. Y. Srinivasan struct hv_input_signal_event_buffer { 632b3bf60c7SK. Y. Srinivasan u64 align8; 633b3bf60c7SK. Y. Srinivasan struct hv_input_signal_event event; 634b3bf60c7SK. Y. Srinivasan }; 635b3bf60c7SK. Y. Srinivasan 63646a97191SGreg Kroah-Hartman struct vmbus_channel { 63746a97191SGreg Kroah-Hartman struct list_head listentry; 63846a97191SGreg Kroah-Hartman 63946a97191SGreg Kroah-Hartman struct hv_device *device_obj; 64046a97191SGreg Kroah-Hartman 64146a97191SGreg Kroah-Hartman struct work_struct work; 64246a97191SGreg Kroah-Hartman 64346a97191SGreg Kroah-Hartman enum vmbus_channel_state state; 64446a97191SGreg Kroah-Hartman 64546a97191SGreg Kroah-Hartman struct vmbus_channel_offer_channel offermsg; 64646a97191SGreg Kroah-Hartman /* 64746a97191SGreg Kroah-Hartman * These are based on the OfferMsg.MonitorId. 64846a97191SGreg Kroah-Hartman * Save it here for easy access. 64946a97191SGreg Kroah-Hartman */ 65046a97191SGreg Kroah-Hartman u8 monitor_grp; 65146a97191SGreg Kroah-Hartman u8 monitor_bit; 65246a97191SGreg Kroah-Hartman 65346a97191SGreg Kroah-Hartman u32 ringbuffer_gpadlhandle; 65446a97191SGreg Kroah-Hartman 65546a97191SGreg Kroah-Hartman /* Allocated memory for ring buffer */ 65646a97191SGreg Kroah-Hartman void *ringbuffer_pages; 65746a97191SGreg Kroah-Hartman u32 ringbuffer_pagecount; 65846a97191SGreg Kroah-Hartman struct hv_ring_buffer_info outbound; /* send to parent */ 65946a97191SGreg Kroah-Hartman struct hv_ring_buffer_info inbound; /* receive from parent */ 66046a97191SGreg Kroah-Hartman spinlock_t inbound_lock; 66146a97191SGreg Kroah-Hartman struct workqueue_struct *controlwq; 66246a97191SGreg Kroah-Hartman 66346a97191SGreg Kroah-Hartman struct vmbus_close_msg close_msg; 66446a97191SGreg Kroah-Hartman 66546a97191SGreg Kroah-Hartman /* Channel callback are invoked in this workqueue context */ 66646a97191SGreg Kroah-Hartman /* HANDLE dataWorkQueue; */ 66746a97191SGreg Kroah-Hartman 66846a97191SGreg Kroah-Hartman void (*onchannel_callback)(void *context); 66946a97191SGreg Kroah-Hartman void *channel_callback_context; 670132368bdSK. Y. Srinivasan 671132368bdSK. Y. Srinivasan /* 672132368bdSK. Y. Srinivasan * A channel can be marked for efficient (batched) 673132368bdSK. Y. Srinivasan * reading: 674132368bdSK. Y. Srinivasan * If batched_reading is set to "true", we read until the 675132368bdSK. Y. Srinivasan * channel is empty and hold off interrupts from the host 676132368bdSK. Y. Srinivasan * during the entire read process. 677132368bdSK. Y. Srinivasan * If batched_reading is set to "false", the client is not 678132368bdSK. Y. Srinivasan * going to perform batched reading. 679132368bdSK. Y. Srinivasan * 680132368bdSK. Y. Srinivasan * By default we will enable batched reading; specific 681132368bdSK. Y. Srinivasan * drivers that don't want this behavior can turn it off. 682132368bdSK. Y. Srinivasan */ 683132368bdSK. Y. Srinivasan 684132368bdSK. Y. Srinivasan bool batched_reading; 685b3bf60c7SK. Y. Srinivasan 686b3bf60c7SK. Y. Srinivasan bool is_dedicated_interrupt; 687b3bf60c7SK. Y. Srinivasan struct hv_input_signal_event_buffer sig_buf; 688b3bf60c7SK. Y. Srinivasan struct hv_input_signal_event *sig_event; 689abbf3b2aSK. Y. Srinivasan 690abbf3b2aSK. Y. Srinivasan /* 691abbf3b2aSK. Y. Srinivasan * Starting with win8, this field will be used to specify 692abbf3b2aSK. Y. Srinivasan * the target virtual processor on which to deliver the interrupt for 693abbf3b2aSK. Y. Srinivasan * the host to guest communication. 694abbf3b2aSK. Y. Srinivasan * Prior to win8, incoming channel interrupts would only 695abbf3b2aSK. Y. Srinivasan * be delivered on cpu 0. Setting this value to 0 would 696abbf3b2aSK. Y. Srinivasan * preserve the earlier behavior. 697abbf3b2aSK. Y. Srinivasan */ 698abbf3b2aSK. Y. Srinivasan u32 target_vp; 699d3ba720dSK. Y. Srinivasan /* The corresponding CPUID in the guest */ 700d3ba720dSK. Y. Srinivasan u32 target_cpu; 701e68d2971SK. Y. Srinivasan /* 702e68d2971SK. Y. Srinivasan * Support for sub-channels. For high performance devices, 703e68d2971SK. Y. Srinivasan * it will be useful to have multiple sub-channels to support 704e68d2971SK. Y. Srinivasan * a scalable communication infrastructure with the host. 705e68d2971SK. Y. Srinivasan * The support for sub-channels is implemented as an extention 706e68d2971SK. Y. Srinivasan * to the current infrastructure. 707e68d2971SK. Y. Srinivasan * The initial offer is considered the primary channel and this 708e68d2971SK. Y. Srinivasan * offer message will indicate if the host supports sub-channels. 709e68d2971SK. Y. Srinivasan * The guest is free to ask for sub-channels to be offerred and can 710e68d2971SK. Y. Srinivasan * open these sub-channels as a normal "primary" channel. However, 711e68d2971SK. Y. Srinivasan * all sub-channels will have the same type and instance guids as the 712e68d2971SK. Y. Srinivasan * primary channel. Requests sent on a given channel will result in a 713e68d2971SK. Y. Srinivasan * response on the same channel. 714e68d2971SK. Y. Srinivasan */ 715e68d2971SK. Y. Srinivasan 716e68d2971SK. Y. Srinivasan /* 717e68d2971SK. Y. Srinivasan * Sub-channel creation callback. This callback will be called in 718e68d2971SK. Y. Srinivasan * process context when a sub-channel offer is received from the host. 719e68d2971SK. Y. Srinivasan * The guest can open the sub-channel in the context of this callback. 720e68d2971SK. Y. Srinivasan */ 721e68d2971SK. Y. Srinivasan void (*sc_creation_callback)(struct vmbus_channel *new_sc); 722e68d2971SK. Y. Srinivasan 723e68d2971SK. Y. Srinivasan spinlock_t sc_lock; 724e68d2971SK. Y. Srinivasan /* 725e68d2971SK. Y. Srinivasan * All Sub-channels of a primary channel are linked here. 726e68d2971SK. Y. Srinivasan */ 727e68d2971SK. Y. Srinivasan struct list_head sc_list; 728e68d2971SK. Y. Srinivasan /* 729e68d2971SK. Y. Srinivasan * The primary channel this sub-channel belongs to. 730e68d2971SK. Y. Srinivasan * This will be NULL for the primary channel. 731e68d2971SK. Y. Srinivasan */ 732e68d2971SK. Y. Srinivasan struct vmbus_channel *primary_channel; 7338a7206a8SK. Y. Srinivasan /* 7348a7206a8SK. Y. Srinivasan * Support per-channel state for use by vmbus drivers. 7358a7206a8SK. Y. Srinivasan */ 7368a7206a8SK. Y. Srinivasan void *per_channel_state; 737*3a28fa35SK. Y. Srinivasan /* 738*3a28fa35SK. Y. Srinivasan * To support per-cpu lookup mapping of relid to channel, 739*3a28fa35SK. Y. Srinivasan * link up channels based on their CPU affinity. 740*3a28fa35SK. Y. Srinivasan */ 741*3a28fa35SK. Y. Srinivasan struct list_head percpu_list; 74246a97191SGreg Kroah-Hartman }; 74346a97191SGreg Kroah-Hartman 744132368bdSK. Y. Srinivasan static inline void set_channel_read_state(struct vmbus_channel *c, bool state) 745132368bdSK. Y. Srinivasan { 746132368bdSK. Y. Srinivasan c->batched_reading = state; 747132368bdSK. Y. Srinivasan } 748132368bdSK. Y. Srinivasan 7498a7206a8SK. Y. Srinivasan static inline void set_per_channel_state(struct vmbus_channel *c, void *s) 7508a7206a8SK. Y. Srinivasan { 7518a7206a8SK. Y. Srinivasan c->per_channel_state = s; 7528a7206a8SK. Y. Srinivasan } 7538a7206a8SK. Y. Srinivasan 7548a7206a8SK. Y. Srinivasan static inline void *get_per_channel_state(struct vmbus_channel *c) 7558a7206a8SK. Y. Srinivasan { 7568a7206a8SK. Y. Srinivasan return c->per_channel_state; 7578a7206a8SK. Y. Srinivasan } 7588a7206a8SK. Y. Srinivasan 75946a97191SGreg Kroah-Hartman void vmbus_onmessage(void *context); 76046a97191SGreg Kroah-Hartman 76146a97191SGreg Kroah-Hartman int vmbus_request_offers(void); 76246a97191SGreg Kroah-Hartman 763e68d2971SK. Y. Srinivasan /* 764e68d2971SK. Y. Srinivasan * APIs for managing sub-channels. 765e68d2971SK. Y. Srinivasan */ 766e68d2971SK. Y. Srinivasan 767e68d2971SK. Y. Srinivasan void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel, 768e68d2971SK. Y. Srinivasan void (*sc_cr_cb)(struct vmbus_channel *new_sc)); 769e68d2971SK. Y. Srinivasan 770e68d2971SK. Y. Srinivasan /* 771e68d2971SK. Y. Srinivasan * Retrieve the (sub) channel on which to send an outgoing request. 772e68d2971SK. Y. Srinivasan * When a primary channel has multiple sub-channels, we choose a 773e68d2971SK. Y. Srinivasan * channel whose VCPU binding is closest to the VCPU on which 774e68d2971SK. Y. Srinivasan * this call is being made. 775e68d2971SK. Y. Srinivasan */ 776e68d2971SK. Y. Srinivasan struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary); 777e68d2971SK. Y. Srinivasan 778e68d2971SK. Y. Srinivasan /* 779e68d2971SK. Y. Srinivasan * Check if sub-channels have already been offerred. This API will be useful 780e68d2971SK. Y. Srinivasan * when the driver is unloaded after establishing sub-channels. In this case, 781e68d2971SK. Y. Srinivasan * when the driver is re-loaded, the driver would have to check if the 782e68d2971SK. Y. Srinivasan * subchannels have already been established before attempting to request 783e68d2971SK. Y. Srinivasan * the creation of sub-channels. 784e68d2971SK. Y. Srinivasan * This function returns TRUE to indicate that subchannels have already been 785e68d2971SK. Y. Srinivasan * created. 786e68d2971SK. Y. Srinivasan * This function should be invoked after setting the callback function for 787e68d2971SK. Y. Srinivasan * sub-channel creation. 788e68d2971SK. Y. Srinivasan */ 789e68d2971SK. Y. Srinivasan bool vmbus_are_subchannels_present(struct vmbus_channel *primary); 790e68d2971SK. Y. Srinivasan 79146a97191SGreg Kroah-Hartman /* The format must be the same as struct vmdata_gpa_direct */ 79246a97191SGreg Kroah-Hartman struct vmbus_channel_packet_page_buffer { 79346a97191SGreg Kroah-Hartman u16 type; 79446a97191SGreg Kroah-Hartman u16 dataoffset8; 79546a97191SGreg Kroah-Hartman u16 length8; 79646a97191SGreg Kroah-Hartman u16 flags; 79746a97191SGreg Kroah-Hartman u64 transactionid; 79846a97191SGreg Kroah-Hartman u32 reserved; 79946a97191SGreg Kroah-Hartman u32 rangecount; 80046a97191SGreg Kroah-Hartman struct hv_page_buffer range[MAX_PAGE_BUFFER_COUNT]; 80146a97191SGreg Kroah-Hartman } __packed; 80246a97191SGreg Kroah-Hartman 80346a97191SGreg Kroah-Hartman /* The format must be the same as struct vmdata_gpa_direct */ 80446a97191SGreg Kroah-Hartman struct vmbus_channel_packet_multipage_buffer { 80546a97191SGreg Kroah-Hartman u16 type; 80646a97191SGreg Kroah-Hartman u16 dataoffset8; 80746a97191SGreg Kroah-Hartman u16 length8; 80846a97191SGreg Kroah-Hartman u16 flags; 80946a97191SGreg Kroah-Hartman u64 transactionid; 81046a97191SGreg Kroah-Hartman u32 reserved; 81146a97191SGreg Kroah-Hartman u32 rangecount; /* Always 1 in this case */ 81246a97191SGreg Kroah-Hartman struct hv_multipage_buffer range; 81346a97191SGreg Kroah-Hartman } __packed; 81446a97191SGreg Kroah-Hartman 81546a97191SGreg Kroah-Hartman 81646a97191SGreg Kroah-Hartman extern int vmbus_open(struct vmbus_channel *channel, 81746a97191SGreg Kroah-Hartman u32 send_ringbuffersize, 81846a97191SGreg Kroah-Hartman u32 recv_ringbuffersize, 81946a97191SGreg Kroah-Hartman void *userdata, 82046a97191SGreg Kroah-Hartman u32 userdatalen, 82146a97191SGreg Kroah-Hartman void(*onchannel_callback)(void *context), 82246a97191SGreg Kroah-Hartman void *context); 82346a97191SGreg Kroah-Hartman 82446a97191SGreg Kroah-Hartman extern void vmbus_close(struct vmbus_channel *channel); 82546a97191SGreg Kroah-Hartman 82646a97191SGreg Kroah-Hartman extern int vmbus_sendpacket(struct vmbus_channel *channel, 827011a7c3cSK. Y. Srinivasan void *buffer, 82846a97191SGreg Kroah-Hartman u32 bufferLen, 82946a97191SGreg Kroah-Hartman u64 requestid, 83046a97191SGreg Kroah-Hartman enum vmbus_packet_type type, 83146a97191SGreg Kroah-Hartman u32 flags); 83246a97191SGreg Kroah-Hartman 83346a97191SGreg Kroah-Hartman extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, 83446a97191SGreg Kroah-Hartman struct hv_page_buffer pagebuffers[], 83546a97191SGreg Kroah-Hartman u32 pagecount, 83646a97191SGreg Kroah-Hartman void *buffer, 83746a97191SGreg Kroah-Hartman u32 bufferlen, 83846a97191SGreg Kroah-Hartman u64 requestid); 83946a97191SGreg Kroah-Hartman 84046a97191SGreg Kroah-Hartman extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, 84146a97191SGreg Kroah-Hartman struct hv_multipage_buffer *mpb, 84246a97191SGreg Kroah-Hartman void *buffer, 84346a97191SGreg Kroah-Hartman u32 bufferlen, 84446a97191SGreg Kroah-Hartman u64 requestid); 84546a97191SGreg Kroah-Hartman 84646a97191SGreg Kroah-Hartman extern int vmbus_establish_gpadl(struct vmbus_channel *channel, 84746a97191SGreg Kroah-Hartman void *kbuffer, 84846a97191SGreg Kroah-Hartman u32 size, 84946a97191SGreg Kroah-Hartman u32 *gpadl_handle); 85046a97191SGreg Kroah-Hartman 85146a97191SGreg Kroah-Hartman extern int vmbus_teardown_gpadl(struct vmbus_channel *channel, 85246a97191SGreg Kroah-Hartman u32 gpadl_handle); 85346a97191SGreg Kroah-Hartman 85446a97191SGreg Kroah-Hartman extern int vmbus_recvpacket(struct vmbus_channel *channel, 85546a97191SGreg Kroah-Hartman void *buffer, 85646a97191SGreg Kroah-Hartman u32 bufferlen, 85746a97191SGreg Kroah-Hartman u32 *buffer_actual_len, 85846a97191SGreg Kroah-Hartman u64 *requestid); 85946a97191SGreg Kroah-Hartman 86046a97191SGreg Kroah-Hartman extern int vmbus_recvpacket_raw(struct vmbus_channel *channel, 86146a97191SGreg Kroah-Hartman void *buffer, 86246a97191SGreg Kroah-Hartman u32 bufferlen, 86346a97191SGreg Kroah-Hartman u32 *buffer_actual_len, 86446a97191SGreg Kroah-Hartman u64 *requestid); 86546a97191SGreg Kroah-Hartman 86646a97191SGreg Kroah-Hartman 86746a97191SGreg Kroah-Hartman extern void vmbus_ontimer(unsigned long data); 86846a97191SGreg Kroah-Hartman 86946a97191SGreg Kroah-Hartman /* Base driver object */ 87046a97191SGreg Kroah-Hartman struct hv_driver { 87146a97191SGreg Kroah-Hartman const char *name; 87246a97191SGreg Kroah-Hartman 87346a97191SGreg Kroah-Hartman /* the device type supported by this driver */ 87446a97191SGreg Kroah-Hartman uuid_le dev_type; 87546a97191SGreg Kroah-Hartman const struct hv_vmbus_device_id *id_table; 87646a97191SGreg Kroah-Hartman 87746a97191SGreg Kroah-Hartman struct device_driver driver; 87846a97191SGreg Kroah-Hartman 87946a97191SGreg Kroah-Hartman int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *); 88046a97191SGreg Kroah-Hartman int (*remove)(struct hv_device *); 88146a97191SGreg Kroah-Hartman void (*shutdown)(struct hv_device *); 88246a97191SGreg Kroah-Hartman 88346a97191SGreg Kroah-Hartman }; 88446a97191SGreg Kroah-Hartman 88546a97191SGreg Kroah-Hartman /* Base device object */ 88646a97191SGreg Kroah-Hartman struct hv_device { 88746a97191SGreg Kroah-Hartman /* the device type id of this device */ 88846a97191SGreg Kroah-Hartman uuid_le dev_type; 88946a97191SGreg Kroah-Hartman 89046a97191SGreg Kroah-Hartman /* the device instance id of this device */ 89146a97191SGreg Kroah-Hartman uuid_le dev_instance; 89246a97191SGreg Kroah-Hartman 89346a97191SGreg Kroah-Hartman struct device device; 89446a97191SGreg Kroah-Hartman 89546a97191SGreg Kroah-Hartman struct vmbus_channel *channel; 89646a97191SGreg Kroah-Hartman }; 89746a97191SGreg Kroah-Hartman 89846a97191SGreg Kroah-Hartman 89946a97191SGreg Kroah-Hartman static inline struct hv_device *device_to_hv_device(struct device *d) 90046a97191SGreg Kroah-Hartman { 90146a97191SGreg Kroah-Hartman return container_of(d, struct hv_device, device); 90246a97191SGreg Kroah-Hartman } 90346a97191SGreg Kroah-Hartman 90446a97191SGreg Kroah-Hartman static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d) 90546a97191SGreg Kroah-Hartman { 90646a97191SGreg Kroah-Hartman return container_of(d, struct hv_driver, driver); 90746a97191SGreg Kroah-Hartman } 90846a97191SGreg Kroah-Hartman 90946a97191SGreg Kroah-Hartman static inline void hv_set_drvdata(struct hv_device *dev, void *data) 91046a97191SGreg Kroah-Hartman { 91146a97191SGreg Kroah-Hartman dev_set_drvdata(&dev->device, data); 91246a97191SGreg Kroah-Hartman } 91346a97191SGreg Kroah-Hartman 91446a97191SGreg Kroah-Hartman static inline void *hv_get_drvdata(struct hv_device *dev) 91546a97191SGreg Kroah-Hartman { 91646a97191SGreg Kroah-Hartman return dev_get_drvdata(&dev->device); 91746a97191SGreg Kroah-Hartman } 91846a97191SGreg Kroah-Hartman 91946a97191SGreg Kroah-Hartman /* Vmbus interface */ 92046a97191SGreg Kroah-Hartman #define vmbus_driver_register(driver) \ 92146a97191SGreg Kroah-Hartman __vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) 92246a97191SGreg Kroah-Hartman int __must_check __vmbus_driver_register(struct hv_driver *hv_driver, 92346a97191SGreg Kroah-Hartman struct module *owner, 92446a97191SGreg Kroah-Hartman const char *mod_name); 92546a97191SGreg Kroah-Hartman void vmbus_driver_unregister(struct hv_driver *hv_driver); 92646a97191SGreg Kroah-Hartman 92746a97191SGreg Kroah-Hartman /** 92846a97191SGreg Kroah-Hartman * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device 92946a97191SGreg Kroah-Hartman * 93046a97191SGreg Kroah-Hartman * This macro is used to create a struct hv_vmbus_device_id that matches a 93146a97191SGreg Kroah-Hartman * specific device. 93246a97191SGreg Kroah-Hartman */ 93346a97191SGreg Kroah-Hartman #define VMBUS_DEVICE(g0, g1, g2, g3, g4, g5, g6, g7, \ 93446a97191SGreg Kroah-Hartman g8, g9, ga, gb, gc, gd, ge, gf) \ 93546a97191SGreg Kroah-Hartman .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \ 93646a97191SGreg Kroah-Hartman g8, g9, ga, gb, gc, gd, ge, gf }, 93746a97191SGreg Kroah-Hartman 93846a97191SGreg Kroah-Hartman /* 9397fb96565SK. Y. Srinivasan * GUID definitions of various offer types - services offered to the guest. 9407fb96565SK. Y. Srinivasan */ 9417fb96565SK. Y. Srinivasan 9427fb96565SK. Y. Srinivasan /* 9437fb96565SK. Y. Srinivasan * Network GUID 9447fb96565SK. Y. Srinivasan * {f8615163-df3e-46c5-913f-f2d2f965ed0e} 9457fb96565SK. Y. Srinivasan */ 9467fb96565SK. Y. Srinivasan #define HV_NIC_GUID \ 9477fb96565SK. Y. Srinivasan .guid = { \ 9487fb96565SK. Y. Srinivasan 0x63, 0x51, 0x61, 0xf8, 0x3e, 0xdf, 0xc5, 0x46, \ 9497fb96565SK. Y. Srinivasan 0x91, 0x3f, 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e \ 9507fb96565SK. Y. Srinivasan } 9517fb96565SK. Y. Srinivasan 9527fb96565SK. Y. Srinivasan /* 9537fb96565SK. Y. Srinivasan * IDE GUID 9547fb96565SK. Y. Srinivasan * {32412632-86cb-44a2-9b5c-50d1417354f5} 9557fb96565SK. Y. Srinivasan */ 9567fb96565SK. Y. Srinivasan #define HV_IDE_GUID \ 9577fb96565SK. Y. Srinivasan .guid = { \ 9587fb96565SK. Y. Srinivasan 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \ 9597fb96565SK. Y. Srinivasan 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 \ 9607fb96565SK. Y. Srinivasan } 9617fb96565SK. Y. Srinivasan 9627fb96565SK. Y. Srinivasan /* 9637fb96565SK. Y. Srinivasan * SCSI GUID 9647fb96565SK. Y. Srinivasan * {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} 9657fb96565SK. Y. Srinivasan */ 9667fb96565SK. Y. Srinivasan #define HV_SCSI_GUID \ 9677fb96565SK. Y. Srinivasan .guid = { \ 9687fb96565SK. Y. Srinivasan 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \ 9697fb96565SK. Y. Srinivasan 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f \ 9707fb96565SK. Y. Srinivasan } 9717fb96565SK. Y. Srinivasan 9727fb96565SK. Y. Srinivasan /* 9737fb96565SK. Y. Srinivasan * Shutdown GUID 9747fb96565SK. Y. Srinivasan * {0e0b6031-5213-4934-818b-38d90ced39db} 9757fb96565SK. Y. Srinivasan */ 9767fb96565SK. Y. Srinivasan #define HV_SHUTDOWN_GUID \ 9777fb96565SK. Y. Srinivasan .guid = { \ 9787fb96565SK. Y. Srinivasan 0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49, \ 9797fb96565SK. Y. Srinivasan 0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb \ 9807fb96565SK. Y. Srinivasan } 9817fb96565SK. Y. Srinivasan 9827fb96565SK. Y. Srinivasan /* 9837fb96565SK. Y. Srinivasan * Time Synch GUID 9847fb96565SK. Y. Srinivasan * {9527E630-D0AE-497b-ADCE-E80AB0175CAF} 9857fb96565SK. Y. Srinivasan */ 9867fb96565SK. Y. Srinivasan #define HV_TS_GUID \ 9877fb96565SK. Y. Srinivasan .guid = { \ 9887fb96565SK. Y. Srinivasan 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, \ 9897fb96565SK. Y. Srinivasan 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf \ 9907fb96565SK. Y. Srinivasan } 9917fb96565SK. Y. Srinivasan 9927fb96565SK. Y. Srinivasan /* 9937fb96565SK. Y. Srinivasan * Heartbeat GUID 9947fb96565SK. Y. Srinivasan * {57164f39-9115-4e78-ab55-382f3bd5422d} 9957fb96565SK. Y. Srinivasan */ 9967fb96565SK. Y. Srinivasan #define HV_HEART_BEAT_GUID \ 9977fb96565SK. Y. Srinivasan .guid = { \ 9987fb96565SK. Y. Srinivasan 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, \ 9997fb96565SK. Y. Srinivasan 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d \ 10007fb96565SK. Y. Srinivasan } 10017fb96565SK. Y. Srinivasan 10027fb96565SK. Y. Srinivasan /* 10037fb96565SK. Y. Srinivasan * KVP GUID 10047fb96565SK. Y. Srinivasan * {a9a0f4e7-5a45-4d96-b827-8a841e8c03e6} 10057fb96565SK. Y. Srinivasan */ 10067fb96565SK. Y. Srinivasan #define HV_KVP_GUID \ 10077fb96565SK. Y. Srinivasan .guid = { \ 10087fb96565SK. Y. Srinivasan 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, \ 10097fb96565SK. Y. Srinivasan 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 \ 10107fb96565SK. Y. Srinivasan } 10117fb96565SK. Y. Srinivasan 10127fb96565SK. Y. Srinivasan /* 10137fb96565SK. Y. Srinivasan * Dynamic memory GUID 10147fb96565SK. Y. Srinivasan * {525074dc-8985-46e2-8057-a307dc18a502} 10157fb96565SK. Y. Srinivasan */ 10167fb96565SK. Y. Srinivasan #define HV_DM_GUID \ 10177fb96565SK. Y. Srinivasan .guid = { \ 10187fb96565SK. Y. Srinivasan 0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46, \ 10197fb96565SK. Y. Srinivasan 0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02 \ 10207fb96565SK. Y. Srinivasan } 10217fb96565SK. Y. Srinivasan 10227fb96565SK. Y. Srinivasan /* 10237fb96565SK. Y. Srinivasan * Mouse GUID 10247fb96565SK. Y. Srinivasan * {cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a} 10257fb96565SK. Y. Srinivasan */ 10267fb96565SK. Y. Srinivasan #define HV_MOUSE_GUID \ 10277fb96565SK. Y. Srinivasan .guid = { \ 10287fb96565SK. Y. Srinivasan 0x9e, 0xb6, 0xa8, 0xcf, 0x4a, 0x5b, 0xc0, 0x4c, \ 10297fb96565SK. Y. Srinivasan 0xb9, 0x8b, 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a \ 10307fb96565SK. Y. Srinivasan } 10317fb96565SK. Y. Srinivasan 10327fb96565SK. Y. Srinivasan /* 103396dd86faSK. Y. Srinivasan * VSS (Backup/Restore) GUID 103496dd86faSK. Y. Srinivasan */ 103596dd86faSK. Y. Srinivasan #define HV_VSS_GUID \ 103696dd86faSK. Y. Srinivasan .guid = { \ 103796dd86faSK. Y. Srinivasan 0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42, \ 103896dd86faSK. Y. Srinivasan 0x96, 0xae, 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40 \ 103996dd86faSK. Y. Srinivasan } 104096dd86faSK. Y. Srinivasan /* 104168a2d20bSHaiyang Zhang * Synthetic Video GUID 104268a2d20bSHaiyang Zhang * {DA0A7802-E377-4aac-8E77-0558EB1073F8} 104368a2d20bSHaiyang Zhang */ 104468a2d20bSHaiyang Zhang #define HV_SYNTHVID_GUID \ 104568a2d20bSHaiyang Zhang .guid = { \ 104668a2d20bSHaiyang Zhang 0x02, 0x78, 0x0a, 0xda, 0x77, 0xe3, 0xac, 0x4a, \ 104768a2d20bSHaiyang Zhang 0x8e, 0x77, 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8 \ 104868a2d20bSHaiyang Zhang } 104968a2d20bSHaiyang Zhang 105068a2d20bSHaiyang Zhang /* 105198b80d89SK. Y. Srinivasan * Synthetic FC GUID 105298b80d89SK. Y. Srinivasan * {2f9bcc4a-0069-4af3-b76b-6fd0be528cda} 105398b80d89SK. Y. Srinivasan */ 105498b80d89SK. Y. Srinivasan #define HV_SYNTHFC_GUID \ 105598b80d89SK. Y. Srinivasan .guid = { \ 105698b80d89SK. Y. Srinivasan 0x4A, 0xCC, 0x9B, 0x2F, 0x69, 0x00, 0xF3, 0x4A, \ 105798b80d89SK. Y. Srinivasan 0xB7, 0x6B, 0x6F, 0xD0, 0xBE, 0x52, 0x8C, 0xDA \ 105898b80d89SK. Y. Srinivasan } 105998b80d89SK. Y. Srinivasan 106098b80d89SK. Y. Srinivasan /* 106101325476SK. Y. Srinivasan * Guest File Copy Service 106201325476SK. Y. Srinivasan * {34D14BE3-DEE4-41c8-9AE7-6B174977C192} 106301325476SK. Y. Srinivasan */ 106401325476SK. Y. Srinivasan 106501325476SK. Y. Srinivasan #define HV_FCOPY_GUID \ 106601325476SK. Y. Srinivasan .guid = { \ 106701325476SK. Y. Srinivasan 0xE3, 0x4B, 0xD1, 0x34, 0xE4, 0xDE, 0xC8, 0x41, \ 106801325476SK. Y. Srinivasan 0x9A, 0xE7, 0x6B, 0x17, 0x49, 0x77, 0xC1, 0x92 \ 106901325476SK. Y. Srinivasan } 107001325476SK. Y. Srinivasan 107101325476SK. Y. Srinivasan /* 107246a97191SGreg Kroah-Hartman * Common header for Hyper-V ICs 107346a97191SGreg Kroah-Hartman */ 107446a97191SGreg Kroah-Hartman 107546a97191SGreg Kroah-Hartman #define ICMSGTYPE_NEGOTIATE 0 107646a97191SGreg Kroah-Hartman #define ICMSGTYPE_HEARTBEAT 1 107746a97191SGreg Kroah-Hartman #define ICMSGTYPE_KVPEXCHANGE 2 107846a97191SGreg Kroah-Hartman #define ICMSGTYPE_SHUTDOWN 3 107946a97191SGreg Kroah-Hartman #define ICMSGTYPE_TIMESYNC 4 108046a97191SGreg Kroah-Hartman #define ICMSGTYPE_VSS 5 108146a97191SGreg Kroah-Hartman 108246a97191SGreg Kroah-Hartman #define ICMSGHDRFLAG_TRANSACTION 1 108346a97191SGreg Kroah-Hartman #define ICMSGHDRFLAG_REQUEST 2 108446a97191SGreg Kroah-Hartman #define ICMSGHDRFLAG_RESPONSE 4 108546a97191SGreg Kroah-Hartman 108646a97191SGreg Kroah-Hartman 108746a97191SGreg Kroah-Hartman /* 108846a97191SGreg Kroah-Hartman * While we want to handle util services as regular devices, 108946a97191SGreg Kroah-Hartman * there is only one instance of each of these services; so 109046a97191SGreg Kroah-Hartman * we statically allocate the service specific state. 109146a97191SGreg Kroah-Hartman */ 109246a97191SGreg Kroah-Hartman 109346a97191SGreg Kroah-Hartman struct hv_util_service { 109446a97191SGreg Kroah-Hartman u8 *recv_buffer; 109546a97191SGreg Kroah-Hartman void (*util_cb)(void *); 109646a97191SGreg Kroah-Hartman int (*util_init)(struct hv_util_service *); 109746a97191SGreg Kroah-Hartman void (*util_deinit)(void); 109846a97191SGreg Kroah-Hartman }; 109946a97191SGreg Kroah-Hartman 110046a97191SGreg Kroah-Hartman struct vmbuspipe_hdr { 110146a97191SGreg Kroah-Hartman u32 flags; 110246a97191SGreg Kroah-Hartman u32 msgsize; 110346a97191SGreg Kroah-Hartman } __packed; 110446a97191SGreg Kroah-Hartman 110546a97191SGreg Kroah-Hartman struct ic_version { 110646a97191SGreg Kroah-Hartman u16 major; 110746a97191SGreg Kroah-Hartman u16 minor; 110846a97191SGreg Kroah-Hartman } __packed; 110946a97191SGreg Kroah-Hartman 111046a97191SGreg Kroah-Hartman struct icmsg_hdr { 111146a97191SGreg Kroah-Hartman struct ic_version icverframe; 111246a97191SGreg Kroah-Hartman u16 icmsgtype; 111346a97191SGreg Kroah-Hartman struct ic_version icvermsg; 111446a97191SGreg Kroah-Hartman u16 icmsgsize; 111546a97191SGreg Kroah-Hartman u32 status; 111646a97191SGreg Kroah-Hartman u8 ictransaction_id; 111746a97191SGreg Kroah-Hartman u8 icflags; 111846a97191SGreg Kroah-Hartman u8 reserved[2]; 111946a97191SGreg Kroah-Hartman } __packed; 112046a97191SGreg Kroah-Hartman 112146a97191SGreg Kroah-Hartman struct icmsg_negotiate { 112246a97191SGreg Kroah-Hartman u16 icframe_vercnt; 112346a97191SGreg Kroah-Hartman u16 icmsg_vercnt; 112446a97191SGreg Kroah-Hartman u32 reserved; 112546a97191SGreg Kroah-Hartman struct ic_version icversion_data[1]; /* any size array */ 112646a97191SGreg Kroah-Hartman } __packed; 112746a97191SGreg Kroah-Hartman 112846a97191SGreg Kroah-Hartman struct shutdown_msg_data { 112946a97191SGreg Kroah-Hartman u32 reason_code; 113046a97191SGreg Kroah-Hartman u32 timeout_seconds; 113146a97191SGreg Kroah-Hartman u32 flags; 113246a97191SGreg Kroah-Hartman u8 display_message[2048]; 113346a97191SGreg Kroah-Hartman } __packed; 113446a97191SGreg Kroah-Hartman 113546a97191SGreg Kroah-Hartman struct heartbeat_msg_data { 113646a97191SGreg Kroah-Hartman u64 seq_num; 113746a97191SGreg Kroah-Hartman u32 reserved[8]; 113846a97191SGreg Kroah-Hartman } __packed; 113946a97191SGreg Kroah-Hartman 114046a97191SGreg Kroah-Hartman /* Time Sync IC defs */ 114146a97191SGreg Kroah-Hartman #define ICTIMESYNCFLAG_PROBE 0 114246a97191SGreg Kroah-Hartman #define ICTIMESYNCFLAG_SYNC 1 114346a97191SGreg Kroah-Hartman #define ICTIMESYNCFLAG_SAMPLE 2 114446a97191SGreg Kroah-Hartman 114546a97191SGreg Kroah-Hartman #ifdef __x86_64__ 114646a97191SGreg Kroah-Hartman #define WLTIMEDELTA 116444736000000000L /* in 100ns unit */ 114746a97191SGreg Kroah-Hartman #else 114846a97191SGreg Kroah-Hartman #define WLTIMEDELTA 116444736000000000LL 114946a97191SGreg Kroah-Hartman #endif 115046a97191SGreg Kroah-Hartman 115146a97191SGreg Kroah-Hartman struct ictimesync_data { 115246a97191SGreg Kroah-Hartman u64 parenttime; 115346a97191SGreg Kroah-Hartman u64 childtime; 115446a97191SGreg Kroah-Hartman u64 roundtriptime; 115546a97191SGreg Kroah-Hartman u8 flags; 115646a97191SGreg Kroah-Hartman } __packed; 115746a97191SGreg Kroah-Hartman 115846a97191SGreg Kroah-Hartman struct hyperv_service_callback { 115946a97191SGreg Kroah-Hartman u8 msg_type; 116046a97191SGreg Kroah-Hartman char *log_msg; 116146a97191SGreg Kroah-Hartman uuid_le data; 116246a97191SGreg Kroah-Hartman struct vmbus_channel *channel; 116346a97191SGreg Kroah-Hartman void (*callback) (void *context); 116446a97191SGreg Kroah-Hartman }; 116546a97191SGreg Kroah-Hartman 1166c836d0abSK. Y. Srinivasan #define MAX_SRV_VER 0x7ffffff 11676741335bSK. Y. Srinivasan extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *, 1168c836d0abSK. Y. Srinivasan struct icmsg_negotiate *, u8 *, int, 1169c836d0abSK. Y. Srinivasan int); 117046a97191SGreg Kroah-Hartman 11712939437cSK. Y. Srinivasan int hv_kvp_init(struct hv_util_service *); 11722939437cSK. Y. Srinivasan void hv_kvp_deinit(void); 11732939437cSK. Y. Srinivasan void hv_kvp_onchannelcallback(void *); 11742939437cSK. Y. Srinivasan 117596dd86faSK. Y. Srinivasan int hv_vss_init(struct hv_util_service *); 117696dd86faSK. Y. Srinivasan void hv_vss_deinit(void); 117796dd86faSK. Y. Srinivasan void hv_vss_onchannelcallback(void *); 117896dd86faSK. Y. Srinivasan 117990eedf0cSGerd Hoffmann extern struct resource hyperv_mmio; 118090f34535SK. Y. Srinivasan 118137f7278bSK. Y. Srinivasan /* 118237f7278bSK. Y. Srinivasan * Negotiated version with the Host. 118337f7278bSK. Y. Srinivasan */ 118437f7278bSK. Y. Srinivasan 118537f7278bSK. Y. Srinivasan extern __u32 vmbus_proto_version; 118637f7278bSK. Y. Srinivasan 118746a97191SGreg Kroah-Hartman #endif /* _HYPERV_H */ 1188