Blame view

drivers/hv/hyperv_vmbus.h 10.6 KB
0f2a6619e   K. Y. Srinivasan   Staging: hv: vmbu...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  /*
   *
   * Copyright (c) 2011, Microsoft Corporation.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms and conditions of the GNU General Public License,
   * version 2, as published by the Free Software Foundation.
   *
   * This program is distributed in the hope it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   * more details.
   *
   * You should have received a copy of the GNU General Public License along with
   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   * Place - Suite 330, Boston, MA 02111-1307 USA.
   *
   * Authors:
   *   Haiyang Zhang <haiyangz@microsoft.com>
   *   Hank Janssen  <hjanssen@microsoft.com>
   *   K. Y. Srinivasan <kys@microsoft.com>
   *
   */
  
  #ifndef _HYPERV_VMBUS_H
  #define _HYPERV_VMBUS_H
43c698b92   K. Y. Srinivasan   Staging: hv: vmbu...
27
28
29
  #include <linux/list.h>
  #include <asm/sync_bitops.h>
  #include <linux/atomic.h>
46a971913   Greg Kroah-Hartman   Staging: hv: move...
30
  #include <linux/hyperv.h>
37cdd991f   Stephen Hemminger   vmbus: put relate...
31
  #include <linux/interrupt.h>
43c698b92   K. Y. Srinivasan   Staging: hv: vmbu...
32

afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
33
  /*
c0b200cfb   K. Y. Srinivasan   Drivers: hv: util...
34
35
36
37
38
   * Timeout for services such as KVP and fcopy.
   */
  #define HV_UTIL_TIMEOUT 30
  
  /*
4dbfc2e68   Vitaly Kuznetsov   Drivers: hv: kvp:...
39
40
   * Timeout for guest-host handshake for services.
   */
d7edd31ba   Vitaly Kuznetsov   Drivers: hv: util...
41
  #define HV_UTIL_NEGO_TIMEOUT 55
4dbfc2e68   Vitaly Kuznetsov   Drivers: hv: kvp:...
42

5c1bec61f   Stephen Hemminger   vmbus: use kernel...
43
44
45
  /* Define synthetic interrupt controller flag constants. */
  #define HV_EVENT_FLAGS_COUNT		(256 * 8)
  #define HV_EVENT_FLAGS_LONG_COUNT	(256 / sizeof(unsigned long))
afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
46

4061ed9e2   K. Y. Srinivasan   Drivers: hv: vmbu...
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  /*
   * Timer configuration register.
   */
  union hv_timer_config {
  	u64 as_uint64;
  	struct {
  		u64 enable:1;
  		u64 periodic:1;
  		u64 lazy:1;
  		u64 auto_enable:1;
  		u64 reserved_z0:12;
  		u64 sintx:4;
  		u64 reserved_z1:44;
  	};
  };
afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
62

afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
63
64
  /* Define the synthetic interrupt controller event flags format. */
  union hv_synic_event_flags {
5c1bec61f   Stephen Hemminger   vmbus: use kernel...
65
  	unsigned long flags[HV_EVENT_FLAGS_LONG_COUNT];
afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
66
  };
afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
  /* Define SynIC control register. */
  union hv_synic_scontrol {
  	u64 as_uint64;
  	struct {
  		u64 enable:1;
  		u64 reserved:63;
  	};
  };
  
  /* Define synthetic interrupt source. */
  union hv_synic_sint {
  	u64 as_uint64;
  	struct {
  		u64 vector:8;
  		u64 reserved1:8;
  		u64 masked:1;
  		u64 auto_eoi:1;
  		u64 reserved2:46;
  	};
  };
  
  /* Define the format of the SIMP register */
  union hv_synic_simp {
  	u64 as_uint64;
  	struct {
  		u64 simp_enabled:1;
  		u64 preserved:11;
  		u64 base_simp_gpa:52;
  	};
  };
  
  /* Define the format of the SIEFP register */
  union hv_synic_siefp {
  	u64 as_uint64;
  	struct {
  		u64 siefp_enabled:1;
  		u64 preserved:11;
  		u64 base_siefp_gpa:52;
  	};
  };
  
  /* Definitions for the monitored notification facility */
  union hv_monitor_trigger_group {
  	u64 as_uint64;
  	struct {
  		u32 pending;
  		u32 armed;
  	};
  };
  
  struct hv_monitor_parameter {
  	union hv_connection_id connectionid;
  	u16 flagnumber;
  	u16 rsvdz;
  };
  
  union hv_monitor_trigger_state {
  	u32 asu32;
  
  	struct {
  		u32 group_enable:4;
  		u32 rsvdz:28;
  	};
  };
  
  /* struct hv_monitor_page Layout */
  /* ------------------------------------------------------ */
  /* | 0   | TriggerState (4 bytes) | Rsvd1 (4 bytes)     | */
  /* | 8   | TriggerGroup[0]                              | */
  /* | 10  | TriggerGroup[1]                              | */
  /* | 18  | TriggerGroup[2]                              | */
  /* | 20  | TriggerGroup[3]                              | */
  /* | 28  | Rsvd2[0]                                     | */
  /* | 30  | Rsvd2[1]                                     | */
  /* | 38  | Rsvd2[2]                                     | */
  /* | 40  | NextCheckTime[0][0]    | NextCheckTime[0][1] | */
  /* | ...                                                | */
  /* | 240 | Latency[0][0..3]                             | */
  /* | 340 | Rsvz3[0]                                     | */
  /* | 440 | Parameter[0][0]                              | */
  /* | 448 | Parameter[0][1]                              | */
  /* | ...                                                | */
  /* | 840 | Rsvd4[0]                                     | */
  /* ------------------------------------------------------ */
  struct hv_monitor_page {
  	union hv_monitor_trigger_state trigger_state;
  	u32 rsvdz1;
  
  	union hv_monitor_trigger_group trigger_group[4];
  	u64 rsvdz2[3];
  
  	s32 next_checktime[4][32];
  
  	u16 latency[4][32];
  	u64 rsvdz3[32];
  
  	struct hv_monitor_parameter parameter[4][32];
  
  	u8 rsvdz4[1984];
  };
8e27a2363   K. Y. Srinivasan   Drivers: hv: vmbu...
167
  #define HV_HYPERCALL_PARAM_ALIGN	sizeof(u64)
afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
168
169
170
171
  /* Definition of the hv_post_message hypercall input structure. */
  struct hv_input_post_message {
  	union hv_connection_id connectionid;
  	u32 reserved;
7797dcf63   Andrey Smetanin   drivers/hv: repla...
172
  	u32 message_type;
afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
173
174
175
  	u32 payload_size;
  	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
  };
afbdc4a98   K. Y. Srinivasan   Staging: hv: vmbu...
176

3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
177
178
179
180
181
182
183
184
185
  enum {
  	VMBUS_MESSAGE_CONNECTION_ID	= 1,
  	VMBUS_MESSAGE_PORT_ID		= 1,
  	VMBUS_EVENT_CONNECTION_ID	= 2,
  	VMBUS_EVENT_PORT_ID		= 2,
  	VMBUS_MONITOR_CONNECTION_ID	= 3,
  	VMBUS_MONITOR_PORT_ID		= 3,
  	VMBUS_MESSAGE_SINT		= 2,
  };
37cdd991f   Stephen Hemminger   vmbus: put relate...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  /*
   * Per cpu state for channel handling
   */
  struct hv_per_cpu_context {
  	void *synic_message_page;
  	void *synic_event_page;
  	/*
  	 * buffer to post messages to the host.
  	 */
  	void *post_msg_page;
  
  	/*
  	 * Starting with win8, we can take channel interrupts on any CPU;
  	 * we will manage the tasklet that handles events messages on a per CPU
  	 * basis.
  	 */
37cdd991f   Stephen Hemminger   vmbus: put relate...
202
203
204
205
206
207
208
209
210
  	struct tasklet_struct msg_dpc;
  
  	/*
  	 * To optimize the mapping of relid to channel, maintain
  	 * per-cpu list of the channels based on their CPU affinity.
  	 */
  	struct list_head chan_list;
  	struct clock_event_device *clk_evt;
  };
