~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201207201942

« back to all changes in this revision

Viewing changes to modules/linux/vsock/linux/af_vsock.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-03-20 10:19:00 UTC
  • mfrom: (1.1.4 upstream) (2.4.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090320101900-1o604camiubq2de8
Tags: 2009.03.18-154848-2
Correcting patch system depends (Closes: #520493).

Show diffs side-by-side

added added

removed removed

Lines of Context:
128
128
#include "compat_workqueue.h"
129
129
#include "compat_list.h"
130
130
#if defined(HAVE_COMPAT_IOCTL) || defined(HAVE_UNLOCKED_IOCTL)
131
 
# include "compat_semaphore.h"
 
131
#   include "compat_semaphore.h"
132
132
#endif
133
133
 
134
134
#include "vmware.h"
 
135
#include "vm_basic_math.h"
135
136
 
136
137
#include "vsockCommon.h"
137
138
#include "vsockPacket.h"
138
139
#include "vsockVmci.h"
139
140
 
140
 
#include "vmci_defs.h"
141
 
#include "vmci_call_defs.h"
142
141
#include "vmci_iocontrols.h"
143
 
#ifdef VMX86_TOOLS
144
 
# include "vmciGuestKernelAPI.h"
145
 
#else
146
 
# include "vmciHostKernelAPI.h"
147
 
#endif
148
142
 
149
143
#include "af_vsock.h"
150
144
#include "util.h"
164
158
/*
165
159
 * Prototypes
166
160
 */
167
 
 
168
161
int VSockVmci_GetAFValue(void);
169
162
 
170
163
/* Internal functions. */
 
164
static int VSockVmciGetAFValue(void);
171
165
static int VSockVmciRecvDgramCB(void *data, VMCIDatagram *dg);
172
 
#ifdef VMX86_TOOLS
173
166
static int VSockVmciRecvStreamCB(void *data, VMCIDatagram *dg);
174
167
static void VSockVmciPeerAttachCB(VMCIId subId,
175
168
                                  VMCI_EventData *ed, void *clientData);
193
186
static int VSockVmciRecvConnectingClientNegotiate(struct sock *sk,
194
187
                                                  VSockPacket *pkt);
195
188
static int VSockVmciRecvConnected(struct sock *sk, VSockPacket *pkt);
196
 
#endif
197
189
static int __VSockVmciBind(struct sock *sk, struct sockaddr_vm *addr);
198
190
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
199
191
static struct sock *__VSockVmciCreate(struct socket *sock, unsigned int priority,
206
198
                                      struct socket *sock, gfp_t priority,
207
199
                                      unsigned short type);
208
200
#endif
 
201
static void VSockVmciTestUnregister(void);
209
202
static int VSockVmciRegisterAddressFamily(void);
210
203
static void VSockVmciUnregisterAddressFamily(void);
 
204
static int64 VSockVmciStreamHasData(VSockVmciSock *vsk);
 
205
static int64 VSockVmciStreamHasSpace(VSockVmciSock *vsk);
211
206
 
212
207
 
213
208
/* Socket operations. */
218
213
                         struct sockaddr *addr, int addrLen);
219
214
static int VSockVmciDgramConnect(struct socket *sock,
220
215
                                 struct sockaddr *addr, int addrLen, int flags);
221
 
#ifdef VMX86_TOOLS
222
216
static int VSockVmciStreamConnect(struct socket *sock,
223
217
                                  struct sockaddr *addr, int addrLen, int flags);
224
218
static int VSockVmciAccept(struct socket *sock, struct socket *newsock, int flags);
225
 
#endif
226
219
static int VSockVmciGetname(struct socket *sock,
227
220
                            struct sockaddr *addr, int *addrLen, int peer);
228
221
static unsigned int VSockVmciPoll(struct file *file,
229
222
                                  struct socket *sock, poll_table *wait);
230
 
#ifdef VMX86_TOOLS
231
223
static int VSockVmciListen(struct socket *sock, int backlog);
232
 
#endif
233
224
static int VSockVmciShutdown(struct socket *sock, int mode);
234
225
 
235
 
#ifdef VMX86_TOOLS
236
226
static int VSockVmciStreamSetsockopt(struct socket *sock, int level, int optname,
237
227
                                     char __user *optval, int optlen);
238
228
static int VSockVmciStreamGetsockopt(struct socket *sock, int level, int optname,
239
229
                                     char __user *optval, int __user * optlen);
240
 
#endif
241
230
 
242
231
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 43)
243
232
static int VSockVmciDgramSendmsg(struct socket *sock, struct msghdr *msg,
244
233
                                 int len, struct scm_cookie *scm);
245
234
static int VSockVmciDgramRecvmsg(struct socket *sock, struct msghdr *msg,
246
235
                                 int len, int flags, struct scm_cookie *scm);
247
 
# ifdef VMX86_TOOLS
248
236
static int VSockVmciStreamSendmsg(struct socket *sock, struct msghdr *msg,
249
237
                                  int len, struct scm_cookie *scm);
250
238
static int VSockVmciStreamRecvmsg(struct socket *sock, struct msghdr *msg,
251
239
                                  int len, int flags, struct scm_cookie *scm);
252
 
# endif
253
240
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 65)
254
241
static int VSockVmciDgramSendmsg(struct kiocb *kiocb, struct socket *sock,
255
242
                                 struct msghdr *msg, int len,
257
244
static int VSockVmciDgramRecvmsg(struct kiocb *kiocb, struct socket *sock,
258
245
                                 struct msghdr *msg, int len,
259
246
                                 int flags, struct scm_cookie *scm);
260
 
# ifdef VMX86_TOOLS
261
247
static int VSockVmciStreamSendmsg(struct kiocb *kiocb, struct socket *sock,
262
248
                                  struct msghdr *msg, int len,
263
249
                                  struct scm_cookie *scm);
264
250
static int VSockVmciStreamRecvmsg(struct kiocb *kiocb, struct socket *sock,
265
251
                                  struct msghdr *msg, int len,
266
252
                                  int flags, struct scm_cookie *scm);
267
 
# endif
268
253
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 2)
269
254
static int VSockVmciDgramSendmsg(struct kiocb *kiocb,
270
255
                                 struct socket *sock, struct msghdr *msg, int len);
271
256
static int VSockVmciDgramRecvmsg(struct kiocb *kiocb, struct socket *sock,
272
257
                                 struct msghdr *msg, int len, int flags);
273
 
# ifdef VMX86_TOOLS
274
258
static int VSockVmciStreamSendmsg(struct kiocb *kiocb,
275
259
                                  struct socket *sock, struct msghdr *msg, int len);
