134
139
typedef kmutex_t VMCIMutex;
135
140
typedef PPN *VMCIPpnList; /* List of PPNs in produce/consume queue. */
136
141
typedef uid_t VMCIHostUser;
142
typedef VA64 VMCIQPGuestMem;
137
143
#endif // VMKERNEL
139
145
/* Callback needed for correctly waiting on events. */
140
146
typedef int (*VMCIEventReleaseCB)(void *clientData);
143
* The VMCI locks use a ranking scheme similar to the one used by
144
* vmkernel. While holding a lock L1 with rank R1, only locks with
145
* rank higher than R1 may be grabbed. The available ranks for VMCI
146
* locks are (in descending order):
147
* - VMCI_LOCK_RANK_HIGH_BH : to be used for locks grabbed while executing
148
* in a bottom half and not held while grabbing other locks.
149
* - VMCI_LOCK_RANK_MIDDLE_BH : to be for locks grabbed while executing in a
150
* bottom half and held while grabbing locks of rank VMCI_LOCK_RANK_HIGH_BH.
151
* - VMCI_LOCK_RANK_LOW_BH : to be for locks grabbed while executing in a
152
* bottom half and held while grabbing locks of rank
153
* VMCI_LOCK_RANK_MIDDLE_BH.
154
* - VMCI_LOCK_RANK_HIGHEST : to be used for locks that are not held while
155
* grabbing other locks except system locks with higher ranks and bottom
157
* - VMCI_LOCK_RANK_HIGHER : to be used for locks that are held while
158
* grabbing locks of rank VMCI_LOCK_RANK_HIGHEST or higher.
159
* - VMCI_LOCK_RANK_HIGH : to be used for locks that are held while
160
* grabbing locks of rank VMCI_LOCK_RANK_HIGHER or higher. This is
161
* the highest lock rank used by core VMCI services
162
* - VMCI_LOCK_RANK_MIDDLE : to be used for locks that are held while
163
* grabbing locks of rank VMCI_LOCK_RANK_HIGH or higher.
164
* - VMCI_LOCK_RANK_LOW : to be used for locks that are held while
165
* grabbing locks of rank VMCI_LOCK_RANK_MIDDLE or higher.
166
* - VMCI_LOCK_RANK_LOWEST : to be used for locks that are held while
167
* grabbing locks of rank VMCI_LOCK_RANK_LOW or higher.
149
* Internal locking dependencies within VMCI:
150
* * CONTEXTFIRE < CONTEXT, CONTEXTLIST, EVENT, HASHTABLE
151
* * DOORBELL < HASHTABLE
152
* * QPHIBERNATE < EVENT
170
typedef SP_Rank VMCILockRank;
172
#define VMCI_LOCK_RANK_HIGH_BH SP_RANK_IRQ_LEAF
173
#define VMCI_LOCK_RANK_MIDDLE_BH (SP_RANK_IRQ_LEAF-1)
174
#define VMCI_LOCK_RANK_LOW_BH SP_RANK_IRQ_LOWEST
175
#define VMCI_LOCK_RANK_HIGHEST SP_RANK_SHM_MGR-1
156
typedef Lock_Rank VMCILockRank;
157
typedef SemaRank VMCISemaRank;
159
#define VMCI_SEMA_RANK_QPHEADER (SEMA_RANK_FS - 1)
161
#define VMCI_LOCK_RANK_MAX (MIN(SP_RANK_WAIT, \
162
SP_RANK_HEAPLOCK_DYNAMIC) - 1)
177
164
typedef unsigned long VMCILockRank;
179
#define VMCI_LOCK_RANK_HIGHER_BH 0x8000
180
#define VMCI_LOCK_RANK_HIGH_BH 0x4000
181
#define VMCI_LOCK_RANK_MIDDLE_BH 0x2000
182
#define VMCI_LOCK_RANK_LOW_BH 0x1000
183
#define VMCI_LOCK_RANK_HIGHEST 0x0fff
165
typedef unsigned long VMCISemaRank;
167
#define VMCI_LOCK_RANK_MAX 0x0fff
169
#define VMCI_SEMA_RANK_QPHEADER 0x0fff
184
170
#endif // VMKERNEL
185
#define VMCI_LOCK_RANK_HIGHER (VMCI_LOCK_RANK_HIGHEST-1)
186
#define VMCI_LOCK_RANK_HIGH (VMCI_LOCK_RANK_HIGHER-1)
187
#define VMCI_LOCK_RANK_MIDDLE_HIGH (VMCI_LOCK_RANK_HIGH-1)
188
#define VMCI_LOCK_RANK_MIDDLE (VMCI_LOCK_RANK_MIDDLE_HIGH-1)
189
#define VMCI_LOCK_RANK_MIDDLE_LOW (VMCI_LOCK_RANK_MIDDLE-1)
190
#define VMCI_LOCK_RANK_LOW (VMCI_LOCK_RANK_MIDDLE_LOW-1)
191
#define VMCI_LOCK_RANK_LOWEST (VMCI_LOCK_RANK_LOW-1)
171
#define VMCI_LOCK_RANK_CONTEXT VMCI_LOCK_RANK_MAX
172
#define VMCI_LOCK_RANK_CONTEXTLIST VMCI_LOCK_RANK_MAX
173
#define VMCI_LOCK_RANK_DATAGRAMVMK VMCI_LOCK_RANK_MAX
174
#define VMCI_LOCK_RANK_EVENT VMCI_LOCK_RANK_MAX
175
#define VMCI_LOCK_RANK_HASHTABLE VMCI_LOCK_RANK_MAX
176
#define VMCI_LOCK_RANK_RESOURCE VMCI_LOCK_RANK_MAX
177
#define VMCI_LOCK_RANK_QPHEADER VMCI_LOCK_RANK_MAX
178
#define VMCI_LOCK_RANK_DOORBELL (VMCI_LOCK_RANK_HASHTABLE - 1)
179
#define VMCI_LOCK_RANK_CONTEXTFIRE (MIN(VMCI_LOCK_RANK_CONTEXT, \
180
MIN(VMCI_LOCK_RANK_CONTEXTLIST, \
181
MIN(VMCI_LOCK_RANK_EVENT, \
182
VMCI_LOCK_RANK_HASHTABLE))) - 1)
183
#define VMCI_LOCK_RANK_QPHIBERNATE (VMCI_LOCK_RANK_EVENT - 1)
184
#define VMCI_LOCK_RANK_PACKET_QP (VMCI_LOCK_RANK_QPHEADER - 1)
185
//#define VMCI_LOCK_RANK_PACKET_QP 0xffd /* For vVol */
187
#define VMCI_SEMA_RANK_QUEUEPAIRLIST (VMCI_SEMA_RANK_QPHEADER - 1)
188
#define VMCI_SEMA_RANK_GUESTMEM (VMCI_SEMA_RANK_QUEUEPAIRLIST - 1)
189
#define VMCI_SEMA_RANK_PACKET_QP (VMCI_SEMA_RANK_QPHEADER - 1)
190
//#define VMCI_SEMA_RANK_PACKET_QP 0xffd /* For vVol */
194
193
* Host specific struct used for signalling.
339
338
struct VMCIQueue;
341
#if !defined(VMKERNEL)
342
340
struct PageStoreAttachInfo;
343
341
struct VMCIQueue *VMCIHost_AllocQueue(uint64 queueSize);
344
342
void VMCIHost_FreeQueue(struct VMCIQueue *queue, uint64 queueSize);
346
int VMCIHost_GetUserMemory(struct PageStoreAttachInfo *attach,
347
struct VMCIQueue *produceQ,
348
struct VMCIQueue *detachQ);
349
void VMCIHost_ReleaseUserMemory(struct PageStoreAttachInfo *attach,
350
struct VMCIQueue *produceQ,
351
struct VMCIQueue *detachQ);
356
* Special routine used on the Windows platform to save a queue when
357
* its backing memory goes away.
360
void VMCIHost_SaveProduceQ(struct PageStoreAttachInfo *attach,
361
struct VMCIQueue *produceQ,
362
struct VMCIQueue *detachQ,
363
const uint64 produceQSize);
367
void VMCI_InitQueueMutex(struct VMCIQueue *produceQ,
368
struct VMCIQueue *consumeQ);
369
void VMCI_AcquireQueueMutex(struct VMCIQueue *queue);
370
void VMCI_ReleaseQueueMutex(struct VMCIQueue *queue);
371
Bool VMCI_EnqueueToDevNull(struct VMCIQueue *queue);
372
int VMCI_ConvertToLocalQueue(struct VMCIQueue *queueInfo,
373
struct VMCIQueue *otherQueueInfo,
374
uint64 size, Bool keepContent,
376
void VMCI_RevertToNonLocalQueue(struct VMCIQueue *queueInfo,
377
void *nonLocalQueue, uint64 size);
378
void VMCI_FreeQueueBuffer(void *queue, uint64 size);
379
Bool VMCI_CanCreate(void);
344
#if defined(VMKERNEL)
345
typedef World_Handle *VMCIGuestMemID;
346
#define INVALID_VMCI_GUEST_MEM_ID NULL
348
typedef uint32 VMCIGuestMemID;
349
#define INVALID_VMCI_GUEST_MEM_ID 0
352
#if defined(VMKERNEL) || defined(__linux__) || defined(_WIN32) || \
354
struct QueuePairPageStore;
355
int VMCIHost_RegisterUserMemory(struct QueuePairPageStore *pageStore,
356
struct VMCIQueue *produceQ,
357
struct VMCIQueue *consumeQ);
358
void VMCIHost_UnregisterUserMemory(struct VMCIQueue *produceQ,
359
struct VMCIQueue *consumeQ);
360
int VMCIHost_MapQueues(struct VMCIQueue *produceQ,
361
struct VMCIQueue *consumeQ,
363
int VMCIHost_UnmapQueues(VMCIGuestMemID gid,
364
struct VMCIQueue *produceQ,
365
struct VMCIQueue *consumeQ);
366
void VMCI_InitQueueMutex(struct VMCIQueue *produceQ,
367
struct VMCIQueue *consumeQ);
368
void VMCI_CleanupQueueMutex(struct VMCIQueue *produceQ,
369
struct VMCIQueue *consumeQ);
370
int VMCI_AcquireQueueMutex(struct VMCIQueue *queue, Bool canBlock);
371
void VMCI_ReleaseQueueMutex(struct VMCIQueue *queue);
372
#else // Below are the guest OS'es without host side support.
381
373
# define VMCI_InitQueueMutex(_pq, _cq)
382
# define VMCI_AcquireQueueMutex(_q)
374
# define VMCI_CleanupQueueMutex(_pq, _cq)
375
# define VMCI_AcquireQueueMutex(_q, _cb) VMCI_SUCCESS
383
376
# define VMCI_ReleaseQueueMutex(_q)
377
# define VMCIHost_RegisterUserMemory(_ps, _pq, _cq) VMCI_ERROR_UNAVAILABLE
378
# define VMCIHost_UnregisterUserMemory(_pq, _cq)
379
# define VMCIHost_MapQueues(_pq, _cq, _f) VMCI_SUCCESS
380
# define VMCIHost_UnmapQueues(_gid, _pq, _cq) VMCI_SUCCESS
383
#if defined(VMKERNEL)
384
void VMCIHost_MarkQueuesAvailable(struct VMCIQueue *produceQ,
385
struct VMCIQueue *consumeQ);
386
void VMCIHost_MarkQueuesUnavailable(struct VMCIQueue *produceQ,
387
struct VMCIQueue *consumeQ);
389
# define VMCIHost_MarkQueuesAvailable(_q, _p) while(0) { }
390
# define VMCIHost_MarkQueuesUnavailable(_q, _p) while(0) { }
393
#if defined(VMKERNEL) || defined(__linux__)
394
void VMCI_LockQueueHeader(struct VMCIQueue *queue);
395
void VMCI_UnlockQueueHeader(struct VMCIQueue *queue);
397
# define VMCI_LockQueueHeader(_q) ASSERT_NOT_IMPLEMENTED(FALSE)
398
# define VMCI_UnlockQueueHeader(_q) ASSERT_NOT_IMPLEMENTED(FALSE)
401
#if (!defined(VMKERNEL) && defined(__linux__)) || defined(_WIN32) || \
402
defined(__APPLE__) || defined(SOLARIS)
403
int VMCIHost_GetUserMemory(VA64 produceUVA, VA64 consumeUVA,
404
struct VMCIQueue *produceQ,
405
struct VMCIQueue *consumeQ);
406
void VMCIHost_ReleaseUserMemory(struct VMCIQueue *produceQ,
407
struct VMCIQueue *consumeQ);
409
# define VMCIHost_GetUserMemory(_puva, _cuva, _pq, _cq) VMCI_ERROR_UNAVAILABLE
410
# define VMCIHost_ReleaseUserMemory(_pq, _cq) ASSERT_NOT_IMPLEMENTED(FALSE)
414
Bool VMCI_EnqueueToDevNull(struct VMCIQueue *queue);
415
int VMCI_ConvertToLocalQueue(struct VMCIQueue *queueInfo,
416
struct VMCIQueue *otherQueueInfo,
417
uint64 size, Bool keepContent,
419
void VMCI_RevertToNonLocalQueue(struct VMCIQueue *queueInfo,
420
void *nonLocalQueue, uint64 size);
421
void VMCI_FreeQueueBuffer(void *queue, uint64 size);
422
Bool VMCI_CanCreate(void);
384
424
# define VMCI_EnqueueToDevNull(_q) FALSE
385
425
# define VMCI_ConvertToLocalQueue(_pq, _cq, _s, _oq, _kc) VMCI_ERROR_UNAVAILABLE
386
426
# define VMCI_RevertToNonLocalQueue(_q, _nlq, _s)