Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

vmbus.c 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329
  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. FILE_LICENCE ( GPL2_OR_LATER );
  20. /** @file
  21. *
  22. * Hyper-V virtual machine bus
  23. *
  24. */
  25. #include <stdint.h>
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include <assert.h>
  31. #include <byteswap.h>
  32. #include <ipxe/nap.h>
  33. #include <ipxe/malloc.h>
  34. #include <ipxe/iobuf.h>
  35. #include <ipxe/hyperv.h>
  36. #include <ipxe/vmbus.h>
  37. /** VMBus initial GPADL ID
  38. *
  39. * This is an opaque value with no meaning. The Linux kernel uses
  40. * 0xe1e10.
  41. */
  42. #define VMBUS_GPADL_MAGIC 0x18ae0000
  43. /**
  44. * Post message
  45. *
  46. * @v hv Hyper-V hypervisor
  47. * @v header Message header
  48. * @v len Length of message (including header)
  49. * @ret rc Return status code
  50. */
  51. static int vmbus_post_message ( struct hv_hypervisor *hv,
  52. const struct vmbus_message_header *header,
  53. size_t len ) {
  54. struct vmbus *vmbus = hv->vmbus;
  55. int rc;
  56. /* Post message */
  57. if ( ( rc = hv_post_message ( hv, VMBUS_MESSAGE_ID, VMBUS_MESSAGE_TYPE,
  58. header, len ) ) != 0 ) {
  59. DBGC ( vmbus, "VMBUS %p could not post message: %s\n",
  60. vmbus, strerror ( rc ) );
  61. return rc;
  62. }
  63. return 0;
  64. }
  65. /**
  66. * Post empty message
  67. *
  68. * @v hv Hyper-V hypervisor
  69. * @v type Message type
  70. * @ret rc Return status code
  71. */
  72. static int vmbus_post_empty_message ( struct hv_hypervisor *hv,
  73. unsigned int type ) {
  74. struct vmbus_message_header header = { .type = cpu_to_le32 ( type ) };
  75. return vmbus_post_message ( hv, &header, sizeof ( header ) );
  76. }
  77. /**
  78. * Wait for received message
  79. *
  80. * @v hv Hyper-V hypervisor
  81. * @ret rc Return status code
  82. */
  83. static int vmbus_wait_for_message ( struct hv_hypervisor *hv ) {
  84. struct vmbus *vmbus = hv->vmbus;
  85. int rc;
  86. /* Wait for message */
  87. if ( ( rc = hv_wait_for_message ( hv, VMBUS_MESSAGE_SINT ) ) != 0 ) {
  88. DBGC ( vmbus, "VMBUS %p failed waiting for message: %s\n",
  89. vmbus, strerror ( rc ) );
  90. return rc;
  91. }
  92. /* Sanity check */
  93. if ( hv->message->received.type != cpu_to_le32 ( VMBUS_MESSAGE_TYPE ) ){
  94. DBGC ( vmbus, "VMBUS %p invalid message type %d\n",
  95. vmbus, le32_to_cpu ( hv->message->received.type ) );
  96. return -EINVAL;
  97. }
  98. return 0;
  99. }
  100. /**
  101. * Initiate contact
  102. *
  103. * @v hv Hyper-V hypervisor
  104. * @v raw VMBus protocol (raw) version
  105. * @ret rc Return status code
  106. */
  107. static int vmbus_initiate_contact ( struct hv_hypervisor *hv,
  108. unsigned int raw ) {
  109. struct vmbus *vmbus = hv->vmbus;
  110. const struct vmbus_version_response *version = &vmbus->message->version;
  111. struct vmbus_initiate_contact initiate;
  112. int rc;
  113. /* Construct message */
  114. memset ( &initiate, 0, sizeof ( initiate ) );
  115. initiate.header.type = cpu_to_le32 ( VMBUS_INITIATE_CONTACT );
  116. initiate.version.raw = cpu_to_le32 ( raw );
  117. initiate.intr = virt_to_phys ( vmbus->intr );
  118. initiate.monitor_in = virt_to_phys ( vmbus->monitor_in );
  119. initiate.monitor_out = virt_to_phys ( vmbus->monitor_out );
  120. /* Post message */
  121. if ( ( rc = vmbus_post_message ( hv, &initiate.header,
  122. sizeof ( initiate ) ) ) != 0 )
  123. return rc;
  124. /* Wait for response */
  125. if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
  126. return rc;
  127. /* Check response */
  128. if ( version->header.type != cpu_to_le32 ( VMBUS_VERSION_RESPONSE ) ) {
  129. DBGC ( vmbus, "VMBUS %p unexpected version response type %d\n",
  130. vmbus, le32_to_cpu ( version->header.type ) );
  131. return -EPROTO;
  132. }
  133. if ( ! version->supported ) {
  134. DBGC ( vmbus, "VMBUS %p requested version not supported\n",
  135. vmbus );
  136. return -ENOTSUP;
  137. }
  138. if ( version->version.raw != cpu_to_le32 ( raw ) ) {
  139. DBGC ( vmbus, "VMBUS %p unexpected version %d.%d\n",
  140. vmbus, le16_to_cpu ( version->version.major ),
  141. le16_to_cpu ( version->version.minor ) );
  142. return -EPROTO;
  143. }
  144. DBGC ( vmbus, "VMBUS %p initiated contact using version %d.%d\n",
  145. vmbus, le16_to_cpu ( version->version.major ),
  146. le16_to_cpu ( version->version.minor ) );
  147. return 0;
  148. }
  149. /**
  150. * Terminate contact
  151. *
  152. * @v hv Hyper-V hypervisor
  153. * @ret rc Return status code
  154. */
  155. static int vmbus_unload ( struct hv_hypervisor *hv ) {
  156. struct vmbus *vmbus = hv->vmbus;
  157. const struct vmbus_message_header *header = &vmbus->message->header;
  158. int rc;
  159. /* Post message */
  160. if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_UNLOAD ) ) != 0 )
  161. return rc;
  162. /* Wait for response */
  163. if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
  164. return rc;
  165. /* Check response */
  166. if ( header->type != cpu_to_le32 ( VMBUS_UNLOAD_RESPONSE ) ) {
  167. DBGC ( vmbus, "VMBUS %p unexpected unload response type %d\n",
  168. vmbus, le32_to_cpu ( header->type ) );
  169. return -EPROTO;
  170. }
  171. return 0;
  172. }
  173. /**
  174. * Negotiate protocol version
  175. *
  176. * @v hv Hyper-V hypervisor
  177. * @ret rc Return status code
  178. */
  179. static int vmbus_negotiate_version ( struct hv_hypervisor *hv ) {
  180. int rc;
  181. /* We require the ability to disconnect from and reconnect to
  182. * VMBus; if we don't have this then there is no (viable) way
  183. * for a loaded operating system to continue to use any VMBus
  184. * devices. (There is also a small but non-zero risk that the
  185. * host will continue to write to our interrupt and monitor
  186. * pages, since the VMBUS_UNLOAD message in earlier versions
  187. * is essentially a no-op.)
  188. *
  189. * This requires us to ensure that the host supports protocol
  190. * version 3.0 (VMBUS_VERSION_WIN8_1). However, we can't
  191. * actually _use_ protocol version 3.0, since doing so causes
  192. * an iSCSI-booted Windows Server 2012 R2 VM to crash due to a
  193. * NULL pointer dereference in vmbus.sys.
  194. *
  195. * To work around this problem, we first ensure that we can
  196. * connect using protocol v3.0, then disconnect and reconnect
  197. * using the oldest known protocol.
  198. */
  199. /* Initiate contact to check for required protocol support */
  200. if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WIN8_1 ) ) != 0 )
  201. return rc;
  202. /* Terminate contact */
  203. if ( ( rc = vmbus_unload ( hv ) ) != 0 )
  204. return rc;
  205. /* Reinitiate contact using the oldest known protocol version */
  206. if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WS2008 ) ) != 0 )
  207. return rc;
  208. return 0;
  209. }
  210. /**
  211. * Establish GPA descriptor list
  212. *
  213. * @v vmdev VMBus device
  214. * @v data Data buffer
  215. * @v len Length of data buffer
  216. * @ret gpadl GPADL ID, or negative error
  217. */
  218. int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
  219. size_t len ) {
  220. struct hv_hypervisor *hv = vmdev->hv;
  221. struct vmbus *vmbus = hv->vmbus;
  222. physaddr_t addr = user_to_phys ( data, 0 );
  223. unsigned int pfn_count = hv_pfn_count ( addr, len );
  224. struct {
  225. struct vmbus_gpadl_header gpadlhdr;
  226. struct vmbus_gpa_range range;
  227. uint64_t pfn[pfn_count];
  228. } __attribute__ (( packed )) gpadlhdr;
  229. const struct vmbus_gpadl_created *created = &vmbus->message->created;
  230. static unsigned int gpadl = VMBUS_GPADL_MAGIC;
  231. unsigned int i;
  232. int rc;
  233. /* Allocate GPADL ID */
  234. gpadl++;
  235. /* Construct message */
  236. memset ( &gpadlhdr, 0, sizeof ( gpadlhdr ) );
  237. gpadlhdr.gpadlhdr.header.type = cpu_to_le32 ( VMBUS_GPADL_HEADER );
  238. gpadlhdr.gpadlhdr.channel = cpu_to_le32 ( vmdev->channel );
  239. gpadlhdr.gpadlhdr.gpadl = cpu_to_le32 ( gpadl );
  240. gpadlhdr.gpadlhdr.range_len =
  241. cpu_to_le16 ( ( sizeof ( gpadlhdr.range ) +
  242. sizeof ( gpadlhdr.pfn ) ) );
  243. gpadlhdr.gpadlhdr.range_count = cpu_to_le16 ( 1 );
  244. gpadlhdr.range.len = cpu_to_le32 ( len );
  245. gpadlhdr.range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
  246. for ( i = 0 ; i < pfn_count ; i++ )
  247. gpadlhdr.pfn[i] = ( ( addr / PAGE_SIZE ) + i );
  248. /* Post message */
  249. if ( ( rc = vmbus_post_message ( hv, &gpadlhdr.gpadlhdr.header,
  250. sizeof ( gpadlhdr ) ) ) != 0 )
  251. return rc;
  252. /* Wait for response */
  253. if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
  254. return rc;
  255. /* Check response */
  256. if ( created->header.type != cpu_to_le32 ( VMBUS_GPADL_CREATED ) ) {
  257. DBGC ( vmdev, "VMBUS %s unexpected GPADL response type %d\n",
  258. vmdev->dev.name, le32_to_cpu ( created->header.type ) );
  259. return -EPROTO;
  260. }
  261. if ( created->channel != cpu_to_le32 ( vmdev->channel ) ) {
  262. DBGC ( vmdev, "VMBUS %s unexpected GPADL channel %d\n",
  263. vmdev->dev.name, le32_to_cpu ( created->channel ) );
  264. return -EPROTO;
  265. }
  266. if ( created->gpadl != cpu_to_le32 ( gpadl ) ) {
  267. DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
  268. vmdev->dev.name, le32_to_cpu ( created->gpadl ) );
  269. return -EPROTO;
  270. }
  271. if ( created->status != 0 ) {
  272. DBGC ( vmdev, "VMBUS %s GPADL creation failed: %#08x\n",
  273. vmdev->dev.name, le32_to_cpu ( created->status ) );
  274. return -EPROTO;
  275. }
  276. DBGC ( vmdev, "VMBUS %s GPADL %#08x is [%08lx,%08lx)\n",
  277. vmdev->dev.name, gpadl, addr, ( addr + len ) );
  278. return gpadl;
  279. }
  280. /**
  281. * Tear down GPA descriptor list
  282. *
  283. * @v vmdev VMBus device
  284. * @v gpadl GPADL ID
  285. * @ret rc Return status code
  286. */
  287. int vmbus_gpadl_teardown ( struct vmbus_device *vmdev, unsigned int gpadl ) {
  288. struct hv_hypervisor *hv = vmdev->hv;
  289. struct vmbus *vmbus = hv->vmbus;
  290. struct vmbus_gpadl_teardown teardown;
  291. const struct vmbus_gpadl_torndown *torndown = &vmbus->message->torndown;
  292. int rc;
  293. /* Construct message */
  294. memset ( &teardown, 0, sizeof ( teardown ) );
  295. teardown.header.type = cpu_to_le32 ( VMBUS_GPADL_TEARDOWN );
  296. teardown.channel = cpu_to_le32 ( vmdev->channel );
  297. teardown.gpadl = cpu_to_le32 ( gpadl );
  298. /* Post message */
  299. if ( ( rc = vmbus_post_message ( hv, &teardown.header,
  300. sizeof ( teardown ) ) ) != 0 )
  301. return rc;
  302. /* Wait for response */
  303. if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
  304. return rc;
  305. /* Check response */
  306. if ( torndown->header.type != cpu_to_le32 ( VMBUS_GPADL_TORNDOWN ) ) {
  307. DBGC ( vmdev, "VMBUS %s unexpected GPADL response type %d\n",
  308. vmdev->dev.name, le32_to_cpu ( torndown->header.type ) );
  309. return -EPROTO;
  310. }
  311. if ( torndown->gpadl != cpu_to_le32 ( gpadl ) ) {
  312. DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
  313. vmdev->dev.name, le32_to_cpu ( torndown->gpadl ) );
  314. return -EPROTO;
  315. }
  316. return 0;
  317. }
  318. /**
  319. * Open VMBus channel
  320. *
  321. * @v vmdev VMBus device
  322. * @v op Channel operations
  323. * @v out_len Outbound ring buffer length
  324. * @v in_len Inbound ring buffer length
  325. * @v mtu Maximum expected data packet length (including headers)
  326. * @ret rc Return status code
  327. *
  328. * Both outbound and inbound ring buffer lengths must be a power of
  329. * two and a multiple of PAGE_SIZE. The requirement to be a power of
  330. * two is a policy decision taken to simplify the ring buffer indexing
  331. * logic.
  332. */
  333. int vmbus_open ( struct vmbus_device *vmdev,
  334. struct vmbus_channel_operations *op,
  335. size_t out_len, size_t in_len, size_t mtu ) {
  336. struct hv_hypervisor *hv = vmdev->hv;
  337. struct vmbus *vmbus = hv->vmbus;
  338. struct vmbus_open_channel open;
  339. const struct vmbus_open_channel_result *opened =
  340. &vmbus->message->opened;
  341. size_t len;
  342. void *ring;
  343. void *packet;
  344. int gpadl;
  345. uint32_t open_id;
  346. int rc;
  347. /* Sanity checks */
  348. assert ( ( out_len % PAGE_SIZE ) == 0 );
  349. assert ( ( out_len & ( out_len - 1 ) ) == 0 );
  350. assert ( ( in_len % PAGE_SIZE ) == 0 );
  351. assert ( ( in_len & ( in_len - 1 ) ) == 0 );
  352. assert ( mtu >= ( sizeof ( struct vmbus_packet_header ) +
  353. sizeof ( struct vmbus_packet_footer ) ) );
  354. /* Allocate packet buffer */
  355. packet = malloc ( mtu );
  356. if ( ! packet ) {
  357. rc = -ENOMEM;
  358. goto err_alloc_packet;
  359. }
  360. /* Allocate ring buffer */
  361. len = ( sizeof ( *vmdev->out ) + out_len +
  362. sizeof ( *vmdev->in ) + in_len );
  363. assert ( ( len % PAGE_SIZE ) == 0 );
  364. ring = malloc_dma ( len, PAGE_SIZE );
  365. if ( ! ring ) {
  366. rc = -ENOMEM;
  367. goto err_alloc_ring;
  368. }
  369. memset ( ring, 0, len );
  370. /* Establish GPADL for ring buffer */
  371. gpadl = vmbus_establish_gpadl ( vmdev, virt_to_user ( ring ), len );
  372. if ( gpadl < 0 ) {
  373. rc = gpadl;
  374. goto err_establish;
  375. }
  376. /* Construct message */
  377. memset ( &open, 0, sizeof ( open ) );
  378. open.header.type = cpu_to_le32 ( VMBUS_OPEN_CHANNEL );
  379. open.channel = cpu_to_le32 ( vmdev->channel );
  380. open_id = random();
  381. open.id = open_id; /* Opaque random value: endianness irrelevant */
  382. open.gpadl = cpu_to_le32 ( gpadl );
  383. open.out_pages = ( ( sizeof ( *vmdev->out ) / PAGE_SIZE ) +
  384. ( out_len / PAGE_SIZE ) );
  385. /* Post message */
  386. if ( ( rc = vmbus_post_message ( hv, &open.header,
  387. sizeof ( open ) ) ) != 0 )
  388. return rc;
  389. /* Wait for response */
  390. if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
  391. return rc;
  392. /* Check response */
  393. if ( opened->header.type != cpu_to_le32 ( VMBUS_OPEN_CHANNEL_RESULT ) ){
  394. DBGC ( vmdev, "VMBUS %s unexpected open response type %d\n",
  395. vmdev->dev.name, le32_to_cpu ( opened->header.type ) );
  396. return -EPROTO;
  397. }
  398. if ( opened->channel != cpu_to_le32 ( vmdev->channel ) ) {
  399. DBGC ( vmdev, "VMBUS %s unexpected opened channel %#08x\n",
  400. vmdev->dev.name, le32_to_cpu ( opened->channel ) );
  401. return -EPROTO;
  402. }
  403. if ( opened->id != open_id /* Non-endian */ ) {
  404. DBGC ( vmdev, "VMBUS %s unexpected open ID %#08x\n",
  405. vmdev->dev.name, le32_to_cpu ( opened->id ) );
  406. return -EPROTO;
  407. }
  408. if ( opened->status != 0 ) {
  409. DBGC ( vmdev, "VMBUS %s open failed: %#08x\n",
  410. vmdev->dev.name, le32_to_cpu ( opened->status ) );
  411. return -EPROTO;
  412. }
  413. /* Store channel parameters */
  414. vmdev->out_len = out_len;
  415. vmdev->in_len = in_len;
  416. vmdev->out = ring;
  417. vmdev->in = ( ring + sizeof ( *vmdev->out ) + out_len );
  418. vmdev->gpadl = gpadl;
  419. vmdev->op = op;
  420. vmdev->mtu = mtu;
  421. vmdev->packet = packet;
  422. DBGC ( vmdev, "VMBUS %s channel GPADL %#08x ring "
  423. "[%#08lx,%#08lx,%#08lx)\n", vmdev->dev.name, vmdev->gpadl,
  424. virt_to_phys ( vmdev->out ), virt_to_phys ( vmdev->in ),
  425. ( virt_to_phys ( vmdev->out ) + len ) );
  426. return 0;
  427. vmbus_gpadl_teardown ( vmdev, vmdev->gpadl );
  428. err_establish:
  429. free_dma ( ring, len );
  430. err_alloc_ring:
  431. free ( packet );
  432. err_alloc_packet:
  433. return rc;
  434. }
  435. /**
  436. * Close VMBus channel
  437. *
  438. * @v vmdev VMBus device
  439. */
  440. void vmbus_close ( struct vmbus_device *vmdev ) {
  441. struct hv_hypervisor *hv = vmdev->hv;
  442. struct vmbus_close_channel close;
  443. size_t len;
  444. int rc;
  445. /* Construct message */
  446. memset ( &close, 0, sizeof ( close ) );
  447. close.header.type = cpu_to_le32 ( VMBUS_CLOSE_CHANNEL );
  448. close.channel = cpu_to_le32 ( vmdev->channel );
  449. /* Post message */
  450. if ( ( rc = vmbus_post_message ( hv, &close.header,
  451. sizeof ( close ) ) ) != 0 ) {
  452. DBGC ( vmdev, "VMBUS %s failed to close: %s\n",
  453. vmdev->dev.name, strerror ( rc ) );
  454. /* Continue to attempt to tear down GPADL, so that our
  455. * memory is no longer accessible by the remote VM.
  456. */
  457. }
  458. /* Tear down GPADL */
  459. if ( ( rc = vmbus_gpadl_teardown ( vmdev,
  460. vmdev->gpadl ) ) != 0 ) {
  461. DBGC ( vmdev, "VMBUS %s failed to tear down channel GPADL: "
  462. "%s\n", vmdev->dev.name, strerror ( rc ) );
  463. /* We can't prevent the remote VM from continuing to
  464. * access this memory, so leak it.
  465. */
  466. return;
  467. }
  468. /* Free ring buffer */
  469. len = ( sizeof ( *vmdev->out ) + vmdev->out_len +
  470. sizeof ( *vmdev->in ) + vmdev->in_len );
  471. free_dma ( vmdev->out, len );
  472. vmdev->out = NULL;
  473. vmdev->in = NULL;
  474. /* Free packet buffer */
  475. free ( vmdev->packet );
  476. vmdev->packet = NULL;
  477. DBGC ( vmdev, "VMBUS %s closed\n", vmdev->dev.name );
  478. }
  479. /**
  480. * Signal channel via monitor page
  481. *
  482. * @v vmdev VMBus device
  483. */
  484. static void vmbus_signal_monitor ( struct vmbus_device *vmdev ) {
  485. struct hv_hypervisor *hv = vmdev->hv;
  486. struct vmbus *vmbus = hv->vmbus;
  487. struct hv_monitor_trigger *trigger;
  488. unsigned int group;
  489. unsigned int bit;
  490. /* Set bit in monitor trigger group */
  491. group = ( vmdev->monitor / ( 8 * sizeof ( trigger->pending ) ));
  492. bit = ( vmdev->monitor % ( 8 * sizeof ( trigger->pending ) ) );
  493. trigger = &vmbus->monitor_out->trigger[group];
  494. hv_set_bit ( trigger, bit );
  495. }
  496. /**
  497. * Signal channel via hypervisor event
  498. *
  499. * @v vmdev VMBus device
  500. */
  501. static void vmbus_signal_event ( struct vmbus_device *vmdev ) {
  502. struct hv_hypervisor *hv = vmdev->hv;
  503. int rc;
  504. /* Signal hypervisor event */
  505. if ( ( rc = hv_signal_event ( hv, VMBUS_EVENT_ID, 0 ) ) != 0 ) {
  506. DBGC ( vmdev, "VMBUS %s could not signal event: %s\n",
  507. vmdev->dev.name, strerror ( rc ) );
  508. return;
  509. }
  510. }
  511. /**
  512. * Fill outbound ring buffer
  513. *
  514. * @v vmdev VMBus device
  515. * @v prod Producer index
  516. * @v data Data
  517. * @v len Length
  518. * @ret prod New producer index
  519. *
  520. * The caller must ensure that there is sufficient space in the ring
  521. * buffer.
  522. */
  523. static size_t vmbus_produce ( struct vmbus_device *vmdev, size_t prod,
  524. const void *data, size_t len ) {
  525. size_t first;
  526. size_t second;
  527. /* Determine fragment lengths */
  528. first = ( vmdev->out_len - prod );
  529. if ( first > len )
  530. first = len;
  531. second = ( len - first );
  532. /* Copy fragment(s) */
  533. memcpy ( &vmdev->out->data[prod], data, first );
  534. if ( second )
  535. memcpy ( &vmdev->out->data[0], ( data + first ), second );
  536. return ( ( prod + len ) & ( vmdev->out_len - 1 ) );
  537. }
  538. /**
  539. * Consume inbound ring buffer
  540. *
  541. * @v vmdev VMBus device
  542. * @v cons Consumer index
  543. * @v data Data buffer, or NULL
  544. * @v len Length to consume
  545. * @ret cons New consumer index
  546. */
  547. static size_t vmbus_consume ( struct vmbus_device *vmdev, size_t cons,
  548. void *data, size_t len ) {
  549. size_t first;
  550. size_t second;
  551. /* Determine fragment lengths */
  552. first = ( vmdev->in_len - cons );
  553. if ( first > len )
  554. first = len;
  555. second = ( len - first );
  556. /* Copy fragment(s) */
  557. memcpy ( data, &vmdev->in->data[cons], first );
  558. if ( second )
  559. memcpy ( ( data + first ), &vmdev->in->data[0], second );
  560. return ( ( cons + len ) & ( vmdev->in_len - 1 ) );
  561. }
  562. /**
  563. * Send packet via ring buffer
  564. *
  565. * @v vmdev VMBus device
  566. * @v header Packet header
  567. * @v data Data
  568. * @v len Length of data
  569. * @ret rc Return status code
  570. *
  571. * Send a packet via the outbound ring buffer. All fields in the
  572. * packet header must be filled in, with the exception of the total
  573. * packet length.
  574. */
  575. static int vmbus_send ( struct vmbus_device *vmdev,
  576. struct vmbus_packet_header *header,
  577. const void *data, size_t len ) {
  578. struct hv_hypervisor *hv = vmdev->hv;
  579. struct vmbus *vmbus = hv->vmbus;
  580. static uint8_t padding[ 8 - 1 ];
  581. struct vmbus_packet_footer footer;
  582. size_t header_len;
  583. size_t pad_len;
  584. size_t footer_len;
  585. size_t ring_len;
  586. size_t cons;
  587. size_t prod;
  588. size_t old_prod;
  589. size_t fill;
  590. /* Sanity check */
  591. assert ( vmdev->out != NULL );
  592. /* Calculate lengths */
  593. header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
  594. pad_len = ( ( -len ) & ( 8 - 1 ) );
  595. footer_len = sizeof ( footer );
  596. ring_len = ( header_len + len + pad_len + footer_len );
  597. /* Check that we have enough room in the outbound ring buffer */
  598. cons = le32_to_cpu ( vmdev->out->cons );
  599. prod = le32_to_cpu ( vmdev->out->prod );
  600. old_prod = prod;
  601. fill = ( ( prod - cons ) & ( vmdev->out_len - 1 ) );
  602. if ( ( fill + ring_len ) >= vmdev->out_len ) {
  603. DBGC ( vmdev, "VMBUS %s ring buffer full\n", vmdev->dev.name );
  604. return -ENOBUFS;
  605. }
  606. /* Complete header */
  607. header->qlen = cpu_to_le16 ( ( ring_len - footer_len ) / 8 );
  608. /* Construct footer */
  609. footer.reserved = 0;
  610. footer.prod = vmdev->out->prod;
  611. /* Copy packet to buffer */
  612. DBGC2 ( vmdev, "VMBUS %s sending:\n", vmdev->dev.name );
  613. DBGC2_HDA ( vmdev, prod, header, header_len );
  614. prod = vmbus_produce ( vmdev, prod, header, header_len );
  615. DBGC2_HDA ( vmdev, prod, data, len );
  616. prod = vmbus_produce ( vmdev, prod, data, len );
  617. prod = vmbus_produce ( vmdev, prod, padding, pad_len );
  618. DBGC2_HDA ( vmdev, prod, &footer, sizeof ( footer ) );
  619. prod = vmbus_produce ( vmdev, prod, &footer, sizeof ( footer ) );
  620. assert ( ( ( prod - old_prod ) & ( vmdev->out_len - 1 ) ) == ring_len );
  621. /* Update producer index */
  622. wmb();
  623. vmdev->out->prod = cpu_to_le32 ( prod );
  624. /* Return if we do not need to signal the host. This follows
  625. * the logic of hv_need_to_signal() in the Linux driver.
  626. */
  627. mb();
  628. if ( vmdev->out->intr_mask )
  629. return 0;
  630. rmb();
  631. cons = le32_to_cpu ( vmdev->out->cons );
  632. if ( cons != old_prod )
  633. return 0;
  634. /* Set channel bit in interrupt page */
  635. hv_set_bit ( vmbus->intr->out, vmdev->channel );
  636. /* Signal the host */
  637. vmdev->signal ( vmdev );
  638. return 0;
  639. }
  640. /**
  641. * Send control packet via ring buffer
  642. *
  643. * @v vmdev VMBus device
  644. * @v xid Transaction ID (or zero to not request completion)
  645. * @v data Data
  646. * @v len Length of data
  647. * @ret rc Return status code
  648. *
  649. * Send data using a VMBUS_DATA_INBAND packet.
  650. */
  651. int vmbus_send_control ( struct vmbus_device *vmdev, uint64_t xid,
  652. const void *data, size_t len ) {
  653. struct vmbus_packet_header *header = vmdev->packet;
  654. /* Construct header in packet buffer */
  655. assert ( header != NULL );
  656. header->type = cpu_to_le16 ( VMBUS_DATA_INBAND );
  657. header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
  658. header->flags = ( xid ?
  659. cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED ) : 0 );
  660. header->xid = xid; /* Non-endian */
  661. return vmbus_send ( vmdev, header, data, len );
  662. }
  663. /**
  664. * Send data packet via ring buffer
  665. *
  666. * @v vmdev VMBus device
  667. * @v xid Transaction ID
  668. * @v data Data
  669. * @v len Length of data
  670. * @v iobuf I/O buffer
  671. * @ret rc Return status code
  672. *
  673. * Send data using a VMBUS_DATA_GPA_DIRECT packet. The caller is
  674. * responsible for ensuring that the I/O buffer remains untouched
  675. * until the corresponding completion has been received.
  676. */
  677. int vmbus_send_data ( struct vmbus_device *vmdev, uint64_t xid,
  678. const void *data, size_t len, struct io_buffer *iobuf ) {
  679. physaddr_t addr = virt_to_phys ( iobuf->data );
  680. unsigned int pfn_count = hv_pfn_count ( addr, iob_len ( iobuf ) );
  681. struct {
  682. struct vmbus_gpa_direct_header gpa;
  683. struct vmbus_gpa_range range;
  684. uint64_t pfn[pfn_count];
  685. } __attribute__ (( packed )) *header = vmdev->packet;
  686. unsigned int i;
  687. /* Sanity check */
  688. assert ( header != NULL );
  689. assert ( sizeof ( *header ) <= vmdev->mtu );
  690. /* Construct header in packet buffer */
  691. header->gpa.header.type = cpu_to_le16 ( VMBUS_DATA_GPA_DIRECT );
  692. header->gpa.header.hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
  693. header->gpa.header.flags = cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED );
  694. header->gpa.header.xid = xid; /* Non-endian */
  695. header->gpa.range_count = 1;
  696. header->range.len = cpu_to_le32 ( iob_len ( iobuf ) );
  697. header->range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
  698. for ( i = 0 ; i < pfn_count ; i++ )
  699. header->pfn[i] = ( ( addr / PAGE_SIZE ) + i );
  700. return vmbus_send ( vmdev, &header->gpa.header, data, len );
  701. }
  702. /**
  703. * Send completion packet via ring buffer
  704. *
  705. * @v vmdev VMBus device
  706. * @v xid Transaction ID
  707. * @v data Data
  708. * @v len Length of data
  709. * @ret rc Return status code
  710. *
  711. * Send data using a VMBUS_COMPLETION packet.
  712. */
  713. int vmbus_send_completion ( struct vmbus_device *vmdev, uint64_t xid,
  714. const void *data, size_t len ) {
  715. struct vmbus_packet_header *header = vmdev->packet;
  716. /* Construct header in packet buffer */
  717. assert ( header != NULL );
  718. header->type = cpu_to_le16 ( VMBUS_COMPLETION );
  719. header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
  720. header->flags = 0;
  721. header->xid = xid; /* Non-endian */
  722. return vmbus_send ( vmdev, header, data, len );
  723. }
  724. /**
  725. * Send cancellation packet via ring buffer
  726. *
  727. * @v vmdev VMBus device
  728. * @v xid Transaction ID
  729. * @ret rc Return status code
  730. *
  731. * Send data using a VMBUS_CANCELLATION packet.
  732. */
  733. int vmbus_send_cancellation ( struct vmbus_device *vmdev, uint64_t xid ) {
  734. struct vmbus_packet_header *header = vmdev->packet;
  735. /* Construct header in packet buffer */
  736. assert ( header != NULL );
  737. header->type = cpu_to_le16 ( VMBUS_CANCELLATION );
  738. header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
  739. header->flags = 0;
  740. header->xid = xid; /* Non-endian */
  741. return vmbus_send ( vmdev, header, NULL, 0 );
  742. }
  743. /**
  744. * Get transfer page set from pageset ID
  745. *
  746. * @v vmdev VMBus device
  747. * @v pageset Page set ID (in protocol byte order)
  748. * @ret pages Page set, or NULL if not found
  749. */
  750. static struct vmbus_xfer_pages * vmbus_xfer_pages ( struct vmbus_device *vmdev,
  751. uint16_t pageset ) {
  752. struct vmbus_xfer_pages *pages;
  753. /* Locate page set */
  754. list_for_each_entry ( pages, &vmdev->pages, list ) {
  755. if ( pages->pageset == pageset )
  756. return pages;
  757. }
  758. DBGC ( vmdev, "VMBUS %s unrecognised page set ID %#04x\n",
  759. vmdev->dev.name, le16_to_cpu ( pageset ) );
  760. return NULL;
  761. }
  762. /**
  763. * Construct I/O buffer list from transfer pages
  764. *
  765. * @v vmdev VMBus device
  766. * @v header Transfer page header
  767. * @v list I/O buffer list to populate
  768. * @ret rc Return status code
  769. */
  770. static int vmbus_xfer_page_iobufs ( struct vmbus_device *vmdev,
  771. struct vmbus_packet_header *header,
  772. struct list_head *list ) {
  773. struct vmbus_xfer_page_header *page_header =
  774. container_of ( header, struct vmbus_xfer_page_header, header );
  775. struct vmbus_xfer_pages *pages;
  776. struct io_buffer *iobuf;
  777. struct io_buffer *tmp;
  778. size_t len;
  779. size_t offset;
  780. unsigned int range_count;
  781. unsigned int i;
  782. int rc;
  783. /* Sanity check */
  784. assert ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) );
  785. /* Locate page set */
  786. pages = vmbus_xfer_pages ( vmdev, page_header->pageset );
  787. if ( ! pages ) {
  788. rc = -ENOENT;
  789. goto err_pages;
  790. }
  791. /* Allocate and populate I/O buffers */
  792. range_count = le32_to_cpu ( page_header->range_count );
  793. for ( i = 0 ; i < range_count ; i++ ) {
  794. /* Parse header */
  795. len = le32_to_cpu ( page_header->range[i].len );
  796. offset = le32_to_cpu ( page_header->range[i].offset );
  797. /* Allocate I/O buffer */
  798. iobuf = alloc_iob ( len );
  799. if ( ! iobuf ) {
  800. DBGC ( vmdev, "VMBUS %s could not allocate %zd-byte "
  801. "I/O buffer\n", vmdev->dev.name, len );
  802. rc = -ENOMEM;
  803. goto err_alloc;
  804. }
  805. /* Add I/O buffer to list */
  806. list_add ( &iobuf->list, list );
  807. /* Populate I/O buffer */
  808. if ( ( rc = pages->op->copy ( pages, iob_put ( iobuf, len ),
  809. offset, len ) ) != 0 ) {
  810. DBGC ( vmdev, "VMBUS %s could not populate I/O buffer "
  811. "range [%zd,%zd): %s\n",
  812. vmdev->dev.name, offset, len, strerror ( rc ) );
  813. goto err_copy;
  814. }
  815. }
  816. return 0;
  817. err_copy:
  818. err_alloc:
  819. list_for_each_entry_safe ( iobuf, tmp, list, list ) {
  820. list_del ( &iobuf->list );
  821. free_iob ( iobuf );
  822. }
  823. err_pages:
  824. return rc;
  825. }
  826. /**
  827. * Poll ring buffer
  828. *
  829. * @v vmdev VMBus device
  830. * @ret rc Return status code
  831. */
  832. int vmbus_poll ( struct vmbus_device *vmdev ) {
  833. struct vmbus_packet_header *header = vmdev->packet;
  834. struct list_head list;
  835. void *data;
  836. size_t header_len;
  837. size_t len;
  838. size_t footer_len;
  839. size_t ring_len;
  840. size_t cons;
  841. size_t old_cons;
  842. uint64_t xid;
  843. int rc;
  844. /* Sanity checks */
  845. assert ( vmdev->packet != NULL );
  846. assert ( vmdev->in != NULL );
  847. /* Return immediately if buffer is empty */
  848. if ( ! vmbus_has_data ( vmdev ) )
  849. return 0;
  850. cons = le32_to_cpu ( vmdev->in->cons );
  851. old_cons = cons;
  852. /* Consume (start of) header */
  853. cons = vmbus_consume ( vmdev, cons, header, sizeof ( *header ) );
  854. /* Parse and sanity check header */
  855. header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
  856. if ( header_len < sizeof ( *header ) ) {
  857. DBGC ( vmdev, "VMBUS %s received underlength header (%zd "
  858. "bytes)\n", vmdev->dev.name, header_len );
  859. return -EINVAL;
  860. }
  861. len = ( ( le16_to_cpu ( header->qlen ) * 8 ) - header_len );
  862. footer_len = sizeof ( struct vmbus_packet_footer );
  863. ring_len = ( header_len + len + footer_len );
  864. if ( ring_len > vmdev->mtu ) {
  865. DBGC ( vmdev, "VMBUS %s received overlength packet (%zd "
  866. "bytes)\n", vmdev->dev.name, ring_len );
  867. return -ERANGE;
  868. }
  869. xid = le64_to_cpu ( header->xid );
  870. /* Consume remainder of packet */
  871. cons = vmbus_consume ( vmdev, cons,
  872. ( ( ( void * ) header ) + sizeof ( *header ) ),
  873. ( ring_len - sizeof ( *header ) ) );
  874. DBGC2 ( vmdev, "VMBUS %s received:\n", vmdev->dev.name );
  875. DBGC2_HDA ( vmdev, old_cons, header, ring_len );
  876. assert ( ( ( cons - old_cons ) & ( vmdev->in_len - 1 ) ) == ring_len );
  877. /* Allocate I/O buffers, if applicable */
  878. INIT_LIST_HEAD ( &list );
  879. if ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) ) {
  880. if ( ( rc = vmbus_xfer_page_iobufs ( vmdev, header,
  881. &list ) ) != 0 )
  882. return rc;
  883. }
  884. /* Update producer index */
  885. rmb();
  886. vmdev->in->cons = cpu_to_le32 ( cons );
  887. /* Handle packet */
  888. data = ( ( ( void * ) header ) + header_len );
  889. switch ( header->type ) {
  890. case cpu_to_le16 ( VMBUS_DATA_INBAND ) :
  891. if ( ( rc = vmdev->op->recv_control ( vmdev, xid, data,
  892. len ) ) != 0 ) {
  893. DBGC ( vmdev, "VMBUS %s could not handle control "
  894. "packet: %s\n",
  895. vmdev->dev.name, strerror ( rc ) );
  896. return rc;
  897. }
  898. break;
  899. case cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) :
  900. if ( ( rc = vmdev->op->recv_data ( vmdev, xid, data, len,
  901. &list ) ) != 0 ) {
  902. DBGC ( vmdev, "VMBUS %s could not handle data packet: "
  903. "%s\n", vmdev->dev.name, strerror ( rc ) );
  904. return rc;
  905. }
  906. break;
  907. case cpu_to_le16 ( VMBUS_COMPLETION ) :
  908. if ( ( rc = vmdev->op->recv_completion ( vmdev, xid, data,
  909. len ) ) != 0 ) {
  910. DBGC ( vmdev, "VMBUS %s could not handle completion: "
  911. "%s\n", vmdev->dev.name, strerror ( rc ) );
  912. return rc;
  913. }
  914. break;
  915. case cpu_to_le16 ( VMBUS_CANCELLATION ) :
  916. if ( ( rc = vmdev->op->recv_cancellation ( vmdev, xid ) ) != 0){
  917. DBGC ( vmdev, "VMBUS %s could not handle cancellation: "
  918. "%s\n", vmdev->dev.name, strerror ( rc ) );
  919. return rc;
  920. }
  921. break;
  922. default:
  923. DBGC ( vmdev, "VMBUS %s unknown packet type %d\n",
  924. vmdev->dev.name, le16_to_cpu ( header->type ) );
  925. return -ENOTSUP;
  926. }
  927. return 0;
  928. }
  929. /**
  930. * Dump channel status (for debugging)
  931. *
  932. * @v vmdev VMBus device
  933. */
  934. void vmbus_dump_channel ( struct vmbus_device *vmdev ) {
  935. size_t out_prod = le32_to_cpu ( vmdev->out->prod );
  936. size_t out_cons = le32_to_cpu ( vmdev->out->cons );
  937. size_t in_prod = le32_to_cpu ( vmdev->in->prod );
  938. size_t in_cons = le32_to_cpu ( vmdev->in->cons );
  939. size_t in_len;
  940. size_t first;
  941. size_t second;
  942. /* Dump ring status */
  943. DBGC ( vmdev, "VMBUS %s out %03zx:%03zx%s in %03zx:%03zx%s\n",
  944. vmdev->dev.name, out_prod, out_cons,
  945. ( vmdev->out->intr_mask ? "(m)" : "" ), in_prod, in_cons,
  946. ( vmdev->in->intr_mask ? "(m)" : "" ) );
  947. /* Dump inbound ring contents, if any */
  948. if ( in_prod != in_cons ) {
  949. in_len = ( ( in_prod - in_cons ) &
  950. ( vmdev->in_len - 1 ) );
  951. first = ( vmdev->in_len - in_cons );
  952. if ( first > in_len )
  953. first = in_len;
  954. second = ( in_len - first );
  955. DBGC_HDA ( vmdev, in_cons, &vmdev->in->data[in_cons], first );
  956. DBGC_HDA ( vmdev, 0, &vmdev->in->data[0], second );
  957. }
  958. }
  959. /**
  960. * Find driver for VMBus device
  961. *
  962. * @v vmdev VMBus device
  963. * @ret driver Driver, or NULL
  964. */
  965. static struct vmbus_driver * vmbus_find_driver ( const union uuid *type ) {
  966. struct vmbus_driver *vmdrv;
  967. for_each_table_entry ( vmdrv, VMBUS_DRIVERS ) {
  968. if ( memcmp ( &vmdrv->type, type, sizeof ( *type ) ) == 0 )
  969. return vmdrv;
  970. }
  971. return NULL;
  972. }
  973. /**
  974. * Probe channels
  975. *
  976. * @v hv Hyper-V hypervisor
  977. * @v parent Parent device
  978. * @ret rc Return status code
  979. */
  980. static int vmbus_probe_channels ( struct hv_hypervisor *hv,
  981. struct device *parent ) {
  982. struct vmbus *vmbus = hv->vmbus;
  983. const struct vmbus_message_header *header = &vmbus->message->header;
  984. const struct vmbus_offer_channel *offer = &vmbus->message->offer;
  985. const union uuid *type;
  986. struct vmbus_driver *driver;
  987. struct vmbus_device *vmdev;
  988. struct vmbus_device *tmp;
  989. unsigned int channel;
  990. int rc;
  991. /* Post message */
  992. if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_REQUEST_OFFERS ) ) !=0)
  993. goto err_post_message;
  994. /* Collect responses */
  995. while ( 1 ) {
  996. /* Wait for response */
  997. if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
  998. goto err_wait_for_message;
  999. /* Handle response */
  1000. if ( header->type == cpu_to_le32 ( VMBUS_OFFER_CHANNEL ) ) {
  1001. /* Parse offer */
  1002. type = &offer->type;
  1003. channel = le32_to_cpu ( offer->channel );
  1004. DBGC2 ( vmbus, "VMBUS %p offer %d type %s",
  1005. vmbus, channel, uuid_ntoa ( type ) );
  1006. if ( offer->monitored )
  1007. DBGC2 ( vmbus, " monitor %d", offer->monitor );
  1008. DBGC2 ( vmbus, "\n" );
  1009. /* Look for a driver */
  1010. driver = vmbus_find_driver ( type );
  1011. if ( ! driver ) {
  1012. DBGC2 ( vmbus, "VMBUS %p has no driver for "
  1013. "type %s\n", vmbus, uuid_ntoa ( type ));
  1014. /* Not a fatal error */
  1015. continue;
  1016. }
  1017. /* Allocate and initialise device */
  1018. vmdev = zalloc ( sizeof ( *vmdev ) );
  1019. if ( ! vmdev ) {
  1020. rc = -ENOMEM;
  1021. goto err_alloc_vmdev;
  1022. }
  1023. snprintf ( vmdev->dev.name, sizeof ( vmdev->dev.name ),
  1024. "vmbus:%02x", channel );
  1025. vmdev->dev.desc.bus_type = BUS_TYPE_HV;
  1026. INIT_LIST_HEAD ( &vmdev->dev.children );
  1027. list_add_tail ( &vmdev->dev.siblings,
  1028. &parent->children );
  1029. vmdev->dev.parent = parent;
  1030. vmdev->hv = hv;
  1031. vmdev->channel = channel;
  1032. vmdev->monitor = offer->monitor;
  1033. vmdev->signal = ( offer->monitored ?
  1034. vmbus_signal_monitor :
  1035. vmbus_signal_event );
  1036. INIT_LIST_HEAD ( &vmdev->pages );
  1037. vmdev->driver = driver;
  1038. vmdev->dev.driver_name = driver->name;
  1039. DBGC ( vmdev, "VMBUS %s has driver \"%s\"\n",
  1040. vmdev->dev.name, vmdev->driver->name );
  1041. } else if ( header->type ==
  1042. cpu_to_le32 ( VMBUS_ALL_OFFERS_DELIVERED ) ) {
  1043. break;
  1044. } else {
  1045. DBGC ( vmbus, "VMBUS %p unexpected offer response type "
  1046. "%d\n", vmbus, le32_to_cpu ( header->type ) );
  1047. rc = -EPROTO;
  1048. goto err_unexpected_offer;
  1049. }
  1050. }
  1051. /* Probe all devices. We do this only after completing
  1052. * enumeration since devices will need to send and receive
  1053. * VMBus messages.
  1054. */
  1055. list_for_each_entry ( vmdev, &parent->children, dev.siblings ) {
  1056. if ( ( rc = vmdev->driver->probe ( vmdev ) ) != 0 ) {
  1057. DBGC ( vmdev, "VMBUS %s could not probe: %s\n",
  1058. vmdev->dev.name, strerror ( rc ) );
  1059. goto err_probe;
  1060. }
  1061. }
  1062. return 0;
  1063. err_probe:
  1064. /* Remove driver from each device that was already probed */
  1065. list_for_each_entry_continue_reverse ( vmdev, &parent->children,
  1066. dev.siblings ) {
  1067. vmdev->driver->remove ( vmdev );
  1068. }
  1069. err_unexpected_offer:
  1070. err_alloc_vmdev:
  1071. err_wait_for_message:
  1072. /* Free any devices allocated (but potentially not yet probed) */
  1073. list_for_each_entry_safe ( vmdev, tmp, &parent->children,
  1074. dev.siblings ) {
  1075. list_del ( &vmdev->dev.siblings );
  1076. free ( vmdev );
  1077. }
  1078. err_post_message:
  1079. return rc;
  1080. }
  1081. /**
  1082. * Remove channels
  1083. *
  1084. * @v hv Hyper-V hypervisor
  1085. * @v parent Parent device
  1086. */
  1087. static void vmbus_remove_channels ( struct hv_hypervisor *hv __unused,
  1088. struct device *parent ) {
  1089. struct vmbus_device *vmdev;
  1090. struct vmbus_device *tmp;
  1091. /* Remove devices */
  1092. list_for_each_entry_safe ( vmdev, tmp, &parent->children,
  1093. dev.siblings ) {
  1094. vmdev->driver->remove ( vmdev );
  1095. assert ( list_empty ( &vmdev->dev.children ) );
  1096. assert ( vmdev->out == NULL );
  1097. assert ( vmdev->in == NULL );
  1098. assert ( vmdev->packet == NULL );
  1099. assert ( list_empty ( &vmdev->pages ) );
  1100. list_del ( &vmdev->dev.siblings );
  1101. free ( vmdev );
  1102. }
  1103. }
  1104. /**
  1105. * Probe Hyper-V virtual machine bus
  1106. *
  1107. * @v hv Hyper-V hypervisor
  1108. * @v parent Parent device
  1109. * @ret rc Return status code
  1110. */
  1111. int vmbus_probe ( struct hv_hypervisor *hv, struct device *parent ) {
  1112. struct vmbus *vmbus;
  1113. int rc;
  1114. /* Allocate and initialise structure */
  1115. vmbus = zalloc ( sizeof ( *vmbus ) );
  1116. if ( ! vmbus ) {
  1117. rc = -ENOMEM;
  1118. goto err_alloc;
  1119. }
  1120. hv->vmbus = vmbus;
  1121. /* Initialise message buffer pointer
  1122. *
  1123. * We use a pointer to the fixed-size Hyper-V received message
  1124. * buffer. This allows us to access fields within received
  1125. * messages without first checking the message size: any
  1126. * fields beyond the end of the message will read as zero.
  1127. */
  1128. vmbus->message = ( ( void * ) hv->message->received.data );
  1129. assert ( sizeof ( *vmbus->message ) <=
  1130. sizeof ( hv->message->received.data ) );
  1131. /* Allocate interrupt and monitor pages */
  1132. if ( ( rc = hv_alloc_pages ( hv, &vmbus->intr, &vmbus->monitor_in,
  1133. &vmbus->monitor_out, NULL ) ) != 0 )
  1134. goto err_alloc_pages;
  1135. /* Enable message interrupt */
  1136. hv_enable_sint ( hv, VMBUS_MESSAGE_SINT );
  1137. /* Negotiate protocol version */
  1138. if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
  1139. goto err_negotiate_version;
  1140. /* Enumerate channels */
  1141. if ( ( rc = vmbus_probe_channels ( hv, parent ) ) != 0 )
  1142. goto err_probe_channels;
  1143. return 0;
  1144. vmbus_remove_channels ( hv, parent );
  1145. err_probe_channels:
  1146. vmbus_unload ( hv );
  1147. err_negotiate_version:
  1148. hv_disable_sint ( hv, VMBUS_MESSAGE_SINT );
  1149. hv_free_pages ( hv, vmbus->intr, vmbus->monitor_in, vmbus->monitor_out,
  1150. NULL );
  1151. err_alloc_pages:
  1152. free ( vmbus );
  1153. err_alloc:
  1154. return rc;
  1155. }
  1156. /**
  1157. * Remove Hyper-V virtual machine bus
  1158. *
  1159. * @v hv Hyper-V hypervisor
  1160. * @v parent Parent device
  1161. */
  1162. void vmbus_remove ( struct hv_hypervisor *hv, struct device *parent ) {
  1163. struct vmbus *vmbus = hv->vmbus;
  1164. vmbus_remove_channels ( hv, parent );
  1165. vmbus_unload ( hv );
  1166. hv_disable_sint ( hv, VMBUS_MESSAGE_SINT );
  1167. hv_free_pages ( hv, vmbus->intr, vmbus->monitor_in, vmbus->monitor_out,
  1168. NULL );
  1169. free ( vmbus );
  1170. }