276
260
static int VSockVmciStreamRecvmsg(struct kiocb *kiocb, struct socket *sock,
277
261
                                  struct msghdr *msg, int len, int flags);
278
 
# endif
279
262
#else
280
263
static int VSockVmciDgramSendmsg(struct kiocb *kiocb,
281
264
                                 struct socket *sock, struct msghdr *msg, size_t len);
282
265
static int VSockVmciDgramRecvmsg(struct kiocb *kiocb, struct socket *sock,
283
266
                                 struct msghdr *msg, size_t len, int flags);
284
 
# ifdef VMX86_TOOLS
285
267
static int VSockVmciStreamSendmsg(struct kiocb *kiocb,
286
268
                                 struct socket *sock, struct msghdr *msg, size_t len);
287
269
static int VSockVmciStreamRecvmsg(struct kiocb *kiocb, struct socket *sock,
288
270
                                 struct msghdr *msg, size_t len, int flags);
289
 
# endif
290
271
#endif
291
272
 
292
273
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
372
353
#endif
373
354
};
374
355
 
375
 
#ifdef VMX86_TOOLS
376
356
static struct proto_ops vsockVmciStreamOps = {
377
357
   .family     = VSOCK_INVALID_FAMILY,
378
358
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 69)
397
377
   .sendpage   = sock_no_sendpage,
398
378
#endif
399
379
};
400
 
#endif
401
380
 
402
381
static struct file_operations vsockVmciDeviceOps = {
403
382
#ifdef HAVE_UNLOCKED_IOCTL
427
406
static DECLARE_MUTEX(registrationMutex);
428
407
static int devOpenCount = 0;
429
408
static int vsockVmciSocketCount = 0;
 
409
static int vsockVmciKernClientCount = 0;
430
410
#ifdef VMX86_TOOLS
 
411
static Bool vmciDevicePresent = FALSE;
 
412
#endif
431
413
static VMCIHandle vmciStreamHandle = { VMCI_INVALID_ID, VMCI_INVALID_ID };
432
 
static Bool vmciDevicePresent = FALSE;
433
414
static VMCIId qpResumedSubId = VMCI_INVALID_ID;
434
 
#endif
435
415
 
436
416
/* Comment this out to compare with old protocol. */
437
417
#define VSOCK_OPTIMIZATION_WAITING_NOTIFY 1
438
 
#if defined(VMX86_TOOLS) && defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 
418
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
439
419
/* Comment this out to remove flow control for "new" protocol */
440
420
#  define VSOCK_OPTIMIZATION_FLOW_CONTROL 1
441
421
#endif
442
422
 
443
 
/* Comment this out to turn off datagram counting. */
444
 
//#define VSOCK_CONTROL_PACKET_COUNT 1
445
 
#ifdef VSOCK_CONTROL_PACKET_COUNT
 
423
/*
 
424
 * Define VSOCK_GATHER_STATISTICS to turn on statistics gathering.
 
425
 * Currently this consists of 2 types of stats:
 
426
 * 1. The number of control datagram messages sent.
 
427
 * 2. The level of queuepair fullness (in 10% buckets) whenever data is
 
428
 *    about to be enqueued or dequeued from the queuepair.
 
429
 */
 
430
//#define VSOCK_GATHER_STATISTICS 1
 
431
#ifdef VSOCK_GATHER_STATISTICS
 
432
#define VSOCK_NUM_QUEUE_LEVEL_BUCKETS 10
446
433
uint64 controlPacketCount[VSOCK_PACKET_TYPE_MAX];
 
434
uint64 consumeQueueLevel[VSOCK_NUM_QUEUE_LEVEL_BUCKETS];
 
435
uint64 produceQueueLevel[VSOCK_NUM_QUEUE_LEVEL_BUCKETS];
447
436
#endif
448
437
 
449
438
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9)
520
509
/*
521
510
 *----------------------------------------------------------------------------
522
511
 *
523
 
 * VSockVmci_GetAFValue --
 
512
 * VMCISock_GetAFValue --
 
513
 *
 
514
 *      Kernel interface that allows external kernel modules to get the current
 
515
 *      VMCI Sockets address family.
 
516
 *      This version of the function is exported to kernel clients and should not
 
517
 *      change.
 
518
 *
 
519
 * Results:
 
520
 *      The address family on success, a negative error on failure.
 
521
 *
 
522
 * Side effects:
 
523
 *      None.
 
524
 *
 
525
 *----------------------------------------------------------------------------
 
526
 */
 
527
 
 
528
int
 
529
VMCISock_GetAFValue(void)
 
530
{
 
531
   int afvalue;
 
532
 
 
533
   down(&registrationMutex);
 
534
 
 
535
   /*
 
536
    * Kernel clients are required to explicitly register themselves before they
 
537
    * can use VMCI Sockets.
 
538
    */
 
539
   if (vsockVmciKernClientCount <= 0) {
 
540
      afvalue = -1;
 
541
      goto exit;
 
542
   }
 
543
 
 
544
   afvalue = VSockVmciGetAFValue();
 
545
 
 
546
exit:
 
547
   up(&registrationMutex);
 
548
   return afvalue;
 
549
 
 
550
}
 
551
 
 
552
 
 
553
/*
 
554
 *----------------------------------------------------------------------------
 
555
 *
 
556
 * VMCISock_KernelRegister --
 
557
 *
 
558
 *      Allows a kernel client to register with VMCI Sockets. Must be called
 
559
 *      before VMCISock_GetAFValue within a kernel module. Note that we don't
 
560
 *      actually register the address family until the first time the module
 
561
 *      needs to use it.
 
562
 *
 
563
 * Results:
 
564
 *      None.
 
565
 *
 
566
 * Side effects:
 
567
 *      None.
 
568
 *
 
569
 *----------------------------------------------------------------------------
 
570
 */
 
571
 
 
572
void
 
573
VMCISock_KernelRegister(void)
 
574
{
 
575
   down(&registrationMutex);
 
576
   vsockVmciKernClientCount++;
 
577
   up(&registrationMutex);
 
578
}
 
579
 
 
580
 
 
581
/*
 
582
 *----------------------------------------------------------------------------
 
583
 *
 
584
 * VMCISock_KernelDeregister --
 
585
 *
 
586
 *      Allows a kernel client to unregister with VMCI Sockets. Every call
 
587
 *      to VMCISock_KernRegister must be matched with a call to
 
588
 *      VMCISock_KernUnregister.
 
589
 *
 
590
 * Results:
 
591
        None.
 
592
 *
 
593
 * Side effects:
 
594
 *      None.
 
595
 *
 
596
 *----------------------------------------------------------------------------
 
597
 */
 
