]>
Commit | Line | Data |
---|---|---|
39adb5c3 TG |
1 | /* $Id: VBoxGuestInternal.h $ */ |
2 | /** @file | |
3 | * VBoxGuest - Guest Additions Driver, Internal Header. | |
4 | */ | |
5 | ||
6 | /* | |
7 | * Copyright (C) 2010-2016 Oracle Corporation | |
8 | * | |
9 | * This file is part of VirtualBox Open Source Edition (OSE), as | |
10 | * available from http://www.virtualbox.org. This file is free software; | |
11 | * you can redistribute it and/or modify it under the terms of the GNU | |
12 | * General Public License (GPL) as published by the Free Software | |
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the | |
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the | |
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. | |
16 | * | |
17 | * The contents of this file may alternatively be used under the terms | |
18 | * of the Common Development and Distribution License Version 1.0 | |
19 | * (CDDL) only, as it comes in the "COPYING.CDDL" file of the | |
20 | * VirtualBox OSE distribution, in which case the provisions of the | |
21 | * CDDL are applicable instead of those of the GPL. | |
22 | * | |
23 | * You may elect to license modified versions of this file under the | |
24 | * terms and conditions of either the GPL or the CDDL or both. | |
25 | */ | |
26 | ||
27 | #ifndef ___VBoxGuestInternal_h | |
28 | #define ___VBoxGuestInternal_h | |
29 | ||
30 | #include <iprt/types.h> | |
31 | #include <iprt/list.h> | |
32 | #include <iprt/semaphore.h> | |
33 | #include <iprt/spinlock.h> | |
34 | #include <iprt/timer.h> | |
35 | #include <VBox/VMMDev.h> | |
36 | #include <VBox/VBoxGuest.h> | |
37 | #include <VBox/VBoxGuestLib.h> | |
38 | ||
39 | /** @def VBOXGUEST_USE_DEFERRED_WAKE_UP | |
40 | * Defer wake-up of waiting thread when defined. */ | |
41 | #if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING) | |
42 | # define VBOXGUEST_USE_DEFERRED_WAKE_UP | |
43 | #endif | |
44 | ||
5410645a SF |
45 | /** @def VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT |
46 | * The mouse notification callback can cause preemption and must not be invoked | |
47 | * while holding a high-level spinlock. | |
48 | */ | |
49 | #if defined(RT_OS_SOLARIS) || defined(DOXYGEN_RUNNING) | |
50 | # define VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT | |
51 | #endif | |
39adb5c3 TG |
52 | |
53 | /** Pointer to the VBoxGuest per session data. */ | |
54 | typedef struct VBOXGUESTSESSION *PVBOXGUESTSESSION; | |
55 | ||
56 | /** Pointer to a wait-for-event entry. */ | |
57 | typedef struct VBOXGUESTWAIT *PVBOXGUESTWAIT; | |
58 | ||
59 | /** | |
60 | * VBox guest wait for event entry. | |
61 | * | |
62 | * Each waiting thread allocates one of these items and adds | |
63 | * it to the wait list before going to sleep on the event sem. | |
64 | */ | |
65 | typedef struct VBOXGUESTWAIT | |
66 | { | |
67 | /** The list node. */ | |
68 | RTLISTNODE ListNode; | |
69 | /** The events we are waiting on. */ | |
70 | uint32_t fReqEvents; | |
71 | /** The events we received. */ | |
72 | uint32_t volatile fResEvents; | |
73 | #ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP | |
74 | /** Set by VGDrvCommonWaitDoWakeUps before leaving the spinlock to call | |
75 | * RTSemEventMultiSignal. */ | |
76 | bool volatile fPendingWakeUp; | |
77 | /** Set by the requestor thread if it got the spinlock before the | |
78 | * signaller. Deals with the race in VGDrvCommonWaitDoWakeUps. */ | |
79 | bool volatile fFreeMe; | |
80 | #endif | |
81 | /** The event semaphore. */ | |
82 | RTSEMEVENTMULTI Event; | |
83 | /** The session that's waiting. */ | |
84 | PVBOXGUESTSESSION pSession; | |
85 | #ifdef VBOX_WITH_HGCM | |
86 | /** The HGCM request we're waiting for to complete. */ | |
87 | VMMDevHGCMRequestHeader volatile *pHGCMReq; | |
88 | #endif | |
89 | } VBOXGUESTWAIT; | |
90 | ||
91 | ||
92 | /** | |
93 | * VBox guest memory balloon. | |
94 | */ | |
95 | typedef struct VBOXGUESTMEMBALLOON | |
96 | { | |
97 | /** Mutex protecting the members below from concurrent access. */ | |
98 | RTSEMFASTMUTEX hMtx; | |
99 | /** The current number of chunks in the balloon. */ | |
100 | uint32_t cChunks; | |
101 | /** The maximum number of chunks in the balloon (typically the amount of guest | |
102 | * memory / chunksize). */ | |
103 | uint32_t cMaxChunks; | |
104 | /** This is true if we are using RTR0MemObjAllocPhysNC() / RTR0MemObjGetPagePhysAddr() | |
105 | * and false otherwise. */ | |
106 | bool fUseKernelAPI; | |
107 | /** The current owner of the balloon. | |
108 | * This is automatically assigned to the first session using the ballooning | |
109 | * API and first released when the session closes. */ | |
110 | PVBOXGUESTSESSION pOwner; | |
111 | /** The pointer to the array of memory objects holding the chunks of the | |
112 | * balloon. This array is cMaxChunks in size when present. */ | |
113 | PRTR0MEMOBJ paMemObj; | |
114 | } VBOXGUESTMEMBALLOON; | |
115 | /** Pointer to a memory balloon. */ | |
116 | typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON; | |
117 | ||
118 | ||
119 | /** | |
120 | * Per bit usage tracker for a uint32_t mask. | |
121 | * | |
122 | * Used for optimal handling of guest properties, mouse status and event filter. | |
123 | */ | |
124 | typedef struct VBOXGUESTBITUSAGETRACER | |
125 | { | |
126 | /** Per bit usage counters. */ | |
127 | uint32_t acPerBitUsage[32]; | |
128 | /** The current mask according to acPerBitUsage. */ | |
129 | uint32_t fMask; | |
130 | } VBOXGUESTBITUSAGETRACER; | |
131 | /** Pointer to a per bit usage tracker. */ | |
132 | typedef VBOXGUESTBITUSAGETRACER *PVBOXGUESTBITUSAGETRACER; | |
133 | /** Pointer to a const per bit usage tracker. */ | |
134 | typedef VBOXGUESTBITUSAGETRACER const *PCVBOXGUESTBITUSAGETRACER; | |
135 | ||
136 | ||
137 | /** | |
138 | * VBox guest device (data) extension. | |
139 | */ | |
140 | typedef struct VBOXGUESTDEVEXT | |
141 | { | |
142 | /** The base of the adapter I/O ports. */ | |
143 | RTIOPORT IOPortBase; | |
144 | /** Pointer to the mapping of the VMMDev adapter memory. */ | |
145 | VMMDevMemory volatile *pVMMDevMemory; | |
146 | /** The memory object reserving space for the guest mappings. */ | |
147 | RTR0MEMOBJ hGuestMappings; | |
148 | /** Spinlock protecting the signaling and resetting of the wait-for-event | |
149 | * semaphores as well as the event acking in the ISR. */ | |
150 | RTSPINLOCK EventSpinlock; | |
151 | /** Preallocated VMMDevEvents for the IRQ handler. */ | |
152 | VMMDevEvents *pIrqAckEvents; | |
153 | /** The physical address of pIrqAckEvents. */ | |
154 | RTCCPHYS PhysIrqAckEvents; | |
155 | /** Wait-for-event list for threads waiting for multiple events | |
156 | * (VBOXGUESTWAIT). */ | |
157 | RTLISTANCHOR WaitList; | |
158 | #ifdef VBOX_WITH_HGCM | |
159 | /** Wait-for-event list for threads waiting on HGCM async completion | |
160 | * (VBOXGUESTWAIT). | |
161 | * | |
162 | * The entire list is evaluated upon the arrival of an HGCM event, unlike | |
163 | * the other lists which are only evaluated till the first thread has | |
164 | * been woken up. */ | |
165 | RTLISTANCHOR HGCMWaitList; | |
166 | #endif | |
167 | #ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP | |
168 | /** List of wait-for-event entries that needs waking up | |
169 | * (VBOXGUESTWAIT). */ | |
170 | RTLISTANCHOR WakeUpList; | |
171 | #endif | |
172 | /** List of wait-for-event entries that has been woken up | |
173 | * (VBOXGUESTWAIT). */ | |
174 | RTLISTANCHOR WokenUpList; | |
175 | /** List of free wait-for-event entries (VBOXGUESTWAIT). */ | |
176 | RTLISTANCHOR FreeList; | |
177 | /** Mask of pending events. */ | |
178 | uint32_t volatile f32PendingEvents; | |
179 | /** Current VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number. | |
180 | * Used to implement polling. */ | |
181 | uint32_t volatile u32MousePosChangedSeq; | |
182 | ||
183 | /** Spinlock various items in the VBOXGUESTSESSION. */ | |
184 | RTSPINLOCK SessionSpinlock; | |
185 | /** List of guest sessions (VBOXGUESTSESSION). We currently traverse this | |
186 | * but do not search it, so a list data type should be fine. Use under the | |
187 | * #SessionSpinlock lock. */ | |
188 | RTLISTANCHOR SessionList; | |
189 | /** Number of session. */ | |
190 | uint32_t cSessions; | |
191 | /** Flag indicating whether logging to the release log | |
192 | * is enabled. */ | |
193 | bool fLoggingEnabled; | |
194 | /** Memory balloon information for RTR0MemObjAllocPhysNC(). */ | |
195 | VBOXGUESTMEMBALLOON MemBalloon; | |
196 | /** Callback and user data for a kernel mouse handler. */ | |
197 | VBoxGuestMouseSetNotifyCallback MouseNotifyCallback; | |
198 | ||
199 | /** @name Host Event Filtering | |
200 | * @{ */ | |
201 | /** Events we won't permit anyone to filter out. */ | |
202 | uint32_t fFixedEvents; | |
203 | /** Usage counters for the host events. (Fixed events are not included.) */ | |
204 | VBOXGUESTBITUSAGETRACER EventFilterTracker; | |
205 | /** The event filter last reported to the host (UINT32_MAX on failure). */ | |
206 | uint32_t fEventFilterHost; | |
207 | /** @} */ | |
208 | ||
209 | /** @name Mouse Status | |
210 | * @{ */ | |
211 | /** Usage counters for the mouse statuses (VMMDEV_MOUSE_XXX). */ | |
212 | VBOXGUESTBITUSAGETRACER MouseStatusTracker; | |
213 | /** The mouse status last reported to the host (UINT32_MAX on failure). */ | |
214 | uint32_t fMouseStatusHost; | |
215 | /** @} */ | |
216 | ||
217 | /** @name Guest Capabilities | |
218 | * @{ */ | |
219 | /** Guest capabilities which have been set to "acquire" mode. This means | |
220 | * that only one session can use them at a time, and that they will be | |
221 | * automatically cleaned up if that session exits without doing so. | |
222 | * | |
223 | * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read | |
224 | * without holding the lock in a couple of places. */ | |
225 | uint32_t volatile fAcquireModeGuestCaps; | |
226 | /** Guest capabilities which have been set to "set" mode. This just means | |
227 | * that they have been blocked from ever being set to "acquire" mode. */ | |
228 | uint32_t fSetModeGuestCaps; | |
229 | /** Mask of all capabilities which are currently acquired by some session | |
230 | * and as such reported to the host. */ | |
231 | uint32_t fAcquiredGuestCaps; | |
232 | /** Usage counters for guest capabilities in "set" mode. Indexed by | |
233 | * capability bit number, one count per session using a capability. */ | |
234 | VBOXGUESTBITUSAGETRACER SetGuestCapsTracker; | |
235 | /** The guest capabilities last reported to the host (UINT32_MAX on failure). */ | |
236 | uint32_t fGuestCapsHost; | |
237 | /** @} */ | |
238 | ||
239 | /** Heartbeat timer which fires with interval | |
240 | * cNsHearbeatInterval and its handler sends | |
241 | * VMMDevReq_GuestHeartbeat to VMMDev. */ | |
242 | PRTTIMER pHeartbeatTimer; | |
243 | /** Heartbeat timer interval in nanoseconds. */ | |
244 | uint64_t cNsHeartbeatInterval; | |
245 | /** Preallocated VMMDevReq_GuestHeartbeat request. */ | |
246 | VMMDevRequestHeader *pReqGuestHeartbeat; | |
247 | } VBOXGUESTDEVEXT; | |
248 | /** Pointer to the VBoxGuest driver data. */ | |
249 | typedef VBOXGUESTDEVEXT *PVBOXGUESTDEVEXT; | |
250 | ||
251 | ||
252 | /** | |
253 | * The VBoxGuest per session data. | |
254 | */ | |
255 | typedef struct VBOXGUESTSESSION | |
256 | { | |
257 | /** The list node. */ | |
258 | RTLISTNODE ListNode; | |
259 | #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS) | |
260 | /** Pointer to the next session with the same hash. */ | |
261 | PVBOXGUESTSESSION pNextHash; | |
262 | #endif | |
263 | #if defined(RT_OS_OS2) | |
264 | /** The system file number of this session. */ | |
265 | uint16_t sfn; | |
266 | uint16_t Alignment; /**< Alignment */ | |
267 | #endif | |
268 | /** The process (id) of the session. | |
269 | * This is NIL if it's a kernel session. */ | |
270 | RTPROCESS Process; | |
271 | /** Which process this session is associated with. | |
272 | * This is NIL if it's a kernel session. */ | |
273 | RTR0PROCESS R0Process; | |
274 | /** Pointer to the device extension. */ | |
275 | PVBOXGUESTDEVEXT pDevExt; | |
276 | ||
277 | #ifdef VBOX_WITH_HGCM | |
278 | /** Array containing HGCM client IDs associated with this session. | |
279 | * This will be automatically disconnected when the session is closed. */ | |
280 | uint32_t volatile aHGCMClientIds[64]; | |
281 | #endif | |
282 | /** The last consumed VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number. | |
283 | * Used to implement polling. */ | |
284 | uint32_t volatile u32MousePosChangedSeq; | |
285 | /** Host events requested by the session. | |
286 | * An event type requested in any guest session will be added to the host | |
287 | * filter. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */ | |
288 | uint32_t fEventFilter; | |
289 | /** Guest capabilities held in "acquired" by this session. | |
290 | * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read | |
291 | * without holding the lock in a couple of places. */ | |
292 | uint32_t volatile fAcquiredGuestCaps; | |
293 | /** Guest capabilities in "set" mode for this session. | |
294 | * These accumulated for sessions via VBOXGUESTDEVEXT::acGuestCapsSet and | |
295 | * reported to the host. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */ | |
296 | uint32_t fCapabilities; | |
297 | /** Mouse features supported. A feature enabled in any guest session will | |
298 | * be enabled for the host. | |
299 | * @note We invert the VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR feature in this | |
300 | * bitmap. The logic of this is that the real feature is when the host | |
301 | * cursor is not needed, and we tell the host it is not needed if any | |
302 | * session explicitly fails to assert it. Storing it inverted simplifies | |
303 | * the checks. | |
304 | * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */ | |
305 | uint32_t fMouseStatus; | |
306 | #ifdef RT_OS_DARWIN | |
307 | /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */ | |
308 | void *pvVBoxGuestClient; | |
309 | /** Whether this session has been opened or not. */ | |
310 | bool fOpened; | |
311 | #endif | |
312 | /** Whether a CANCEL_ALL_WAITEVENTS is pending. This happens when | |
313 | * CANCEL_ALL_WAITEVENTS is called, but no call to WAITEVENT is in process | |
314 | * in the current session. In that case the next call will be interrupted | |
315 | * at once. */ | |
316 | bool volatile fPendingCancelWaitEvents; | |
317 | /** Does this session belong to a root process or a user one? */ | |
318 | bool fUserSession; | |
319 | } VBOXGUESTSESSION; | |
320 | ||
321 | RT_C_DECLS_BEGIN | |
322 | ||
323 | int VGDrvCommonInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase, void *pvMMIOBase, uint32_t cbMMIO, | |
324 | VBOXOSTYPE enmOSType, uint32_t fEvents); | |
5410645a | 325 | bool VGDrvCommonIsOurIRQ(PVBOXGUESTDEVEXT pDevExt); |
39adb5c3 TG |
326 | bool VGDrvCommonISR(PVBOXGUESTDEVEXT pDevExt); |
327 | void VGDrvCommonDeleteDevExt(PVBOXGUESTDEVEXT pDevExt); | |
328 | int VGDrvCommonReinitDevExtAfterHibernation(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enmOSType); | |
329 | #ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP | |
330 | void VGDrvCommonWaitDoWakeUps(PVBOXGUESTDEVEXT pDevExt); | |
331 | #endif | |
332 | ||
333 | int VGDrvCommonCreateUserSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession); | |
334 | int VGDrvCommonCreateKernelSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession); | |
335 | void VGDrvCommonCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession); | |
336 | ||
337 | int VGDrvCommonIoCtlFast(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession); | |
338 | int VGDrvCommonIoCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, | |
339 | void *pvData, size_t cbData, size_t *pcbDataReturned); | |
340 | ||
341 | /** | |
342 | * ISR callback for notifying threads polling for mouse events. | |
343 | * | |
344 | * This is called at the end of the ISR, after leaving the event spinlock, if | |
345 | * VMMDEV_EVENT_MOUSE_POSITION_CHANGED was raised by the host. | |
346 | * | |
347 | * @param pDevExt The device extension. | |
348 | */ | |
349 | void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt); | |
350 | ||
351 | ||
352 | #ifdef VBOX_WITH_DPC_LATENCY_CHECKER | |
353 | int VGDrvNtIOCtl_DpcLatencyChecker(void); | |
354 | #endif | |
355 | ||
5410645a SF |
356 | #ifdef VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT |
357 | int VGDrvNativeSetMouseNotifyCallback(PVBOXGUESTDEVEXT pDevExt, VBoxGuestMouseSetNotifyCallback *pNotify); | |
358 | #endif | |
359 | ||
39adb5c3 TG |
360 | RT_C_DECLS_END |
361 | ||
362 | #endif | |
363 |