VMCIHandle dst = VMCI_MAKE_HANDLE(peer, VMCI_INVALID_ID);
VMCIRoute route;
+ /*
+ * Restrict the size of a queuepair. The device already enforces a limit
+ * on the total amount of memory that can be allocated to queuepairs for a
+ * guest. However, we try to allocate this memory before we make the
+ * queuepair allocation hypercall. On Windows and Mac OS, we request a
+ * single, continguous block, and it will fail if the OS cannot satisfy the
+ * request. On Linux, we allocate each page separately, which means rather
+ * than fail, the guest will thrash while it tries to allocate, and will
+ * become increasingly unresponsive to the point where it appears to be hung.
+ * So we place a limit on the size of an individual queuepair here, and
+ * leave the device to enforce the restriction on total queuepair memory.
+ * (Note that this doesn't prevent all cases; a user with only this much
+ * physical memory could still get into trouble.) The error used by the
+ * device is NO_RESOURCES, so use that here too.
+ */
+
+ if (produceQSize + consumeQSize < MAX(produceQSize, consumeQSize) ||
+ produceQSize + consumeQSize > VMCI_MAX_GUEST_QP_MEMORY) {
+ return VMCI_ERROR_NO_RESOURCES;
+ }
+
myQPair = VMCI_AllocKernelMem(sizeof *myQPair, VMCI_MEMORY_NONPAGED);
if (!myQPair) {
return VMCI_ERROR_NO_MEM;
sizeof *queue + sizeof *(queue->kernelIf) +
numDataPages * sizeof *(queue->kernelIf->page);
+ /*
+ * Size should be enforced by VMCIQPair_Alloc(), double-check here.
+ * Allocating too much on Linux can cause the system to become
+ * unresponsive, because we allocate page-by-page, and we allow the
+ * system to wait for pages rather than fail.
+ */
+ if (size > VMCI_MAX_GUEST_QP_MEMORY) {
+ ASSERT(FALSE);
+ return NULL;
+ }
+
qHeader = (VMCIQueueHeader *)vmalloc(queueSize);
if (!qHeader) {
return NULL;
#ifndef _VMCI_VERSION_H_
#define _VMCI_VERSION_H_
-#define VMCI_DRIVER_VERSION 9.1.15.0
-#define VMCI_DRIVER_VERSION_COMMAS 9,1,15,0
-#define VMCI_DRIVER_VERSION_STRING "9.1.15.0"
+#define VMCI_DRIVER_VERSION 9.1.16.0
+#define VMCI_DRIVER_VERSION_COMMAS 9,1,16,0
+#define VMCI_DRIVER_VERSION_STRING "9.1.16.0"
#endif /* _VMCI_VERSION_H_ */