598
 
 
599
void
 
600
VMCISock_KernelDeregister(void)
 
601
{
 
602
   down(&registrationMutex);
 
603
   vsockVmciKernClientCount--;
 
604
   VSockVmciTestUnregister();
 
605
   up(&registrationMutex);
 
606
}
 
607
 
 
608
 
 
609
/*
 
610
 *----------------------------------------------------------------------------
 
611
 *
 
612
 * VSockVmciGetAFValue --
524
613
 *
525
614
 *      Returns the address family value being used.
 
615
 *      Note: The registration mutex must be held when calling this function.
526
616
 *
527
617
 * Results:
528
618
 *      The address family on success, a negative error on failure.
533
623
 *----------------------------------------------------------------------------
534
624
 */
535
625
 
536
 
int
537
 
VSockVmci_GetAFValue(void)
 
626
static int
 
627
VSockVmciGetAFValue(void)
538
628
{
539
629
   int afvalue;
540
630
 
541
 
   down(&registrationMutex);
542
 
 
543
631
   afvalue = vsockVmciFamilyOps.family;
544
632
   if (!VSOCK_AF_IS_REGISTERED(afvalue)) {
545
633
      afvalue = VSockVmciRegisterAddressFamily();
546
634
   }
547
635
 
 
636
   return afvalue;
 
637
}
 
638
 
 
639
/*
 
640
 *----------------------------------------------------------------------------
 
641
 *
 
642
 * VSockVmci_GetAFValue --
 
643
 *
 
644
 *      Returns the address family value being used.
 
645
 *
 
646
 * Results:
 
647
 *      The address family on success, a negative error on failure.
 
648
 *
 
649
 * Side effects:
 
650
 *      None.
 
651
 *
 
652
 *----------------------------------------------------------------------------
 
653
 */
 
654
 
 
655
int
 
656
VSockVmci_GetAFValue(void)
 
657
{
 
658
   int afvalue;
 
659
 
 
660
   down(&registrationMutex);
 
661
   afvalue = VSockVmciGetAFValue();
548
662
   up(&registrationMutex);
 
663
 
549
664
   return afvalue;
550
665
}
551
666
 
552
667
 
553
668
/*
 
669
 * Helper functions.
 
670
 */
 
671
 
 
672
 
 
673
/*
554
674
 *----------------------------------------------------------------------------
555
675
 *
556
676
 * VSockVmciTestUnregister --
568
688
 *----------------------------------------------------------------------------
569
689
 */
570
690
 
571
 
static inline void
 
