You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

vmbus.c 35KB

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