iPXE
vmbus.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Hyper-V virtual machine bus
29  *
30  */
31 
32 #include <stdint.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <assert.h>
38 #include <byteswap.h>
39 #include <ipxe/nap.h>
40 #include <ipxe/malloc.h>
41 #include <ipxe/iobuf.h>
42 #include <ipxe/bitops.h>
43 #include <ipxe/hyperv.h>
44 #include <ipxe/vmbus.h>
45 
46 /** VMBus initial GPADL ID
47  *
48  * This is an opaque value with no meaning. The Linux kernel uses
49  * 0xe1e10.
50  */
51 #define VMBUS_GPADL_MAGIC 0x18ae0000
52 
53 /** Current (i.e. most recently issued) GPADL ID */
54 static unsigned int vmbus_gpadl = VMBUS_GPADL_MAGIC;
55 
56 /** Obsolete GPADL ID threshold
57  *
58  * When the Hyper-V connection is reset, any previous GPADLs are
59  * automatically rendered obsolete.
60  */
61 unsigned int vmbus_obsolete_gpadl;
62 
63 /**
64  * Post message
65  *
66  * @v hv Hyper-V hypervisor
67  * @v header Message header
68  * @v len Length of message (including header)
69  * @ret rc Return status code
70  */
71 static int vmbus_post_message ( struct hv_hypervisor *hv,
72  const struct vmbus_message_header *header,
73  size_t len ) {
74  struct vmbus *vmbus = hv->vmbus;
75  int rc;
76 
77  /* Post message */
79  header, len ) ) != 0 ) {
80  DBGC ( vmbus, "VMBUS %p could not post message: %s\n",
81  vmbus, strerror ( rc ) );
82  return rc;
83  }
84 
85  return 0;
86 }
87 
88 /**
89  * Post empty message
90  *
91  * @v hv Hyper-V hypervisor
92  * @v type Message type
93  * @ret rc Return status code
94  */
95 static int vmbus_post_empty_message ( struct hv_hypervisor *hv,
96  unsigned int type ) {
97  struct vmbus_message_header header = { .type = cpu_to_le32 ( type ) };
98 
99  return vmbus_post_message ( hv, &header, sizeof ( header ) );
100 }
101 
102 /**
103  * Wait for received message of any type
104  *
105  * @v hv Hyper-V hypervisor
106  * @ret rc Return status code
107  */
108 static int vmbus_wait_for_any_message ( struct hv_hypervisor *hv ) {
109  struct vmbus *vmbus = hv->vmbus;
110  int rc;
111 
112  /* Wait for message */
113  if ( ( rc = hv_wait_for_message ( hv, VMBUS_MESSAGE_SINT ) ) != 0 ) {
114  DBGC ( vmbus, "VMBUS %p failed waiting for message: %s\n",
115  vmbus, strerror ( rc ) );
116  return rc;
117  }
118 
119  /* Sanity check */
121  DBGC ( vmbus, "VMBUS %p invalid message type %d\n",
122  vmbus, le32_to_cpu ( hv->message->received.type ) );
123  return -EINVAL;
124  }
125 
126  return 0;
127 }
128 
129 /**
130  * Wait for received message of a specified type, ignoring any others
131  *
132  * @v hv Hyper-V hypervisor
133  * @v type Message type
134  * @ret rc Return status code
135  */
136 static int vmbus_wait_for_message ( struct hv_hypervisor *hv,
137  unsigned int type ) {
138  struct vmbus *vmbus = hv->vmbus;
139  const struct vmbus_message_header *header = &vmbus->message->header;
140  int rc;
141 
142  /* Loop until specified message arrives, or until an error occurs */
143  while ( 1 ) {
144 
145  /* Wait for message */
146  if ( ( rc = vmbus_wait_for_any_message ( hv ) ) != 0 )
147  return rc;
148 
149  /* Check for requested message type */
150  if ( header->type == cpu_to_le32 ( type ) )
151  return 0;
152 
153  /* Ignore any other messages (e.g. due to additional
154  * channels being offered at runtime).
155  */
156  DBGC ( vmbus, "VMBUS %p ignoring message type %d (expecting "
157  "%d)\n", vmbus, le32_to_cpu ( header->type ), type );
158  }
159 }
160 
161 /**
162  * Initiate contact
163  *
164  * @v hv Hyper-V hypervisor
165  * @v raw VMBus protocol (raw) version
166  * @ret rc Return status code
167  */
168 static int vmbus_initiate_contact ( struct hv_hypervisor *hv,
169  unsigned int raw ) {
170  struct vmbus *vmbus = hv->vmbus;
172  struct vmbus_initiate_contact initiate;
173  int rc;
174 
175  /* Construct message */
176  memset ( &initiate, 0, sizeof ( initiate ) );
178  initiate.version.raw = cpu_to_le32 ( raw );
179  initiate.intr = virt_to_phys ( vmbus->intr );
180  initiate.monitor_in = virt_to_phys ( vmbus->monitor_in );
181  initiate.monitor_out = virt_to_phys ( vmbus->monitor_out );
182 
183  /* Post message */
184  if ( ( rc = vmbus_post_message ( hv, &initiate.header,
185  sizeof ( initiate ) ) ) != 0 )
186  return rc;
187 
188  /* Wait for response */
189  if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_VERSION_RESPONSE ) ) !=0)
190  return rc;
191 
192  /* Check response */
193  if ( ! version->supported ) {
194  DBGC ( vmbus, "VMBUS %p requested version not supported\n",
195  vmbus );
196  return -ENOTSUP;
197  }
198 
199  DBGC ( vmbus, "VMBUS %p initiated contact using version %d.%d\n",
200  vmbus, le16_to_cpu ( initiate.version.major ),
201  le16_to_cpu ( initiate.version.minor ) );
202  return 0;
203 }
204 
205 /**
206  * Terminate contact
207  *
208  * @v hv Hyper-V hypervisor
209  * @ret rc Return status code
210  */
211 static int vmbus_unload ( struct hv_hypervisor *hv ) {
212  int rc;
213 
214  /* Post message */
215  if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_UNLOAD ) ) != 0 )
216  return rc;
217 
218  /* Wait for response */
219  if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_UNLOAD_RESPONSE ) ) != 0)
220  return rc;
221 
222  return 0;
223 }
224 
225 /**
226  * Negotiate protocol version
227  *
228  * @v hv Hyper-V hypervisor
229  * @ret rc Return status code
230  */
231 static int vmbus_negotiate_version ( struct hv_hypervisor *hv ) {
232  int rc;
233 
234  /* We require the ability to disconnect from and reconnect to
235  * VMBus; if we don't have this then there is no (viable) way
236  * for a loaded operating system to continue to use any VMBus
237  * devices. (There is also a small but non-zero risk that the
238  * host will continue to write to our interrupt and monitor
239  * pages, since the VMBUS_UNLOAD message in earlier versions
240  * is essentially a no-op.)
241  *
242  * This requires us to ensure that the host supports protocol
243  * version 3.0 (VMBUS_VERSION_WIN8_1). However, we can't
244  * actually _use_ protocol version 3.0, since doing so causes
245  * an iSCSI-booted Windows Server 2012 R2 VM to crash due to a
246  * NULL pointer dereference in vmbus.sys.
247  *
248  * To work around this problem, we first ensure that we can
249  * connect using protocol v3.0, then disconnect and reconnect
250  * using the oldest known protocol.
251  */
252 
253  /* Initiate contact to check for required protocol support */
254  if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WIN8_1 ) ) != 0 )
255  return rc;
256 
257  /* Terminate contact */
258  if ( ( rc = vmbus_unload ( hv ) ) != 0 )
259  return rc;
260 
261  /* Reinitiate contact using the oldest known protocol version */
262  if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WS2008 ) ) != 0 )
263  return rc;
264 
265  return 0;
266 }
267 
268 /**
269  * Establish GPA descriptor list
270  *
271  * @v vmdev VMBus device
272  * @v data Data buffer
273  * @v len Length of data buffer
274  * @ret gpadl GPADL ID, or negative error
275  */
277  size_t len ) {
278  struct hv_hypervisor *hv = vmdev->hv;
279  struct vmbus *vmbus = hv->vmbus;
280  physaddr_t addr = user_to_phys ( data, 0 );
281  unsigned int pfn_count = hv_pfn_count ( addr, len );
282  struct {
283  struct vmbus_gpadl_header gpadlhdr;
284  struct vmbus_gpa_range range;
285  uint64_t pfn[pfn_count];
286  } __attribute__ (( packed )) gpadlhdr;
287  const struct vmbus_gpadl_created *created = &vmbus->message->created;
288  unsigned int gpadl;
289  unsigned int i;
290  int rc;
291 
292  /* Allocate GPADL ID */
293  gpadl = ++vmbus_gpadl;
294 
295  /* Construct message */
296  memset ( &gpadlhdr, 0, sizeof ( gpadlhdr ) );
297  gpadlhdr.gpadlhdr.header.type = cpu_to_le32 ( VMBUS_GPADL_HEADER );
298  gpadlhdr.gpadlhdr.channel = cpu_to_le32 ( vmdev->channel );
299  gpadlhdr.gpadlhdr.gpadl = cpu_to_le32 ( gpadl );
300  gpadlhdr.gpadlhdr.range_len =
301  cpu_to_le16 ( ( sizeof ( gpadlhdr.range ) +
302  sizeof ( gpadlhdr.pfn ) ) );
303  gpadlhdr.gpadlhdr.range_count = cpu_to_le16 ( 1 );
304  gpadlhdr.range.len = cpu_to_le32 ( len );
305  gpadlhdr.range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
306  for ( i = 0 ; i < pfn_count ; i++ )
307  gpadlhdr.pfn[i] = ( ( addr / PAGE_SIZE ) + i );
308 
309  /* Post message */
310  if ( ( rc = vmbus_post_message ( hv, &gpadlhdr.gpadlhdr.header,
311  sizeof ( gpadlhdr ) ) ) != 0 )
312  return rc;
313 
314  /* Wait for response */
315  if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_GPADL_CREATED ) ) != 0 )
316  return rc;
317 
318  /* Check response */
319  if ( created->channel != cpu_to_le32 ( vmdev->channel ) ) {
320  DBGC ( vmdev, "VMBUS %s unexpected GPADL channel %d\n",
321  vmdev->dev.name, le32_to_cpu ( created->channel ) );
322  return -EPROTO;
323  }
324  if ( created->gpadl != cpu_to_le32 ( gpadl ) ) {
325  DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
326  vmdev->dev.name, le32_to_cpu ( created->gpadl ) );
327  return -EPROTO;
328  }
329  if ( created->status != 0 ) {
330  DBGC ( vmdev, "VMBUS %s GPADL creation failed: %#08x\n",
331  vmdev->dev.name, le32_to_cpu ( created->status ) );
332  return -EPROTO;
333  }
334 
335  DBGC ( vmdev, "VMBUS %s GPADL %#08x is [%08lx,%08lx)\n",
336  vmdev->dev.name, gpadl, addr, ( addr + len ) );
337  return gpadl;
338 }
339 
340 /**
341  * Tear down GPA descriptor list
342  *
343  * @v vmdev VMBus device
344  * @v gpadl GPADL ID
345  * @ret rc Return status code
346  */
347 int vmbus_gpadl_teardown ( struct vmbus_device *vmdev, unsigned int gpadl ) {
348  struct hv_hypervisor *hv = vmdev->hv;
349  struct vmbus *vmbus = hv->vmbus;
350  struct vmbus_gpadl_teardown teardown;
351  const struct vmbus_gpadl_torndown *torndown = &vmbus->message->torndown;
352  int rc;
353 
354  /* If GPADL is obsolete (i.e. was created before the most
355  * recent Hyper-V reset), then we will never receive a
356  * response to the teardown message. Since the GPADL is
357  * already destroyed as far as the hypervisor is concerned, no
358  * further action is required.
359  */
360  if ( vmbus_gpadl_is_obsolete ( gpadl ) )
361  return 0;
362 
363  /* Construct message */
364  memset ( &teardown, 0, sizeof ( teardown ) );
366  teardown.channel = cpu_to_le32 ( vmdev->channel );
367  teardown.gpadl = cpu_to_le32 ( gpadl );
368 
369  /* Post message */
370  if ( ( rc = vmbus_post_message ( hv, &teardown.header,
371  sizeof ( teardown ) ) ) != 0 )
372  return rc;
373 
374  /* Wait for response */
375  if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_GPADL_TORNDOWN ) ) != 0 )
376  return rc;
377 
378  /* Check response */
379  if ( torndown->gpadl != cpu_to_le32 ( gpadl ) ) {
380  DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
381  vmdev->dev.name, le32_to_cpu ( torndown->gpadl ) );
382  return -EPROTO;
383  }
384 
385  return 0;
386 }
387 
388 /**
389  * Open VMBus channel
390  *
391  * @v vmdev VMBus device
392  * @v op Channel operations
393  * @v out_len Outbound ring buffer length
394  * @v in_len Inbound ring buffer length
395  * @v mtu Maximum expected data packet length (including headers)
396  * @ret rc Return status code
397  *
398  * Both outbound and inbound ring buffer lengths must be a power of
399  * two and a multiple of PAGE_SIZE. The requirement to be a power of
400  * two is a policy decision taken to simplify the ring buffer indexing
401  * logic.
402  */
403 int vmbus_open ( struct vmbus_device *vmdev,
405  size_t out_len, size_t in_len, size_t mtu ) {
406  struct hv_hypervisor *hv = vmdev->hv;
407  struct vmbus *vmbus = hv->vmbus;
408  struct vmbus_open_channel open;
409  const struct vmbus_open_channel_result *opened =
410  &vmbus->message->opened;
411  size_t len;
412  void *ring;
413  void *packet;
414  int gpadl;
415  uint32_t open_id;
416  int rc;
417 
418  /* Sanity checks */
419  assert ( ( out_len % PAGE_SIZE ) == 0 );
420  assert ( ( out_len & ( out_len - 1 ) ) == 0 );
421  assert ( ( in_len % PAGE_SIZE ) == 0 );
422  assert ( ( in_len & ( in_len - 1 ) ) == 0 );
423  assert ( mtu >= ( sizeof ( struct vmbus_packet_header ) +
424  sizeof ( struct vmbus_packet_footer ) ) );
425 
426  /* Allocate packet buffer */
427  packet = malloc ( mtu );
428  if ( ! packet ) {
429  rc = -ENOMEM;
430  goto err_alloc_packet;
431  }
432 
433  /* Allocate ring buffer */
434  len = ( sizeof ( *vmdev->out ) + out_len +
435  sizeof ( *vmdev->in ) + in_len );
436  assert ( ( len % PAGE_SIZE ) == 0 );
437  ring = malloc_phys ( len, PAGE_SIZE );
438  if ( ! ring ) {
439  rc = -ENOMEM;
440  goto err_alloc_ring;
441  }
442  memset ( ring, 0, len );
443 
444  /* Establish GPADL for ring buffer */
445  gpadl = vmbus_establish_gpadl ( vmdev, virt_to_user ( ring ), len );
446  if ( gpadl < 0 ) {
447  rc = gpadl;
448  goto err_establish;
449  }
450 
451  /* Construct message */
452  memset ( &open, 0, sizeof ( open ) );
453  open.header.type = cpu_to_le32 ( VMBUS_OPEN_CHANNEL );
454  open.channel = cpu_to_le32 ( vmdev->channel );
455  open_id = random();
456  open.id = open_id; /* Opaque random value: endianness irrelevant */
457  open.gpadl = cpu_to_le32 ( gpadl );
458  open.out_pages = ( ( sizeof ( *vmdev->out ) / PAGE_SIZE ) +
459  ( out_len / PAGE_SIZE ) );
460 
461  /* Post message */
462  if ( ( rc = vmbus_post_message ( hv, &open.header,
463  sizeof ( open ) ) ) != 0 )
464  goto err_post_message;
465 
466  /* Wait for response */
467  if ( ( rc = vmbus_wait_for_message ( hv,
468  VMBUS_OPEN_CHANNEL_RESULT ) ) != 0)
469  goto err_wait_for_message;
470 
471  /* Check response */
472  if ( opened->channel != cpu_to_le32 ( vmdev->channel ) ) {
473  DBGC ( vmdev, "VMBUS %s unexpected opened channel %#08x\n",
474  vmdev->dev.name, le32_to_cpu ( opened->channel ) );
475  rc = -EPROTO;
476  goto err_check_response;
477  }
478  if ( opened->id != open_id /* Non-endian */ ) {
479  DBGC ( vmdev, "VMBUS %s unexpected open ID %#08x\n",
480  vmdev->dev.name, le32_to_cpu ( opened->id ) );
481  rc = -EPROTO;
482  goto err_check_response;
483  }
484  if ( opened->status != 0 ) {
485  DBGC ( vmdev, "VMBUS %s open failed: %#08x\n",
486  vmdev->dev.name, le32_to_cpu ( opened->status ) );
487  rc = -EPROTO;
488  goto err_check_response;
489  }
490 
491  /* Store channel parameters */
492  vmdev->out_len = out_len;
493  vmdev->in_len = in_len;
494  vmdev->out = ring;
495  vmdev->in = ( ring + sizeof ( *vmdev->out ) + out_len );
496  vmdev->gpadl = gpadl;
497  vmdev->op = op;
498  vmdev->mtu = mtu;
499  vmdev->packet = packet;
500 
501  DBGC ( vmdev, "VMBUS %s channel GPADL %#08x ring "
502  "[%#08lx,%#08lx,%#08lx)\n", vmdev->dev.name, vmdev->gpadl,
503  virt_to_phys ( vmdev->out ), virt_to_phys ( vmdev->in ),
504  ( virt_to_phys ( vmdev->out ) + len ) );
505  return 0;
506 
507  err_check_response:
508  err_wait_for_message:
509  err_post_message:
510  vmbus_gpadl_teardown ( vmdev, vmdev->gpadl );
511  err_establish:
512  free_phys ( ring, len );
513  err_alloc_ring:
514  free ( packet );
515  err_alloc_packet:
516  return rc;
517 }
518 
519 /**
520  * Close VMBus channel
521  *
522  * @v vmdev VMBus device
523  */
524 void vmbus_close ( struct vmbus_device *vmdev ) {
525  struct hv_hypervisor *hv = vmdev->hv;
526  struct vmbus_close_channel close;
527  size_t len;
528  int rc;
529 
530  /* Construct message */
531  memset ( &close, 0, sizeof ( close ) );
532  close.header.type = cpu_to_le32 ( VMBUS_CLOSE_CHANNEL );
533  close.channel = cpu_to_le32 ( vmdev->channel );
534 
535  /* Post message */
536  if ( ( rc = vmbus_post_message ( hv, &close.header,
537  sizeof ( close ) ) ) != 0 ) {
538  DBGC ( vmdev, "VMBUS %s failed to close: %s\n",
539  vmdev->dev.name, strerror ( rc ) );
540  /* Continue to attempt to tear down GPADL, so that our
541  * memory is no longer accessible by the remote VM.
542  */
543  }
544 
545  /* Tear down GPADL */
546  if ( ( rc = vmbus_gpadl_teardown ( vmdev, vmdev->gpadl ) ) != 0 ) {
547  DBGC ( vmdev, "VMBUS %s failed to tear down channel GPADL: "
548  "%s\n", vmdev->dev.name, strerror ( rc ) );
549  /* We can't prevent the remote VM from continuing to
550  * access this memory, so leak it.
551  */
552  return;
553  }
554 
555  /* Free ring buffer */
556  len = ( sizeof ( *vmdev->out ) + vmdev->out_len +
557  sizeof ( *vmdev->in ) + vmdev->in_len );
558  free_phys ( vmdev->out, len );
559  vmdev->out = NULL;
560  vmdev->in = NULL;
561 
562  /* Free packet buffer */
563  free ( vmdev->packet );
564  vmdev->packet = NULL;
565 
566  DBGC ( vmdev, "VMBUS %s closed\n", vmdev->dev.name );
567 }
568 
569 /**
570  * Signal channel via monitor page
571  *
572  * @v vmdev VMBus device
573  */
574 static void vmbus_signal_monitor ( struct vmbus_device *vmdev ) {
575  struct hv_hypervisor *hv = vmdev->hv;
576  struct vmbus *vmbus = hv->vmbus;
577  struct hv_monitor_trigger *trigger;
578  unsigned int group;
579  unsigned int bit;
580 
581  /* Set bit in monitor trigger group */
582  group = ( vmdev->monitor / ( 8 * sizeof ( trigger->pending ) ));
583  bit = ( vmdev->monitor % ( 8 * sizeof ( trigger->pending ) ) );
585  set_bit ( bit, trigger );
586 }
587 
588 /**
589  * Signal channel via hypervisor event
590  *
591  * @v vmdev VMBus device
592  */
593 static void vmbus_signal_event ( struct vmbus_device *vmdev ) {
594  struct hv_hypervisor *hv = vmdev->hv;
595  int rc;
596 
597  /* Signal hypervisor event */
598  if ( ( rc = hv_signal_event ( hv, VMBUS_EVENT_ID, 0 ) ) != 0 ) {
599  DBGC ( vmdev, "VMBUS %s could not signal event: %s\n",
600  vmdev->dev.name, strerror ( rc ) );
601  return;
602  }
603 }
604 
605 /**
606  * Fill outbound ring buffer
607  *
608  * @v vmdev VMBus device
609  * @v prod Producer index
610  * @v data Data
611  * @v len Length
612  * @ret prod New producer index
613  *
614  * The caller must ensure that there is sufficient space in the ring
615  * buffer.
616  */
617 static size_t vmbus_produce ( struct vmbus_device *vmdev, size_t prod,
618  const void *data, size_t len ) {
619  size_t first;
620  size_t second;
621 
622  /* Determine fragment lengths */
623  first = ( vmdev->out_len - prod );
624  if ( first > len )
625  first = len;
626  second = ( len - first );
627 
628  /* Copy fragment(s) */
629  memcpy ( &vmdev->out->data[prod], data, first );
630  if ( second )
631  memcpy ( &vmdev->out->data[0], ( data + first ), second );
632 
633  return ( ( prod + len ) & ( vmdev->out_len - 1 ) );
634 }
635 
636 /**
637  * Consume inbound ring buffer
638  *
639  * @v vmdev VMBus device
640  * @v cons Consumer index
641  * @v data Data buffer, or NULL
642  * @v len Length to consume
643  * @ret cons New consumer index
644  */
645 static size_t vmbus_consume ( struct vmbus_device *vmdev, size_t cons,
646  void *data, size_t len ) {
647  size_t first;
648  size_t second;
649 
650  /* Determine fragment lengths */
651  first = ( vmdev->in_len - cons );
652  if ( first > len )
653  first = len;
654  second = ( len - first );
655 
656  /* Copy fragment(s) */
657  memcpy ( data, &vmdev->in->data[cons], first );
658  if ( second )
659  memcpy ( ( data + first ), &vmdev->in->data[0], second );
660 
661  return ( ( cons + len ) & ( vmdev->in_len - 1 ) );
662 }
663 
664 /**
665  * Send packet via ring buffer
666  *
667  * @v vmdev VMBus device
668  * @v header Packet header
669  * @v data Data
670  * @v len Length of data
671  * @ret rc Return status code
672  *
673  * Send a packet via the outbound ring buffer. All fields in the
674  * packet header must be filled in, with the exception of the total
675  * packet length.
676  */
677 static int vmbus_send ( struct vmbus_device *vmdev,
678  struct vmbus_packet_header *header,
679  const void *data, size_t len ) {
680  struct hv_hypervisor *hv = vmdev->hv;
681  struct vmbus *vmbus = hv->vmbus;
682  static uint8_t padding[ 8 - 1 ];
683  struct vmbus_packet_footer footer;
684  size_t header_len;
685  size_t pad_len;
686  size_t footer_len;
687  size_t ring_len;
688  size_t cons;
689  size_t prod;
690  size_t old_prod;
691  size_t fill;
692 
693  /* Sanity check */
694  assert ( vmdev->out != NULL );
695 
696  /* Calculate lengths */
697  header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
698  pad_len = ( ( -len ) & ( 8 - 1 ) );
699  footer_len = sizeof ( footer );
700  ring_len = ( header_len + len + pad_len + footer_len );
701 
702  /* Check that we have enough room in the outbound ring buffer */
703  cons = le32_to_cpu ( vmdev->out->cons );
704  prod = le32_to_cpu ( vmdev->out->prod );
705  old_prod = prod;
706  fill = ( ( prod - cons ) & ( vmdev->out_len - 1 ) );
707  if ( ( fill + ring_len ) >= vmdev->out_len ) {
708  DBGC ( vmdev, "VMBUS %s ring buffer full\n", vmdev->dev.name );
709  return -ENOBUFS;
710  }
711 
712  /* Complete header */
713  header->qlen = cpu_to_le16 ( ( ring_len - footer_len ) / 8 );
714 
715  /* Construct footer */
716  footer.reserved = 0;
717  footer.prod = vmdev->out->prod;
718 
719  /* Copy packet to buffer */
720  DBGC2 ( vmdev, "VMBUS %s sending:\n", vmdev->dev.name );
721  DBGC2_HDA ( vmdev, prod, header, header_len );
722  prod = vmbus_produce ( vmdev, prod, header, header_len );
723  DBGC2_HDA ( vmdev, prod, data, len );
724  prod = vmbus_produce ( vmdev, prod, data, len );
725  prod = vmbus_produce ( vmdev, prod, padding, pad_len );
726  DBGC2_HDA ( vmdev, prod, &footer, sizeof ( footer ) );
727  prod = vmbus_produce ( vmdev, prod, &footer, sizeof ( footer ) );
728  assert ( ( ( prod - old_prod ) & ( vmdev->out_len - 1 ) ) == ring_len );
729 
730  /* Update producer index */
731  wmb();
732  vmdev->out->prod = cpu_to_le32 ( prod );
733 
734  /* Return if we do not need to signal the host. This follows
735  * the logic of hv_need_to_signal() in the Linux driver.
736  */
737  mb();
738  if ( vmdev->out->intr_mask )
739  return 0;
740  rmb();
741  cons = le32_to_cpu ( vmdev->out->cons );
742  if ( cons != old_prod )
743  return 0;
744 
745  /* Set channel bit in interrupt page */
746  set_bit ( vmdev->channel, vmbus->intr->out );
747 
748  /* Signal the host */
749  vmdev->signal ( vmdev );
750 
751  return 0;
752 }
753 
754 /**
755  * Send control packet via ring buffer
756  *
757  * @v vmdev VMBus device
758  * @v xid Transaction ID (or zero to not request completion)
759  * @v data Data
760  * @v len Length of data
761  * @ret rc Return status code
762  *
763  * Send data using a VMBUS_DATA_INBAND packet.
764  */
765 int vmbus_send_control ( struct vmbus_device *vmdev, uint64_t xid,
766  const void *data, size_t len ) {
767  struct vmbus_packet_header *header = vmdev->packet;
768 
769  /* Construct header in packet buffer */
770  assert ( header != NULL );
772  header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
773  header->flags = ( xid ?
775  header->xid = xid; /* Non-endian */
776 
777  return vmbus_send ( vmdev, header, data, len );
778 }
779 
780 /**
781  * Send data packet via ring buffer
782  *
783  * @v vmdev VMBus device
784  * @v xid Transaction ID
785  * @v data Data
786  * @v len Length of data
787  * @v iobuf I/O buffer
788  * @ret rc Return status code
789  *
790  * Send data using a VMBUS_DATA_GPA_DIRECT packet. The caller is
791  * responsible for ensuring that the I/O buffer remains untouched
792  * until the corresponding completion has been received.
793  */
795  const void *data, size_t len, struct io_buffer *iobuf ) {
796  physaddr_t addr = virt_to_phys ( iobuf->data );
797  unsigned int pfn_count = hv_pfn_count ( addr, iob_len ( iobuf ) );
798  struct {
799  struct vmbus_gpa_direct_header gpa;
800  struct vmbus_gpa_range range;
801  uint64_t pfn[pfn_count];
802  } __attribute__ (( packed )) *header = vmdev->packet;
803  unsigned int i;
804 
805  /* Sanity check */
806  assert ( header != NULL );
807  assert ( sizeof ( *header ) <= vmdev->mtu );
808 
809  /* Construct header in packet buffer */
810  header->gpa.header.type = cpu_to_le16 ( VMBUS_DATA_GPA_DIRECT );
811  header->gpa.header.hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
813  header->gpa.header.xid = xid; /* Non-endian */
814  header->gpa.range_count = 1;
815  header->range.len = cpu_to_le32 ( iob_len ( iobuf ) );
816  header->range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
817  for ( i = 0 ; i < pfn_count ; i++ )
818  header->pfn[i] = ( ( addr / PAGE_SIZE ) + i );
819 
820  return vmbus_send ( vmdev, &header->gpa.header, data, len );
821 }
822 
823 /**
824  * Send completion packet via ring buffer
825  *
826  * @v vmdev VMBus device
827  * @v xid Transaction ID
828  * @v data Data
829  * @v len Length of data
830  * @ret rc Return status code
831  *
832  * Send data using a VMBUS_COMPLETION packet.
833  */
834 int vmbus_send_completion ( struct vmbus_device *vmdev, uint64_t xid,
835  const void *data, size_t len ) {
836  struct vmbus_packet_header *header = vmdev->packet;
837 
838  /* Construct header in packet buffer */
839  assert ( header != NULL );
840  header->type = cpu_to_le16 ( VMBUS_COMPLETION );
841  header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
842  header->flags = 0;
843  header->xid = xid; /* Non-endian */
844 
845  return vmbus_send ( vmdev, header, data, len );
846 }
847 
848 /**
849  * Send cancellation packet via ring buffer
850  *
851  * @v vmdev VMBus device
852  * @v xid Transaction ID
853  * @ret rc Return status code
854  *
855  * Send data using a VMBUS_CANCELLATION packet.
856  */
858  struct vmbus_packet_header *header = vmdev->packet;
859 
860  /* Construct header in packet buffer */
861  assert ( header != NULL );
863  header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
864  header->flags = 0;
865  header->xid = xid; /* Non-endian */
866 
867  return vmbus_send ( vmdev, header, NULL, 0 );
868 }
869 
870 /**
871  * Get transfer page set from pageset ID
872  *
873  * @v vmdev VMBus device
874  * @v pageset Page set ID (in protocol byte order)
875  * @ret pages Page set, or NULL if not found
876  */
877 static struct vmbus_xfer_pages * vmbus_xfer_pages ( struct vmbus_device *vmdev,
878  uint16_t pageset ) {
879  struct vmbus_xfer_pages *pages;
880 
881  /* Locate page set */
882  list_for_each_entry ( pages, &vmdev->pages, list ) {
883  if ( pages->pageset == pageset )
884  return pages;
885  }
886 
887  DBGC ( vmdev, "VMBUS %s unrecognised page set ID %#04x\n",
888  vmdev->dev.name, le16_to_cpu ( pageset ) );
889  return NULL;
890 }
891 
892 /**
893  * Construct I/O buffer list from transfer pages
894  *
895  * @v vmdev VMBus device
896  * @v header Transfer page header
897  * @v list I/O buffer list to populate
898  * @ret rc Return status code
899  */
900 static int vmbus_xfer_page_iobufs ( struct vmbus_device *vmdev,
901  struct vmbus_packet_header *header,
902  struct list_head *list ) {
903  struct vmbus_xfer_page_header *page_header =
905  struct vmbus_xfer_pages *pages;
906  struct io_buffer *iobuf;
907  struct io_buffer *tmp;
908  size_t len;
909  size_t offset;
910  unsigned int range_count;
911  unsigned int i;
912  int rc;
913 
914  /* Sanity check */
916 
917  /* Locate page set */
918  pages = vmbus_xfer_pages ( vmdev, page_header->pageset );
919  if ( ! pages ) {
920  rc = -ENOENT;
921  goto err_pages;
922  }
923 
924  /* Allocate and populate I/O buffers */
925  range_count = le32_to_cpu ( page_header->range_count );
926  for ( i = 0 ; i < range_count ; i++ ) {
927 
928  /* Parse header */
929  len = le32_to_cpu ( page_header->range[i].len );
930  offset = le32_to_cpu ( page_header->range[i].offset );
931 
932  /* Allocate I/O buffer */
933  iobuf = alloc_iob ( len );
934  if ( ! iobuf ) {
935  DBGC ( vmdev, "VMBUS %s could not allocate %zd-byte "
936  "I/O buffer\n", vmdev->dev.name, len );
937  rc = -ENOMEM;
938  goto err_alloc;
939  }
940 
941  /* Add I/O buffer to list */
942  list_add ( &iobuf->list, list );
943 
944  /* Populate I/O buffer */
945  if ( ( rc = pages->op->copy ( pages, iob_put ( iobuf, len ),
946  offset, len ) ) != 0 ) {
947  DBGC ( vmdev, "VMBUS %s could not populate I/O buffer "
948  "range [%zd,%zd): %s\n",
949  vmdev->dev.name, offset, len, strerror ( rc ) );
950  goto err_copy;
951  }
952  }
953 
954  return 0;
955 
956  err_copy:
957  err_alloc:
958  list_for_each_entry_safe ( iobuf, tmp, list, list ) {
959  list_del ( &iobuf->list );
960  free_iob ( iobuf );
961  }
962  err_pages:
963  return rc;
964 }
965 
966 /**
967  * Poll ring buffer
968  *
969  * @v vmdev VMBus device
970  * @ret rc Return status code
971  */
972 int vmbus_poll ( struct vmbus_device *vmdev ) {
973  struct vmbus_packet_header *header = vmdev->packet;
974  struct list_head list;
975  void *data;
976  size_t header_len;
977  size_t len;
978  size_t footer_len;
979  size_t ring_len;
980  size_t cons;
981  size_t old_cons;
982  uint64_t xid;
983  int rc;
984 
985  /* Sanity checks */
986  assert ( vmdev->packet != NULL );
987  assert ( vmdev->in != NULL );
988 
989  /* Return immediately if buffer is empty */
990  if ( ! vmbus_has_data ( vmdev ) )
991  return 0;
992  cons = le32_to_cpu ( vmdev->in->cons );
993  old_cons = cons;
994 
995  /* Consume (start of) header */
996  cons = vmbus_consume ( vmdev, cons, header, sizeof ( *header ) );
997 
998  /* Parse and sanity check header */
999  header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
1000  if ( header_len < sizeof ( *header ) ) {
1001  DBGC ( vmdev, "VMBUS %s received underlength header (%zd "
1002  "bytes)\n", vmdev->dev.name, header_len );
1003  return -EINVAL;
1004  }
1005  len = ( ( le16_to_cpu ( header->qlen ) * 8 ) - header_len );
1006  footer_len = sizeof ( struct vmbus_packet_footer );
1007  ring_len = ( header_len + len + footer_len );
1008  if ( ring_len > vmdev->mtu ) {
1009  DBGC ( vmdev, "VMBUS %s received overlength packet (%zd "
1010  "bytes)\n", vmdev->dev.name, ring_len );
1011  return -ERANGE;
1012  }
1013  xid = le64_to_cpu ( header->xid );
1014 
1015  /* Consume remainder of packet */
1016  cons = vmbus_consume ( vmdev, cons,
1017  ( ( ( void * ) header ) + sizeof ( *header ) ),
1018  ( ring_len - sizeof ( *header ) ) );
1019  DBGC2 ( vmdev, "VMBUS %s received:\n", vmdev->dev.name );
1020  DBGC2_HDA ( vmdev, old_cons, header, ring_len );
1021  assert ( ( ( cons - old_cons ) & ( vmdev->in_len - 1 ) ) == ring_len );
1022 
1023  /* Allocate I/O buffers, if applicable */
1024  INIT_LIST_HEAD ( &list );
1025  if ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) ) {
1026  if ( ( rc = vmbus_xfer_page_iobufs ( vmdev, header,
1027  &list ) ) != 0 )
1028  return rc;
1029  }
1030 
1031  /* Update producer index */
1032  rmb();
1033  vmdev->in->cons = cpu_to_le32 ( cons );
1034 
1035  /* Handle packet */
1036  data = ( ( ( void * ) header ) + header_len );
1037  switch ( header->type ) {
1038 
1039  case cpu_to_le16 ( VMBUS_DATA_INBAND ) :
1040  if ( ( rc = vmdev->op->recv_control ( vmdev, xid, data,
1041  len ) ) != 0 ) {
1042  DBGC ( vmdev, "VMBUS %s could not handle control "
1043  "packet: %s\n",
1044  vmdev->dev.name, strerror ( rc ) );
1045  return rc;
1046  }
1047  break;
1048 
1050  if ( ( rc = vmdev->op->recv_data ( vmdev, xid, data, len,
1051  &list ) ) != 0 ) {
1052  DBGC ( vmdev, "VMBUS %s could not handle data packet: "
1053  "%s\n", vmdev->dev.name, strerror ( rc ) );
1054  return rc;
1055  }
1056  break;
1057 
1058  case cpu_to_le16 ( VMBUS_COMPLETION ) :
1059  if ( ( rc = vmdev->op->recv_completion ( vmdev, xid, data,
1060  len ) ) != 0 ) {
1061  DBGC ( vmdev, "VMBUS %s could not handle completion: "
1062  "%s\n", vmdev->dev.name, strerror ( rc ) );
1063  return rc;
1064  }
1065  break;
1066 
1067  case cpu_to_le16 ( VMBUS_CANCELLATION ) :
1068  if ( ( rc = vmdev->op->recv_cancellation ( vmdev, xid ) ) != 0){
1069  DBGC ( vmdev, "VMBUS %s could not handle cancellation: "
1070  "%s\n", vmdev->dev.name, strerror ( rc ) );
1071  return rc;
1072  }
1073  break;
1074 
1075  default:
1076  DBGC ( vmdev, "VMBUS %s unknown packet type %d\n",
1077  vmdev->dev.name, le16_to_cpu ( header->type ) );
1078  return -ENOTSUP;
1079  }
1080 
1081  return 0;
1082 }
1083 
1084 /**
1085  * Dump channel status (for debugging)
1086  *
1087  * @v vmdev VMBus device
1088  */
1089 void vmbus_dump_channel ( struct vmbus_device *vmdev ) {
1090  size_t out_prod = le32_to_cpu ( vmdev->out->prod );
1091  size_t out_cons = le32_to_cpu ( vmdev->out->cons );
1092  size_t in_prod = le32_to_cpu ( vmdev->in->prod );
1093  size_t in_cons = le32_to_cpu ( vmdev->in->cons );
1094  size_t in_len;
1095  size_t first;
1096  size_t second;
1097 
1098  /* Dump ring status */
1099  DBGC ( vmdev, "VMBUS %s out %03zx:%03zx%s in %03zx:%03zx%s\n",
1100  vmdev->dev.name, out_prod, out_cons,
1101  ( vmdev->out->intr_mask ? "(m)" : "" ), in_prod, in_cons,
1102  ( vmdev->in->intr_mask ? "(m)" : "" ) );
1103 
1104  /* Dump inbound ring contents, if any */
1105  if ( in_prod != in_cons ) {
1106  in_len = ( ( in_prod - in_cons ) &
1107  ( vmdev->in_len - 1 ) );
1108  first = ( vmdev->in_len - in_cons );
1109  if ( first > in_len )
1110  first = in_len;
1111  second = ( in_len - first );
1112  DBGC_HDA ( vmdev, in_cons, &vmdev->in->data[in_cons], first );
1113  DBGC_HDA ( vmdev, 0, &vmdev->in->data[0], second );
1114  }
1115 }
1116 
1117 /**
1118  * Find driver for VMBus device
1119  *
1120  * @v vmdev VMBus device
1121  * @ret driver Driver, or NULL
1122  */
1123 static struct vmbus_driver * vmbus_find_driver ( const union uuid *type ) {
1124  struct vmbus_driver *vmdrv;
1125 
1126  for_each_table_entry ( vmdrv, VMBUS_DRIVERS ) {
1127  if ( memcmp ( &vmdrv->type, type, sizeof ( *type ) ) == 0 )
1128  return vmdrv;
1129  }
1130  return NULL;
1131 }
1132 
1133 /**
1134  * Probe channels
1135  *
1136  * @v hv Hyper-V hypervisor
1137  * @v parent Parent device
1138  * @ret rc Return status code
1139  */
1140 static int vmbus_probe_channels ( struct hv_hypervisor *hv,
1141  struct device *parent ) {
1142  struct vmbus *vmbus = hv->vmbus;
1143  const struct vmbus_message_header *header = &vmbus->message->header;
1144  const struct vmbus_offer_channel *offer = &vmbus->message->offer;
1145  const union uuid *type;
1146  union uuid instance;
1147  struct vmbus_driver *driver;
1148  struct vmbus_device *vmdev;
1149  struct vmbus_device *tmp;
1150  unsigned int channel;
1151  int rc;
1152 
1153  /* Post message */
1154  if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_REQUEST_OFFERS ) ) !=0)
1155  goto err_post_message;
1156 
1157  /* Collect responses */
1158  while ( 1 ) {
1159 
1160  /* Wait for response */
1161  if ( ( rc = vmbus_wait_for_any_message ( hv ) ) != 0 )
1162  goto err_wait_for_any_message;
1163 
1164  /* Handle response */
1165  if ( header->type == cpu_to_le32 ( VMBUS_OFFER_CHANNEL ) ) {
1166 
1167  /* Parse offer */
1168  type = &offer->type;
1169  channel = le32_to_cpu ( offer->channel );
1170  DBGC2 ( vmbus, "VMBUS %p offer %d type %s",
1171  vmbus, channel, uuid_ntoa ( type ) );
1172  if ( offer->monitored )
1173  DBGC2 ( vmbus, " monitor %d", offer->monitor );
1174  DBGC2 ( vmbus, "\n" );
1175 
1176  /* Look for a driver */
1178  if ( ! driver ) {
1179  DBGC2 ( vmbus, "VMBUS %p has no driver for "
1180  "type %s\n", vmbus, uuid_ntoa ( type ));
1181  /* Not a fatal error */
1182  continue;
1183  }
1184 
1185  /* Allocate and initialise device */
1186  vmdev = zalloc ( sizeof ( *vmdev ) );
1187  if ( ! vmdev ) {
1188  rc = -ENOMEM;
1189  goto err_alloc_vmdev;
1190  }
1191  memcpy ( &instance, &offer->instance,
1192  sizeof ( instance ) );
1193  uuid_mangle ( &instance );
1194  snprintf ( vmdev->dev.name, sizeof ( vmdev->dev.name ),
1195  "{%s}", uuid_ntoa ( &instance ) );
1196  vmdev->dev.desc.bus_type = BUS_TYPE_HV;
1197  INIT_LIST_HEAD ( &vmdev->dev.children );
1198  list_add_tail ( &vmdev->dev.siblings,
1199  &parent->children );
1200  vmdev->dev.parent = parent;
1201  vmdev->hv = hv;
1202  memcpy ( &vmdev->instance, &offer->instance,
1203  sizeof ( vmdev->instance ) );
1204  vmdev->channel = channel;
1205  vmdev->monitor = offer->monitor;
1206  vmdev->signal = ( offer->monitored ?
1209  INIT_LIST_HEAD ( &vmdev->pages );
1210  vmdev->driver = driver;
1211  vmdev->dev.driver_name = driver->name;
1212  DBGC ( vmdev, "VMBUS %s has driver \"%s\"\n",
1213  vmdev->dev.name, vmdev->driver->name );
1214 
1215  } else if ( header->type ==
1217 
1218  /* End of offer list */
1219  break;
1220 
1221  } else {
1222  DBGC ( vmbus, "VMBUS %p unexpected offer response type "
1223  "%d\n", vmbus, le32_to_cpu ( header->type ) );
1224  rc = -EPROTO;
1225  goto err_unexpected_offer;
1226  }
1227  }
1228 
1229  /* Probe all devices. We do this only after completing
1230  * enumeration since devices will need to send and receive
1231  * VMBus messages.
1232  */
1233  list_for_each_entry ( vmdev, &parent->children, dev.siblings ) {
1234  if ( ( rc = vmdev->driver->probe ( vmdev ) ) != 0 ) {
1235  DBGC ( vmdev, "VMBUS %s could not probe: %s\n",
1236  vmdev->dev.name, strerror ( rc ) );
1237  goto err_probe;
1238  }
1239  }
1240 
1241  return 0;
1242 
1243  err_probe:
1244  /* Remove driver from each device that was already probed */
1246  dev.siblings ) {
1247  vmdev->driver->remove ( vmdev );
1248  }
1249  err_unexpected_offer:
1250  err_alloc_vmdev:
1251  err_wait_for_any_message:
1252  /* Free any devices allocated (but potentially not yet probed) */
1253  list_for_each_entry_safe ( vmdev, tmp, &parent->children,
1254  dev.siblings ) {
1255  list_del ( &vmdev->dev.siblings );
1256  free ( vmdev );
1257  }
1258  err_post_message:
1259  return rc;
1260 }
1261 
1262 
1263 /**
1264  * Reset channels
1265  *
1266  * @v hv Hyper-V hypervisor
1267  * @v parent Parent device
1268  * @ret rc Return status code
1269  */
1271  struct device *parent ) {
1272  struct vmbus *vmbus = hv->vmbus;
1273  const struct vmbus_message_header *header = &vmbus->message->header;
1274  const struct vmbus_offer_channel *offer = &vmbus->message->offer;
1275  const union uuid *type;
1276  struct vmbus_device *vmdev;
1277  unsigned int channel;
1278  int rc;
1279 
1280  /* Post message */
1281  if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_REQUEST_OFFERS ) ) !=0)
1282  return rc;
1283 
1284  /* Collect responses */
1285  while ( 1 ) {
1286 
1287  /* Wait for response */
1288  if ( ( rc = vmbus_wait_for_any_message ( hv ) ) != 0 )
1289  return rc;
1290 
1291  /* Handle response */
1292  if ( header->type == cpu_to_le32 ( VMBUS_OFFER_CHANNEL ) ) {
1293 
1294  /* Parse offer */
1295  type = &offer->type;
1296  channel = le32_to_cpu ( offer->channel );
1297  DBGC2 ( vmbus, "VMBUS %p offer %d type %s",
1298  vmbus, channel, uuid_ntoa ( type ) );
1299  if ( offer->monitored )
1300  DBGC2 ( vmbus, " monitor %d", offer->monitor );
1301  DBGC2 ( vmbus, "\n" );
1302 
1303  /* Do nothing with the offer; we already have all
1304  * of the relevant state from the initial probe.
1305  */
1306 
1307  } else if ( header->type ==
1309 
1310  /* End of offer list */
1311  break;
1312 
1313  } else {
1314  DBGC ( vmbus, "VMBUS %p unexpected offer response type "
1315  "%d\n", vmbus, le32_to_cpu ( header->type ) );
1316  return -EPROTO;
1317  }
1318  }
1319 
1320  /* Reset all devices */
1321  list_for_each_entry ( vmdev, &parent->children, dev.siblings ) {
1322  if ( ( rc = vmdev->driver->reset ( vmdev ) ) != 0 ) {
1323  DBGC ( vmdev, "VMBUS %s could not reset: %s\n",
1324  vmdev->dev.name, strerror ( rc ) );
1325  /* Continue attempting to reset other devices */
1326  continue;
1327  }
1328  }
1329 
1330  return 0;
1331 }
1332 
1333 /**
1334  * Remove channels
1335  *
1336  * @v hv Hyper-V hypervisor
1337  * @v parent Parent device
1338  */
1340  struct device *parent ) {
1341  struct vmbus_device *vmdev;
1342  struct vmbus_device *tmp;
1343 
1344  /* Remove devices */
1345  list_for_each_entry_safe ( vmdev, tmp, &parent->children,
1346  dev.siblings ) {
1347  vmdev->driver->remove ( vmdev );
1348  assert ( list_empty ( &vmdev->dev.children ) );
1349  assert ( vmdev->out == NULL );
1350  assert ( vmdev->in == NULL );
1351  assert ( vmdev->packet == NULL );
1352  assert ( list_empty ( &vmdev->pages ) );
1353  list_del ( &vmdev->dev.siblings );
1354  free ( vmdev );
1355  }
1356 }
1357 
1358 /**
1359  * Probe Hyper-V virtual machine bus
1360  *
1361  * @v hv Hyper-V hypervisor
1362  * @v parent Parent device
1363  * @ret rc Return status code
1364  */
1365 int vmbus_probe ( struct hv_hypervisor *hv, struct device *parent ) {
1366  struct vmbus *vmbus;
1367  int rc;
1368 
1369  /* Allocate and initialise structure */
1370  vmbus = zalloc ( sizeof ( *vmbus ) );
1371  if ( ! vmbus ) {
1372  rc = -ENOMEM;
1373  goto err_alloc;
1374  }
1375  hv->vmbus = vmbus;
1376 
1377  /* Initialise message buffer pointer
1378  *
1379  * We use a pointer to the fixed-size Hyper-V received message
1380  * buffer. This allows us to access fields within received
1381  * messages without first checking the message size: any
1382  * fields beyond the end of the message will read as zero.
1383  */
1384  vmbus->message = ( ( void * ) hv->message->received.data );
1385  assert ( sizeof ( *vmbus->message ) <=
1386  sizeof ( hv->message->received.data ) );
1387 
1388  /* Allocate interrupt and monitor pages */
1389  if ( ( rc = hv_alloc_pages ( hv, &vmbus->intr, &vmbus->monitor_in,
1390  &vmbus->monitor_out, NULL ) ) != 0 )
1391  goto err_alloc_pages;
1392 
1393  /* Enable message interrupt */
1395 
1396  /* Negotiate protocol version */
1397  if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
1398  goto err_negotiate_version;
1399 
1400  /* Enumerate channels */
1401  if ( ( rc = vmbus_probe_channels ( hv, parent ) ) != 0 )
1402  goto err_probe_channels;
1403 
1404  return 0;
1405 
1406  vmbus_remove_channels ( hv, parent );
1407  err_probe_channels:
1408  vmbus_unload ( hv );
1409  err_negotiate_version:
1412  NULL );
1413  err_alloc_pages:
1414  free ( vmbus );
1415  err_alloc:
1416  return rc;
1417 }
1418 
1419 /**
1420  * Reset Hyper-V virtual machine bus
1421  *
1422  * @v hv Hyper-V hypervisor
1423  * @v parent Parent device
1424  * @ret rc Return status code
1425  */
1426 int vmbus_reset ( struct hv_hypervisor *hv, struct device *parent ) {
1427  struct vmbus *vmbus = hv->vmbus;
1428  int rc;
1429 
1430  /* Mark all existent GPADLs as obsolete */
1432 
1433  /* Clear interrupt and monitor pages */
1434  memset ( vmbus->intr, 0, PAGE_SIZE );
1435  memset ( vmbus->monitor_in, 0, PAGE_SIZE );
1436  memset ( vmbus->monitor_out, 0, PAGE_SIZE );
1437 
1438  /* Enable message interrupt */
1440 
1441  /* Renegotiate protocol version */
1442  if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
1443  return rc;
1444 
1445  /* Reenumerate channels */
1446  if ( ( rc = vmbus_reset_channels ( hv, parent ) ) != 0 )
1447  return rc;
1448 
1449  return 0;
1450 }
1451 
1452 /**
1453  * Remove Hyper-V virtual machine bus
1454  *
1455  * @v hv Hyper-V hypervisor
1456  * @v parent Parent device
1457  */
1458 void vmbus_remove ( struct hv_hypervisor *hv, struct device *parent ) {
1459  struct vmbus *vmbus = hv->vmbus;
1460 
1461  vmbus_remove_channels ( hv, parent );
1462  vmbus_unload ( hv );
1465  NULL );
1466  free ( vmbus );
1467 }
uint32_t type
Type.
Definition: hyperv.h:102
CPU sleeping.
uint32_t channel
Channel ID.
Definition: vmbus.h:150
#define __attribute__(x)
Definition: compiler.h:10
VMBus transfer page header.
Definition: vmbus.h:318
#define EINVAL
Invalid argument.
Definition: errno.h:428
const char * name
Name.
Definition: vmbus.h:523
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
struct vmbus_ring * out
Outbound ring buffer.
Definition: vmbus.h:499
uint8_t out[PAGE_SIZE/2]
Outbound interrupts.
Definition: vmbus.h:379
uint32_t raw
Raw version.
Definition: vmbus.h:35
wmb()
int vmbus_send_completion(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Send completion packet via ring buffer.
Definition: vmbus.c:834
uint16_t pageset
Page set ID.
Definition: netvsc.h:16
#define iob_put(iobuf, len)
Definition: iobuf.h:120
static __always_inline void struct pci_range * range
Definition: efi_pci_api.h:43
VMBus message header.
Definition: vmbus.h:72
struct device dev
Generic iPXE device.
Definition: vmbus.h:478
static int vmbus_has_data(struct vmbus_device *vmdev)
Check if data is present in ring buffer.
Definition: vmbus.h:586
struct vmbus_offer_channel offer
"Offer channel" message
Definition: vmbus.h:244
static unsigned int unsigned int bit
Definition: bigint.h:208
#define le32_to_cpu(value)
Definition: byteswap.h:113
int hv_wait_for_message(struct hv_hypervisor *hv, unsigned int sintx)
Wait for received message.
Definition: hyperv.c:486
struct hv_monitor_trigger trigger[4]
Trigger groups.
Definition: hyperv.h:16
int(* recv_control)(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Handle received control packet.
Definition: vmbus.h:407
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
int(* recv_data)(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct list_head *list)
Handle received data packet.
Definition: vmbus.h:423
Error codes.
A universally unique ID.
Definition: uuid.h:15
uint8_t monitor
Monitor ID.
Definition: vmbus.h:118
struct list_head list
List of all transfer page sets.
Definition: vmbus.h:468
struct vmbus_channel_operations * op
Channel operations.
Definition: vmbus.h:506
int(* recv_completion)(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Handle received completion packet.
Definition: vmbus.h:435
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
uint32_t channel
Channel ID.
Definition: vmbus.h:116
int vmbus_open(struct vmbus_device *vmdev, struct vmbus_channel_operations *op, size_t out_len, size_t in_len, size_t mtu)
Open VMBus channel.
Definition: vmbus.c:403
static __always_inline int off_t userptr_t second
Definition: efi_uaccess.h:80
#define VMBUS_MESSAGE_TYPE
VMBus message type.
Definition: vmbus.h:27
uint64_t monitor_in
Parent to child monitor page base address.
Definition: vmbus.h:222
unsigned long user_to_phys(userptr_t userptr, off_t offset)
Convert user pointer to physical address.
static int vmbus_reset_channels(struct hv_hypervisor *hv, struct device *parent)
Reset channels.
Definition: vmbus.c:1270
uint64_t monitor_out
Child to parent monitor page base address.
Definition: vmbus.h:224
#define DBGC(...)
Definition: compiler.h:505
int vmbus_reset(struct hv_hypervisor *hv, struct device *parent)
Reset Hyper-V virtual machine bus.
Definition: vmbus.c:1426
char name[40]
Name.
Definition: device.h:75
#define ENOENT
No such file or directory.
Definition: errno.h:514
A VMBus device.
Definition: vmbus.h:476
uint32_t status
Status.
Definition: vmbus.h:154
unsigned long long uint64_t
Definition: stdint.h:13
static void *__malloc malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition: malloc.h:62
struct vmbus_message_header header
Message header.
Definition: vmbus.h:196
static int vmbus_send(struct vmbus_device *vmdev, struct vmbus_packet_header *header, const void *data, size_t len)
Send packet via ring buffer.
Definition: vmbus.c:677
uint32_t out_len
Outbound ring buffer length.
Definition: vmbus.h:495
Bit operations.
uint32_t gpadl
GPADL ID.
Definition: vmbus.h:208
A signalled event.
Definition: hyperv.h:119
struct vmbus_xfer_pages_operations * op
Page set operations.
Definition: vmbus.h:472
#define PAGE_SIZE
Page size.
Definition: io.h:27
static int vmbus_post_empty_message(struct hv_hypervisor *hv, unsigned int type)
Post empty message.
Definition: vmbus.c:95
uint64_t intr
Interrupt page base address.
Definition: vmbus.h:220
uint8_t data[240]
Message.
Definition: hyperv.h:112
union vmbus_version version
Requested version.
Definition: vmbus.h:216
uint32_t status
Creation status.
Definition: vmbus.h:190
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
VMBus "open channel" message.
Definition: vmbus.h:128
struct device * parent
Bus device.
Definition: device.h:85
VMBus "GPADL created" message.
Definition: vmbus.h:182
struct vmbus_gpadl_torndown torndown
"GPADL torndown" message
Definition: vmbus.h:258
static size_t vmbus_produce(struct vmbus_device *vmdev, size_t prod, const void *data, size_t len)
Fill outbound ring buffer.
Definition: vmbus.c:617
static int vmbus_initiate_contact(struct hv_hypervisor *hv, unsigned int raw)
Initiate contact.
Definition: vmbus.c:168
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A doubly-linked list entry (or list head)
Definition: list.h:18
VMBus "version response" message.
Definition: vmbus.h:228
Dynamic memory allocation.
static int vmbus_xfer_page_iobufs(struct vmbus_device *vmdev, struct vmbus_packet_header *header, struct list_head *list)
Construct I/O buffer list from transfer pages.
Definition: vmbus.c:900
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
static void uuid_mangle(union uuid *uuid)
Change UUID endianness.
Definition: uuid.h:43
Hyper-V virtual machine bus.
unsigned long tmp
Definition: linux_pci.h:53
uint16_t pageset
Page set ID.
Definition: vmbus.h:322
const union vmbus_message * message
Received message buffer.
Definition: vmbus.h:391
Hyper-V interface.
Guest physical address range descriptor.
Definition: vmbus.h:58
void vmbus_remove(struct hv_hypervisor *hv, struct device *parent)
Remove Hyper-V virtual machine bus.
Definition: vmbus.c:1458
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
VMBus "initiate contact" message.
Definition: vmbus.h:212
uint32_t gpadl
GPADL ID.
Definition: vmbus.h:188
struct hv_message received
Received message.
Definition: hyperv.h:197
#define rmb()
Definition: io.h:484
#define ENOMEM
Not enough space.
Definition: errno.h:534
A hardware device.
Definition: device.h:73
uint32_t channel
Channel ID.
Definition: vmbus.h:186
uint32_t range_count
Number of range descriptors.
Definition: vmbus.h:328
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t prod
Producer index (modulo ring length)
Definition: vmbus.h:363
uint16_t group
Type of event.
Definition: ena.h:12
uint16_t pageset
Page set ID (in protocol byte order)
Definition: vmbus.h:470
static int vmbus_gpadl_is_obsolete(unsigned int gpadl)
Check if GPADL is obsolete.
Definition: vmbus.h:632
uint32_t cons
Consumer index (modulo ring length)
Definition: vmbus.h:365
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
uint32_t intr_mask
Interrupt mask.
Definition: vmbus.h:367
int hv_alloc_pages(struct hv_hypervisor *hv,...)
Allocate zeroed pages.
Definition: hyperv.c:78
VMBus packet header.
Definition: vmbus.h:266
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
static size_t vmbus_consume(struct vmbus_device *vmdev, size_t cons, void *data, size_t len)
Consume inbound ring buffer.
Definition: vmbus.c:645
#define DBGC_HDA(...)
Definition: compiler.h:506
uint32_t in_len
Inbound ring buffer length.
Definition: vmbus.h:497
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
void * packet
Packet buffer.
Definition: vmbus.h:510
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static int vmbus_post_message(struct hv_hypervisor *hv, const struct vmbus_message_header *header, size_t len)
Post message.
Definition: vmbus.c:71
uint8_t flags
Flags.
Definition: ena.h:92
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
static struct vmbus_driver * vmbus_find_driver(const union uuid *type)
Find driver for VMBus device.
Definition: vmbus.c:1123
static unsigned int vmbus_gpadl
Current (i.e.
Definition: vmbus.c:54
A virtual machine bus.
Definition: vmbus.h:383
const char * driver_name
Driver name.
Definition: device.h:77
#define VMBUS_DRIVERS
VMBus device driver table.
Definition: vmbus.h:546
union uuid type
Channel type.
Definition: vmbus.h:102
VMBus "GPADL torndown" message.
Definition: vmbus.h:204
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define EPROTO
Protocol error.
Definition: errno.h:624
uint64_t xid
Transaction ID.
Definition: vmbus.h:280
struct vmbus_gpadl_created created
"GPADL created" message
Definition: vmbus.h:254
#define DBGC2_HDA(...)
Definition: compiler.h:523
VMBus GPA direct header.
Definition: vmbus.h:298
uint8_t data[0]
Ring buffer contents.
Definition: vmbus.h:371
static unsigned int hv_pfn_count(physaddr_t data, size_t len)
Calculate the number of pages covering an address range.
Definition: hyperv.h:223
#define ERANGE
Result too large.
Definition: errno.h:639
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
Windows 8.1.
Definition: vmbus.h:54
uint16_t minor
Minor version.
Definition: vmbus.h:39
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
uint16_t cons
Consumer index.
Definition: ena.h:22
void hv_free_pages(struct hv_hypervisor *hv,...)
Free pages.
Definition: hyperv.c:113
struct list_head siblings
Devices on the same bus.
Definition: device.h:81
union uuid type
Device type.
Definition: vmbus.h:525
struct vmbus_driver * driver
Driver.
Definition: vmbus.h:515
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
uint32_t channel
Channel ID.
Definition: vmbus.h:198
A VMBus device driver.
Definition: vmbus.h:521
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
uint32_t offset
Offset.
Definition: vmbus.h:314
u32 addr
Definition: sky2.h:8
unsigned char uint8_t
Definition: stdint.h:10
struct hv_monitor * monitor_in
Inbound notifications.
Definition: vmbus.h:387
A posted message.
Definition: hyperv.h:81
void set_bit(unsigned int bit, volatile void *bits)
static int vmbus_wait_for_message(struct hv_hypervisor *hv, unsigned int type)
Wait for received message of a specified type, ignoring any others.
Definition: vmbus.c:136
uint32_t gpadl
GPADL ID.
Definition: netvsc.h:14
int vmbus_gpadl_teardown(struct vmbus_device *vmdev, unsigned int gpadl)
Tear down GPA descriptor list.
Definition: vmbus.c:347
struct vmbus_ring * in
Inbound ring buffer.
Definition: vmbus.h:501
#define le16_to_cpu(value)
Definition: byteswap.h:112
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition: uuid.c:45
#define VMBUS_GPADL_MAGIC
VMBus initial GPADL ID.
Definition: vmbus.c:51
int(* copy)(struct vmbus_xfer_pages *pages, void *data, size_t offset, size_t len)
Copy data from transfer page.
Definition: vmbus.h:461
u32 version
Driver version.
Definition: ath9k_hw.c:1983
uint8_t monitored
Monitor exists.
Definition: vmbus.h:120
static int vmbus_unload(struct hv_hypervisor *hv)
Terminate contact.
Definition: vmbus.c:211
int vmbus_send_cancellation(struct vmbus_device *vmdev, uint64_t xid)
Send cancellation packet via ring buffer.
Definition: vmbus.c:857
union hv_message_buffer * message
Message buffer.
Definition: hyperv.h:209
int vmbus_poll(struct vmbus_device *vmdev)
Poll ring buffer.
Definition: vmbus.c:972
unsigned long physaddr_t
Definition: stdint.h:20
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
A monitor trigger group.
Definition: hyperv.h:139
long pad_len
Definition: bigint.h:30
uint32_t gpadl
GPADL ID.
Definition: vmbus.h:200
struct vmbus_version_response version
"Version response" message
Definition: vmbus.h:262
uint32_t id
Open ID.
Definition: vmbus.h:152
#define list_for_each_entry_continue_reverse(pos, head, member)
Iterate over entries in a list in reverse, starting after current position.
Definition: list.h:486
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
static int vmbus_wait_for_any_message(struct hv_hypervisor *hv)
Wait for received message of any type.
Definition: vmbus.c:108
int vmbus_send_control(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Send control packet via ring buffer.
Definition: vmbus.c:765
VMBus transfer page set.
Definition: vmbus.h:466
A Hyper-V hypervisor.
Definition: hyperv.h:203
VMBus "open channel result" message.
Definition: vmbus.h:146
unsigned int bus_type
Bus type.
Definition: device.h:24
static int vmbus_negotiate_version(struct hv_hypervisor *hv)
Negotiate protocol version.
Definition: vmbus.c:231
unsigned int channel
Channel ID.
Definition: vmbus.h:485
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
unsigned int monitor
Monitor ID.
Definition: vmbus.h:487
uint32_t len
Length.
Definition: ena.h:14
uint32_t type
Operating system type.
Definition: ena.h:12
VMBus "close channel" message.
Definition: vmbus.h:158
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
uint32_t len
Length.
Definition: vmbus.h:312
uint64_t pfn[0]
Page frame numbers.
Definition: vmbus.h:68
struct hv_hypervisor * hv
Hyper-V hypervisor.
Definition: vmbus.h:480
#define DBGC2(...)
Definition: compiler.h:522
void hv_disable_sint(struct hv_hypervisor *hv, unsigned int sintx)
Disable synthetic interrupt.
Definition: hyperv.c:423
#define VMBUS_MESSAGE_SINT
VMBus message synthetic interrupt.
Definition: vmbus.h:30
VMBus channel operations.
Definition: vmbus.h:397
struct vmbus_message_header header
Message header.
Definition: vmbus.h:214
uint32_t mtu
Maximum MTU.
Definition: ena.h:28
static int vmbus_probe_channels(struct hv_hypervisor *hv, struct device *parent)
Probe channels.
Definition: vmbus.c:1140
unsigned int gpadl
Ring buffer GPADL ID.
Definition: vmbus.h:503
void * data
Start of data.
Definition: iobuf.h:48
VMBus "offer channel" message.
Definition: vmbus.h:98
struct list_head children
Devices attached to this device.
Definition: device.h:83
static void vmbus_signal_event(struct vmbus_device *vmdev)
Signal channel via hypervisor event.
Definition: vmbus.c:593
struct vmbus_open_channel_result opened
"Open channel result" message
Definition: vmbus.h:248
struct ena_aq_header header
Header.
Definition: ena.h:12
struct vmbus_interrupt * intr
Interrupt page.
Definition: vmbus.h:385
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
uint8_t fill
Length pair.
Definition: deflate.h:12
#define cpu_to_le16(value)
Definition: byteswap.h:106
int open(const char *uri_string)
Open file.
Definition: posix_io.c:176
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct device_description desc
Device description.
Definition: device.h:79
Windows Server 2008.
Definition: vmbus.h:48
union uuid instance
Channel instance.
Definition: vmbus.h:104
union uuid instance
Channel instance.
Definition: vmbus.h:483
int(* probe)(struct vmbus_device *vmdev)
Probe device.
Definition: vmbus.h:531
void(* remove)(struct vmbus_device *vmdev)
Remove device.
Definition: vmbus.h:542
uint16_t major
Major version.
Definition: vmbus.h:41
__be32 raw[7]
Definition: CIB_PRM.h:28
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
static void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition: malloc.h:77
void mb(void)
Memory barrier.
struct hv_monitor * monitor_out
Outbound notifications.
Definition: vmbus.h:389
uint32_t type
Message type.
Definition: vmbus.h:74
void hv_enable_sint(struct hv_hypervisor *hv, unsigned int sintx)
Enable synthetic interrupt.
Definition: hyperv.c:397
int vmbus_probe(struct hv_hypervisor *hv, struct device *parent)
Probe Hyper-V virtual machine bus.
Definition: vmbus.c:1365
struct vmbus * vmbus
Virtual machine bus.
Definition: hyperv.h:211
VMBus "GPADL teardown" message.
Definition: vmbus.h:194
void vmbus_close(struct vmbus_device *vmdev)
Close VMBus channel.
Definition: vmbus.c:524
void(* signal)(struct vmbus_device *vmdev)
Signal channel.
Definition: vmbus.h:492
static struct evtchn_close * close
Definition: xenevent.h:23
#define VMBUS_EVENT_ID
VMBus event connection ID.
Definition: vmbus.h:24
int vmbus_establish_gpadl(struct vmbus_device *vmdev, userptr_t data, size_t len)
Establish GPA descriptor list.
Definition: vmbus.c:276
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
void vmbus_dump_channel(struct vmbus_device *vmdev)
Dump channel status (for debugging)
Definition: vmbus.c:1089
#define le64_to_cpu(value)
Definition: byteswap.h:114
struct hv_monitor_trigger trigger[4]
Trigger groups.
Definition: hyperv.h:171
unsigned int vmbus_obsolete_gpadl
Obsolete GPADL ID threshold.
Definition: vmbus.c:61
uint32_t pending
Pending events.
Definition: hyperv.h:141
static void vmbus_remove_channels(struct hv_hypervisor *hv __unused, struct device *parent)
Remove channels.
Definition: vmbus.c:1339
struct list_head pages
List of transfer page sets.
Definition: vmbus.h:512
struct vmbus_message_header header
Common message header.
Definition: vmbus.h:242
size_t mtu
Maximum expected data packet length.
Definition: vmbus.h:508
static void vmbus_signal_monitor(struct vmbus_device *vmdev)
Signal channel via monitor page.
Definition: vmbus.c:574
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
VMBus "GPADL header" message.
Definition: vmbus.h:166
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int vmbus_send_data(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct io_buffer *iobuf)
Send data packet via ring buffer.
Definition: vmbus.c:794
String functions.
#define VMBUS_MESSAGE_ID
VMBus message connection ID.
Definition: vmbus.h:21
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23
int(* recv_cancellation)(struct vmbus_device *vmdev, uint64_t xid)
Handle received cancellation packet.
Definition: vmbus.h:444
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
#define BUS_TYPE_HV
Hyper-V bus type.
Definition: device.h:67
static struct vmbus_xfer_pages * vmbus_xfer_pages(struct vmbus_device *vmdev, uint16_t pageset)
Get transfer page set from pageset ID.
Definition: vmbus.c:877
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33
int(* reset)(struct vmbus_device *vmdev)
Reset device.
Definition: vmbus.h:537
struct vmbus_xfer_page_range range[0]
Range descriptors.
Definition: vmbus.h:330