691
static void
572
692
VSockVmciTestUnregister(void)
573
693
{
574
 
   if (devOpenCount <= 0 && vsockVmciSocketCount <= 0) {
 
694
   if (devOpenCount <= 0 && vsockVmciSocketCount <= 0 &&
 
695
       vsockVmciKernClientCount <= 0) {
575
696
      if (VSOCK_AF_IS_REGISTERED(vsockVmciFamilyOps.family)) {
576
697
         VSockVmciUnregisterAddressFamily();
577
698
      }
578
699
   }
579
700
}
580
701
 
581
 
 
 
702
#ifdef VSOCK_GATHER_STATISTICS
582
703
/*
583
 
 * Helper functions.
 
704
 *----------------------------------------------------------------------------
 
705
 *
 
706
 * VSockVmciUpdateQueueBucketCount --
 
707
 *
 
708
 *      Given a queue, determine how much data is enqueued and add that to
 
709
 *      the specified queue level statistic bucket.
 
710
 *
 
711
 * Results:
 
712
 *      None.
 
713
 *
 
714
 * Side effects:
 
715
 *      None.
 
716
 *
 
717
 *----------------------------------------------------------------------------
584
718
 */
585
719
 
 
720
static void
 
721
VSockVmciUpdateQueueBucketCount(VMCIQueue *mainQueue,  // IN
 
722
                                VMCIQueue *otherQueue, // IN
 
723
                                uint64 mainQueueSize,  // IN
 
724
                                uint64 queueLevel[])   // IN
 
725
{
 
726
   uint64 bucket = 0;
 
727
   uint32 remainder = 0;
 
728
   uint64 dataReady = VMCIQueue_BufReady(mainQueue,
 
729
                                         otherQueue,
 
730
                                         mainQueueSize);
 
731
   /*
 
732
    * We can't do 64 / 64 = 64 bit divides on linux because it requires a libgcc
 
733
    * which is not linked into the kernel module. Since this code is only used by
 
734
    * developers we just limit the mainQueueSize to be less than MAX_UINT for now.
 
735
    */
 
736
   ASSERT(mainQueueSize <= MAX_UINT32);
 
737
   Div643264(dataReady * 10, mainQueueSize, &bucket, &remainder);
 
738
   ASSERT(bucket < VSOCK_NUM_QUEUE_LEVEL_BUCKETS);
 
739
   ++queueLevel[bucket];
 
740
}
 
741
#endif
586
742
 
587
 
#ifdef VMX86_TOOLS
588
743
/*
589
744
 *----------------------------------------------------------------------------
590
745
 *
604
759
static Bool
605
760
VSockVmciNotifyWaitingWrite(VSockVmciSock *vsk)    // IN
606
761
{
607
 
#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 
762
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
608
763
   Bool retval;
609
764
   uint64 notifyLimit;
610
765
  
688
843
static Bool
689
844
VSockVmciNotifyWaitingRead(VSockVmciSock *vsk)  // IN
690
845
{
691
 
#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 
846
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
692
847
   if (!vsk->peerWaitingRead) {
693
848
      return FALSE;
694
849
   }
730
885
                     struct sockaddr_vm *dst,    // IN: unused
731
886
                     struct sockaddr_vm *src)    // IN: unused
732
887
{
733
 
#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 
888
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
734
889
   VSockVmciSock *vsk;
735
890
 
736
891
   vsk = vsock_sk(sk);
764
919
                    struct sockaddr_vm *dst,    // IN: unused
765
920
                    struct sockaddr_vm *src)    // IN: unused
766
921
{
767
 
#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 
922
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
768
923
   VSockVmciSock *vsk;
769
924
 
770
925
   vsk = vsock_sk(sk);
799
954
                            struct sockaddr_vm *dst,    // IN
800
955
                            struct sockaddr_vm *src)    // IN
801
956
{
802
 
#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 
957
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
803
958
   VSockVmciSock *vsk;
804
959
 
805
960
   vsk = vsock_sk(sk);
849
1004
                           struct sockaddr_vm *dst,     // IN
850
1005
                           struct sockaddr_vm *src)     // IN
851
1006
{
852
 
#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 
1007
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
853
1008
   VSockVmciSock *vsk;
854
1009
 
855
1010
   vsk = vsock_sk(sk);
873
1028
   }
874
1029
#endif
875
1030
}
876
 
#endif
877
1031
 
878
1032
 
879
1033
/*
932
1086
}
933
1087
 
934
1088
 
935
 
#ifdef VMX86_TOOLS
936
1089
/*
937
1090
 *----------------------------------------------------------------------------
938
1091
 *
1178
1331
 *----------------------------------------------------------------------------
1179
1332
 */
1180
1333
 
1181
 
static INLINE void
 
1334
static void
1182
1335
VSockVmciHandleDetach(struct sock *sk) // IN
1183
1336
{
1184
1337
   VSockVmciSock *vsk;
1190
1343
      ASSERT(vsk->produceQ);
1191
1344
      ASSERT(vsk->consumeQ);
1192
1345
 
1193
 
#ifdef VMX86_TOOLS
1194
 
      if (sk->compat_sk_type == SOCK_STREAM &&
1195
 
          sk->compat_sk_state == SS_CONNECTED) {
1196
 
         compat_sock_set_done(sk);
1197
 
      }
1198
 
#endif
 
1346
      compat_sock_set_done(sk);
1199
1347
 
1200
1348
      /* On a detach the peer will not be sending or receiving anymore. */
1201
1349
      vsk->peerShutdown = SHUTDOWN_MASK;
1206
1354
       * queue.
1207
1355
       */
1208
1356
      sk->compat_sk_shutdown |= SEND_SHUTDOWN;
1209
 
      if (VMCIQueue_BufReady(vsk->consumeQ,
1210
 
                             vsk->produceQ, vsk->consumeSize) <= 0) {
 
1357
      if (VSockVmciStreamHasData(vsk) <= 0) {
1211
1358
         sk->compat_sk_shutdown |= RCV_SHUTDOWN;
1212
1359
         sk->compat_sk_state = SS_UNCONNECTED;
1213
1360
      }
1439
1586
   case SS_LISTEN:
1440
1587
      err = VSockVmciRecvListen(sk, pkt);
1441
1588
      break;
1442
 
   case SS_UNCONNECTED:
1443
 
      Log("packet received for socket in unconnected state; dropping.\n");
1444
 
      goto out;
1445
1589
   case SS_CONNECTING:
1446
1590
      /*
1447
1591
       * Processing of pending connections for servers goes through the
1452
1596
   case SS_CONNECTED:
1453
1597
      err = VSockVmciRecvConnected(sk, pkt);
1454
1598
      break;
1455
 
   case SS_DISCONNECTING:
1456
 
      Log("packet receieved for socket in disconnecting state; dropping.\n");
1457
 
      goto out;
1458
 
   case SS_FREE:
1459
 
      Log("packet receieved for socket in free state; dropping.\n");
1460
 
      goto out;
1461
1599
   default:
1462
 
      Log("socket is in invalid state; dropping packet.\n");
 
1600
      /*
 
1601
       * Because this function does not run in the same context as
 
1602
       * VSockVmciRecvStreamCB it is possible that the socket
 
1603
       * has closed. We need to let the other side know or it could
 
1604
       * be sitting in a connect and hang forever. Send a reset to prevent
 
1605
       * that.
 
1606
       */
 
1607
      VSOCK_SEND_RESET(sk, pkt);
1463
1608
      goto out;
1464
1609
   }
1465
1610
 
2066
2211
VSockVmciRecvConnected(struct sock *sk,      // IN
2067
2212
                       VSockPacket *pkt)     // IN
2068
2213
{
 
2214
   VSockVmciSock *vsk;
 
2215
 
2069
2216
   ASSERT(sk);
2070
2217
   ASSERT(pkt);
2071
2218
   ASSERT(sk->compat_sk_state == SS_CONNECTED);
2089
2236
      break;
2090
2237
 
2091
2238
   case VSOCK_PACKET_TYPE_RST:
2092
 
      sk->compat_sk_state = SS_DISCONNECTING;
2093
 
      sk->compat_sk_shutdown = SHUTDOWN_MASK;
2094
 
      sk->compat_sk_err = ECONNRESET;
2095
 
      sk->compat_sk_error_report(sk);
 
2239
      vsk = vsock_sk(sk);
 
2240
      /*
 
2241
       * It is possible that we sent our peer a message (e.g
 
2242
       * a WAITING_READ) right before we got notified that the peer
 
2243
       * had detached. If that happens then we can get a RST pkt back
 
2244
       * from our peer even though there is data available for us
 
2245
       * to read. In that case, don't shutdown the socket completely
 
2246
       * but instead allow the local client to finish reading data
 
2247
       * off the queuepair. Always treat a RST pkt in connected mode
 
2248
       * like a clean shutdown.
 
2249
       */
 
2250
      compat_sock_set_done(sk);
 
2251
      vsk->peerShutdown = SHUTDOWN_MASK;
 
2252
      sk->compat_sk_shutdown |= SEND_SHUTDOWN;
 
2253
      if (VSockVmciStreamHasData(vsk) <= 0) {
 
2254
         sk->compat_sk_state = SS_DISCONNECTING;
 
2255
         sk->compat_sk_shutdown = SHUTDOWN_MASK;
 
2256
      }
 
2257
      sk->compat_sk_state_change(sk);
2096
2258
      break;
2097
2259
 
2098
2260
   case VSOCK_PACKET_TYPE_WROTE:
2157
2319
   VSockPacket_Init(&pkt, src, dst, type, size, mode, wait, handle);
2158
2320
 
2159
2321
   LOG_PACKET(&pkt);
2160
 
#ifdef VSOCK_CONTROL_PACKET_COUNT
 
2322
#ifdef VSOCK_GATHER_STATISTICS
2161
2323
   controlPacketCount[pkt.type]++;
2162
2324
#endif
2163
2325
   return VMCIDatagram_Send(&pkt.dg);
2226
2388
      return VSockVmci_ErrorToVSockError(err);
2227
2389
   }
2228
2390
 
2229
 
#ifdef VSOCK_CONTROL_PACKET_COUNT
 
2391
#ifdef VSOCK_GATHER_STATISTICS
2230
2392
   controlPacketCount[pkt->type]++;
2231
2393
#endif
2232
2394
 
2233
2395
   return err;
2234
2396
}
2235
 
#endif
2236
2397
 
2237
2398
 
2238
2399
/*
2382
2543
}
2383
2544
 
2384
2545
 
2385
 
#ifdef VMX86_TOOLS
2386
2546
/*
2387
2547
 *----------------------------------------------------------------------------
2388
2548
 *
2406
2566
VSockVmciSendWaitingWrite(struct sock *sk,   // IN
2407
2567
                          uint64 roomNeeded) // IN
2408
2568
{
2409
 
#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 
2569
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
2410
2570
   VSockVmciSock *vsk;
2411
2571
   VSockWaitingInfo waitingInfo;
2412
2572
   uint64 tail;
2465
2625
VSockVmciSendWaitingRead(struct sock *sk,    // IN
2466
2626
                         uint64 roomNeeded)  // IN
2467
2627
{
2468
 
#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 
2628
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
2469
2629
   VSockVmciSock *vsk;
2470
2630
   VSockWaitingInfo waitingInfo;
2471
2631
   uint64 tail;
2568
2728
   }
2569
2729
   return err;
2570
2730
}
2571
 
#endif // VMX86_TOOLS
2572
2731
 
2573
2732
 
2574
2733
/*
2688
2847
   INIT_LIST_HEAD(&vsk->boundTable);
2689
2848
   INIT_LIST_HEAD(&vsk->connectedTable);
2690
2849
   vsk->dgHandle = VMCI_INVALID_HANDLE;
2691
 
#ifdef VMX86_TOOLS
2692
2850
   vsk->qpHandle = VMCI_INVALID_HANDLE;
2693
2851
   vsk->produceQ = vsk->consumeQ = NULL;
2694
2852
   vsk->produceQGeneration = vsk->consumeQGeneration = 0;
2709
2867
   vsk->rejected = FALSE;
2710
2868
   vsk->attachSubId = vsk->detachSubId = VMCI_INVALID_ID;
2711
2869
   vsk->peerShutdown = 0;
2712
 
#endif
2713
2870
 
2714
2871
   if (sock) {
2715
2872
      VSockVmciInsertBound(vsockUnboundSockets, sk);
2768
2925
      }
2769
2926
 
2770
2927
      /* Clean up any sockets that never were accepted. */
2771
 
#ifdef VMX86_TOOLS
2772
2928
      while ((pending = VSockVmciDequeueAccept(sk)) != NULL) {
2773
2929
         __VSockVmciRelease(pending);
2774
2930
         sock_put(pending);
2775
2931
      }
2776
 
#endif
2777
2932
 
2778
2933
      release_sock(sk);
2779
2934
      sock_put(sk);
2809
2964
 
2810
2965
   vsk = vsock_sk(sk);
2811
2966
 
2812
 
#ifdef VMX86_TOOLS
2813
2967
   if (vsk->attachSubId != VMCI_INVALID_ID) {
2814
2968
      VMCIEvent_Unsubscribe(vsk->attachSubId);
2815
2969
      vsk->attachSubId = VMCI_INVALID_ID;
2826
2980
      vsk->produceQ = vsk->consumeQ = NULL;
2827
2981
      vsk->produceSize = vsk->consumeSize = 0;
2828
2982
   }
2829
 
#endif
2830
2983
 
2831
2984
   /*
2832
2985
    * Each list entry holds a reference on the socket, so we should not even be
2835
2988
    */
2836
2989
   ASSERT(!VSockVmciInBoundTable(sk));
2837
2990
   ASSERT(!VSockVmciInConnectedTable(sk));
2838
 
#ifdef VMX86_TOOLS
2839
2991
   ASSERT(!VSockVmciIsPending(sk));
2840
2992
   ASSERT(!VSockVmciInAcceptQueue(sk));
2841
 
#endif
2842
2993
 
2843
2994
   /*
2844
2995
    * When clearing these addresses, there's no need to set the family and
2857
3008
   VSockVmciTestUnregister();
2858
3009
   up(&registrationMutex);
2859
3010
 
2860
 
#ifdef VSOCK_CONTROL_PACKET_COUNT
 
3011
#ifdef VSOCK_GATHER_STATISTICS
2861
3012
   {
2862
3013
      uint32 index;
2863
3014
      for (index = 0; index < ARRAYSIZE(controlPacketCount); index++) {
2864
3015
         Warning("Control packet count: Type = %u, Count = %"FMT64"u\n",
2865
3016
                 index, controlPacketCount[index]);
2866
3017
      }
 
3018
 
 
3019
      for (index = 0; index < ARRAYSIZE(consumeQueueLevel); index++) {
 
3020
         Warning("Consume Bucket: %u Count: %"FMT64"u\n",
 
3021
                 index, consumeQueueLevel[index]);
 
3022
      }
 
3023
 
 
3024
      for (index = 0; index < ARRAYSIZE(produceQueueLevel); index++) {
 
3025
         Warning("Produce Bucket: %u Count: %"FMT64"u\n",
 
3026
                 index, produceQueueLevel[index]);
 
3027
      }
 
3028
 
2867
3029
   }
2868
3030
#endif
2869
3031
}
2916
3078
 *----------------------------------------------------------------------------
2917
3079
 */
2918
3080
 
2919
 
static INLINE int
 
3081
static int
2920
3082
VSockVmciRegisterProto(void)
2921
3083
{
2922
 
   int err;
2923
 
 
2924
 
   err = 0;
 
3084
   int err = 0;
2925
3085
 
2926
3086
   /*
2927
3087
    * Before 2.6.9, each address family created their own slab (by calling
2971
3131
 *----------------------------------------------------------------------------
2972
3132
 */
2973
3133
 
2974
 
static INLINE void
 
3134
static void
2975
3135
VSockVmciUnregisterProto(void)
2976
3136
{
2977
3137
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 5)
2984
3144
   proto_unregister(&vsockVmciProto);
2985
3145
#endif
2986
3146
 
2987
 
#ifdef VSOCK_CONTROL_PACKET_COUNT
 
3147
#ifdef VSOCK_GATHER_STATISTICS
2988
3148
   {
2989
3149
      uint32 index;
2990
3150
      for (index = 0; index < ARRAYSIZE(controlPacketCount); index++) {
2991
3151
         controlPacketCount[index] = 0;
2992
3152
      }
 
3153
 
 
3154
      for (index = 0; index < ARRAYSIZE(consumeQueueLevel); index++) {
 
3155
         consumeQueueLevel[index] = 0;
 
3156
      }
 
3157
 
 
3158
      for (index = 0; index < ARRAYSIZE(produceQueueLevel); index++) {
 
3159
         produceQueueLevel[index] = 0;
 
3160
      }
 
3161
 
2993
3162
   }
2994
3163
#endif
2995
3164
}
3030
3199
      Log("Could not register VMCI Sockets because VMCI device is not present.\n");
3031
3200
      return -1;
3032
3201
   }
 
