]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/hyperv/include/hyperv.h
hyperv/vmbus: Busdma-fy channel bufring.
[FreeBSD/FreeBSD.git] / sys / dev / hyperv / include / hyperv.h
1 /*-
2  * Copyright (c) 2009-2012,2016 Microsoft Corp.
3  * Copyright (c) 2012 NetApp Inc.
4  * Copyright (c) 2012 Citrix Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 /**
32  * HyperV definitions for messages that are sent between instances of the
33  * Channel Management Library in separate partitions, or in some cases,
34  * back to itself.
35  */
36
37 #ifndef __HYPERV_H__
38 #define __HYPERV_H__
39
40 #include <sys/param.h>
41 #include <sys/mbuf.h>
42 #include <sys/queue.h>
43 #include <sys/malloc.h>
44 #include <sys/kthread.h>
45 #include <sys/taskqueue.h>
46 #include <sys/systm.h>
47 #include <sys/lock.h>
48 #include <sys/sema.h>
49 #include <sys/smp.h>
50 #include <sys/mutex.h>
51 #include <sys/bus.h>
52 #include <sys/sysctl.h>
53 #include <vm/vm.h>
54 #include <vm/vm_param.h>
55 #include <vm/pmap.h>
56
57 #include <amd64/include/xen/synch_bitops.h>
58 #include <amd64/include/atomic.h>
59 #include <dev/hyperv/include/hyperv_busdma.h>
60
61 typedef uint8_t hv_bool_uint8_t;
62
63 #define HV_S_OK                 0x00000000
64 #define HV_E_FAIL               0x80004005
65 #define HV_ERROR_NOT_SUPPORTED  0x80070032
66 #define HV_ERROR_MACHINE_LOCKED 0x800704F7
67
68 /*
69  * VMBUS version is 32 bit, upper 16 bit for major_number and lower
70  * 16 bit for minor_number.
71  *
72  * 0.13  --  Windows Server 2008
73  * 1.1   --  Windows 7
74  * 2.4   --  Windows 8
75  * 3.0   --  Windows 8.1
76  */
77 #define VMBUS_VERSION_WS2008            ((0 << 16) | (13))
78 #define VMBUS_VERSION_WIN7              ((1 << 16) | (1))
79 #define VMBUS_VERSION_WIN8              ((2 << 16) | (4))
80 #define VMBUS_VERSION_WIN8_1            ((3 << 16) | (0))
81
82 #define VMBUS_VERSION_MAJOR(ver)        (((uint32_t)(ver)) >> 16)
83 #define VMBUS_VERSION_MINOR(ver)        (((uint32_t)(ver)) & 0xffff)
84
85 #define HV_MAX_PAGE_BUFFER_COUNT        32
86 #define HV_MAX_MULTIPAGE_BUFFER_COUNT   32
87
88 #define HV_ALIGN_UP(value, align)                                       \
89                 (((value) & (align-1)) ?                                \
90                     (((value) + (align-1)) & ~(align-1) ) : (value))
91
92 #define HV_ALIGN_DOWN(value, align) ( (value) & ~(align-1) )
93
94 #define HV_NUM_PAGES_SPANNED(addr, len)                                 \
95                 ((HV_ALIGN_UP(addr+len, PAGE_SIZE) -                    \
96                     HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT )
97
98 struct hyperv_guid {
99         uint8_t         hv_guid[16];
100 } __packed;
101
102 #define HYPERV_GUID_STRLEN      40
103
104 int     hyperv_guid2str(const struct hyperv_guid *, char *, size_t);
105
106 typedef struct {
107         uint16_t type;
108         uint16_t data_offset8;
109         uint16_t length8;
110         uint16_t flags;
111         uint64_t transaction_id;
112 } __packed hv_vm_packet_descriptor;
113
114 typedef struct {
115         uint32_t byte_count;
116         uint32_t byte_offset;
117 } __packed hv_vm_transfer_page;
118
119 typedef struct {
120         hv_vm_packet_descriptor d;
121         uint16_t                transfer_page_set_id;
122         hv_bool_uint8_t         sender_owns_set;
123         uint8_t                 reserved;
124         uint32_t                range_count;
125         hv_vm_transfer_page     ranges[1];
126 } __packed hv_vm_transfer_page_packet_header;
127
128 typedef enum {
129         HV_VMBUS_PACKET_TYPE_INVALID                            = 0x0,
130         HV_VMBUS_PACKET_TYPES_SYNCH                             = 0x1,
131         HV_VMBUS_PACKET_TYPE_ADD_TRANSFER_PAGE_SET              = 0x2,
132         HV_VMBUS_PACKET_TYPE_REMOVE_TRANSFER_PAGE_SET           = 0x3,
133         HV_VMBUS_PACKET_TYPE_ESTABLISH_GPADL                    = 0x4,
134         HV_VMBUS_PACKET_TYPE_TEAR_DOWN_GPADL                    = 0x5,
135         HV_VMBUS_PACKET_TYPE_DATA_IN_BAND                       = 0x6,
136         HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES          = 0x7,
137         HV_VMBUS_PACKET_TYPE_DATA_USING_GPADL                   = 0x8,
138         HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT              = 0x9,
139         HV_VMBUS_PACKET_TYPE_CANCEL_REQUEST                     = 0xa,
140         HV_VMBUS_PACKET_TYPE_COMPLETION                         = 0xb,
141         HV_VMBUS_PACKET_TYPE_DATA_USING_ADDITIONAL_PACKETS      = 0xc,
142         HV_VMBUS_PACKET_TYPE_ADDITIONAL_DATA = 0xd
143 } hv_vmbus_packet_type;
144
145 #define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED    1
146
147 #define HW_MACADDR_LEN  6
148
149 /*
150  * Common defines for Hyper-V ICs
151  */
152 #define HV_ICMSGTYPE_NEGOTIATE          0
153 #define HV_ICMSGTYPE_HEARTBEAT          1
154 #define HV_ICMSGTYPE_KVPEXCHANGE        2
155 #define HV_ICMSGTYPE_SHUTDOWN           3
156 #define HV_ICMSGTYPE_TIMESYNC           4
157 #define HV_ICMSGTYPE_VSS                5
158
159 #define HV_ICMSGHDRFLAG_TRANSACTION     1
160 #define HV_ICMSGHDRFLAG_REQUEST         2
161 #define HV_ICMSGHDRFLAG_RESPONSE        4
162
163 typedef struct hv_vmbus_pipe_hdr {
164         uint32_t flags;
165         uint32_t msgsize;
166 } __packed hv_vmbus_pipe_hdr;
167
168 typedef struct hv_vmbus_ic_version {
169         uint16_t major;
170         uint16_t minor;
171 } __packed hv_vmbus_ic_version;
172
173 typedef struct hv_vmbus_icmsg_hdr {
174         hv_vmbus_ic_version     icverframe;
175         uint16_t                icmsgtype;
176         hv_vmbus_ic_version     icvermsg;
177         uint16_t                icmsgsize;
178         uint32_t                status;
179         uint8_t                 ictransaction_id;
180         uint8_t                 icflags;
181         uint8_t                 reserved[2];
182 } __packed hv_vmbus_icmsg_hdr;
183
184 typedef struct hv_vmbus_icmsg_negotiate {
185         uint16_t                icframe_vercnt;
186         uint16_t                icmsg_vercnt;
187         uint32_t                reserved;
188         hv_vmbus_ic_version     icversion_data[1]; /* any size array */
189 } __packed hv_vmbus_icmsg_negotiate;
190
191 typedef struct hv_vmbus_shutdown_msg_data {
192         uint32_t                reason_code;
193         uint32_t                timeout_seconds;
194         uint32_t                flags;
195         uint8_t                 display_message[2048];
196 } __packed hv_vmbus_shutdown_msg_data;
197
198 typedef struct hv_vmbus_heartbeat_msg_data {
199         uint64_t                seq_num;
200         uint32_t                reserved[8];
201 } __packed hv_vmbus_heartbeat_msg_data;
202
203 typedef struct {
204         /*
205          * offset in bytes from the start of ring data below
206          */
207         volatile uint32_t       write_index;
208         /*
209          * offset in bytes from the start of ring data below
210          */
211         volatile uint32_t       read_index;
212         /*
213          * NOTE: The interrupt_mask field is used only for channels, but
214          * vmbus connection also uses this data structure
215          */
216         volatile uint32_t       interrupt_mask;
217         /* pad it to PAGE_SIZE so that data starts on a page */
218         uint8_t                 reserved[4084];
219
220         /*
221          * WARNING: Ring data starts here
222          *  !!! DO NOT place any fields below this !!!
223          */
224         uint8_t                 buffer[0];      /* doubles as interrupt mask */
225 } __packed hv_vmbus_ring_buffer;
226
227 typedef struct {
228         int             length;
229         int             offset;
230         uint64_t        pfn;
231 } __packed hv_vmbus_page_buffer;
232
233 typedef struct {
234         int             length;
235         int             offset;
236         uint64_t        pfn_array[HV_MAX_MULTIPAGE_BUFFER_COUNT];
237 } __packed hv_vmbus_multipage_buffer;
238
239 typedef struct {
240         hv_vmbus_ring_buffer*   ring_buffer;
241         struct mtx              ring_lock;
242         uint32_t                ring_data_size; /* ring_size */
243 } hv_vmbus_ring_buffer_info;
244
245 typedef void (*hv_vmbus_pfn_channel_callback)(void *context);
246
247 typedef struct hv_vmbus_channel {
248         device_t                        ch_dev;
249         struct vmbus_softc              *vmbus_sc;
250         uint32_t                        ch_flags;       /* VMBUS_CHAN_FLAG_ */
251         uint32_t                        ch_id;          /* channel id */
252
253         /*
254          * These are based on the offer_msg.monitor_id.
255          * Save it here for easy access.
256          */
257         int                             ch_montrig_idx; /* MNF trig index */
258         uint32_t                        ch_montrig_mask;/* MNF trig mask */
259
260         /*
261          * send to parent
262          */
263         hv_vmbus_ring_buffer_info       outbound;
264         /*
265          * receive from parent
266          */
267         hv_vmbus_ring_buffer_info       inbound;
268
269         struct taskqueue *              rxq;
270         struct task                     channel_task;
271         hv_vmbus_pfn_channel_callback   on_channel_callback;
272         void*                           channel_callback_context;
273
274         struct hyperv_mon_param         *ch_monprm;
275         struct hyperv_dma               ch_monprm_dma;
276
277         /*
278          * From Win8, this field specifies the target virtual process
279          * on which to deliver the interrupt from the host to guest.
280          * Before Win8, all channel interrupts would only be
281          * delivered on cpu 0. Setting this value to 0 would preserve
282          * the earlier behavior.
283          */
284         uint32_t                        target_vcpu;
285         /* The corresponding CPUID in the guest */
286         uint32_t                        target_cpu;
287
288         /*
289          * If this is a primary channel, ch_subchan* fields
290          * contain sub-channels belonging to this primary
291          * channel.
292          */
293         struct mtx                      ch_subchan_lock;
294         TAILQ_HEAD(, hv_vmbus_channel)  ch_subchans;
295         int                             ch_subchan_cnt;
296
297         /* If this is a sub-channel */
298         TAILQ_ENTRY(hv_vmbus_channel)   ch_sublink;     /* sub-channel link */
299         struct hv_vmbus_channel         *ch_prichan;    /* owner primary chan */
300
301         /*
302          * Driver private data
303          */
304         void                            *hv_chan_priv1;
305         void                            *hv_chan_priv2;
306         void                            *hv_chan_priv3;
307
308         void                            *ch_bufring;    /* TX+RX bufrings */
309         struct hyperv_dma               ch_bufring_dma;
310         uint32_t                        ch_bufring_gpadl;
311
312         struct task                     ch_detach_task;
313         TAILQ_ENTRY(hv_vmbus_channel)   ch_prilink;     /* primary chan link */
314         uint32_t                        ch_subidx;      /* subchan index */
315         volatile uint32_t               ch_stflags;     /* atomic-op */
316                                                         /* VMBUS_CHAN_ST_ */
317         struct hyperv_guid              ch_guid_type;
318         struct hyperv_guid              ch_guid_inst;
319
320         struct sysctl_ctx_list          ch_sysctl_ctx;
321 } hv_vmbus_channel;
322
323 #define VMBUS_CHAN_ISPRIMARY(chan)      ((chan)->ch_subidx == 0)
324
325 #define VMBUS_CHAN_FLAG_HASMNF          0x0001
326 /*
327  * If this flag is set, this channel's interrupt will be masked in ISR,
328  * and the RX bufring will be drained before this channel's interrupt is
329  * unmasked.
330  *
331  * This flag is turned on by default.  Drivers can turn it off according
332  * to their own requirement.
333  */
334 #define VMBUS_CHAN_FLAG_BATCHREAD       0x0002
335
336 #define VMBUS_CHAN_ST_OPENED_SHIFT      0
337 #define VMBUS_CHAN_ST_OPENED            (1 << VMBUS_CHAN_ST_OPENED_SHIFT)
338
339 static inline void
340 hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t on)
341 {
342         if (!on)
343                 channel->ch_flags &= ~VMBUS_CHAN_FLAG_BATCHREAD;
344         else
345                 channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD;
346 }
347
348 int             hv_vmbus_channel_recv_packet(
349                                 hv_vmbus_channel*       channel,
350                                 void*                   buffer,
351                                 uint32_t                buffer_len,
352                                 uint32_t*               buffer_actual_len,
353                                 uint64_t*               request_id);
354
355 int             hv_vmbus_channel_recv_packet_raw(
356                                 hv_vmbus_channel*       channel,
357                                 void*                   buffer,
358                                 uint32_t                buffer_len,
359                                 uint32_t*               buffer_actual_len,
360                                 uint64_t*               request_id);
361
362 int             hv_vmbus_channel_open(
363                                 hv_vmbus_channel*       channel,
364                                 uint32_t                send_ring_buffer_size,
365                                 uint32_t                recv_ring_buffer_size,
366                                 void*                   user_data,
367                                 uint32_t                user_data_len,
368                                 hv_vmbus_pfn_channel_callback
369                                                         pfn_on_channel_callback,
370                                 void*                   context);
371
372 void            hv_vmbus_channel_close(hv_vmbus_channel *channel);
373
374 int             hv_vmbus_channel_send_packet(
375                                 hv_vmbus_channel*       channel,
376                                 void*                   buffer,
377                                 uint32_t                buffer_len,
378                                 uint64_t                request_id,
379                                 hv_vmbus_packet_type    type,
380                                 uint32_t                flags);
381
382 int             hv_vmbus_channel_send_packet_pagebuffer(
383                                 hv_vmbus_channel*       channel,
384                                 hv_vmbus_page_buffer    page_buffers[],
385                                 uint32_t                page_count,
386                                 void*                   buffer,
387                                 uint32_t                buffer_len,
388                                 uint64_t                request_id);
389
390 int             hv_vmbus_channel_send_packet_multipagebuffer(
391                                 hv_vmbus_channel*           channel,
392                                 hv_vmbus_multipage_buffer*  multi_page_buffer,
393                                 void*                       buffer,
394                                 uint32_t                    buffer_len,
395                                 uint64_t                    request_id);
396
397 int             hv_vmbus_channel_establish_gpadl(
398                                 hv_vmbus_channel*       channel,
399                                 /* must be phys and virt contiguous */
400                                 void*                   contig_buffer,
401                                 /*  page-size multiple  */
402                                 uint32_t                size,
403                                 uint32_t*               gpadl_handle);
404
405 int             hv_vmbus_channel_teardown_gpdal(
406                                 hv_vmbus_channel*       channel,
407                                 uint32_t                gpadl_handle);
408
409 int             vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan,
410                     bus_addr_t paddr, int size, uint32_t *gpadl);
411
412 struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary);
413
414 void            vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu);
415 void            vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan);
416 struct hv_vmbus_channel **
417                 vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt);
418 void            vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt);
419 void            vmbus_drain_subchan(struct hv_vmbus_channel *pri_chan);
420
421 /**
422  * @brief Get physical address from virtual
423  */
424 static inline unsigned long
425 hv_get_phys_addr(void *virt)
426 {
427         unsigned long ret;
428         ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK));
429         return (ret);
430 }
431
432 static __inline struct hv_vmbus_channel *
433 vmbus_get_channel(device_t dev)
434 {
435         return device_get_ivars(dev);
436 }
437
438 #endif  /* __HYPERV_H__ */