1 #ifndef _IPXE_VMBUS_H
2 #define _IPXE_VMBUS_H
3 
4 /** @file
5  *
6  * Hyper-V virtual machine bus
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <byteswap.h>
13 #include <ipxe/uuid.h>
14 #include <ipxe/device.h>
15 #include <ipxe/tables.h>
16 #include <ipxe/uaccess.h>
17 #include <ipxe/iobuf.h>
18 #include <ipxe/hyperv.h>
19 
20 /** VMBus message connection ID */
21 #define VMBUS_MESSAGE_ID 1
22 
23 /** VMBus event connection ID */
24 #define VMBUS_EVENT_ID 2
25 
26 /** VMBus message type */
27 #define VMBUS_MESSAGE_TYPE 1
28 
29 /** VMBus message synthetic interrupt */
30 #define VMBUS_MESSAGE_SINT 2
31 
32 /** VMBus version number */
33 union vmbus_version {
34 	/** Raw version */
35 	uint32_t raw;
36 	/** Major/minor version */
37 	struct {
38 		/** Minor version */
39 		uint16_t minor;
40 		/** Major version */
41 		uint16_t major;
42 	};
43 } __attribute__ (( packed ));
44 
45 /** Known VMBus protocol versions */
46 enum vmbus_raw_version {
47 	/** Windows Server 2008 */
48 	VMBUS_VERSION_WS2008 = ( ( 0 << 16 ) | ( 13 << 0 ) ),
49 	/** Windows 7 */
50 	VMBUS_VERSION_WIN7 = ( ( 1 << 16 ) | ( 1 << 0 ) ),
51 	/** Windows 8 */
52 	VMBUS_VERSION_WIN8 = ( ( 2 << 16 ) | ( 4 << 0 ) ),
53 	/** Windows 8.1 */
54 	VMBUS_VERSION_WIN8_1 = ( ( 3 << 16 ) | ( 0 << 0 ) ),
55 };
56 
57 /** Guest physical address range descriptor */
58 struct vmbus_gpa_range {
59 	/** Byte count */
60 	uint32_t len;
61 	/** Starting byte offset */
62 	uint32_t offset;
63 	/** Page frame numbers
64 	 *
65 	 * The length of this array is implied by the byte count and
66 	 * starting offset.
67 	 */
68 	uint64_t pfn[0];
69 } __attribute__ (( packed ));
70 
71 /** VMBus message header */
72 struct vmbus_message_header {
73 	/** Message type */
74 	uint32_t type;
75 	/** Reserved */
76 	uint32_t reserved;
77 } __attribute__ (( packed ));
78 
79 /** VMBus message types */
80 enum vmbus_message_type {
81 	VMBUS_OFFER_CHANNEL = 1,
82 	VMBUS_REQUEST_OFFERS = 3,
83 	VMBUS_ALL_OFFERS_DELIVERED = 4,
84 	VMBUS_OPEN_CHANNEL = 5,
85 	VMBUS_OPEN_CHANNEL_RESULT = 6,
86 	VMBUS_CLOSE_CHANNEL = 7,
87 	VMBUS_GPADL_HEADER = 8,
88 	VMBUS_GPADL_CREATED = 10,
89 	VMBUS_GPADL_TEARDOWN = 11,
90 	VMBUS_GPADL_TORNDOWN = 12,
91 	VMBUS_INITIATE_CONTACT = 14,
92 	VMBUS_VERSION_RESPONSE = 15,
93 	VMBUS_UNLOAD = 16,
94 	VMBUS_UNLOAD_RESPONSE = 17,
95 };
96 
97 /** VMBus "offer channel" message */
98 struct vmbus_offer_channel {
99 	/** Message header */
100 	struct vmbus_message_header header;
101 	/** Channel type */
102 	union uuid type;
103 	/** Channel instance */
104 	union uuid instance;
105 	/** Reserved */
106 	uint8_t reserved_a[16];
107 	/** Flags */
108 	uint16_t flags;
109 	/** Reserved */
110 	uint8_t reserved_b[2];
111 	/** User data */
112 	uint8_t data[120];
113 	/** Reserved */
114 	uint8_t reserved_c[4];
115 	/** Channel ID */
116 	uint32_t channel;
117 	/** Monitor ID */
118 	uint8_t monitor;
119 	/** Monitor exists */
120 	uint8_t monitored;
121 	/** Reserved */
122 	uint8_t reserved[2];
123 	/** Connection ID */
124 	uint32_t connection;
125 } __attribute__ (( packed ));
126 
127 /** VMBus "open channel" message */
128 struct vmbus_open_channel {
129 	/** Message header */
130 	struct vmbus_message_header header;
131 	/** Channel ID */
132 	uint32_t channel;
133 	/** Open ID */
134 	uint32_t id;
135 	/** Ring buffer GPADL ID */
136 	uint32_t gpadl;
137 	/** Reserved */
138 	uint32_t reserved;
139 	/** Outbound ring buffer size (in pages) */
140 	uint32_t out_pages;
141 	/** User-specific data */
142 	uint8_t data[120];
143 } __attribute__ (( packed ));
144 
145 /** VMBus "open channel result" message */
146 struct vmbus_open_channel_result {
147 	/** Message header */
148 	struct vmbus_message_header header;
149 	/** Channel ID */
150 	uint32_t channel;
151 	/** Open ID */
152 	uint32_t id;
153 	/** Status */
154 	uint32_t status;
155 } __attribute__ (( packed ));
156 
157 /** VMBus "close channel" message */
158 struct vmbus_close_channel {
159 	/** Message header */
160 	struct vmbus_message_header header;
161 	/** Channel ID */
162 	uint32_t channel;
163 } __attribute__ (( packed ));
164 
165 /** VMBus "GPADL header" message */
166 struct vmbus_gpadl_header {
167 	/** Message header */
168 	struct vmbus_message_header header;
169 	/** Channel ID */
170 	uint32_t channel;
171 	/** GPADL ID */
172 	uint32_t gpadl;
173 	/** Length of range descriptors */
174 	uint16_t range_len;
175 	/** Number of range descriptors */
176 	uint16_t range_count;
177 	/** Range descriptors */
178 	struct vmbus_gpa_range range[0];
179 } __attribute__ (( packed ));
180 
181 /** VMBus "GPADL created" message */
182 struct vmbus_gpadl_created {
183 	/** Message header */
184 	struct vmbus_message_header header;
185 	/** Channel ID */
186 	uint32_t channel;
187 	/** GPADL ID */
188 	uint32_t gpadl;
189 	/** Creation status */
190 	uint32_t status;
191 } __attribute__ (( packed ));
192 
193 /** VMBus "GPADL teardown" message */
194 struct vmbus_gpadl_teardown {
195 	/** Message header */
196 	struct vmbus_message_header header;
197 	/** Channel ID */
198 	uint32_t channel;
199 	/** GPADL ID */
200 	uint32_t gpadl;
201 } __attribute__ (( packed ));
202 
203 /** VMBus "GPADL torndown" message */
204 struct vmbus_gpadl_torndown {
205 	/** Message header */
206 	struct vmbus_message_header header;
207 	/** GPADL ID */
208 	uint32_t gpadl;
209 } __attribute__ (( packed ));
210 
211 /** VMBus "initiate contact" message */
212 struct vmbus_initiate_contact {
213 	/** Message header */
214 	struct vmbus_message_header header;
215 	/** Requested version */
216 	union vmbus_version version;
217 	/** Target virtual CPU */
218 	uint32_t vcpu;
219 	/** Interrupt page base address */
220 	uint64_t intr;
221 	/** Parent to child monitor page base address */
222 	uint64_t monitor_in;
223 	/** Child to parent monitor page base address */
224 	uint64_t monitor_out;
225 } __attribute__ (( packed ));
226 
227 /** VMBus "version response" message */
228 struct vmbus_version_response {
229 	/** Message header */
230 	struct vmbus_message_header header;
231 	/** Version is supported */
232 	uint8_t supported;
233 	/** Reserved */
234 	uint8_t reserved[3];
235 	/** Version */
236 	union vmbus_version version;
237 } __attribute__ (( packed ));
238 
239 /** VMBus message */
240 union vmbus_message {
241 	/** Common message header */
242 	struct vmbus_message_header header;
243 	/** "Offer channel" message */
244 	struct vmbus_offer_channel offer;
245 	/** "Open channel" message */
246 	struct vmbus_open_channel open;
247 	/** "Open channel result" message */
248 	struct vmbus_open_channel_result opened;
249 	/** "Close channel" message */
250 	struct vmbus_close_channel close;
251 	/** "GPADL header" message */
252 	struct vmbus_gpadl_header gpadlhdr;
253 	/** "GPADL created" message */
254 	struct vmbus_gpadl_created created;
255 	/** "GPADL teardown" message */
256 	struct vmbus_gpadl_teardown teardown;
257 	/** "GPADL torndown" message */
258 	struct vmbus_gpadl_torndown torndown;
259 	/** "Initiate contact" message */
260 	struct vmbus_initiate_contact initiate;
261 	/** "Version response" message */
262 	struct vmbus_version_response version;
263 };
264 
265 /** VMBus packet header */
266 struct vmbus_packet_header {
267 	/** Type */
268 	uint16_t type;
269 	/** Length of packet header (in quadwords) */
270 	uint16_t hdr_qlen;
271 	/** Length of packet (in quadwords) */
272 	uint16_t qlen;
273 	/** Flags */
274 	uint16_t flags;
275 	/** Transaction ID
276 	 *
277 	 * This is an opaque token: we therefore treat it as
278 	 * native-endian and don't worry about byte-swapping.
279 	 */
280 	uint64_t xid;
281 } __attribute__ (( packed ));
282 
283 /** VMBus packet types */
284 enum vmbus_packet_type {
285 	VMBUS_DATA_INBAND = 6,
286 	VMBUS_DATA_XFER_PAGES = 7,
287 	VMBUS_DATA_GPA_DIRECT = 9,
288 	VMBUS_CANCELLATION = 10,
289 	VMBUS_COMPLETION = 11,
290 };
291 
292 /** VMBus packet flags */
293 enum vmbus_packet_flags {
294 	VMBUS_COMPLETION_REQUESTED = 0x0001,
295 };
296 
297 /** VMBus GPA direct header */
298 struct vmbus_gpa_direct_header {
299 	/** Packet header */
300 	struct vmbus_packet_header header;
301 	/** Reserved */
302 	uint32_t reserved;
303 	/** Number of range descriptors */
304 	uint32_t range_count;
305 	/** Range descriptors */
306 	struct vmbus_gpa_range range[0];
307 } __attribute__ (( packed ));
308 
309 /** VMBus transfer page range */
310 struct vmbus_xfer_page_range {
311 	/** Length */
312 	uint32_t len;
313 	/** Offset */
314 	uint32_t offset;
315 } __attribute__ (( packed ));
316 
317 /** VMBus transfer page header */
318 struct vmbus_xfer_page_header {
319 	/** Packet header */
320 	struct vmbus_packet_header header;
321 	/** Page set ID */
322 	uint16_t pageset;
323 	/** Sender owns page set */
324 	uint8_t owner;
325 	/** Reserved */
326 	uint8_t reserved;
327 	/** Number of range descriptors */
328 	uint32_t range_count;
329 	/** Range descriptors */
330 	struct vmbus_xfer_page_range range[0];
331 } __attribute__ (( packed ));
332 
333 /** Maximum expected size of VMBus packet header */
334 #define VMBUS_PACKET_MAX_HEADER_LEN 64
335 
336 /** VMBus maximum-sized packet header */
337 union vmbus_packet_header_max {
338 	/** Common header */
339 	struct vmbus_packet_header header;
340 	/** GPA direct header */
341 	struct vmbus_gpa_direct_header gpa;
342 	/** Transfer page header */
343 	struct vmbus_xfer_page_header xfer;
344 	/** Padding to maximum supported size */
345 	uint8_t padding[VMBUS_PACKET_MAX_HEADER_LEN];
346 } __attribute__ (( packed ));
347 
348 /** VMBus packet footer */
349 struct vmbus_packet_footer {
350 	/** Reserved */
351 	uint32_t reserved;
352 	/** Producer index of the first byte of the packet */
353 	uint32_t prod;
354 } __attribute__ (( packed ));
355 
356 /** VMBus ring buffer
357  *
358  * This is the structure of the each of the ring buffers created when
359  * a VMBus channel is opened.
360  */
361 struct vmbus_ring {
362 	/** Producer index (modulo ring length) */
363 	uint32_t prod;
364 	/** Consumer index (modulo ring length) */
365 	uint32_t cons;
366 	/** Interrupt mask */
367 	uint32_t intr_mask;
368 	/** Reserved */
369 	uint8_t reserved[4084];
370 	/** Ring buffer contents */
371 	uint8_t data[0];
372 } __attribute__ (( packed ));
373 
374 /** VMBus interrupt page */
375 struct vmbus_interrupt {
376 	/** Inbound interrupts */
377 	uint8_t in[ PAGE_SIZE / 2 ];
378 	/** Outbound interrupts */
379 	uint8_t out[ PAGE_SIZE / 2 ];
380 } __attribute__ (( packed ));
381 
382 /** A virtual machine bus */
383 struct vmbus {
384 	/** Interrupt page */
385 	struct vmbus_interrupt *intr;
386 	/** Inbound notifications */
387 	struct hv_monitor *monitor_in;
388 	/** Outbound notifications */
389 	struct hv_monitor *monitor_out;
390 	/** Received message buffer */
391 	const union vmbus_message *message;
392 };
393 
394 struct vmbus_device;
395 
396 /** VMBus channel operations */
397 struct vmbus_channel_operations {
398 	/**
399 	 * Handle received control packet
400 	 *
401 	 * @v vmdev		VMBus device
402 	 * @v xid		Transaction ID
403 	 * @v data		Data
404 	 * @v len		Length of data
405 	 * @ret rc		Return status code
406 	 */
407 	int ( * recv_control ) ( struct vmbus_device *vmdev, uint64_t xid,
408 				 const void *data, size_t len );
409 	/**
410 	 * Handle received data packet
411 	 *
412 	 * @v vmdev		VMBus device
413 	 * @v xid		Transaction ID
414 	 * @v data		Data
415 	 * @v len		Length of data
416 	 * @v list		List of I/O buffers
417 	 * @ret rc		Return status code
418 	 *
419 	 * This function takes ownership of the I/O buffer.  It should
420 	 * eventually call vmbus_send_completion() to indicate to the
421 	 * host that the buffer can be reused.
422 	 */
423 	int ( * recv_data ) ( struct vmbus_device *vmdev, uint64_t xid,
424 			      const void *data, size_t len,
425 			      struct list_head *list );
426 	/**
427 	 * Handle received completion packet
428 	 *
429 	 * @v vmdev		VMBus device
430 	 * @v xid		Transaction ID
431 	 * @v data		Data
432 	 * @v len		Length of data
433 	 * @ret rc		Return status code
434 	 */
435 	int ( * recv_completion ) ( struct vmbus_device *vmdev, uint64_t xid,
436 				    const void *data, size_t len );
437 	/**
438 	 * Handle received cancellation packet
439 	 *
440 	 * @v vmdev		VMBus device
441 	 * @v xid		Transaction ID
442 	 * @ret rc		Return status code
443 	 */
444 	int ( * recv_cancellation ) ( struct vmbus_device *vmdev,
445 				      uint64_t xid );
446 };
447 
448 struct vmbus_xfer_pages;
449 
450 /** VMBus transfer page set operations */
451 struct vmbus_xfer_pages_operations {
452 	/**
453 	 * Copy data from transfer page
454 	 *
455 	 * @v pages		Transfer page set
456 	 * @v data		Data buffer
457 	 * @v offset		Offset within page set
458 	 * @v len		Length within page set
459 	 * @ret rc		Return status code
460 	 */
461 	int ( * copy ) ( struct vmbus_xfer_pages *pages, void *data,
462 			 size_t offset, size_t len );
463 };
464 
465 /** VMBus transfer page set */
466 struct vmbus_xfer_pages {
467 	/** List of all transfer page sets */
468 	struct list_head list;
469 	/** Page set ID (in protocol byte order) */
470 	uint16_t pageset;
471 	/** Page set operations */
472 	struct vmbus_xfer_pages_operations *op;
473 };
474 
475 /** A VMBus device */
476 struct vmbus_device {
477 	/** Generic iPXE device */
478 	struct device dev;
479 	/** Hyper-V hypervisor */
480 	struct hv_hypervisor *hv;
481 
482 	/** Channel instance */
483 	union uuid instance;
484 	/** Channel ID */
485 	unsigned int channel;
486 	/** Monitor ID */
487 	unsigned int monitor;
488 	/** Signal channel
489 	 *
490 	 * @v vmdev		VMBus device
491 	 */
492 	void ( * signal ) ( struct vmbus_device *vmdev );
493 
494 	/** Outbound ring buffer length */
495 	uint32_t out_len;
496 	/** Inbound ring buffer length */
497 	uint32_t in_len;
498 	/** Outbound ring buffer */
499 	struct vmbus_ring *out;
500 	/** Inbound ring buffer */
501 	struct vmbus_ring *in;
502 	/** Ring buffer GPADL ID */
503 	unsigned int gpadl;
504 
505 	/** Channel operations */
506 	struct vmbus_channel_operations *op;
507 	/** Maximum expected data packet length */
508 	size_t mtu;
509 	/** Packet buffer */
510 	void *packet;
511 	/** List of transfer page sets */
512 	struct list_head pages;
513 
514 	/** Driver */
515 	struct vmbus_driver *driver;
516 	/** Driver-private data */
517 	void *priv;
518 };
519 
520 /** A VMBus device driver */
521 struct vmbus_driver {
522 	/** Name */
523 	const char *name;
524 	/** Device type */
525 	union uuid type;
526 	/** Probe device
527 	 *
528 	 * @v vmdev		VMBus device
529 	 * @ret rc		Return status code
530 	 */
531 	int ( * probe ) ( struct vmbus_device *vmdev );
532 	/** Reset device
533 	 *
534 	 * @v vmdev		VMBus device
535 	 * @ret rc		Return status code
536 	 */
537 	int ( * reset ) ( struct vmbus_device *vmdev );
538 	/** Remove device
539 	 *
540 	 * @v vmdev		VMBus device
541 	 */
542 	void ( * remove ) ( struct vmbus_device *vmdev );
543 };
544 
545 /** VMBus device driver table */
546 #define VMBUS_DRIVERS __table ( struct vmbus_driver, "vmbus_drivers" )
547 
548 /** Declare a VMBus device driver */
549 #define __vmbus_driver __table_entry ( VMBUS_DRIVERS, 01 )
550 
551 /**
552  * Set VMBus device driver-private data
553  *
554  * @v vmdev		VMBus device
555  * @v priv		Private data
556  */
vmbus_set_drvdata(struct vmbus_device * vmdev,void * priv)557 static inline void vmbus_set_drvdata ( struct vmbus_device *vmdev, void *priv ){
558 	vmdev->priv = priv;
559 }
560 
561 /**
562  * Get VMBus device driver-private data
563  *
564  * @v vmdev		VMBus device
565  * @ret priv		Private data
566  */
vmbus_get_drvdata(struct vmbus_device * vmdev)567 static inline void * vmbus_get_drvdata ( struct vmbus_device *vmdev ) {
568 	return vmdev->priv;
569 }
570 
571 /** Construct VMBus type */
572 #define VMBUS_TYPE( a, b, c, d, e0, e1, e2, e3, e4, e5 ) {		\
573 	.canonical = {							\
574 		cpu_to_le32 ( a ), cpu_to_le16 ( b ),			\
575 		cpu_to_le16 ( c ), cpu_to_be16 ( d ),			\
576 		{ e0, e1, e2, e3, e4, e5 }				\
577 	 } }
578 
579 /**
580  * Check if data is present in ring buffer
581  *
582  * @v vmdev		VMBus device
583  * @v has_data		Data is present
584  */
585 static inline __attribute__ (( always_inline )) int
vmbus_has_data(struct vmbus_device * vmdev)586 vmbus_has_data ( struct vmbus_device *vmdev ) {
587 
588 	return ( vmdev->in->prod != vmdev->in->cons );
589 }
590 
591 /**
592  * Register transfer page set
593  *
594  * @v vmdev		VMBus device
595  * @v pages		Transfer page set
596  * @ret rc		Return status code
597  */
598 static inline __attribute__ (( always_inline )) int
vmbus_register_pages(struct vmbus_device * vmdev,struct vmbus_xfer_pages * pages)599 vmbus_register_pages ( struct vmbus_device *vmdev,
600 		       struct vmbus_xfer_pages *pages ) {
601 
602 	list_add ( &pages->list, &vmdev->pages );
603 	return 0;
604 }
605 
606 /**
607  * Unregister transfer page set
608  *
609  * @v vmdev		VMBus device
610  * @v pages		Transfer page set
611  */
612 static inline __attribute__ (( always_inline )) void
vmbus_unregister_pages(struct vmbus_device * vmdev,struct vmbus_xfer_pages * pages)613 vmbus_unregister_pages ( struct vmbus_device *vmdev,
614 			 struct vmbus_xfer_pages *pages ) {
615 
616 	list_check_contains_entry ( pages, &vmdev->pages, list );
617 	list_del ( &pages->list );
618 }
619 
620 extern unsigned int vmbus_obsolete_gpadl;
621 
622 /**
623  * Check if GPADL is obsolete
624  *
625  * @v gpadl		GPADL ID
626  * @v is_obsolete	GPADL ID is obsolete
627  *
628  * Check if GPADL is obsolete (i.e. was created before the most recent
629  * Hyper-V reset).
630  */
631 static inline __attribute__ (( always_inline )) int
vmbus_gpadl_is_obsolete(unsigned int gpadl)632 vmbus_gpadl_is_obsolete ( unsigned int gpadl ) {
633 
634 	return ( gpadl <= vmbus_obsolete_gpadl );
635 }
636 
637 extern int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
638 				   size_t len );
639 extern int vmbus_gpadl_teardown ( struct vmbus_device *vmdev,
640 				  unsigned int gpadl );
641 extern int vmbus_open ( struct vmbus_device *vmdev,
642 			struct vmbus_channel_operations *op,
643 			size_t out_len, size_t in_len, size_t mtu );
644 extern void vmbus_close ( struct vmbus_device *vmdev );
645 extern int vmbus_send_control ( struct vmbus_device *vmdev, uint64_t xid,
646 				const void *data, size_t len );
647 extern int vmbus_send_data ( struct vmbus_device *vmdev, uint64_t xid,
648 			     const void *data, size_t len,
649 			     struct io_buffer *iobuf );
650 extern int vmbus_send_completion ( struct vmbus_device *vmdev, uint64_t xid,
651 				   const void *data, size_t len );
652 extern int vmbus_send_cancellation ( struct vmbus_device *vmdev, uint64_t xid );
653 extern int vmbus_poll ( struct vmbus_device *vmdev );
654 extern void vmbus_dump_channel ( struct vmbus_device *vmdev );
655 
656 extern int vmbus_probe ( struct hv_hypervisor *hv, struct device *parent );
657 extern int vmbus_reset ( struct hv_hypervisor *hv, struct device *parent );
658 extern void vmbus_remove ( struct hv_hypervisor *hv, struct device *parent );
659 
660 #endif /* _IPXE_VMBUS_H */
661