iPXE
vmbus.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 /** @file
00027  *
00028  * Hyper-V virtual machine bus
00029  *
00030  */
00031 
00032 #include <stdint.h>
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <errno.h>
00037 #include <assert.h>
00038 #include <byteswap.h>
00039 #include <ipxe/nap.h>
00040 #include <ipxe/malloc.h>
00041 #include <ipxe/iobuf.h>
00042 #include <ipxe/bitops.h>
00043 #include <ipxe/hyperv.h>
00044 #include <ipxe/vmbus.h>
00045 
00046 /** VMBus initial GPADL ID
00047  *
00048  * This is an opaque value with no meaning.  The Linux kernel uses
00049  * 0xe1e10.
00050  */
00051 #define VMBUS_GPADL_MAGIC 0x18ae0000
00052 
00053 /** Current (i.e. most recently issued) GPADL ID */
00054 static unsigned int vmbus_gpadl = VMBUS_GPADL_MAGIC;
00055 
00056 /** Obsolete GPADL ID threshold
00057  *
00058  * When the Hyper-V connection is reset, any previous GPADLs are
00059  * automatically rendered obsolete.
00060  */
00061 unsigned int vmbus_obsolete_gpadl;
00062 
00063 /**
00064  * Post message
00065  *
00066  * @v hv                Hyper-V hypervisor
00067  * @v header            Message header
00068  * @v len               Length of message (including header)
00069  * @ret rc              Return status code
00070  */
00071 static int vmbus_post_message ( struct hv_hypervisor *hv,
00072                                 const struct vmbus_message_header *header,
00073                                 size_t len ) {
00074         struct vmbus *vmbus = hv->vmbus;
00075         int rc;
00076 
00077         /* Post message */
00078         if ( ( rc = hv_post_message ( hv, VMBUS_MESSAGE_ID, VMBUS_MESSAGE_TYPE,
00079                                       header, len ) ) != 0 ) {
00080                 DBGC ( vmbus, "VMBUS %p could not post message: %s\n",
00081                        vmbus, strerror ( rc ) );
00082                 return rc;
00083         }
00084 
00085         return 0;
00086 }
00087 
00088 /**
00089  * Post empty message
00090  *
00091  * @v hv                Hyper-V hypervisor
00092  * @v type              Message type
00093  * @ret rc              Return status code
00094  */
00095 static int vmbus_post_empty_message ( struct hv_hypervisor *hv,
00096                                       unsigned int type ) {
00097         struct vmbus_message_header header = { .type = cpu_to_le32 ( type ) };
00098 
00099         return vmbus_post_message ( hv, &header, sizeof ( header ) );
00100 }
00101 
00102 /**
00103  * Wait for received message of any type
00104  *
00105  * @v hv                Hyper-V hypervisor
00106  * @ret rc              Return status code
00107  */
00108 static int vmbus_wait_for_any_message ( struct hv_hypervisor *hv ) {
00109         struct vmbus *vmbus = hv->vmbus;
00110         int rc;
00111 
00112         /* Wait for message */
00113         if ( ( rc = hv_wait_for_message ( hv, VMBUS_MESSAGE_SINT ) ) != 0 ) {
00114                 DBGC ( vmbus, "VMBUS %p failed waiting for message: %s\n",
00115                        vmbus, strerror ( rc ) );
00116                 return rc;
00117         }
00118 
00119         /* Sanity check */
00120         if ( hv->message->received.type != cpu_to_le32 ( VMBUS_MESSAGE_TYPE ) ){
00121                 DBGC ( vmbus, "VMBUS %p invalid message type %d\n",
00122                        vmbus, le32_to_cpu ( hv->message->received.type ) );
00123                 return -EINVAL;
00124         }
00125 
00126         return 0;
00127 }
00128 
00129 /**
00130  * Wait for received message of a specified type, ignoring any others
00131  *
00132  * @v hv                Hyper-V hypervisor
00133  * @v type              Message type
00134  * @ret rc              Return status code
00135  */
00136 static int vmbus_wait_for_message ( struct hv_hypervisor *hv,
00137                                     unsigned int type ) {
00138         struct vmbus *vmbus = hv->vmbus;
00139         const struct vmbus_message_header *header = &vmbus->message->header;
00140         int rc;
00141 
00142         /* Loop until specified message arrives, or until an error occurs */
00143         while ( 1 ) {
00144 
00145                 /* Wait for message */
00146                 if ( ( rc = vmbus_wait_for_any_message ( hv ) ) != 0 )
00147                         return rc;
00148 
00149                 /* Check for requested message type */
00150                 if ( header->type == cpu_to_le32 ( type ) )
00151                         return 0;
00152 
00153                 /* Ignore any other messages (e.g. due to additional
00154                  * channels being offered at runtime).
00155                  */
00156                 DBGC ( vmbus, "VMBUS %p ignoring message type %d (expecting "
00157                        "%d)\n", vmbus, le32_to_cpu ( header->type ), type );
00158         }
00159 }
00160 
00161 /**
00162  * Initiate contact
00163  *
00164  * @v hv                Hyper-V hypervisor
00165  * @v raw               VMBus protocol (raw) version
00166  * @ret rc              Return status code
00167  */
00168 static int vmbus_initiate_contact ( struct hv_hypervisor *hv,
00169                                     unsigned int raw ) {
00170         struct vmbus *vmbus = hv->vmbus;
00171         const struct vmbus_version_response *version = &vmbus->message->version;
00172         struct vmbus_initiate_contact initiate;
00173         int rc;
00174 
00175         /* Construct message */
00176         memset ( &initiate, 0, sizeof ( initiate ) );
00177         initiate.header.type = cpu_to_le32 ( VMBUS_INITIATE_CONTACT );
00178         initiate.version.raw = cpu_to_le32 ( raw );
00179         initiate.intr = virt_to_phys ( vmbus->intr );
00180         initiate.monitor_in = virt_to_phys ( vmbus->monitor_in );
00181         initiate.monitor_out = virt_to_phys ( vmbus->monitor_out );
00182 
00183         /* Post message */
00184         if ( ( rc = vmbus_post_message ( hv, &initiate.header,
00185                                          sizeof ( initiate ) ) ) != 0 )
00186                 return rc;
00187 
00188         /* Wait for response */
00189         if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_VERSION_RESPONSE ) ) !=0)
00190                 return rc;
00191 
00192         /* Check response */
00193         if ( ! version->supported ) {
00194                 DBGC ( vmbus, "VMBUS %p requested version not supported\n",
00195                        vmbus );
00196                 return -ENOTSUP;
00197         }
00198 
00199         DBGC ( vmbus, "VMBUS %p initiated contact using version %d.%d\n",
00200                vmbus, le16_to_cpu ( initiate.version.major ),
00201                le16_to_cpu ( initiate.version.minor ) );
00202         return 0;
00203 }
00204 
00205 /**
00206  * Terminate contact
00207  *
00208  * @v hv                Hyper-V hypervisor
00209  * @ret rc              Return status code
00210  */
00211 static int vmbus_unload ( struct hv_hypervisor *hv ) {
00212         int rc;
00213 
00214         /* Post message */
00215         if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_UNLOAD ) ) != 0 )
00216                 return rc;
00217 
00218         /* Wait for response */
00219         if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_UNLOAD_RESPONSE ) ) != 0)
00220                 return rc;
00221 
00222         return 0;
00223 }
00224 
00225 /**
00226  * Negotiate protocol version
00227  *
00228  * @v hv                Hyper-V hypervisor
00229  * @ret rc              Return status code
00230  */
00231 static int vmbus_negotiate_version ( struct hv_hypervisor *hv ) {
00232         int rc;
00233 
00234         /* We require the ability to disconnect from and reconnect to
00235          * VMBus; if we don't have this then there is no (viable) way
00236          * for a loaded operating system to continue to use any VMBus
00237          * devices.  (There is also a small but non-zero risk that the
00238          * host will continue to write to our interrupt and monitor
00239          * pages, since the VMBUS_UNLOAD message in earlier versions
00240          * is essentially a no-op.)
00241          *
00242          * This requires us to ensure that the host supports protocol
00243          * version 3.0 (VMBUS_VERSION_WIN8_1).  However, we can't
00244          * actually _use_ protocol version 3.0, since doing so causes
00245          * an iSCSI-booted Windows Server 2012 R2 VM to crash due to a
00246          * NULL pointer dereference in vmbus.sys.
00247          *
00248          * To work around this problem, we first ensure that we can
00249          * connect using protocol v3.0, then disconnect and reconnect
00250          * using the oldest known protocol.
00251          */
00252 
00253         /* Initiate contact to check for required protocol support */
00254         if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WIN8_1 ) ) != 0 )
00255                 return rc;
00256 
00257         /* Terminate contact */
00258         if ( ( rc = vmbus_unload ( hv ) ) != 0 )
00259                 return rc;
00260 
00261         /* Reinitiate contact using the oldest known protocol version */
00262         if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WS2008 ) ) != 0 )
00263                 return rc;
00264 
00265         return 0;
00266 }
00267 
00268 /**
00269  * Establish GPA descriptor list
00270  *
00271  * @v vmdev             VMBus device
00272  * @v data              Data buffer
00273  * @v len               Length of data buffer
00274  * @ret gpadl           GPADL ID, or negative error
00275  */
00276 int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
00277                             size_t len ) {
00278         struct hv_hypervisor *hv = vmdev->hv;
00279         struct vmbus *vmbus = hv->vmbus;
00280         physaddr_t addr = user_to_phys ( data, 0 );
00281         unsigned int pfn_count = hv_pfn_count ( addr, len );
00282         struct {
00283                 struct vmbus_gpadl_header gpadlhdr;
00284                 struct vmbus_gpa_range range;
00285                 uint64_t pfn[pfn_count];
00286         } __attribute__ (( packed )) gpadlhdr;
00287         const struct vmbus_gpadl_created *created = &vmbus->message->created;
00288         unsigned int gpadl;
00289         unsigned int i;
00290         int rc;
00291 
00292         /* Allocate GPADL ID */
00293         gpadl = ++vmbus_gpadl;
00294 
00295         /* Construct message */
00296         memset ( &gpadlhdr, 0, sizeof ( gpadlhdr ) );
00297         gpadlhdr.gpadlhdr.header.type = cpu_to_le32 ( VMBUS_GPADL_HEADER );
00298         gpadlhdr.gpadlhdr.channel = cpu_to_le32 ( vmdev->channel );
00299         gpadlhdr.gpadlhdr.gpadl = cpu_to_le32 ( gpadl );
00300         gpadlhdr.gpadlhdr.range_len =
00301                 cpu_to_le16 ( ( sizeof ( gpadlhdr.range ) +
00302                                 sizeof ( gpadlhdr.pfn ) ) );
00303         gpadlhdr.gpadlhdr.range_count = cpu_to_le16 ( 1 );
00304         gpadlhdr.range.len = cpu_to_le32 ( len );
00305         gpadlhdr.range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
00306         for ( i = 0 ; i < pfn_count ; i++ )
00307                 gpadlhdr.pfn[i] = ( ( addr / PAGE_SIZE ) + i );
00308 
00309         /* Post message */
00310         if ( ( rc = vmbus_post_message ( hv, &gpadlhdr.gpadlhdr.header,
00311                                          sizeof ( gpadlhdr ) ) ) != 0 )
00312                 return rc;
00313 
00314         /* Wait for response */
00315         if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_GPADL_CREATED ) ) != 0 )
00316                 return rc;
00317 
00318         /* Check response */
00319         if ( created->channel != cpu_to_le32 ( vmdev->channel ) ) {
00320                 DBGC ( vmdev, "VMBUS %s unexpected GPADL channel %d\n",
00321                        vmdev->dev.name, le32_to_cpu ( created->channel ) );
00322                 return -EPROTO;
00323         }
00324         if ( created->gpadl != cpu_to_le32 ( gpadl ) ) {
00325                 DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
00326                        vmdev->dev.name, le32_to_cpu ( created->gpadl ) );
00327                 return -EPROTO;
00328         }
00329         if ( created->status != 0 ) {
00330                 DBGC ( vmdev, "VMBUS %s GPADL creation failed: %#08x\n",
00331                        vmdev->dev.name, le32_to_cpu ( created->status ) );
00332                 return -EPROTO;
00333         }
00334 
00335         DBGC ( vmdev, "VMBUS %s GPADL %#08x is [%08lx,%08lx)\n",
00336                vmdev->dev.name, gpadl, addr, ( addr + len ) );
00337         return gpadl;
00338 }
00339 
00340 /**
00341  * Tear down GPA descriptor list
00342  *
00343  * @v vmdev             VMBus device
00344  * @v gpadl             GPADL ID
00345  * @ret rc              Return status code
00346  */
00347 int vmbus_gpadl_teardown ( struct vmbus_device *vmdev, unsigned int gpadl ) {
00348         struct hv_hypervisor *hv = vmdev->hv;
00349         struct vmbus *vmbus = hv->vmbus;
00350         struct vmbus_gpadl_teardown teardown;
00351         const struct vmbus_gpadl_torndown *torndown = &vmbus->message->torndown;
00352         int rc;
00353 
00354         /* If GPADL is obsolete (i.e. was created before the most
00355          * recent Hyper-V reset), then we will never receive a
00356          * response to the teardown message.  Since the GPADL is
00357          * already destroyed as far as the hypervisor is concerned, no
00358          * further action is required.
00359          */
00360         if ( vmbus_gpadl_is_obsolete ( gpadl ) )
00361                 return 0;
00362 
00363         /* Construct message */
00364         memset ( &teardown, 0, sizeof ( teardown ) );
00365         teardown.header.type = cpu_to_le32 ( VMBUS_GPADL_TEARDOWN );
00366         teardown.channel = cpu_to_le32 ( vmdev->channel );
00367         teardown.gpadl = cpu_to_le32 ( gpadl );
00368 
00369         /* Post message */
00370         if ( ( rc = vmbus_post_message ( hv, &teardown.header,
00371                                          sizeof ( teardown ) ) ) != 0 )
00372                 return rc;
00373 
00374         /* Wait for response */
00375         if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_GPADL_TORNDOWN ) ) != 0 )
00376                 return rc;
00377 
00378         /* Check response */
00379         if ( torndown->gpadl != cpu_to_le32 ( gpadl ) ) {
00380                 DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
00381                        vmdev->dev.name, le32_to_cpu ( torndown->gpadl ) );
00382                 return -EPROTO;
00383         }
00384 
00385         return 0;
00386 }
00387 
00388 /**
00389  * Open VMBus channel
00390  *
00391  * @v vmdev             VMBus device
00392  * @v op                Channel operations
00393  * @v out_len           Outbound ring buffer length
00394  * @v in_len            Inbound ring buffer length
00395  * @v mtu               Maximum expected data packet length (including headers)
00396  * @ret rc              Return status code
00397  *
00398  * Both outbound and inbound ring buffer lengths must be a power of
00399  * two and a multiple of PAGE_SIZE.  The requirement to be a power of
00400  * two is a policy decision taken to simplify the ring buffer indexing
00401  * logic.
00402  */
00403 int vmbus_open ( struct vmbus_device *vmdev,
00404                  struct vmbus_channel_operations *op,
00405                  size_t out_len, size_t in_len, size_t mtu ) {
00406         struct hv_hypervisor *hv = vmdev->hv;
00407         struct vmbus *vmbus = hv->vmbus;
00408         struct vmbus_open_channel open;
00409         const struct vmbus_open_channel_result *opened =
00410                 &vmbus->message->opened;
00411         size_t len;
00412         void *ring;
00413         void *packet;
00414         int gpadl;
00415         uint32_t open_id;
00416         int rc;
00417 
00418         /* Sanity checks */
00419         assert ( ( out_len % PAGE_SIZE ) == 0 );
00420         assert ( ( out_len & ( out_len - 1 ) ) == 0 );
00421         assert ( ( in_len % PAGE_SIZE ) == 0 );
00422         assert ( ( in_len & ( in_len - 1 ) ) == 0 );
00423         assert ( mtu >= ( sizeof ( struct vmbus_packet_header ) +
00424                           sizeof ( struct vmbus_packet_footer ) ) );
00425 
00426         /* Allocate packet buffer */
00427         packet = malloc ( mtu );
00428         if ( ! packet ) {
00429                 rc = -ENOMEM;
00430                 goto err_alloc_packet;
00431         }
00432 
00433         /* Allocate ring buffer */
00434         len = ( sizeof ( *vmdev->out ) + out_len +
00435                 sizeof ( *vmdev->in ) + in_len );
00436         assert ( ( len % PAGE_SIZE ) == 0 );
00437         ring = malloc_dma ( len, PAGE_SIZE );
00438         if ( ! ring ) {
00439                 rc = -ENOMEM;
00440                 goto err_alloc_ring;
00441         }
00442         memset ( ring, 0, len );
00443 
00444         /* Establish GPADL for ring buffer */
00445         gpadl = vmbus_establish_gpadl ( vmdev, virt_to_user ( ring ), len );
00446         if ( gpadl < 0 ) {
00447                 rc = gpadl;
00448                 goto err_establish;
00449         }
00450 
00451         /* Construct message */
00452         memset ( &open, 0, sizeof ( open ) );
00453         open.header.type = cpu_to_le32 ( VMBUS_OPEN_CHANNEL );
00454         open.channel = cpu_to_le32 ( vmdev->channel );
00455         open_id = random();
00456         open.id = open_id; /* Opaque random value: endianness irrelevant */
00457         open.gpadl = cpu_to_le32 ( gpadl );
00458         open.out_pages = ( ( sizeof ( *vmdev->out ) / PAGE_SIZE ) +
00459                            ( out_len / PAGE_SIZE ) );
00460 
00461         /* Post message */
00462         if ( ( rc = vmbus_post_message ( hv, &open.header,
00463                                          sizeof ( open ) ) ) != 0 )
00464                 goto err_post_message;
00465 
00466         /* Wait for response */
00467         if ( ( rc = vmbus_wait_for_message ( hv,
00468                                              VMBUS_OPEN_CHANNEL_RESULT ) ) != 0)
00469                 goto err_wait_for_message;
00470 
00471         /* Check response */
00472         if ( opened->channel != cpu_to_le32 ( vmdev->channel ) ) {
00473                 DBGC ( vmdev, "VMBUS %s unexpected opened channel %#08x\n",
00474                        vmdev->dev.name, le32_to_cpu ( opened->channel ) );
00475                 rc = -EPROTO;
00476                 goto err_check_response;
00477         }
00478         if ( opened->id != open_id /* Non-endian */ ) {
00479                 DBGC ( vmdev, "VMBUS %s unexpected open ID %#08x\n",
00480                        vmdev->dev.name, le32_to_cpu ( opened->id ) );
00481                 rc = -EPROTO;
00482                 goto err_check_response;
00483         }
00484         if ( opened->status != 0 ) {
00485                 DBGC ( vmdev, "VMBUS %s open failed: %#08x\n",
00486                        vmdev->dev.name, le32_to_cpu ( opened->status ) );
00487                 rc = -EPROTO;
00488                 goto err_check_response;
00489         }
00490 
00491         /* Store channel parameters */
00492         vmdev->out_len = out_len;
00493         vmdev->in_len = in_len;
00494         vmdev->out = ring;
00495         vmdev->in = ( ring + sizeof ( *vmdev->out ) + out_len );
00496         vmdev->gpadl = gpadl;
00497         vmdev->op = op;
00498         vmdev->mtu = mtu;
00499         vmdev->packet = packet;
00500 
00501         DBGC ( vmdev, "VMBUS %s channel GPADL %#08x ring "
00502                 "[%#08lx,%#08lx,%#08lx)\n", vmdev->dev.name, vmdev->gpadl,
00503                 virt_to_phys ( vmdev->out ), virt_to_phys ( vmdev->in ),
00504                 ( virt_to_phys ( vmdev->out ) + len ) );
00505         return 0;
00506 
00507  err_check_response:
00508  err_wait_for_message:
00509  err_post_message:
00510         vmbus_gpadl_teardown ( vmdev, vmdev->gpadl );
00511  err_establish:
00512         free_dma ( ring, len );
00513  err_alloc_ring:
00514         free ( packet );
00515  err_alloc_packet:
00516         return rc;
00517 }
00518 
00519 /**
00520  * Close VMBus channel
00521  *
00522  * @v vmdev             VMBus device
00523  */
00524 void vmbus_close ( struct vmbus_device *vmdev ) {
00525         struct hv_hypervisor *hv = vmdev->hv;
00526         struct vmbus_close_channel close;
00527         size_t len;
00528         int rc;
00529 
00530         /* Construct message */
00531         memset ( &close, 0, sizeof ( close ) );
00532         close.header.type = cpu_to_le32 ( VMBUS_CLOSE_CHANNEL );
00533         close.channel = cpu_to_le32 ( vmdev->channel );
00534 
00535         /* Post message */
00536         if ( ( rc = vmbus_post_message ( hv, &close.header,
00537                                          sizeof ( close ) ) ) != 0 ) {
00538                 DBGC ( vmdev, "VMBUS %s failed to close: %s\n",
00539                        vmdev->dev.name, strerror ( rc ) );
00540                 /* Continue to attempt to tear down GPADL, so that our
00541                  * memory is no longer accessible by the remote VM.
00542                  */
00543         }
00544 
00545         /* Tear down GPADL */
00546         if ( ( rc = vmbus_gpadl_teardown ( vmdev, vmdev->gpadl ) ) != 0 ) {
00547                 DBGC ( vmdev, "VMBUS %s failed to tear down channel GPADL: "
00548                        "%s\n", vmdev->dev.name, strerror ( rc ) );
00549                 /* We can't prevent the remote VM from continuing to
00550                  * access this memory, so leak it.
00551                  */
00552                 return;
00553         }
00554 
00555         /* Free ring buffer */
00556         len = ( sizeof ( *vmdev->out ) + vmdev->out_len +
00557                 sizeof ( *vmdev->in ) + vmdev->in_len );
00558         free_dma ( vmdev->out, len );
00559         vmdev->out = NULL;
00560         vmdev->in = NULL;
00561 
00562         /* Free packet buffer */
00563         free ( vmdev->packet );
00564         vmdev->packet = NULL;
00565 
00566         DBGC ( vmdev, "VMBUS %s closed\n", vmdev->dev.name );
00567 }
00568 
00569 /**
00570  * Signal channel via monitor page
00571  *
00572  * @v vmdev             VMBus device
00573  */
00574 static void vmbus_signal_monitor ( struct vmbus_device *vmdev ) {
00575         struct hv_hypervisor *hv = vmdev->hv;
00576         struct vmbus *vmbus = hv->vmbus;
00577         struct hv_monitor_trigger *trigger;
00578         unsigned int group;
00579         unsigned int bit;
00580 
00581         /* Set bit in monitor trigger group */
00582         group = ( vmdev->monitor / ( 8 * sizeof ( trigger->pending ) ));
00583         bit = ( vmdev->monitor % ( 8 * sizeof ( trigger->pending ) ) );
00584         trigger = &vmbus->monitor_out->trigger[group];
00585         set_bit ( bit, trigger );
00586 }
00587 
00588 /**
00589  * Signal channel via hypervisor event
00590  *
00591  * @v vmdev             VMBus device
00592  */
00593 static void vmbus_signal_event ( struct vmbus_device *vmdev ) {
00594         struct hv_hypervisor *hv = vmdev->hv;
00595         int rc;
00596 
00597         /* Signal hypervisor event */
00598         if ( ( rc = hv_signal_event ( hv, VMBUS_EVENT_ID, 0 ) ) != 0 ) {
00599                 DBGC ( vmdev, "VMBUS %s could not signal event: %s\n",
00600                        vmdev->dev.name, strerror ( rc ) );
00601                 return;
00602         }
00603 }
00604 
00605 /**
00606  * Fill outbound ring buffer
00607  *
00608  * @v vmdev             VMBus device
00609  * @v prod              Producer index
00610  * @v data              Data
00611  * @v len               Length
00612  * @ret prod            New producer index
00613  *
00614  * The caller must ensure that there is sufficient space in the ring
00615  * buffer.
00616  */
00617 static size_t vmbus_produce ( struct vmbus_device *vmdev, size_t prod,
00618                               const void *data, size_t len ) {
00619         size_t first;
00620         size_t second;
00621 
00622         /* Determine fragment lengths */
00623         first = ( vmdev->out_len - prod );
00624         if ( first > len )
00625                 first = len;
00626         second = ( len - first );
00627 
00628         /* Copy fragment(s) */
00629         memcpy ( &vmdev->out->data[prod], data, first );
00630         if ( second )
00631                 memcpy ( &vmdev->out->data[0], ( data + first ), second );
00632 
00633         return ( ( prod + len ) & ( vmdev->out_len - 1 ) );
00634 }
00635 
00636 /**
00637  * Consume inbound ring buffer
00638  *
00639  * @v vmdev             VMBus device
00640  * @v cons              Consumer index
00641  * @v data              Data buffer, or NULL
00642  * @v len               Length to consume
00643  * @ret cons            New consumer index
00644  */
00645 static size_t vmbus_consume ( struct vmbus_device *vmdev, size_t cons,
00646                               void *data, size_t len ) {
00647         size_t first;
00648         size_t second;
00649 
00650         /* Determine fragment lengths */
00651         first = ( vmdev->in_len - cons );
00652         if ( first > len )
00653                 first = len;
00654         second = ( len - first );
00655 
00656         /* Copy fragment(s) */
00657         memcpy ( data, &vmdev->in->data[cons], first );
00658         if ( second )
00659                 memcpy ( ( data + first ), &vmdev->in->data[0], second );
00660 
00661         return ( ( cons + len ) & ( vmdev->in_len - 1 ) );
00662 }
00663 
00664 /**
00665  * Send packet via ring buffer
00666  *
00667  * @v vmdev             VMBus device
00668  * @v header            Packet header
00669  * @v data              Data
00670  * @v len               Length of data
00671  * @ret rc              Return status code
00672  *
00673  * Send a packet via the outbound ring buffer.  All fields in the
00674  * packet header must be filled in, with the exception of the total
00675  * packet length.
00676  */
00677 static int vmbus_send ( struct vmbus_device *vmdev,
00678                         struct vmbus_packet_header *header,
00679                         const void *data, size_t len ) {
00680         struct hv_hypervisor *hv = vmdev->hv;
00681         struct vmbus *vmbus = hv->vmbus;
00682         static uint8_t padding[ 8 - 1 ];
00683         struct vmbus_packet_footer footer;
00684         size_t header_len;
00685         size_t pad_len;
00686         size_t footer_len;
00687         size_t ring_len;
00688         size_t cons;
00689         size_t prod;
00690         size_t old_prod;
00691         size_t fill;
00692 
00693         /* Sanity check */
00694         assert ( vmdev->out != NULL );
00695 
00696         /* Calculate lengths */
00697         header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
00698         pad_len = ( ( -len ) & ( 8 - 1 ) );
00699         footer_len = sizeof ( footer );
00700         ring_len = ( header_len + len + pad_len + footer_len );
00701 
00702         /* Check that we have enough room in the outbound ring buffer */
00703         cons = le32_to_cpu ( vmdev->out->cons );
00704         prod = le32_to_cpu ( vmdev->out->prod );
00705         old_prod = prod;
00706         fill = ( ( prod - cons ) & ( vmdev->out_len - 1 ) );
00707         if ( ( fill + ring_len ) >= vmdev->out_len ) {
00708                 DBGC ( vmdev, "VMBUS %s ring buffer full\n", vmdev->dev.name );
00709                 return -ENOBUFS;
00710         }
00711 
00712         /* Complete header */
00713         header->qlen = cpu_to_le16 ( ( ring_len - footer_len ) / 8 );
00714 
00715         /* Construct footer */
00716         footer.reserved = 0;
00717         footer.prod = vmdev->out->prod;
00718 
00719         /* Copy packet to buffer */
00720         DBGC2 ( vmdev, "VMBUS %s sending:\n", vmdev->dev.name );
00721         DBGC2_HDA ( vmdev, prod, header, header_len );
00722         prod = vmbus_produce ( vmdev, prod, header, header_len );
00723         DBGC2_HDA ( vmdev, prod, data, len );
00724         prod = vmbus_produce ( vmdev, prod, data, len );
00725         prod = vmbus_produce ( vmdev, prod, padding, pad_len );
00726         DBGC2_HDA ( vmdev, prod, &footer, sizeof ( footer ) );
00727         prod = vmbus_produce ( vmdev, prod, &footer, sizeof ( footer ) );
00728         assert ( ( ( prod - old_prod ) & ( vmdev->out_len - 1 ) ) == ring_len );
00729 
00730         /* Update producer index */
00731         wmb();
00732         vmdev->out->prod = cpu_to_le32 ( prod );
00733 
00734         /* Return if we do not need to signal the host.  This follows
00735          * the logic of hv_need_to_signal() in the Linux driver.
00736          */
00737         mb();
00738         if ( vmdev->out->intr_mask )
00739                 return 0;
00740         rmb();
00741         cons = le32_to_cpu ( vmdev->out->cons );
00742         if ( cons != old_prod )
00743                 return 0;
00744 
00745         /* Set channel bit in interrupt page */
00746         set_bit ( vmdev->channel, vmbus->intr->out );
00747 
00748         /* Signal the host */
00749         vmdev->signal ( vmdev );
00750 
00751         return 0;
00752 }
00753 
00754 /**
00755  * Send control packet via ring buffer
00756  *
00757  * @v vmdev             VMBus device
00758  * @v xid               Transaction ID (or zero to not request completion)
00759  * @v data              Data
00760  * @v len               Length of data
00761  * @ret rc              Return status code
00762  *
00763  * Send data using a VMBUS_DATA_INBAND packet.
00764  */
00765 int vmbus_send_control ( struct vmbus_device *vmdev, uint64_t xid,
00766                          const void *data, size_t len ) {
00767         struct vmbus_packet_header *header = vmdev->packet;
00768 
00769         /* Construct header in packet buffer */
00770         assert ( header != NULL );
00771         header->type = cpu_to_le16 ( VMBUS_DATA_INBAND );
00772         header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
00773         header->flags = ( xid ?
00774                           cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED ) : 0 );
00775         header->xid = xid; /* Non-endian */
00776 
00777         return vmbus_send ( vmdev, header, data, len );
00778 }
00779 
00780 /**
00781  * Send data packet via ring buffer
00782  *
00783  * @v vmdev             VMBus device
00784  * @v xid               Transaction ID
00785  * @v data              Data
00786  * @v len               Length of data
00787  * @v iobuf             I/O buffer
00788  * @ret rc              Return status code
00789  *
00790  * Send data using a VMBUS_DATA_GPA_DIRECT packet.  The caller is
00791  * responsible for ensuring that the I/O buffer remains untouched
00792  * until the corresponding completion has been received.
00793  */
00794 int vmbus_send_data ( struct vmbus_device *vmdev, uint64_t xid,
00795                       const void *data, size_t len, struct io_buffer *iobuf ) {
00796         physaddr_t addr = virt_to_phys ( iobuf->data );
00797         unsigned int pfn_count = hv_pfn_count ( addr, iob_len ( iobuf ) );
00798         struct {
00799                 struct vmbus_gpa_direct_header gpa;
00800                 struct vmbus_gpa_range range;
00801                 uint64_t pfn[pfn_count];
00802         } __attribute__ (( packed )) *header = vmdev->packet;
00803         unsigned int i;
00804 
00805         /* Sanity check */
00806         assert ( header != NULL );
00807         assert ( sizeof ( *header ) <= vmdev->mtu );
00808 
00809         /* Construct header in packet buffer */
00810         header->gpa.header.type = cpu_to_le16 ( VMBUS_DATA_GPA_DIRECT );
00811         header->gpa.header.hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
00812         header->gpa.header.flags = cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED );
00813         header->gpa.header.xid = xid; /* Non-endian */
00814         header->gpa.range_count = 1;
00815         header->range.len = cpu_to_le32 ( iob_len ( iobuf ) );
00816         header->range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
00817         for ( i = 0 ; i < pfn_count ; i++ )
00818                 header->pfn[i] = ( ( addr / PAGE_SIZE ) + i );
00819 
00820         return vmbus_send ( vmdev, &header->gpa.header, data, len );
00821 }
00822 
00823 /**
00824  * Send completion packet via ring buffer
00825  *
00826  * @v vmdev             VMBus device
00827  * @v xid               Transaction ID
00828  * @v data              Data
00829  * @v len               Length of data
00830  * @ret rc              Return status code
00831  *
00832  * Send data using a VMBUS_COMPLETION packet.
00833  */
00834 int vmbus_send_completion ( struct vmbus_device *vmdev, uint64_t xid,
00835                             const void *data, size_t len ) {
00836         struct vmbus_packet_header *header = vmdev->packet;
00837 
00838         /* Construct header in packet buffer */
00839         assert ( header != NULL );
00840         header->type = cpu_to_le16 ( VMBUS_COMPLETION );
00841         header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
00842         header->flags = 0;
00843         header->xid = xid; /* Non-endian */
00844 
00845         return vmbus_send ( vmdev, header, data, len );
00846 }
00847 
00848 /**
00849  * Send cancellation packet via ring buffer
00850  *
00851  * @v vmdev             VMBus device
00852  * @v xid               Transaction ID
00853  * @ret rc              Return status code
00854  *
00855  * Send data using a VMBUS_CANCELLATION packet.
00856  */
00857 int vmbus_send_cancellation ( struct vmbus_device *vmdev, uint64_t xid ) {
00858         struct vmbus_packet_header *header = vmdev->packet;
00859 
00860         /* Construct header in packet buffer */
00861         assert ( header != NULL );
00862         header->type = cpu_to_le16 ( VMBUS_CANCELLATION );
00863         header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
00864         header->flags = 0;
00865         header->xid = xid; /* Non-endian */
00866 
00867         return vmbus_send ( vmdev, header, NULL, 0 );
00868 }
00869 
00870 /**
00871  * Get transfer page set from pageset ID
00872  *
00873  * @v vmdev             VMBus device
00874  * @v pageset           Page set ID (in protocol byte order)
00875  * @ret pages           Page set, or NULL if not found
00876  */
00877 static struct vmbus_xfer_pages * vmbus_xfer_pages ( struct vmbus_device *vmdev,
00878                                                     uint16_t pageset ) {
00879         struct vmbus_xfer_pages *pages;
00880 
00881         /* Locate page set */
00882         list_for_each_entry ( pages, &vmdev->pages, list ) {
00883                 if ( pages->pageset == pageset )
00884                         return pages;
00885         }
00886 
00887         DBGC ( vmdev, "VMBUS %s unrecognised page set ID %#04x\n",
00888                vmdev->dev.name, le16_to_cpu ( pageset ) );
00889         return NULL;
00890 }
00891 
00892 /**
00893  * Construct I/O buffer list from transfer pages
00894  *
00895  * @v vmdev             VMBus device
00896  * @v header            Transfer page header
00897  * @v list              I/O buffer list to populate
00898  * @ret rc              Return status code
00899  */
00900 static int vmbus_xfer_page_iobufs ( struct vmbus_device *vmdev,
00901                                     struct vmbus_packet_header *header,
00902                                     struct list_head *list ) {
00903         struct vmbus_xfer_page_header *page_header =
00904                 container_of ( header, struct vmbus_xfer_page_header, header );
00905         struct vmbus_xfer_pages *pages;
00906         struct io_buffer *iobuf;
00907         struct io_buffer *tmp;
00908         size_t len;
00909         size_t offset;
00910         unsigned int range_count;
00911         unsigned int i;
00912         int rc;
00913 
00914         /* Sanity check */
00915         assert ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) );
00916 
00917         /* Locate page set */
00918         pages = vmbus_xfer_pages ( vmdev, page_header->pageset );
00919         if ( ! pages ) {
00920                 rc = -ENOENT;
00921                 goto err_pages;
00922         }
00923 
00924         /* Allocate and populate I/O buffers */
00925         range_count = le32_to_cpu ( page_header->range_count );
00926         for ( i = 0 ; i < range_count ; i++ ) {
00927 
00928                 /* Parse header */
00929                 len = le32_to_cpu ( page_header->range[i].len );
00930                 offset = le32_to_cpu ( page_header->range[i].offset );
00931 
00932                 /* Allocate I/O buffer */
00933                 iobuf = alloc_iob ( len );
00934                 if ( ! iobuf ) {
00935                         DBGC ( vmdev, "VMBUS %s could not allocate %zd-byte "
00936                                "I/O buffer\n", vmdev->dev.name, len );
00937                         rc = -ENOMEM;
00938                         goto err_alloc;
00939                 }
00940 
00941                 /* Add I/O buffer to list */
00942                 list_add ( &iobuf->list, list );
00943 
00944                 /* Populate I/O buffer */
00945                 if ( ( rc = pages->op->copy ( pages, iob_put ( iobuf, len ),
00946                                               offset, len ) ) != 0 ) {
00947                         DBGC ( vmdev, "VMBUS %s could not populate I/O buffer "
00948                                "range [%zd,%zd): %s\n",
00949                                vmdev->dev.name, offset, len, strerror ( rc ) );
00950                         goto err_copy;
00951                 }
00952         }
00953 
00954         return 0;
00955 
00956  err_copy:
00957  err_alloc:
00958         list_for_each_entry_safe ( iobuf, tmp, list, list ) {
00959                 list_del ( &iobuf->list );
00960                 free_iob ( iobuf );
00961         }
00962  err_pages:
00963         return rc;
00964 }
00965 
00966 /**
00967  * Poll ring buffer
00968  *
00969  * @v vmdev             VMBus device
00970  * @ret rc              Return status code
00971  */
00972 int vmbus_poll ( struct vmbus_device *vmdev ) {
00973         struct vmbus_packet_header *header = vmdev->packet;
00974         struct list_head list;
00975         void *data;
00976         size_t header_len;
00977         size_t len;
00978         size_t footer_len;
00979         size_t ring_len;
00980         size_t cons;
00981         size_t old_cons;
00982         uint64_t xid;
00983         int rc;
00984 
00985         /* Sanity checks */
00986         assert ( vmdev->packet != NULL );
00987         assert ( vmdev->in != NULL );
00988 
00989         /* Return immediately if buffer is empty */
00990         if ( ! vmbus_has_data ( vmdev ) )
00991                 return 0;
00992         cons = le32_to_cpu ( vmdev->in->cons );
00993         old_cons = cons;
00994 
00995         /* Consume (start of) header */
00996         cons = vmbus_consume ( vmdev, cons, header, sizeof ( *header ) );
00997 
00998         /* Parse and sanity check header */
00999         header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
01000         if ( header_len < sizeof ( *header ) ) {
01001                 DBGC ( vmdev, "VMBUS %s received underlength header (%zd "
01002                        "bytes)\n", vmdev->dev.name, header_len );
01003                 return -EINVAL;
01004         }
01005         len = ( ( le16_to_cpu ( header->qlen ) * 8 ) - header_len );
01006         footer_len = sizeof ( struct vmbus_packet_footer );
01007         ring_len = ( header_len + len + footer_len );
01008         if ( ring_len > vmdev->mtu ) {
01009                 DBGC ( vmdev, "VMBUS %s received overlength packet (%zd "
01010                        "bytes)\n", vmdev->dev.name, ring_len );
01011                 return -ERANGE;
01012         }
01013         xid = le64_to_cpu ( header->xid );
01014 
01015         /* Consume remainder of packet */
01016         cons = vmbus_consume ( vmdev, cons,
01017                                ( ( ( void * ) header ) + sizeof ( *header ) ),
01018                                ( ring_len - sizeof ( *header ) ) );
01019         DBGC2 ( vmdev, "VMBUS %s received:\n", vmdev->dev.name );
01020         DBGC2_HDA ( vmdev, old_cons, header, ring_len );
01021         assert ( ( ( cons - old_cons ) & ( vmdev->in_len - 1 ) ) == ring_len );
01022 
01023         /* Allocate I/O buffers, if applicable */
01024         INIT_LIST_HEAD ( &list );
01025         if ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) ) {
01026                 if ( ( rc = vmbus_xfer_page_iobufs ( vmdev, header,
01027                                                      &list ) ) != 0 )
01028                         return rc;
01029         }
01030 
01031         /* Update producer index */
01032         rmb();
01033         vmdev->in->cons = cpu_to_le32 ( cons );
01034 
01035         /* Handle packet */
01036         data = ( ( ( void * ) header ) + header_len );
01037         switch ( header->type ) {
01038 
01039         case cpu_to_le16 ( VMBUS_DATA_INBAND ) :
01040                 if ( ( rc = vmdev->op->recv_control ( vmdev, xid, data,
01041                                                       len ) ) != 0 ) {
01042                         DBGC ( vmdev, "VMBUS %s could not handle control "
01043                                "packet: %s\n",
01044                                vmdev->dev.name, strerror ( rc ) );
01045                         return rc;
01046                 }
01047                 break;
01048 
01049         case cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) :
01050                 if ( ( rc = vmdev->op->recv_data ( vmdev, xid, data, len,
01051                                                    &list ) ) != 0 ) {
01052                         DBGC ( vmdev, "VMBUS %s could not handle data packet: "
01053                                "%s\n", vmdev->dev.name, strerror ( rc ) );
01054                         return rc;
01055                 }
01056                 break;
01057 
01058         case cpu_to_le16 ( VMBUS_COMPLETION ) :
01059                 if ( ( rc = vmdev->op->recv_completion ( vmdev, xid, data,
01060                                                          len ) ) != 0 ) {
01061                         DBGC ( vmdev, "VMBUS %s could not handle completion: "
01062                                "%s\n", vmdev->dev.name, strerror ( rc ) );
01063                         return rc;
01064                 }
01065                 break;
01066 
01067         case cpu_to_le16 ( VMBUS_CANCELLATION ) :
01068                 if ( ( rc = vmdev->op->recv_cancellation ( vmdev, xid ) ) != 0){
01069                         DBGC ( vmdev, "VMBUS %s could not handle cancellation: "
01070                                "%s\n", vmdev->dev.name, strerror ( rc ) );
01071                         return rc;
01072                 }
01073                 break;
01074 
01075         default:
01076                 DBGC ( vmdev, "VMBUS %s unknown packet type %d\n",
01077                        vmdev->dev.name, le16_to_cpu ( header->type ) );
01078                 return -ENOTSUP;
01079         }
01080 
01081         return 0;
01082 }
01083 
01084 /**
01085  * Dump channel status (for debugging)
01086  *
01087  * @v vmdev             VMBus device
01088  */
01089 void vmbus_dump_channel ( struct vmbus_device *vmdev ) {
01090         size_t out_prod = le32_to_cpu ( vmdev->out->prod );
01091         size_t out_cons = le32_to_cpu ( vmdev->out->cons );
01092         size_t in_prod = le32_to_cpu ( vmdev->in->prod );
01093         size_t in_cons = le32_to_cpu ( vmdev->in->cons );
01094         size_t in_len;
01095         size_t first;
01096         size_t second;
01097 
01098         /* Dump ring status */
01099         DBGC ( vmdev, "VMBUS %s out %03zx:%03zx%s in %03zx:%03zx%s\n",
01100                vmdev->dev.name, out_prod, out_cons,
01101                ( vmdev->out->intr_mask ? "(m)" : "" ), in_prod, in_cons,
01102                ( vmdev->in->intr_mask ? "(m)" : "" ) );
01103 
01104         /* Dump inbound ring contents, if any */
01105         if ( in_prod != in_cons ) {
01106                 in_len = ( ( in_prod - in_cons ) &
01107                            ( vmdev->in_len - 1 ) );
01108                 first = ( vmdev->in_len - in_cons );
01109                 if ( first > in_len )
01110                         first = in_len;
01111                 second = ( in_len - first );
01112                 DBGC_HDA ( vmdev, in_cons, &vmdev->in->data[in_cons], first );
01113                 DBGC_HDA ( vmdev, 0, &vmdev->in->data[0], second );
01114         }
01115 }
01116 
01117 /**
01118  * Find driver for VMBus device
01119  *
01120  * @v vmdev             VMBus device
01121  * @ret driver          Driver, or NULL
01122  */
01123 static struct vmbus_driver * vmbus_find_driver ( const union uuid *type ) {
01124         struct vmbus_driver *vmdrv;
01125 
01126         for_each_table_entry ( vmdrv, VMBUS_DRIVERS ) {
01127                 if ( memcmp ( &vmdrv->type, type, sizeof ( *type ) ) == 0 )
01128                         return vmdrv;
01129         }
01130         return NULL;
01131 }
01132 
01133 /**
01134  * Probe channels
01135  *
01136  * @v hv                Hyper-V hypervisor
01137  * @v parent            Parent device
01138  * @ret rc              Return status code
01139  */
01140 static int vmbus_probe_channels ( struct hv_hypervisor *hv,
01141                                   struct device *parent ) {
01142         struct vmbus *vmbus = hv->vmbus;
01143         const struct vmbus_message_header *header = &vmbus->message->header;
01144         const struct vmbus_offer_channel *offer = &vmbus->message->offer;
01145         const union uuid *type;
01146         union uuid instance;
01147         struct vmbus_driver *driver;
01148         struct vmbus_device *vmdev;
01149         struct vmbus_device *tmp;
01150         unsigned int channel;
01151         int rc;
01152 
01153         /* Post message */
01154         if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_REQUEST_OFFERS ) ) !=0)
01155                 goto err_post_message;
01156 
01157         /* Collect responses */
01158         while ( 1 ) {
01159 
01160                 /* Wait for response */
01161                 if ( ( rc = vmbus_wait_for_any_message ( hv ) ) != 0 )
01162                         goto err_wait_for_any_message;
01163 
01164                 /* Handle response */
01165                 if ( header->type == cpu_to_le32 ( VMBUS_OFFER_CHANNEL ) ) {
01166 
01167                         /* Parse offer */
01168                         type = &offer->type;
01169                         channel = le32_to_cpu ( offer->channel );
01170                         DBGC2 ( vmbus, "VMBUS %p offer %d type %s",
01171                                 vmbus, channel, uuid_ntoa ( type ) );
01172                         if ( offer->monitored )
01173                                 DBGC2 ( vmbus, " monitor %d", offer->monitor );
01174                         DBGC2 ( vmbus, "\n" );
01175 
01176                         /* Look for a driver */
01177                         driver = vmbus_find_driver ( type );
01178                         if ( ! driver ) {
01179                                 DBGC2 ( vmbus, "VMBUS %p has no driver for "
01180                                         "type %s\n", vmbus, uuid_ntoa ( type ));
01181                                 /* Not a fatal error */
01182                                 continue;
01183                         }
01184 
01185                         /* Allocate and initialise device */
01186                         vmdev = zalloc ( sizeof ( *vmdev ) );
01187                         if ( ! vmdev ) {
01188                                 rc = -ENOMEM;
01189                                 goto err_alloc_vmdev;
01190                         }
01191                         memcpy ( &instance, &offer->instance,
01192                                  sizeof ( instance ) );
01193                         uuid_mangle ( &instance );
01194                         snprintf ( vmdev->dev.name, sizeof ( vmdev->dev.name ),
01195                                    "{%s}", uuid_ntoa ( &instance ) );
01196                         vmdev->dev.desc.bus_type = BUS_TYPE_HV;
01197                         INIT_LIST_HEAD ( &vmdev->dev.children );
01198                         list_add_tail ( &vmdev->dev.siblings,
01199                                         &parent->children );
01200                         vmdev->dev.parent = parent;
01201                         vmdev->hv = hv;
01202                         memcpy ( &vmdev->instance, &offer->instance,
01203                                  sizeof ( vmdev->instance ) );
01204                         vmdev->channel = channel;
01205                         vmdev->monitor = offer->monitor;
01206                         vmdev->signal = ( offer->monitored ?
01207                                           vmbus_signal_monitor :
01208                                           vmbus_signal_event );
01209                         INIT_LIST_HEAD ( &vmdev->pages );
01210                         vmdev->driver = driver;
01211                         vmdev->dev.driver_name = driver->name;
01212                         DBGC ( vmdev, "VMBUS %s has driver \"%s\"\n",
01213                                vmdev->dev.name, vmdev->driver->name );
01214 
01215                 } else if ( header->type ==
01216                             cpu_to_le32 ( VMBUS_ALL_OFFERS_DELIVERED ) ) {
01217 
01218                         /* End of offer list */
01219                         break;
01220 
01221                 } else {
01222                         DBGC ( vmbus, "VMBUS %p unexpected offer response type "
01223                                "%d\n", vmbus, le32_to_cpu ( header->type ) );
01224                         rc = -EPROTO;
01225                         goto err_unexpected_offer;
01226                 }
01227         }
01228 
01229         /* Probe all devices.  We do this only after completing
01230          * enumeration since devices will need to send and receive
01231          * VMBus messages.
01232          */
01233         list_for_each_entry ( vmdev, &parent->children, dev.siblings ) {
01234                 if ( ( rc = vmdev->driver->probe ( vmdev ) ) != 0 ) {
01235                         DBGC ( vmdev, "VMBUS %s could not probe: %s\n",
01236                                vmdev->dev.name, strerror ( rc ) );
01237                         goto err_probe;
01238                 }
01239         }
01240 
01241         return 0;
01242 
01243  err_probe:
01244         /* Remove driver from each device that was already probed */
01245         list_for_each_entry_continue_reverse ( vmdev, &parent->children,
01246                                                dev.siblings ) {
01247                 vmdev->driver->remove ( vmdev );
01248         }
01249  err_unexpected_offer:
01250  err_alloc_vmdev:
01251  err_wait_for_any_message:
01252         /* Free any devices allocated (but potentially not yet probed) */
01253         list_for_each_entry_safe ( vmdev, tmp, &parent->children,
01254                                    dev.siblings ) {
01255                 list_del ( &vmdev->dev.siblings );
01256                 free ( vmdev );
01257         }
01258  err_post_message:
01259         return rc;
01260 }
01261 
01262 
01263 /**
01264  * Reset channels
01265  *
01266  * @v hv                Hyper-V hypervisor
01267  * @v parent            Parent device
01268  * @ret rc              Return status code
01269  */
01270 static int vmbus_reset_channels ( struct hv_hypervisor *hv,
01271                                   struct device *parent ) {
01272         struct vmbus *vmbus = hv->vmbus;
01273         const struct vmbus_message_header *header = &vmbus->message->header;
01274         const struct vmbus_offer_channel *offer = &vmbus->message->offer;
01275         const union uuid *type;
01276         struct vmbus_device *vmdev;
01277         unsigned int channel;
01278         int rc;
01279 
01280         /* Post message */
01281         if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_REQUEST_OFFERS ) ) !=0)
01282                 return rc;
01283 
01284         /* Collect responses */
01285         while ( 1 ) {
01286 
01287                 /* Wait for response */
01288                 if ( ( rc = vmbus_wait_for_any_message ( hv ) ) != 0 )
01289                         return rc;
01290 
01291                 /* Handle response */
01292                 if ( header->type == cpu_to_le32 ( VMBUS_OFFER_CHANNEL ) ) {
01293 
01294                         /* Parse offer */
01295                         type = &offer->type;
01296                         channel = le32_to_cpu ( offer->channel );
01297                         DBGC2 ( vmbus, "VMBUS %p offer %d type %s",
01298                                 vmbus, channel, uuid_ntoa ( type ) );
01299                         if ( offer->monitored )
01300                                 DBGC2 ( vmbus, " monitor %d", offer->monitor );
01301                         DBGC2 ( vmbus, "\n" );
01302 
01303                         /* Do nothing with the offer; we already have all
01304                          * of the relevant state from the initial probe.
01305                          */
01306 
01307                 } else if ( header->type ==
01308                             cpu_to_le32 ( VMBUS_ALL_OFFERS_DELIVERED ) ) {
01309 
01310                         /* End of offer list */
01311                         break;
01312 
01313                 } else {
01314                         DBGC ( vmbus, "VMBUS %p unexpected offer response type "
01315                                "%d\n", vmbus, le32_to_cpu ( header->type ) );
01316                         return -EPROTO;
01317                 }
01318         }
01319 
01320         /* Reset all devices */
01321         list_for_each_entry ( vmdev, &parent->children, dev.siblings ) {
01322                 if ( ( rc = vmdev->driver->reset ( vmdev ) ) != 0 ) {
01323                         DBGC ( vmdev, "VMBUS %s could not reset: %s\n",
01324                                vmdev->dev.name, strerror ( rc ) );
01325                         /* Continue attempting to reset other devices */
01326                         continue;
01327                 }
01328         }
01329 
01330         return 0;
01331 }
01332 
01333 /**
01334  * Remove channels
01335  *
01336  * @v hv                Hyper-V hypervisor
01337  * @v parent            Parent device
01338  */
01339 static void vmbus_remove_channels ( struct hv_hypervisor *hv __unused,
01340                                     struct device *parent ) {
01341         struct vmbus_device *vmdev;
01342         struct vmbus_device *tmp;
01343 
01344         /* Remove devices */
01345         list_for_each_entry_safe ( vmdev, tmp, &parent->children,
01346                                    dev.siblings ) {
01347                 vmdev->driver->remove ( vmdev );
01348                 assert ( list_empty ( &vmdev->dev.children ) );
01349                 assert ( vmdev->out == NULL );
01350                 assert ( vmdev->in == NULL );
01351                 assert ( vmdev->packet == NULL );
01352                 assert ( list_empty ( &vmdev->pages ) );
01353                 list_del ( &vmdev->dev.siblings );
01354                 free ( vmdev );
01355         }
01356 }
01357 
01358 /**
01359  * Probe Hyper-V virtual machine bus
01360  *
01361  * @v hv                Hyper-V hypervisor
01362  * @v parent            Parent device
01363  * @ret rc              Return status code
01364  */
01365 int vmbus_probe ( struct hv_hypervisor *hv, struct device *parent ) {
01366         struct vmbus *vmbus;
01367         int rc;
01368 
01369         /* Allocate and initialise structure */
01370         vmbus = zalloc ( sizeof ( *vmbus ) );
01371         if ( ! vmbus ) {
01372                 rc = -ENOMEM;
01373                 goto err_alloc;
01374         }
01375         hv->vmbus = vmbus;
01376 
01377         /* Initialise message buffer pointer
01378          *
01379          * We use a pointer to the fixed-size Hyper-V received message
01380          * buffer.  This allows us to access fields within received
01381          * messages without first checking the message size: any
01382          * fields beyond the end of the message will read as zero.
01383          */
01384         vmbus->message = ( ( void * ) hv->message->received.data );
01385         assert ( sizeof ( *vmbus->message ) <=
01386                  sizeof ( hv->message->received.data ) );
01387 
01388         /* Allocate interrupt and monitor pages */
01389         if ( ( rc = hv_alloc_pages ( hv, &vmbus->intr, &vmbus->monitor_in,
01390                                      &vmbus->monitor_out, NULL ) ) != 0 )
01391                 goto err_alloc_pages;
01392 
01393         /* Enable message interrupt */
01394         hv_enable_sint ( hv, VMBUS_MESSAGE_SINT );
01395 
01396         /* Negotiate protocol version */
01397         if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
01398                 goto err_negotiate_version;
01399 
01400         /* Enumerate channels */
01401         if ( ( rc = vmbus_probe_channels ( hv, parent ) ) != 0 )
01402                 goto err_probe_channels;
01403 
01404         return 0;
01405 
01406         vmbus_remove_channels ( hv, parent );
01407  err_probe_channels:
01408         vmbus_unload ( hv );
01409  err_negotiate_version:
01410         hv_disable_sint ( hv, VMBUS_MESSAGE_SINT );
01411         hv_free_pages ( hv, vmbus->intr, vmbus->monitor_in, vmbus->monitor_out,
01412                         NULL );
01413  err_alloc_pages:
01414         free ( vmbus );
01415  err_alloc:
01416         return rc;
01417 }
01418 
01419 /**
01420  * Reset Hyper-V virtual machine bus
01421  *
01422  * @v hv                Hyper-V hypervisor
01423  * @v parent            Parent device
01424  * @ret rc              Return status code
01425  */
01426 int vmbus_reset ( struct hv_hypervisor *hv, struct device *parent ) {
01427         struct vmbus *vmbus = hv->vmbus;
01428         int rc;
01429 
01430         /* Mark all existent GPADLs as obsolete */
01431         vmbus_obsolete_gpadl = vmbus_gpadl;
01432 
01433         /* Clear interrupt and monitor pages */
01434         memset ( vmbus->intr, 0, PAGE_SIZE );
01435         memset ( vmbus->monitor_in, 0, PAGE_SIZE );
01436         memset ( vmbus->monitor_out, 0, PAGE_SIZE );
01437 
01438         /* Enable message interrupt */
01439         hv_enable_sint ( hv, VMBUS_MESSAGE_SINT );
01440 
01441         /* Renegotiate protocol version */
01442         if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
01443                 return rc;
01444 
01445         /* Reenumerate channels */
01446         if ( ( rc = vmbus_reset_channels ( hv, parent ) ) != 0 )
01447                 return rc;
01448 
01449         return 0;
01450 }
01451 
01452 /**
01453  * Remove Hyper-V virtual machine bus
01454  *
01455  * @v hv                Hyper-V hypervisor
01456  * @v parent            Parent device
01457  */
01458 void vmbus_remove ( struct hv_hypervisor *hv, struct device *parent ) {
01459         struct vmbus *vmbus = hv->vmbus;
01460 
01461         vmbus_remove_channels ( hv, parent );
01462         vmbus_unload ( hv );
01463         hv_disable_sint ( hv, VMBUS_MESSAGE_SINT );
01464         hv_free_pages ( hv, vmbus->intr, vmbus->monitor_in, vmbus->monitor_out,
01465                         NULL );
01466         free ( vmbus );
01467 }