3202
#endif
3033
3203
 
3034
3204
   /*
3035
3205
    * Create the datagram handle that we will use to send and receive all
3054
3224
      qpResumedSubId = VMCI_INVALID_ID;
3055
3225
      goto error;
3056
3226
   }
3057
 
#endif
3058
3227
 
3059
3228
   /*
3060
3229
    * Linux will not allocate an address family to code that is not part of the
3075
3244
         vsockVmciFamilyOps.family = VSOCK_INVALID_FAMILY;
3076
3245
      } else {
3077
3246
         vsockVmciDgramOps.family = i;
3078
 
#ifdef VMX86_TOOLS
3079
3247
         vsockVmciStreamOps.family = i;
3080
 
#endif
3081
3248
         break;
3082
3249
      }
3083
3250
   }
3089
3256
   return vsockVmciFamilyOps.family;
3090
3257
 
3091
3258
error:
3092
 
#ifdef VMX86_TOOLS
3093
3259
   if (qpResumedSubId != VMCI_INVALID_ID) {
3094
3260
      VMCIEvent_Unsubscribe(qpResumedSubId);
3095
3261
      qpResumedSubId = VMCI_INVALID_ID;
3096
3262
   }
3097
3263
   VMCIDatagram_DestroyHnd(vmciStreamHandle);
3098
 
#endif
3099
3264
   return err;
3100
3265
}
3101
3266
 
3126
3291
      /* Nothing was registered. */