3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
211
212
  struct hv_context {
  	/* We only support running on top of Hyper-V
2a9d7de20   Stephen Hemminger   vmbus: cleanup he...
213
214
  	 * So at this point this really can only contain the Hyper-V ID
  	 */
3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
215
  	u64 guestid;
ca9357bd2   K. Y. Srinivasan   Drivers: hv: vmbu...
216
  	void *tsc_page;
3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
217
218
  
  	bool synic_initialized;
37cdd991f   Stephen Hemminger   vmbus: put relate...
219
  	struct hv_per_cpu_context __percpu *cpu_context;
917ea427c   K. Y. Srinivasan   Drivers: hv: Setu...
220
  	/*
9f01ec534   K. Y. Srinivasan   Drivers: hv: vmbu...
221
222
223
224
  	 * To manage allocations in a NUMA node.
  	 * Array indexed by numa node ID.
  	 */
  	struct cpumask *hv_numa_map;
3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
225
226
227
  };
  
  extern struct hv_context hv_context;
3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
228
229
230
  /* Hv Interface */
  
  extern int hv_init(void);
415f0a02a   Dan Carpenter   hv: fix return ty...
231
  extern int hv_post_message(union hv_connection_id connection_id,
3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
232
233
  			 enum hv_message_type message_type,
  			 void *payload, size_t payload_size);
2608fb653   Jason Wang   drivers: hv: allo...
234
235
236
  extern int hv_synic_alloc(void);
  
  extern void hv_synic_free(void);
76d36ab79   Vitaly Kuznetsov   hv: switch to cpu...
237
  extern int hv_synic_init(unsigned int cpu);
3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
238

76d36ab79   Vitaly Kuznetsov   hv: switch to cpu...
239
  extern int hv_synic_cleanup(unsigned int cpu);
3645a917f   K. Y. Srinivasan   Staging: hv: vmbu...
240

e086748c6   Vitaly Kuznetsov   Drivers: hv: vmbu...
241
  extern void hv_synic_clockevents_cleanup(void);
940655c10   K. Y. Srinivasan   Staging: hv: vmbu...
242
  /* Interface */
9988ce685   Vitaly Kuznetsov   Drivers: hv: ring...
243
244
  int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
  		       struct page *pages, u32 pagecnt);
940655c10   K. Y. Srinivasan   Staging: hv: vmbu...
245
246
  
  void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
1f6ee4e7d   K. Y. Srinivasan   Drivers: hv: vmbu...
247
  int hv_ringbuffer_write(struct vmbus_channel *channel,
e4165a0fa   Stephen Hemminger   vmbus: constify p...
248
  			const struct kvec *kv_list, u32 kv_count);
940655c10   K. Y. Srinivasan   Staging: hv: vmbu...
249

3372592a1   K. Y. Srinivasan   Drivers: hv: vmbu...
250
  int hv_ringbuffer_read(struct vmbus_channel *channel,
940b68e2c   Vitaly Kuznetsov   Drivers: hv: ring...
251
  		       void *buffer, u32 buflen, u32 *buffer_actual_len,
3372592a1   K. Y. Srinivasan   Drivers: hv: vmbu...
252
  		       u64 *requestid, bool raw);
940655c10   K. Y. Srinivasan   Staging: hv: vmbu...
253

