~n-muench/ubuntu/maverick/open-vm-tools/open-vm-tools.fix-632101

« back to all changes in this revision

Viewing changes to lib/hgfsServer/hgfsServerPacketUtil.c

  • Committer: Evan Broder
  • Date: 2010-05-29 17:35:25 UTC
  • mfrom: (2.4.16 sid)
  • Revision ID: evan@mingo-20100529173525-u1clyo2h18k7l0kx
Tags: 2010.04.25-253928-2+ubuntu1
* Merge from debian testing, remaining changes:
    - Recommend open-vm-toolbox in open-vm-tools.
* Dropping la files.
* Updating rules for pvscsi removal (Closes: #581160).
* Merging upstream version 2010.04.25-253928.
* Updating packaging for upstreams pvscsi module removal.
* Removing remote_fs from initscript again (Closes: #577163).
* Updating lintian overrides for open-vm-tools.
* Updating date and version in manpage headers.
* Adding manpage for vmxnet3.
* Adding manpage for vmci.
* Fixing spelling typo in vmsync manpage.
* Adding manpage for vmsock.
* Update formating of newly added manpages.
* Adding vmware-toolbox-cmd manpage.
* Adding guestlib manpage.
* Adding libvmtools manpage.
* Renaming guestlib manpage to libguestlib.
* Including vmware-toolbox-cmd manpage in open-vm-tools package.
* Updating initscript start/stop declarations (Closes: #576843,
  #577163).
* Adding misc depends.
* Running open-vm-dkms postinst script with set -e.
* Adding remote_fs to init depends.
* Avoid including license files in open-vm-dkms.
* Marking makefiles in open-vm-dkms executable to please lintian.
* Adding make to open-vm-dkms depends.
* Also stopping in runlevel 1.
* Addding dkms support based on the work of Evan Broder
  <broder@mit.edu> on the ubuntu package (Closes: #516251).
* Simplyfing initramfs triggers (Closes: #516355).
* Merging upstream version 2010.03.20-243334.
* Moving local Makefile to subdirectory.
* Adding build-depends to libfuse-dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*********************************************************
 
2
 * Copyright (C) 2010 VMware, Inc. All rights reserved.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify it
 
5
 * under the terms of the GNU Lesser General Public License as published
 
6
 * by the Free Software Foundation version 2.1 and no later version.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
10
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
 
11
 * License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 
15
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
 
16
 *
 
17
 *********************************************************/
 
18
 
 
19
/*
 
20
 * hgfsServerPacketUtil.c --
 
21
 *
 
22
 * Utility functions for manipulating packet used by hgfs server code
 
23
 */
 
24
#include <stdlib.h>
 
25
#include <stdio.h>
 
26
#include <string.h>
 
27
 
 
28
#include "vmware.h"
 
29
#include "hgfsServer.h"
 
30
#include "hgfsServerInt.h"
 
31
#include "util.h"
 
32
 
 
33
#define LOGLEVEL_MODULE hgfs
 
34
#include "loglevel_user.h"
 
35
 
 
36
 
 
37
/*
 
38
 *-----------------------------------------------------------------------------
 
39
 *
 
40
 * HSPU_GetReplyPacket --
 
41
 *
 
42
 *    Get a reply packet given an hgfs packet.
 
43
 *    Guest mappings may be established.
 
44
 *
 
45
 * Results:
 
46
 *    Pointer to reply packet.
 
47
 *
 
48
 * Side effects:
 
49
 *    Buffer may be allocated.
 
50
 *-----------------------------------------------------------------------------
 
51
 */
 
52
 
 
53
void *
 
54
HSPU_GetReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 
55
                    size_t *replyPacketSize,   // IN/OUT: Size of reply Packet
 
56
                    HgfsSessionInfo *session)  // IN: Session Info
 
57
{
 
58
   ASSERT(session);
 
59
   if (packet->replyPacket) {
 
60
      /*
 
61
       * When we are transferring packets over backdoor, reply packet
 
62
       * is a static buffer. Backdoor should always return from here.
 
63
       */
 
64
      LOG(4, ("Exising reply packet %s %Zu %Zu\n", __FUNCTION__,
 
65
              *replyPacketSize, packet->replyPacketSize));
 
66
      /*
 
67
       * HgfsServer_ProcessPacket does not tell us the real size of packetOut.
 
68
       * It assumes that size of reply packet can never be bigger than size of
 
69
       * the outgoing packet. I changed it to HGFS_LARGE_PACKET_MAX.
 
70
       */
 
71
      ASSERT_DEVEL(*replyPacketSize <= packet->replyPacketSize);
 
72
   } else if (session->channelCbTable && session->channelCbTable->getWriteVa) {
 
73
     /* Can we write directly into guest memory ? */
 
74
      if (packet->metaPacket) {
 
75
         LOG(10, ("%s Using meta packet for reply packet\n", __FUNCTION__));
 
76
         ASSERT_DEVEL(*replyPacketSize <= packet->metaPacketSize);
 
77
         packet->replyPacket = packet->metaPacket;
 
78
         packet->replyPacketSize = packet->metaPacketSize;
 
79
      } else {
 
80
         /* This should really never happen in existing scenarios */
 
81
         ASSERT_DEVEL(0);
 
82
         LOG(10, ("%s Mapping meta packet for reply packet\n", __FUNCTION__));
 
83
         packet->replyPacket = HSPU_GetBuf(packet, 0, &packet->metaPacket,
 
84
                                           packet->metaPacketSize,
 
85
                                           &packet->metaPacketIsAllocated,
 
86
                                           HGFS_BUF_WRITEABLE,
 
87
                                           session);
 
88
         /*
 
89
          * Really this can never happen, we would have caught bad physical address
 
90
          * during getMetaPacket.
 
91
          */
 
92
         ASSERT(packet->replyPacket);
 
93
         packet->replyPacketSize = packet->metaPacketSize;
 
94
      }
 
95
   } else {
 
96
      /* For sockets channel we always need to allocate buffer */
 
97
      LOG(10, ("%s Allocating reply packet\n", __FUNCTION__));
 
98
      packet->replyPacket = Util_SafeMalloc(*replyPacketSize);
 
99
      packet->replyPacketIsAllocated = TRUE;
 
100
      packet->replyPacketSize = *replyPacketSize;
 
101
   }
 
102
 
 
103
   *replyPacketSize = packet->replyPacketSize;
 
104
   return packet->replyPacket;
 
105
}
 
106
 
 
107
 
 
108
/*
 
109
 *-----------------------------------------------------------------------------
 
110
 *
 
111
 * HSPU_PutReplyPacket --
 
112
 *
 
113
 *    Free buffer if reply packet was allocated.
 
114
 *
 
115
 * Results:
 
116
 *    None.
 
117
 *
 
118
 * Side effects:
 
119
 *    None.
 
120
 *-----------------------------------------------------------------------------
 
121
 */
 
122
 
 
123
void
 
124
HSPU_PutReplyPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 
125
                    HgfsSessionInfo *session)  // IN: Session Info
 
126
{
 
127
   if (packet->replyPacketIsAllocated) {
 
128
      LOG(10, ("%s Freeing reply packet", __FUNCTION__));
 
129
      free(packet->replyPacket);
 
130
      packet->replyPacketIsAllocated = FALSE;
 
131
      packet->replyPacket = NULL;
 
132
      packet->replyPacketSize = 0;
 
133
   }
 
134
}
 
135
 
 
136
 
 
137
/*
 
138
 *-----------------------------------------------------------------------------
 
139
 *
 
140
 * HSPU_GetMetaPacket --
 
141
 *
 
142
 *    Get a meta packet given an hgfs packet.
 
143
 *    Guest mappings will be established.
 
144
 *
 
145
 * Results:
 
146
 *    Pointer to meta packet.
 
147
 *
 
148
 * Side effects:
 
149
 *    Buffer may be allocated.
 
150
 *-----------------------------------------------------------------------------
 
151
 */
 
152
 
 
153
void *
 
154
HSPU_GetMetaPacket(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 
155
                   size_t *metaPacketSize,    // OUT: Size of metaPacket
 
156
                   HgfsSessionInfo *session)  // IN: Session Info
 
157
{
 
158
   *metaPacketSize = packet->metaPacketSize;
 
159
   return HSPU_GetBuf(packet, 0, &packet->metaPacket,
 
160
                      packet->metaPacketSize,
 
161
                      &packet->metaPacketIsAllocated,
 
162
                      HGFS_BUF_WRITEABLE, session);
 
163
}
 
164
 
 
165
 
 
166
/*
 
167
 *-----------------------------------------------------------------------------
 
168
 *
 
169
 * HSPU_GetDataPacketIov --
 
170
 *
 
171
 *    Get a data packet in an iov form given an hgfs packet.
 
172
 *    Guest mappings will be established.
 
173
 *
 
174
 * Results:
 
175
 *    Pointer to data packet iov.
 
176
 *
 
177
 * Side effects:
 
178
 *    Buffer may be allocated.
 
179
 *-----------------------------------------------------------------------------
 
180
 */
 
181
 
 
182
void *
 
183
HSPU_GetDataPacketIov(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
 
184
                      HgfsSessionInfo *session, // IN: Session Info
 
185
                      HgfsVaIov iov)            // OUT: I/O vector
 
186
{
 
187
   NOT_IMPLEMENTED();
 
188
   return NULL;
 
189
 
 
190
}
 
191
 
 
192
 
 
193
/*
 
194
 *-----------------------------------------------------------------------------
 
195
 *
 
196
 * HSPU_GetDataPacketBuf --
 
197
 *
 
198
 *    Get a data packet given an hgfs packet.
 
199
 *    Guest mappings will be established.
 
200
 *
 
201
 * Results:
 
202
 *    Pointer to data packet.
 
203
 *
 
204
 * Side effects:
 
205
 *    Buffer may be allocated.
 
206
 *-----------------------------------------------------------------------------
 
207
 */
 
208
 
 
209
void *
 
210
HSPU_GetDataPacketBuf(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
 
211
                      uint32 mappingType,       // IN: Writeable/Readable
 
212
                      HgfsSessionInfo *session) // IN: Session Info
 
213
{
 
214
   packet->dataMappingType = mappingType;
 
215
   return HSPU_GetBuf(packet, packet->dataPacketIovIndex,
 
216
                      &packet->dataPacket, packet->dataPacketSize,
 
217
                      &packet->dataPacketIsAllocated, mappingType, session);
 
218
}
 
219
 
 
220
 
 
221
/*
 
222
 *-----------------------------------------------------------------------------
 
223
 *
 
224
 * HSPU_GetBuf --
 
225
 *
 
226
 *    Get a {meta, data} packet given an hgfs packet.
 
227
 *    Guest mappings will be established.
 
228
 *
 
229
 * Results:
 
230
 *    Pointer to buffer.
 
231
 *
 
232
 * Side effects:
 
233
 *    Buffer may be allocated.
 
234
 *-----------------------------------------------------------------------------
 
235
 */
 
236
 
 
237
void *
 
238
HSPU_GetBuf(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
 
239
            uint32 startIndex,            // IN: start index of iov
 
240
            void **buf,                   // OUT: Contigous buffer
 
241
            size_t  bufSize,              // IN: Size of buffer
 
242
            Bool *isAllocated,            // OUT: Was buffer allocated ?
 
243
            uint32 mappingType,           // IN: Readable/Writeable ?
 
244
            HgfsSessionInfo *session)     // IN: Session Info
 
245
{
 
246
   uint32 iovCount;
 
247
   uint32 iovMapped = 0;
 
248
   int32 size = bufSize;
 
249
   int i;
 
250
   void* (*func)(uint64, uint32, char **);
 
251
   ASSERT(buf);
 
252
 
 
253
   if (*buf) {
 
254
      return *buf;
 
255
   } else if (bufSize == 0) {
 
256
      return NULL;
 
257
   }
 
258
 
 
259
   ASSERT_DEVEL(session->channelCbTable);
 
260
   if (!session->channelCbTable) {
 
261
      return NULL;
 
262
   }
 
263
 
 
264
   if (mappingType == HGFS_BUF_WRITEABLE) {
 
265
      func = session->channelCbTable->getWriteVa;
 
266
   } else {
 
267
      ASSERT(mappingType == HGFS_BUF_READABLE);
 
268
      func = session->channelCbTable->getReadVa;
 
269
   }
 
270
 
 
271
   ASSERT_DEVEL(func);
 
272
   if (func == NULL) {
 
273
      return NULL;
 
274
   }
 
275
 
 
276
   /* Establish guest memory mappings */
 
277
   for (iovCount = startIndex; iovCount < packet->iovCount && size > 0;
 
278
        iovCount++) {
 
279
 
 
280
      packet->iov[iovCount].token = NULL;
 
281
 
 
282
      /* Debugging check: Iov in VMCI should never cross page boundary */
 
283
      ASSERT_DEVEL(packet->iov[iovCount].len <=
 
284
      (4096 - (packet->iov[iovCount].pa & 0xfff)));
 
285
 
 
286
      packet->iov[iovCount].va = func(packet->iov[iovCount].pa,
 
287
                                      packet->iov[iovCount].len,
 
288
                                      &packet->iov[iovCount].token);
 
289
      ASSERT_DEVEL(packet->iov[iovCount].va);
 
290
      if (packet->iov[iovCount].va == NULL) {
 
291
         /* Guest probably passed us bad physical address */
 
292
         *buf = NULL;
 
293
         goto freeMem;
 
294
      }
 
295
      iovMapped++;
 
296
      size -= packet->iov[iovCount].len;
 
297
   }
 
298
 
 
299
   if (iovMapped > 1) {
 
300
      /* Seems like more than one page was requested. */
 
301
      uint32 copiedAmount = 0;
 
302
      uint32 copyAmount;
 
303
      int32 remainingSize;
 
304
      int i;
 
305
      ASSERT_DEVEL(packet->iov[startIndex].len < bufSize);
 
306
      *buf = Util_SafeMalloc(bufSize);
 
307
      *isAllocated = TRUE;
 
308
 
 
309
      LOG(10, ("%s: Hgfs Allocating buffer \n", __FUNCTION__));
 
310
 
 
311
      /*
 
312
       * Since we are allocating seperate buffer, it does not make sense
 
313
       * to continue to hold on to mappings. Let's release it, we will
 
314
       * reacquire mappings when we need in HSPU_CopyBufToIovec.
 
315
       */
 
316
      remainingSize = bufSize;
 
317
      for (i = startIndex; i < packet->iovCount && remainingSize > 0; i++) {
 
318
         copyAmount = remainingSize < packet->iov[i].len ?
 
319
                      remainingSize : packet->iov[i].len;
 
320
         memcpy((char *)*buf + copiedAmount, packet->iov[i].va, copyAmount);
 
321
         copiedAmount += copyAmount;
 
322
         remainingSize -= copyAmount;
 
323
      }
 
324
      ASSERT_DEVEL(copiedAmount == bufSize);
 
325
   } else {
 
326
      /* We will continue to hold on to guest mappings */
 
327
      *buf = packet->iov[startIndex].va;
 
328
      return *buf;
 
329
   }
 
330
 
 
331
freeMem:
 
332
   for (i = 0; i < iovCount; i++) {
 
333
      session->channelCbTable->putVa(&packet->iov[i].token);
 
334
      packet->iov[i].va = NULL;
 
335
   }
 
336
 
 
337
   return *buf;
 
338
}
 
339
 
 
340
 
 
341
/*
 
342
 *-----------------------------------------------------------------------------
 
343
 *
 
344
 * HSPU_PutMetaPacket --
 
345
 *
 
346
 *    Free meta packet buffer if allocated.
 
347
 *    Guest mappings will be released.
 
348
 *
 
349
 * Results:
 
350
 *    void.
 
351
 *
 
352
 * Side effects:
 
353
 *
 
354
 *-----------------------------------------------------------------------------
 
355
 */
 
356
 
 
357
void
 
358
HSPU_PutMetaPacket(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
 
359
                   HgfsSessionInfo *session) // IN: Session Info
 
360
{
 
361
   LOG(4, ("%s Hgfs Putting Meta packet\n", __FUNCTION__));
 
362
   HSPU_PutBuf(packet, 0, &packet->metaPacket,
 
363
               &packet->metaPacketSize,
 
364
               &packet->metaPacketIsAllocated,
 
365
               HGFS_BUF_WRITEABLE, session);
 
366
}
 
367
 
 
368
 
 
369
/*
 
370
 *-----------------------------------------------------------------------------
 
371
 *
 
372
 * HSPU_PutDataPacketIov --
 
373
 *
 
374
 *    Free data packet Iov if allocated.
 
375
 *
 
376
 * Results:
 
377
 *    void.
 
378
 *
 
379
 * Side effects:
 
380
 *    Guest mappings will be released.
 
381
 *-----------------------------------------------------------------------------
 
382
 */
 
383
 
 
384
void
 
385
HSPU_PutDataPacketIov()
 
386
{
 
387
   NOT_IMPLEMENTED();
 
388
}
 
389
 
 
390
 
 
391
/*
 
392
 *-----------------------------------------------------------------------------
 
393
 *
 
394
 * HSPU_PutDataPacketBuf --
 
395
 *
 
396
 *    Free data packet buffer if allocated.
 
397
 *    Guest mappings will be released.
 
398
 *
 
399
 * Results:
 
400
 *    void.
 
401
 *
 
402
 * Side effects:
 
403
 *    None.
 
404
 *-----------------------------------------------------------------------------
 
405
 */
 
406
 
 
407
void
 
408
HSPU_PutDataPacketBuf(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 
409
                      HgfsSessionInfo *session)  // IN: Session Info
 
410
{
 
411
 
 
412
   LOG(4, ("%s Hgfs Putting Data packet\n", __FUNCTION__));
 
413
   HSPU_PutBuf(packet, packet->dataPacketIovIndex,
 
414
               &packet->dataPacket, &packet->dataPacketSize,
 
415
               &packet->dataPacketIsAllocated,
 
416
               packet->dataMappingType, session);
 
417
}
 
418
 
 
419
 
 
420
/*
 
421
 *-----------------------------------------------------------------------------
 
422
 *
 
423
 * HSPU_PutBuf --
 
424
 *
 
425
 *    Free buffer if allocated and release guest mappings.
 
426
 *
 
427
 * Results:
 
428
 *    None.
 
429
 *
 
430
 * Side effects:
 
431
 *    None.
 
432
 *-----------------------------------------------------------------------------
 
433
 */
 
434
 
 
435
void
 
436
HSPU_PutBuf(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 
437
            uint32 startIndex,         // IN: Start of iov
 
438
            void **buf,                // IN/OUT: Buffer to be freed
 
439
            size_t *bufSize,           // IN: Size of the buffer
 
440
            Bool *isAllocated,         // IN: Was buffer allocated ?
 
441
            uint32 mappingType,        // IN: Readable / Writeable ?
 
442
            HgfsSessionInfo *session)  // IN: Session info
 
443
{
 
444
   uint32 iovCount = 0;
 
445
   int size = *bufSize;
 
446
   ASSERT(buf);
 
447
 
 
448
   if (!session->channelCbTable) {
 
449
      return;
 
450
   }
 
451
 
 
452
   if (!session->channelCbTable->putVa || *buf == NULL) {
 
453
      return;
 
454
   }
 
455
 
 
456
   if (*isAllocated) {
 
457
      if (mappingType == HGFS_BUF_WRITEABLE) {
 
458
         HSPU_CopyBufToIovec(packet, startIndex, *buf, *bufSize, session);
 
459
      }
 
460
      LOG(10, ("%s: Hgfs Freeing buffer \n", __FUNCTION__));
 
461
      free(*buf);
 
462
      *isAllocated = FALSE;
 
463
   } else {
 
464
      for (iovCount = startIndex;
 
465
           iovCount < packet->iovCount && size > 0;
 
466
           iovCount++) {
 
467
         ASSERT_DEVEL(packet->iov[iovCount].token);
 
468
         session->channelCbTable->putVa(&packet->iov[iovCount].token);
 
469
         size -= packet->iov[iovCount].len;
 
470
      }
 
471
      LOG(10, ("%s: Hgfs bufSize = %d \n", __FUNCTION__, size));
 
472
      ASSERT(size <= 0);
 
473
   }
 
474
   *buf = NULL;
 
475
   *bufSize = 0;
 
476
}
 
477
 
 
478
 
 
479
/*
 
480
 *-----------------------------------------------------------------------------
 
481
 *
 
482
 * HSPU_CopyBufToMetaIovec --
 
483
 *
 
484
 *    Write out buffer to data Iovec.
 
485
 *
 
486
 * Results:
 
487
 *    void
 
488
 *
 
489
 * Side effects:
 
490
 *    @iov is populated with contents of @buf
 
491
 *-----------------------------------------------------------------------------
 
492
 */
 
493
 
 
494
void
 
495
HSPU_CopyBufToMetaIovec(HgfsPacket *packet,      // IN/OUT: Hgfs packet
 
496
                        void *buf,               // IN: Buffer to copy from
 
497
                        size_t bufSize,          // IN: Size of buffer
 
498
                        HgfsSessionInfo *session)// IN: Session Info
 
499
{
 
500
   HSPU_CopyBufToIovec(packet, 0, buf, bufSize, session);
 
501
}
 
502
 
 
503
 
 
504
/*
 
505
 *-----------------------------------------------------------------------------
 
506
 *
 
507
 * HSPU_CopyBufToDataIovec --
 
508
 *
 
509
 *    Write out buffer to data Iovec.
 
510
 *
 
511
 * Results:
 
512
 *    void
 
513
 *
 
514
 * Side effects:
 
515
 *    @iov is populated with contents of @buf
 
516
 *-----------------------------------------------------------------------------
 
517
 */
 
518
 
 
519
void
 
520
HSPU_CopyBufToDataIovec(HgfsPacket *packet,   // IN: Hgfs packet
 
521
                        void *buf,            // IN: Buffer to copy from
 
522
                        uint32 bufSize,       // IN: Size of buffer
 
523
                        HgfsSessionInfo *session)
 
524
{
 
525
   HSPU_CopyBufToIovec(packet, packet->dataPacketIovIndex, buf, bufSize,
 
526
                       session);
 
527
}
 
528
 
 
529
 
 
530
/*
 
531
 *-----------------------------------------------------------------------------
 
532
 *
 
533
 * HSPU_CopyBufToDataIovec --
 
534
 *
 
535
 *    Write out buffer to data Iovec.
 
536
 *
 
537
 * Results:
 
538
 *    void
 
539
 *
 
540
 * Side effects:
 
541
 *    @iov is populated with contents of @buf
 
542
 *-----------------------------------------------------------------------------
 
543
 */
 
544
 
 
545
void
 
546
HSPU_CopyBufToIovec(HgfsPacket *packet,       // IN/OUT: Hgfs Packet
 
547
                    uint32 startIndex,        // IN: start index into iov
 
548
                    void *buf,                // IN: Contigous Buffer
 
549
                    size_t bufSize,           // IN: Size of buffer
 
550
                    HgfsSessionInfo *session) // IN: Session Info
 
551
{
 
552
   uint32 iovCount;
 
553
   size_t remainingSize = bufSize;
 
554
   size_t copyAmount;
 
555
   size_t copiedAmount = 0;
 
556
 
 
557
   ASSERT(packet);
 
558
   ASSERT(buf);
 
559
 
 
560
   if (!session->channelCbTable) {
 
561
      return;
 
562
   }
 
563
 
 
564
   ASSERT_DEVEL(session->channelCbTable->getWriteVa);
 
565
   if (!session->channelCbTable->getWriteVa) {
 
566
      return;
 
567
   }
 
568
 
 
569
   for (iovCount = startIndex; iovCount < packet->iovCount
 
570
        && remainingSize > 0; iovCount++) {
 
571
      copyAmount = remainingSize < packet->iov[iovCount].len ?
 
572
                   remainingSize: packet->iov[iovCount].len;
 
573
 
 
574
      packet->iov[iovCount].token = NULL;
 
575
 
 
576
      /* Debugging check: Iov in VMCI should never cross page boundary */
 
577
      ASSERT_DEVEL(packet->iov[iovCount].len <=
 
578
                  (4096 - (packet->iov[iovCount].pa & 0xfff)));
 
579
 
 
580
      packet->iov[iovCount].va = session->channelCbTable->getWriteVa(packet->iov[iovCount].pa,
 
581
                                                     packet->iov[iovCount].len,
 
582
                                                     &packet->iov[iovCount].token);
 
583
      ASSERT_DEVEL(packet->iov[iovCount].va);
 
584
      if (packet->iov[iovCount].va != NULL) {
 
585
         memcpy(packet->iov[iovCount].va, (char *)buf + copiedAmount, copyAmount);
 
586
         session->channelCbTable->putVa(&packet->iov[iovCount].token);
 
587
         remainingSize -= copyAmount;
 
588
         copiedAmount += copyAmount;
 
589
      } else {
 
590
         break;
 
591
      }
 
592
   }
 
593
 
 
594
   ASSERT_DEVEL(remainingSize == 0);
 
595
}
 
596
 
 
597