3127
3292
      return;
3128
3293
   }
 
3294
#endif
3129
3295
 
3130
3296
   if (!VMCI_HANDLE_INVALID(vmciStreamHandle)) {
3131
3297
      if (VMCIDatagram_DestroyHnd(vmciStreamHandle) != VMCI_SUCCESS) {
3137
3303
      VMCIEvent_Unsubscribe(qpResumedSubId);
3138
3304
      qpResumedSubId = VMCI_INVALID_ID;
3139
3305
   }
3140
 
#endif
3141
3306
 
3142
3307
   if (vsockVmciFamilyOps.family != VSOCK_INVALID_FAMILY) {
3143
3308
      sock_unregister(vsockVmciFamilyOps.family);
3144
3309
   }
3145
3310
 
3146
3311
   vsockVmciDgramOps.family = vsockVmciFamilyOps.family = VSOCK_INVALID_FAMILY;
3147
 
#ifdef VMX86_TOOLS
3148
3312
   vsockVmciStreamOps.family = vsockVmciFamilyOps.family;
3149
 
#endif
3150
 
 
 
3313
 
 
3314
}
 
3315
 
 
3316
 
 
3317
/*
 
3318
 *----------------------------------------------------------------------------
 
3319
 *
 
3320
 * VSockVmciStreamHasData --
 
3321
 *
 
3322
 *      Gets the amount of data available for a given stream socket's consume
 
3323
 *      queue.
 
3324
 *
 
3325
 *      Note that this assumes the socket lock is held.
 
3326
 *
 
3327
 * Results:
 
3328
 *      The amount of data available or a VMCI error code on failure.
 
3329
 *
 
3330
 * Side effects:
 
3331
 *      None.
 
3332
 *
 
3333
 *----------------------------------------------------------------------------
 
3334
 */
 
3335
 
 
3336
static int64
 
3337
VSockVmciStreamHasData(VSockVmciSock *vsk) // IN
 
3338
{
 
3339
   ASSERT(vsk);
 
3340
 
 
3341
   return VMCIQueue_BufReady(vsk->consumeQ,
 
3342
                             vsk->produceQ, vsk->consumeSize);
 
3343
}
 
3344
 
 
3345
 
 
3346
/*
 
3347
 *----------------------------------------------------------------------------
 
3348
 *
 
3349
 * VSockVmciStreamHasSpace --
 
3350
 *
 
3351
 *      Gets the amount of space available for a give stream socket's produce
 
3352
 *      queue.
 
3353
 *
 
3354
 *      Note that this assumes the socket lock is held.
 
3355
 *
 
3356
 * Results:
 
3357
 *      The amount of space available or a VMCI error code on failure.
 
3358
 *
 
3359
 * Side effects:
 
3360
 *      None.
 
3361
 *
 
3362
 *----------------------------------------------------------------------------
 
3363
 */
 
3364
 
 
3365
static int64
 
3366
VSockVmciStreamHasSpace(VSockVmciSock *vsk) // IN
 
3367
{
 
3368
   ASSERT(vsk);
 
3369
 
 
3370
   return VMCIQueue_FreeSpace(vsk->produceQ,
 
3371
                              vsk->consumeQ, vsk->produceSize);
3151
3372
}
3152
3373
 
3153
3374
 
3286
3507
}
3287
3508
 
3288
3509
 
3289
 
#ifdef VMX86_TOOLS
3290
3510
/*
3291
3511
 *----------------------------------------------------------------------------
3292
3512
 *
3540
3760
   release_sock(listener);
3541
3761
   return err;
3542
3762
}
3543
 
#endif
3544
3763
 
3545
3764
 
3546
3765
/*
3664
3883
      if (!(sk->compat_sk_shutdown & SEND_SHUTDOWN)) {
3665
3884
         mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
3666
3885
      }
3667
 
#ifdef VMX86_TOOLS
3668
3886
   } else if (sock->type == SOCK_STREAM) {
3669
3887
      VSockVmciSock *vsk;
3670
3888
 
3684
3902
       */