89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
  /*
   * Maximum channels is determined by the size of the interrupt page
   * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
   * and the other is receive endpoint interrupt
   */
  #define MAX_NUM_CHANNELS	((PAGE_SIZE >> 1) << 3)	/* 16348 channels */
  
  /* The value here must be in multiple of 32 */
  /* TODO: Need to make this configurable */
  #define MAX_NUM_CHANNELS_SUPPORTED	256
  
  
  enum vmbus_connect_state {
  	DISCONNECTED,
  	CONNECTING,
  	CONNECTED,
  	DISCONNECTING
  };
  
  #define MAX_SIZE_CHANNEL_MESSAGE	HV_MESSAGE_PAYLOAD_BYTE_COUNT
  
  struct vmbus_connection {
54a66265d   K. Y. Srinivasan   Drivers: hv: vmbu...
276
277
278
279
280
281
  	/*
  	 * CPU on which the initial host contact was made.
  	 */
  	int connect_cpu;
  
  	atomic_t offer_in_progress;
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
282
283
284
  	enum vmbus_connect_state conn_state;
  
  	atomic_t next_gpadl_handle;
2db84eff1   K. Y. Srinivasan   Drivers: hv: vmbu...
285
  	struct completion  unload_event;
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
  	/*
  	 * Represents channel interrupts. Each bit position represents a
  	 * channel.  When a channel sends an interrupt via VMBUS, it finds its
  	 * bit in the sendInterruptPage, set it and calls Hv to generate a port
  	 * event. The other end receives the port event and parse the
  	 * recvInterruptPage to see which bit is set
  	 */
  	void *int_page;
  	void *send_int_page;
  	void *recv_int_page;
  
  	/*
  	 * 2 pages - 1st page for parent->child notification and 2nd
  	 * is child->parent notification
  	 */
8681db445   Greg Kroah-Hartman   hv: make "monitor...
301
  	struct hv_monitor_page *monitor_pages[2];
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
302
303
304
305
306
  	struct list_head chn_msg_list;
  	spinlock_t channelmsg_lock;
  
  	/* List of channels */
  	struct list_head chn_list;
d6f591e33   Dexuan Cui   Drivers: hv: vmbu...
307
  	struct mutex channel_mutex;
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
308

c1063941e   Dexuan Cui   Drivers: hv: vmbu...
309
310
311
312
313
  	/*
  	 * An offer message is handled first on the work_queue, and then
  	 * is further handled on handle_primary_chan_wq or
  	 * handle_sub_chan_wq.
  	 */
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
314
  	struct workqueue_struct *work_queue;
c1063941e   Dexuan Cui   Drivers: hv: vmbu...
315
316
  	struct workqueue_struct *handle_primary_chan_wq;
  	struct workqueue_struct *handle_sub_chan_wq;
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
317
318
319
320
321
322
323
324
325
326
327
328
329
  };
  
  
  struct vmbus_msginfo {
  	/* Bookkeeping stuff */
  	struct list_head msglist_entry;
  
  	/* The message itself */
  	unsigned char msg[0];
  };
  
  
  extern struct vmbus_connection vmbus_connection;
5c1bec61f   Stephen Hemminger   vmbus: use kernel...
330
331
332
333
  static inline void vmbus_send_interrupt(u32 relid)
  {
  	sync_set_bit(relid, vmbus_connection.send_int_page);
  }
652594c7d   Dexuan Cui   hv: run non-block...
334
335
336
337
338
339
340
341
342
343
344
345
346
  enum vmbus_message_handler_type {
  	/* The related handler can sleep. */
  	VMHT_BLOCKING = 0,
  
  	/* The related handler must NOT sleep. */
  	VMHT_NON_BLOCKING = 1,
  };
  
  struct vmbus_channel_message_table_entry {
  	enum vmbus_channel_message_type message_type;
  	enum vmbus_message_handler_type handler_type;
  	void (*message_handler)(struct vmbus_channel_message_header *msg);
  };
e6242fa0f   Stephen Hemminger   vmbus: make chann...
347
  extern const struct vmbus_channel_message_table_entry
652594c7d   Dexuan Cui   hv: run non-block...
348
  	channel_message_table[CHANNELMSG_COUNT];
0f70b6697   Vitaly Kuznetsov   Drivers: hv: vmbu...
349

89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
350
  /* General vmbus interface */
1b9d48f2a   stephen hemminger   hyper-v: make uui...
351
352
353
  struct hv_device *vmbus_device_create(const uuid_le *type,
  				      const uuid_le *instance,
  				      struct vmbus_channel *channel);
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
354

227942819   K. Y. Srinivasan   Staging: hv: vmbu...
355
  int vmbus_device_register(struct hv_device *child_device_obj);
696453ba2   K. Y. Srinivasan   Staging: hv: vmbu...
356
  void vmbus_device_unregister(struct hv_device *device_obj);
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
357

