@@ -322,125 +322,89 @@ static int create_gpadl_header(enum hv_gpadl_type type, void *kbuffer,
322322
323323 pagecount = hv_gpadl_size (type , size ) >> HV_HYP_PAGE_SHIFT ;
324324
325- /* do we need a gpadl body msg */
326325 pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
327326 sizeof (struct vmbus_channel_gpadl_header ) -
328327 sizeof (struct gpa_range );
328+ pfncount = umin (pagecount , pfnsize / sizeof (u64 ));
329+
330+ msgsize = sizeof (struct vmbus_channel_msginfo ) +
331+ sizeof (struct vmbus_channel_gpadl_header ) +
332+ sizeof (struct gpa_range ) + pfncount * sizeof (u64 );
333+ msgheader = kzalloc (msgsize , GFP_KERNEL );
334+ if (!msgheader )
335+ return - ENOMEM ;
336+
337+ INIT_LIST_HEAD (& msgheader -> submsglist );
338+ msgheader -> msgsize = msgsize ;
339+
340+ gpadl_header = (struct vmbus_channel_gpadl_header * )
341+ msgheader -> msg ;
342+ gpadl_header -> rangecount = 1 ;
343+ gpadl_header -> range_buflen = sizeof (struct gpa_range ) +
344+ pagecount * sizeof (u64 );
345+ gpadl_header -> range [0 ].byte_offset = 0 ;
346+ gpadl_header -> range [0 ].byte_count = hv_gpadl_size (type , size );
347+ for (i = 0 ; i < pfncount ; i ++ )
348+ gpadl_header -> range [0 ].pfn_array [i ] = hv_gpadl_hvpfn (
349+ type , kbuffer , size , send_offset , i );
350+ * msginfo = msgheader ;
351+
352+ pfnsum = pfncount ;
353+ pfnleft = pagecount - pfncount ;
354+
355+ /* how many pfns can we fit in a body message */
356+ pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
357+ sizeof (struct vmbus_channel_gpadl_body );
329358 pfncount = pfnsize / sizeof (u64 );
330359
331- if (pagecount > pfncount ) {
332- /* we need a gpadl body */
333- /* fill in the header */
360+ /*
361+ * If pfnleft is zero, everything fits in the header and no body
362+ * messages are needed
363+ */
364+ while (pfnleft ) {
365+ pfncurr = umin (pfncount , pfnleft );
334366 msgsize = sizeof (struct vmbus_channel_msginfo ) +
335- sizeof (struct vmbus_channel_gpadl_header ) +
336- sizeof (struct gpa_range ) + pfncount * sizeof (u64 );
337- msgheader = kzalloc (msgsize , GFP_KERNEL );
338- if (!msgheader )
339- goto nomem ;
340-
341- INIT_LIST_HEAD (& msgheader -> submsglist );
342- msgheader -> msgsize = msgsize ;
343-
344- gpadl_header = (struct vmbus_channel_gpadl_header * )
345- msgheader -> msg ;
346- gpadl_header -> rangecount = 1 ;
347- gpadl_header -> range_buflen = sizeof (struct gpa_range ) +
348- pagecount * sizeof (u64 );
349- gpadl_header -> range [0 ].byte_offset = 0 ;
350- gpadl_header -> range [0 ].byte_count = hv_gpadl_size (type , size );
351- for (i = 0 ; i < pfncount ; i ++ )
352- gpadl_header -> range [0 ].pfn_array [i ] = hv_gpadl_hvpfn (
353- type , kbuffer , size , send_offset , i );
354- * msginfo = msgheader ;
355-
356- pfnsum = pfncount ;
357- pfnleft = pagecount - pfncount ;
358-
359- /* how many pfns can we fit */
360- pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
361- sizeof (struct vmbus_channel_gpadl_body );
362- pfncount = pfnsize / sizeof (u64 );
363-
364- /* fill in the body */
365- while (pfnleft ) {
366- if (pfnleft > pfncount )
367- pfncurr = pfncount ;
368- else
369- pfncurr = pfnleft ;
370-
371- msgsize = sizeof (struct vmbus_channel_msginfo ) +
372- sizeof (struct vmbus_channel_gpadl_body ) +
373- pfncurr * sizeof (u64 );
374- msgbody = kzalloc (msgsize , GFP_KERNEL );
375-
376- if (!msgbody ) {
377- struct vmbus_channel_msginfo * pos = NULL ;
378- struct vmbus_channel_msginfo * tmp = NULL ;
379- /*
380- * Free up all the allocated messages.
381- */
382- list_for_each_entry_safe (pos , tmp ,
383- & msgheader -> submsglist ,
384- msglistentry ) {
385-
386- list_del (& pos -> msglistentry );
387- kfree (pos );
388- }
389-
390- goto nomem ;
391- }
392-
393- msgbody -> msgsize = msgsize ;
394- gpadl_body =
395- (struct vmbus_channel_gpadl_body * )msgbody -> msg ;
367+ sizeof (struct vmbus_channel_gpadl_body ) +
368+ pfncurr * sizeof (u64 );
369+ msgbody = kzalloc (msgsize , GFP_KERNEL );
396370
371+ if (!msgbody ) {
372+ struct vmbus_channel_msginfo * pos = NULL ;
373+ struct vmbus_channel_msginfo * tmp = NULL ;
397374 /*
398- * Gpadl is u32 and we are using a pointer which could
399- * be 64-bit
400- * This is governed by the guest/host protocol and
401- * so the hypervisor guarantees that this is ok.
375+ * Free up all the allocated messages.
402376 */
403- for ( i = 0 ; i < pfncurr ; i ++ )
404- gpadl_body -> pfn [ i ] = hv_gpadl_hvpfn ( type ,
405- kbuffer , size , send_offset , pfnsum + i );
406-
407- /* add to msg header */
408- list_add_tail ( & msgbody -> msglistentry ,
409- & msgheader -> submsglist );
410- pfnsum += pfncurr ;
411- pfnleft -= pfncurr ;
377+ list_for_each_entry_safe ( pos , tmp ,
378+ & msgheader -> submsglist ,
379+ msglistentry ) {
380+
381+ list_del ( & pos -> msglistentry );
382+ kfree ( pos );
383+ }
384+ kfree ( msgheader ) ;
385+ return - ENOMEM ;
412386 }
413- } else {
414- /* everything fits in a header */
415- msgsize = sizeof (struct vmbus_channel_msginfo ) +
416- sizeof (struct vmbus_channel_gpadl_header ) +
417- sizeof (struct gpa_range ) + pagecount * sizeof (u64 );
418- msgheader = kzalloc (msgsize , GFP_KERNEL );
419- if (msgheader == NULL )
420- goto nomem ;
421-
422- INIT_LIST_HEAD (& msgheader -> submsglist );
423- msgheader -> msgsize = msgsize ;
424-
425- gpadl_header = (struct vmbus_channel_gpadl_header * )
426- msgheader -> msg ;
427- gpadl_header -> rangecount = 1 ;
428- gpadl_header -> range_buflen = sizeof (struct gpa_range ) +
429- pagecount * sizeof (u64 );
430- gpadl_header -> range [0 ].byte_offset = 0 ;
431- gpadl_header -> range [0 ].byte_count = hv_gpadl_size (type , size );
432- for (i = 0 ; i < pagecount ; i ++ )
433- gpadl_header -> range [0 ].pfn_array [i ] = hv_gpadl_hvpfn (
434- type , kbuffer , size , send_offset , i );
435-
436- * msginfo = msgheader ;
387+
388+ msgbody -> msgsize = msgsize ;
389+ gpadl_body = (struct vmbus_channel_gpadl_body * )msgbody -> msg ;
390+
391+ /*
392+ * Gpadl is u32 and we are using a pointer which could
393+ * be 64-bit
394+ * This is governed by the guest/host protocol and
395+ * so the hypervisor guarantees that this is ok.
396+ */
397+ for (i = 0 ; i < pfncurr ; i ++ )
398+ gpadl_body -> pfn [i ] = hv_gpadl_hvpfn (type ,
399+ kbuffer , size , send_offset , pfnsum + i );
400+
401+ /* add to msg header */
402+ list_add_tail (& msgbody -> msglistentry , & msgheader -> submsglist );
403+ pfnsum += pfncurr ;
404+ pfnleft -= pfncurr ;
437405 }
438406
439407 return 0 ;
440- nomem :
441- kfree (msgheader );
442- kfree (msgbody );
443- return - ENOMEM ;
444408}
445409
446410/*
0 commit comments