3685
3903
      if (!VMCI_HANDLE_INVALID(vsk->qpHandle) &&
3686
3904
          !(sk->compat_sk_shutdown & RCV_SHUTDOWN)) {
3687
 
         if (VMCIQueue_BufReady(vsk->consumeQ,
3688
 
                                vsk->produceQ, vsk->consumeSize)) {
 
3905
         if (VSockVmciStreamHasData(vsk)) {
3689
3906
            mask |= POLLIN | POLLRDNORM;
3690
3907
         } else {
3691
3908
            /*
3714
3931
      if (sk->compat_sk_state == SS_CONNECTED) {
3715
3932
         if (!(sk->compat_sk_shutdown & SEND_SHUTDOWN)) {
3716
3933
            int64 produceQFreeSpace =
3717
 
               VMCIQueue_FreeSpace(vsk->produceQ,
3718
 
                                   vsk->consumeQ, vsk->produceSize);
 
3934
               VSockVmciStreamHasSpace(vsk);
3719
3935
            if (produceQFreeSpace > 0) {
3720
3936
               mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
3721
3937
            } else if (produceQFreeSpace == 0) {
3735
3951
      }
3736
3952
 
3737
3953
      release_sock(sk);
3738
 
#endif
3739
3954
   }
3740
3955
 
3741
3956
   return mask;
3742
3957
}
3743
3958
 
3744
3959
 
3745
 
#ifdef VMX86_TOOLS
3746
3960
/*
3747
3961
 *----------------------------------------------------------------------------
3748
3962
 *
3797
4011
   release_sock(sk);
3798
4012
   return err;
3799
4013
}
3800
 
#endif
3801
4014
 
3802
4015
 
3803
4016
/*
3851
4064
      release_sock(sk);
3852
4065
   }
3853
4066
 
3854
 
#ifdef VMX86_TOOLS
3855
4067
   if (sk->compat_sk_type == SOCK_STREAM && mode) {
3856
4068
      compat_sock_reset_done(sk);
3857
4069
      VSOCK_SEND_SHUTDOWN(sk, mode);
3858
4070
   }
3859
 
#endif
3860
4071
 
3861
4072
   return 0;
3862
4073
}
4001
4212
   return err;
4002
4213
}
4003
4214
 
4004
 
#ifdef VMX86_TOOLS
4005
4215
/*
4006
4216
 *----------------------------------------------------------------------------
4007
4217
 *
4090
4300
   return err;
4091
4301
}
4092
4302
 
4093
 
#endif
4094
4303
 
4095
 
#ifdef VMX86_TOOLS
4096
4304
/*
4097
4305
 *----------------------------------------------------------------------------
4098
4306
 *
4164
4372
    }
4165
4373
    return 0;
4166
4374
}
4167
 
#endif
4168
 
 
4169
 
 
4170
 
#ifdef VMX86_TOOLS
 
4375
 
 
4376
 
4171
4377
/*
4172
4378
 *----------------------------------------------------------------------------
4173
4379
 *
4216
4422
   ssize_t totalWritten;
4217
4423
   long timeout;
4218
4424
   int err;
4219
 
#if defined(VMX86_TOOLS) && defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 
4425
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
4220
4426
   uint64 produceTail;
4221
4427
   uint64 consumeHead;
4222
4428
#endif
4269
4475
      sentWrote = FALSE;
4270
4476
      retries = 0;
4271
4477
 
4272
 
      while (VMCIQueue_FreeSpace(vsk->produceQ,
4273
 
                                 vsk->consumeQ, vsk->produceSize) == 0 &&
 
4478
      while (VSockVmciStreamHasSpace(vsk) == 0 &&
4274
4479
             sk->compat_sk_err == 0 &&
4275
4480
             !(sk->compat_sk_shutdown & SEND_SHUTDOWN) &&
4276
4481
             !(vsk->peerShutdown & RCV_SHUTDOWN)) {
4315
4520
         goto outWait;
4316
4521
      }
4317
4522
 
 
4523
#if defined(VSOCK_GATHER_STATISTICS)
 
4524
      VSockVmciUpdateQueueBucketCount(vsk->produceQ,
 
4525
                                      vsk->consumeQ,
 
4526
                                      vsk->produceSize,
 
4527
                                      produceQueueLevel);
 
4528
#endif
 
4529
 
4318
4530
      /*
4319
4531
       * Note that enqueue will only write as many bytes as are free in the
4320
4532
       * produce queue, so we don't need to ensure len is smaller than the queue
4321
4533
       * size.  It is the caller's responsibility to check how many bytes we were
4322
4534
       * able to send.
4323
4535
       */
4324
 
#if defined(VMX86_TOOLS) && defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 
4536
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
4325
4537
      VMCIQueue_GetPointers(vsk->produceQ, vsk->consumeQ,
4326
4538
                            &produceTail, &consumeHead);
4327
4539
#endif
4334
4546
         goto outWait;
4335
4547
      }
4336
4548
 
4337
 
#if defined(VMX86_TOOLS) && defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 
4549
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
4338
4550
      /*
4339
4551
       * Detect a wrap-around to maintain queue generation.  Note that this is
4340
4552
       * safe since we hold the socket lock across the two queue pair
4368
4580
            Warning("unable to send wrote notification to peer for socket %p.\n", sk);
4369
4581
            goto outWait;
4370
4582
         } else {
4371
 
#if defined(VMX86_TOOLS) && defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 
4583
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
4372
4584
            vsk->peerWaitingRead = FALSE;
4373
4585
#endif
4374
4586
         }
4386
4598
   release_sock(sk);
4387
4599
   return err;
4388
4600
}
4389
 
#endif
4390
4601
 
4391
4602
 
4392
4603
/*
4504
4715
}
4505
4716
 
4506
4717
 
4507
 
#ifdef VMX86_TOOLS
4508
4718
/*
4509
4719
 *----------------------------------------------------------------------------
4510
4720
 *
4561
4771
   ssize_t copied;
4562
4772
   Bool sentRead;
4563
4773
   unsigned int retries;
4564
 
#if defined(VMX86_TOOLS) && defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 
4774
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
4565
4775
   uint64 consumeHead;
4566
4776
   uint64 produceTail;
4567
4777
#ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL
4641
4851
 
4642
4852
   compat_init_prepare_to_wait(sk->compat_sk_sleep, &wait, TASK_INTERRUPTIBLE);
4643
4853
 
4644
 
   while ((ready = VMCIQueue_BufReady(vsk->consumeQ,
4645
 
                                      vsk->produceQ,
4646
 
                                      vsk->consumeSize)) < target &&
 
4854
   while ((ready = VSockVmciStreamHasData(vsk)) < target &&
4647
4855
          sk->compat_sk_err == 0 &&
4648
4856
          !(sk->compat_sk_shutdown & RCV_SHUTDOWN) &&
4649
4857
          !(vsk->peerShutdown & SEND_SHUTDOWN)) {
4650
4858
 
4651
4859
      if (ready < 0) {
4652
 
         /* 
 
4860
         /*
4653
4861
          * Invalid queue pair content. XXX This should be changed to
4654
4862
          * a connection reset in a later change.
4655
4863
          */
4702
4910
      err = 0;
4703
4911
      goto outWait;
4704
4912
   } else if ((vsk->peerShutdown & SEND_SHUTDOWN) &&
4705
 
              VMCIQueue_BufReady(vsk->consumeQ,
4706
 
                                 vsk->produceQ, vsk->consumeSize) < target) {
 
4913
              VSockVmciStreamHasData(vsk) < target) {
4707
4914
      err = 0;
4708
4915
      goto outWait;
4709
4916
   }
 
4917
#if defined(VSOCK_GATHER_STATISTICS)
 
4918
   VSockVmciUpdateQueueBucketCount(vsk->consumeQ,
 
4919
                                   vsk->produceQ,
 
4920
                                   vsk->consumeSize,
 
4921
                                   consumeQueueLevel);
 
4922
#endif
 
4923
 
4710
4924
 
4711
4925
   /*
4712
4926
    * Now consume up to len bytes from the queue.  Note that since we have the
4713
4927
    * socket locked we should copy at least ready bytes.
4714
4928
    */
4715
 
#if defined(VMX86_TOOLS) && defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 
4929
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
4716
4930
   VMCIQueue_GetPointers(vsk->consumeQ, vsk->produceQ,
4717
4931
                         &produceTail, &consumeHead);
4718
4932
#endif
4719
4933
 
4720
 
   copied = VMCIQueue_DequeueV(vsk->produceQ, vsk->consumeQ,
 
4934
   if (flags & MSG_PEEK) {
 
4935
      copied = VMCIQueue_PeekV(vsk->produceQ, vsk->consumeQ,
4721
4936
                               vsk->consumeSize, msg->msg_iov, len);
 
4937
   } else {
 
4938
      copied = VMCIQueue_DequeueV(vsk->produceQ, vsk->consumeQ,
 
4939
                                  vsk->consumeSize, msg->msg_iov, len);
 
4940
   }
 
4941
 
4722
4942
   if (copied < 0) {
4723
4943
      err = -ENOMEM;
4724
4944
      goto outWait;
4725
4945
   }
4726
4946
 
4727
 
#if defined(VMX86_TOOLS) && defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
4728
 
   /*
4729
 
    * Detect a wrap-around to maintain queue generation.  Note that this is
4730
 
    * safe since we hold the socket lock across the two queue pair
4731
 
    * operations.
4732
 
    */
4733
 
   if (copied >= vsk->consumeSize - consumeHead) {
4734
 
      vsk->consumeQGeneration++;
4735
 
   }
4736
 
#endif
4737
 
 
4738
4947
   ASSERT(copied >= target);
4739
4948
 
4740
4949
   /*
4741
 
    * If the other side has shutdown for sending and there is nothing more to
4742
 
    * read, then set our socket's RCV_SHUTDOWN flag and modify the socket
4743
 
    * state.
 
4950
    * We only do these additional bookkeeping/notification steps if we actually
 
4951
    * copied something out of the queue pair instead of just peeking ahead.
4744
4952
    */
4745
 
   if (vsk->peerShutdown & SEND_SHUTDOWN) {
4746
 
      if (VMCIQueue_BufReady(vsk->consumeQ,
4747
 
                             vsk->produceQ, vsk->consumeSize) <= 0) {
4748
 
         sk->compat_sk_shutdown |= RCV_SHUTDOWN;
4749
 
         sk->compat_sk_state = SS_UNCONNECTED;
4750
 
         compat_sock_set_done(sk);
4751
 
         sk->compat_sk_state_change(sk);
4752
 
      }
4753
 
   }
4754
 
 
4755
 
   err = VSockVmciSendReadNotification(sk);
4756
 
   if (err < 0) {
4757
 
      goto outWait;
 
4953
   if (!(flags & MSG_PEEK)) {
 
4954
#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 
4955
      /*
 
4956
       * Detect a wrap-around to maintain queue generation.  Note that this is
 
4957
       * safe since we hold the socket lock across the two queue pair
 
4958
       * operations.
 
4959
       */
 
4960
      if (copied >= vsk->consumeSize - consumeHead) {
 
4961
         vsk->consumeQGeneration++;
 
4962
      }
 
4963
#endif
 
4964
 
 
4965
      /*
 
4966
       * If the other side has shutdown for sending and there is nothing more to
 
4967
       * read, then set our socket's RCV_SHUTDOWN flag and modify the socket
 
4968
       * state.
 
4969
       */
 
4970
      if (vsk->peerShutdown & SEND_SHUTDOWN) {
 
4971
         if (VSockVmciStreamHasData(vsk) <= 0) {
 
4972
            sk->compat_sk_shutdown |= RCV_SHUTDOWN;
 
4973
            sk->compat_sk_state = SS_UNCONNECTED;
 
4974
            compat_sock_set_done(sk);
 
4975
            sk->compat_sk_state_change(sk);
 
4976
         }
 
4977
      }
 
4978
 
 
4979
      err = VSockVmciSendReadNotification(sk);
 
4980
      if (err < 0) {
 
4981
         goto outWait;
 
4982
      }
4758
4983
   }
4759
4984
 
4760
4985
   ASSERT(copied <= INT_MAX);
4766
4991
   release_sock(sk);
4767
4992
   return err;
4768
4993
}
4769
 
#endif
4770
4994
 
4771
4995
 
4772
4996
/*
4812
5036
   case SOCK_DGRAM:
4813
5037
      sock->ops = &vsockVmciDgramOps;
4814
5038
      break;
4815
 
#  ifdef VMX86_TOOLS
4816
 
   /*
4817
 
    * Queue pairs are /currently/ only supported within guests, so stream
4818
 
    * sockets are only supported within guests.
4819
 
    */
4820
5039
   case SOCK_STREAM:
4821
5040
      sock->ops = &vsockVmciStreamOps;
4822
5041
      break;
4823
 
#  endif
4824
5042
   default:
4825
5043
      return -ESOCKTNOSUPPORT;
4826
5044
   }
5188
5406
MODULE_DESCRIPTION("VMware Virtual Socket Family");
5189
5407
MODULE_VERSION(VSOCK_DRIVER_VERSION_STRING);
5190
5408
MODULE_LICENSE("GPL v2");
 
5409
/*
 
5410
 * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement
 
5411
 * with them and mark their kernel modules as externally supported via a
 
5412
 * change to the module header. If this isn't done, the module will not load
 
5413
 * by default (i.e., neither mkinitrd nor modprobe will accept it).
 
5414
 */
 
5415
MODULE_INFO(supported, "external");