d43e2fe7d   Dexuan Cui   hv: don't schedul...
358
  struct vmbus_channel *relid2channel(u32 relid);
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
359

93e5bd06a   K. Y. Srinivasan   Drivers: hv: Make...
360
  void vmbus_free_channels(void);
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
361
362
363
364
  
  /* Connection interface */
  
  int vmbus_connect(void);
09a196288   Vitaly Kuznetsov   Drivers: hv: vmbu...
365
  void vmbus_disconnect(void);
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
366

c0bb03924   Vitaly Kuznetsov   Drivers: hv: vmbu...
367
  int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep);
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
368

89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
369
  void vmbus_on_event(unsigned long data);
d81274aae   K. Y. Srinivasan   Drivers: hv: vmbu...
370
  void vmbus_on_msg_dpc(unsigned long data);
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
371

2a9d7de20   Stephen Hemminger   vmbus: cleanup he...
372
  int hv_kvp_init(struct hv_util_service *srv);
3647a83d9   Vitaly Kuznetsov   Drivers: hv: util...
373
  void hv_kvp_deinit(void);
2a9d7de20   Stephen Hemminger   vmbus: cleanup he...
374
  void hv_kvp_onchannelcallback(void *context);
3647a83d9   Vitaly Kuznetsov   Drivers: hv: util...
375

2a9d7de20   Stephen Hemminger   vmbus: cleanup he...
376
  int hv_vss_init(struct hv_util_service *srv);
3647a83d9   Vitaly Kuznetsov   Drivers: hv: util...
377
  void hv_vss_deinit(void);
2a9d7de20   Stephen Hemminger   vmbus: cleanup he...
378
  void hv_vss_onchannelcallback(void *context);
3647a83d9   Vitaly Kuznetsov   Drivers: hv: util...
379

2a9d7de20   Stephen Hemminger   vmbus: cleanup he...
380
  int hv_fcopy_init(struct hv_util_service *srv);
01325476d   K. Y. Srinivasan   Drivers: hv: Impl...
381
  void hv_fcopy_deinit(void);
2a9d7de20   Stephen Hemminger   vmbus: cleanup he...
382
  void hv_fcopy_onchannelcallback(void *context);
75ff3a8a9   Vitaly Kuznetsov   Drivers: hv: vmbu...
383
  void vmbus_initiate_unload(bool crash);
01325476d   K. Y. Srinivasan   Drivers: hv: Impl...
384

8efe78fdb   Vitaly Kuznetsov   Drivers: hv: kvp:...
385
386
387
388
389
  static inline void hv_poll_channel(struct vmbus_channel *channel,
  				   void (*cb)(void *))
  {
  	if (!channel)
  		return;
1e052a16e   K. Y. Srinivasan   Drivers: hv: util...
390
391
392
393
  	if (in_interrupt() && (channel->target_cpu == smp_processor_id())) {
  		cb(channel);
  		return;
  	}
3cace4a61   Olaf Hering   Drivers: hv: util...
394
  	smp_call_function_single(channel->target_cpu, cb, channel, true);
8efe78fdb   Vitaly Kuznetsov   Drivers: hv: kvp:...
395
  }
89b2ca478   K. Y. Srinivasan   Staging: hv: vmbu...
396

636c88da6   Vitaly Kuznetsov   Drivers: hv: util...
397
398
399
400
401
402
403
404
  enum hvutil_device_state {
  	HVUTIL_DEVICE_INIT = 0,  /* driver is loaded, waiting for userspace */
  	HVUTIL_READY,            /* userspace is registered */
  	HVUTIL_HOSTMSG_RECEIVED, /* message from the host was received */
  	HVUTIL_USERSPACE_REQ,    /* request to userspace was sent */
  	HVUTIL_USERSPACE_RECV,   /* reply from userspace was received */
  	HVUTIL_DEVICE_DYING,     /* driver unload is in progress */
  };
0f2a6619e   K. Y. Srinivasan   Staging: hv: vmbu...
405
  #endif /* _HYPERV_VMBUS_H */