VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h@ 96399

Last change on this file since 96399 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.7 KB
Line 
1/* $Id: VBoxGuestInternal.h 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * VBoxGuest - Guest Additions Driver, Internal Header.
4 */
5
6/*
7 * Copyright (C) 2010-2022 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 GA_INCLUDED_SRC_common_VBoxGuest_VBoxGuestInternal_h
28#define GA_INCLUDED_SRC_common_VBoxGuest_VBoxGuestInternal_h
29#ifndef RT_WITHOUT_PRAGMA_ONCE
30# pragma once
31#endif
32
33#include <iprt/types.h>
34#include <iprt/list.h>
35#include <iprt/semaphore.h>
36#include <iprt/spinlock.h>
37#include <iprt/timer.h>
38#include <VBox/VMMDev.h>
39#include <VBox/VBoxGuest.h>
40#include <VBox/VBoxGuestLib.h>
41
42/** @def VBOXGUEST_USE_DEFERRED_WAKE_UP
43 * Defer wake-up of waiting thread when defined. */
44#if defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
45# define VBOXGUEST_USE_DEFERRED_WAKE_UP
46#endif
47
48/** @def VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT
49 * The mouse notification callback can cause preemption and must not be invoked
50 * while holding a high-level spinlock.
51 */
52#if defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
53# define VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT
54#endif
55
56/** Pointer to the VBoxGuest per session data. */
57typedef struct VBOXGUESTSESSION *PVBOXGUESTSESSION;
58
59/** Pointer to a wait-for-event entry. */
60typedef struct VBOXGUESTWAIT *PVBOXGUESTWAIT;
61
62/**
63 * VBox guest wait for event entry.
64 *
65 * Each waiting thread allocates one of these items and adds
66 * it to the wait list before going to sleep on the event sem.
67 */
68typedef struct VBOXGUESTWAIT
69{
70 /** The list node. */
71 RTLISTNODE ListNode;
72 /** The events we are waiting on. */
73 uint32_t fReqEvents;
74 /** The events we received. */
75 uint32_t volatile fResEvents;
76#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
77 /** Set by VGDrvCommonWaitDoWakeUps before leaving the spinlock to call
78 * RTSemEventMultiSignal. */
79 bool volatile fPendingWakeUp;
80 /** Set by the requestor thread if it got the spinlock before the
81 * signaller. Deals with the race in VGDrvCommonWaitDoWakeUps. */
82 bool volatile fFreeMe;
83#endif
84 /** The event semaphore. */
85 RTSEMEVENTMULTI Event;
86 /** The session that's waiting. */
87 PVBOXGUESTSESSION pSession;
88#ifdef VBOX_WITH_HGCM
89 /** The HGCM request we're waiting for to complete. */
90 VMMDevHGCMRequestHeader volatile *pHGCMReq;
91#endif
92} VBOXGUESTWAIT;
93
94
95/**
96 * VBox guest memory balloon.
97 */
98typedef struct VBOXGUESTMEMBALLOON
99{
100 /** Mutex protecting the members below from concurrent access. */
101 RTSEMFASTMUTEX hMtx;
102 /** The current number of chunks in the balloon. */
103 uint32_t cChunks;
104 /** The maximum number of chunks in the balloon (typically the amount of guest
105 * memory / chunksize). */
106 uint32_t cMaxChunks;
107 /** This is true if we are using RTR0MemObjAllocPhysNC() / RTR0MemObjGetPagePhysAddr()
108 * and false otherwise. */
109 bool fUseKernelAPI;
110 /** The current owner of the balloon.
111 * This is automatically assigned to the first session using the ballooning
112 * API and first released when the session closes. */
113 PVBOXGUESTSESSION pOwner;
114 /** The pointer to the array of memory objects holding the chunks of the
115 * balloon. This array is cMaxChunks in size when present. */
116 PRTR0MEMOBJ paMemObj;
117} VBOXGUESTMEMBALLOON;
118/** Pointer to a memory balloon. */
119typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON;
120
121
122/**
123 * Per bit usage tracker for a uint32_t mask.
124 *
125 * Used for optimal handling of guest properties, mouse status and event filter.
126 */
127typedef struct VBOXGUESTBITUSAGETRACER
128{
129 /** Per bit usage counters. */
130 uint32_t acPerBitUsage[32];
131 /** The current mask according to acPerBitUsage. */
132 uint32_t fMask;
133} VBOXGUESTBITUSAGETRACER;
134/** Pointer to a per bit usage tracker. */
135typedef VBOXGUESTBITUSAGETRACER *PVBOXGUESTBITUSAGETRACER;
136/** Pointer to a const per bit usage tracker. */
137typedef VBOXGUESTBITUSAGETRACER const *PCVBOXGUESTBITUSAGETRACER;
138
139
140/**
141 * VBox guest device (data) extension.
142 */
143typedef struct VBOXGUESTDEVEXT
144{
145 /** VBOXGUESTDEVEXT_INIT_STATE_XXX. */
146 uint32_t uInitState;
147 /** The base of the adapter I/O ports. */
148 RTIOPORT IOPortBase;
149 /** Pointer to the mapping of the VMMDev adapter memory. */
150 VMMDevMemory volatile *pVMMDevMemory;
151 /** The memory object reserving space for the guest mappings. */
152 RTR0MEMOBJ hGuestMappings;
153 /** Spinlock protecting the signaling and resetting of the wait-for-event
154 * semaphores as well as the event acking in the ISR. */
155 RTSPINLOCK EventSpinlock;
156 /** Host feature flags (VMMDEV_HVF_XXX). */
157 uint32_t fHostFeatures;
158 /** Preallocated VMMDevEvents for the IRQ handler. */
159 VMMDevEvents *pIrqAckEvents;
160 /** The physical address of pIrqAckEvents. */
161 RTCCPHYS PhysIrqAckEvents;
162 /** Wait-for-event list for threads waiting for multiple events
163 * (VBOXGUESTWAIT). */
164 RTLISTANCHOR WaitList;
165#ifdef VBOX_WITH_HGCM
166 /** Wait-for-event list for threads waiting on HGCM async completion
167 * (VBOXGUESTWAIT).
168 *
169 * The entire list is evaluated upon the arrival of an HGCM event, unlike
170 * the other lists which are only evaluated till the first thread has
171 * been woken up. */
172 RTLISTANCHOR HGCMWaitList;
173#endif
174#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
175 /** List of wait-for-event entries that needs waking up
176 * (VBOXGUESTWAIT). */
177 RTLISTANCHOR WakeUpList;
178#endif
179 /** List of wait-for-event entries that has been woken up
180 * (VBOXGUESTWAIT). */
181 RTLISTANCHOR WokenUpList;
182 /** List of free wait-for-event entries (VBOXGUESTWAIT). */
183 RTLISTANCHOR FreeList;
184 /** Mask of pending events. */
185 uint32_t volatile f32PendingEvents;
186 /** Current VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
187 * Used to implement polling. */
188 uint32_t volatile u32MousePosChangedSeq;
189
190 /** Spinlock various items in the VBOXGUESTSESSION. */
191 RTSPINLOCK SessionSpinlock;
192 /** List of guest sessions (VBOXGUESTSESSION). We currently traverse this
193 * but do not search it, so a list data type should be fine. Use under the
194 * #SessionSpinlock lock. */
195 RTLISTANCHOR SessionList;
196 /** Number of session. */
197 uint32_t cSessions;
198 /** Flag indicating whether logging to the release log
199 * is enabled. */
200 bool fLoggingEnabled;
201 /** Memory balloon information for RTR0MemObjAllocPhysNC(). */
202 VBOXGUESTMEMBALLOON MemBalloon;
203 /** Mouse notification callback function. */
204 PFNVBOXGUESTMOUSENOTIFY pfnMouseNotifyCallback;
205 /** The callback argument for the mouse ntofication callback. */
206 void *pvMouseNotifyCallbackArg;
207
208 /** @name Host Event Filtering
209 * @{ */
210 /** Events we won't permit anyone to filter out. */
211 uint32_t fFixedEvents;
212 /** Usage counters for the host events. (Fixed events are not included.) */
213 VBOXGUESTBITUSAGETRACER EventFilterTracker;
214 /** The event filter last reported to the host (UINT32_MAX on failure). */
215 uint32_t fEventFilterHost;
216 /** @} */
217
218 /** @name Mouse Status
219 * @{ */
220 /** Usage counters for the mouse statuses (VMMDEV_MOUSE_XXX). */
221 VBOXGUESTBITUSAGETRACER MouseStatusTracker;
222 /** The mouse status last reported to the host (UINT32_MAX on failure). */
223 uint32_t fMouseStatusHost;
224 /** @} */
225
226 /** @name Guest Capabilities
227 * @{ */
228 /** Guest capabilities which have been set to "acquire" mode. This means
229 * that only one session can use them at a time, and that they will be
230 * automatically cleaned up if that session exits without doing so.
231 *
232 * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
233 * without holding the lock in a couple of places. */
234 uint32_t volatile fAcquireModeGuestCaps;
235 /** Guest capabilities which have been set to "set" mode. This just means
236 * that they have been blocked from ever being set to "acquire" mode. */
237 uint32_t fSetModeGuestCaps;
238 /** Mask of all capabilities which are currently acquired by some session
239 * and as such reported to the host. */
240 uint32_t fAcquiredGuestCaps;
241 /** Usage counters for guest capabilities in "set" mode. Indexed by
242 * capability bit number, one count per session using a capability. */
243 VBOXGUESTBITUSAGETRACER SetGuestCapsTracker;
244 /** The guest capabilities last reported to the host (UINT32_MAX on failure). */
245 uint32_t fGuestCapsHost;
246 /** @} */
247
248 /** Heartbeat timer which fires with interval
249 * cNsHearbeatInterval and its handler sends
250 * VMMDevReq_GuestHeartbeat to VMMDev. */
251 PRTTIMER pHeartbeatTimer;
252 /** Heartbeat timer interval in nanoseconds. */
253 uint64_t cNsHeartbeatInterval;
254 /** Preallocated VMMDevReq_GuestHeartbeat request. */
255 VMMDevRequestHeader *pReqGuestHeartbeat;
256} VBOXGUESTDEVEXT;
257/** Pointer to the VBoxGuest driver data. */
258typedef VBOXGUESTDEVEXT *PVBOXGUESTDEVEXT;
259
260/** @name VBOXGUESTDEVEXT_INIT_STATE_XXX - magic values for validating init
261 * state of the device extension structur.
262 * @{ */
263#define VBOXGUESTDEVEXT_INIT_STATE_FUNDAMENT UINT32_C(0x0badcafe)
264#define VBOXGUESTDEVEXT_INIT_STATE_RESOURCES UINT32_C(0xcafebabe)
265#define VBOXGUESTDEVEXT_INIT_STATE_DELETED UINT32_C(0xdeadd0d0)
266/** @} */
267
268/**
269 * The VBoxGuest per session data.
270 */
271typedef struct VBOXGUESTSESSION
272{
273 /** The list node. */
274 RTLISTNODE ListNode;
275#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
276 /** Pointer to the next session with the same hash. */
277 PVBOXGUESTSESSION pNextHash;
278#endif
279#if defined(RT_OS_OS2)
280 /** The system file number of this session. */
281 uint16_t sfn;
282 uint16_t Alignment; /**< Alignment */
283#endif
284 /** The requestor information to pass to the host for this session.
285 * @sa VMMDevRequestHeader::fRequestor */
286 uint32_t fRequestor;
287 /** The process (id) of the session.
288 * This is NIL if it's a kernel session. */
289 RTPROCESS Process;
290 /** Which process this session is associated with.
291 * This is NIL if it's a kernel session. */
292 RTR0PROCESS R0Process;
293 /** Pointer to the device extension. */
294 PVBOXGUESTDEVEXT pDevExt;
295
296#ifdef VBOX_WITH_HGCM
297 /** Array containing HGCM client IDs associated with this session.
298 * This will be automatically disconnected when the session is closed. */
299 uint32_t volatile aHGCMClientIds[64];
300#endif
301 /** The last consumed VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
302 * Used to implement polling. */
303 uint32_t volatile u32MousePosChangedSeq;
304 /** Host events requested by the session.
305 * An event type requested in any guest session will be added to the host
306 * filter. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */
307 uint32_t fEventFilter;
308 /** Guest capabilities held in "acquired" by this session.
309 * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
310 * without holding the lock in a couple of places. */
311 uint32_t volatile fAcquiredGuestCaps;
312 /** Guest capabilities in "set" mode for this session.
313 * These accumulated for sessions via VBOXGUESTDEVEXT::acGuestCapsSet and
314 * reported to the host. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */
315 uint32_t fCapabilities;
316 /** Mouse features supported. A feature enabled in any guest session will
317 * be enabled for the host.
318 * @note We invert the VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR feature in this
319 * bitmap. The logic of this is that the real feature is when the host
320 * cursor is not needed, and we tell the host it is not needed if any
321 * session explicitly fails to assert it. Storing it inverted simplifies
322 * the checks.
323 * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
324 uint32_t fMouseStatus;
325#ifdef RT_OS_DARWIN
326 /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
327 void *pvVBoxGuestClient;
328 /** Whether this session has been opened or not. */
329 bool fOpened;
330#endif
331 /** Whether a CANCEL_ALL_WAITEVENTS is pending. This happens when
332 * CANCEL_ALL_WAITEVENTS is called, but no call to WAITEVENT is in process
333 * in the current session. In that case the next call will be interrupted
334 * at once. */
335 bool volatile fPendingCancelWaitEvents;
336 /** Does this session belong to a root process or a user one? */
337 bool fUserSession;
338} VBOXGUESTSESSION;
339
340RT_C_DECLS_BEGIN
341
342int VGDrvCommonInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase, void *pvMMIOBase, uint32_t cbMMIO,
343 VBOXOSTYPE enmOSType, uint32_t fEvents);
344void VGDrvCommonDeleteDevExt(PVBOXGUESTDEVEXT pDevExt);
345
346int VGDrvCommonInitLoggers(void);
347void VGDrvCommonDestroyLoggers(void);
348int VGDrvCommonInitDevExtFundament(PVBOXGUESTDEVEXT pDevExt);
349void VGDrvCommonDeleteDevExtFundament(PVBOXGUESTDEVEXT pDevExt);
350int VGDrvCommonInitDevExtResources(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
351 void *pvMMIOBase, uint32_t cbMMIO, VBOXOSTYPE enmOSType, uint32_t fFixedEvents);
352void VGDrvCommonDeleteDevExtResources(PVBOXGUESTDEVEXT pDevExt);
353int VGDrvCommonReinitDevExtAfterHibernation(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enmOSType);
354
355bool VBDrvCommonIsOptionValueTrue(const char *pszValue);
356void VGDrvCommonProcessOption(PVBOXGUESTDEVEXT pDevExt, const char *pszName, const char *pszValue);
357void VGDrvCommonProcessOptionsFromHost(PVBOXGUESTDEVEXT pDevExt);
358bool VGDrvCommonIsOurIRQ(PVBOXGUESTDEVEXT pDevExt);
359bool VGDrvCommonISR(PVBOXGUESTDEVEXT pDevExt);
360
361#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
362void VGDrvCommonWaitDoWakeUps(PVBOXGUESTDEVEXT pDevExt);
363#endif
364
365int VGDrvCommonCreateUserSession(PVBOXGUESTDEVEXT pDevExt, uint32_t fRequestor, PVBOXGUESTSESSION *ppSession);
366int VGDrvCommonCreateKernelSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession);
367void VGDrvCommonCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
368
369int VGDrvCommonIoCtlFast(uintptr_t iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
370int VGDrvCommonIoCtl(uintptr_t iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
371 PVBGLREQHDR pReqHdr, size_t cbReq);
372
373/**
374 * ISR callback for notifying threads polling for mouse events.
375 *
376 * This is called at the end of the ISR, after leaving the event spinlock, if
377 * VMMDEV_EVENT_MOUSE_POSITION_CHANGED was raised by the host.
378 *
379 * @param pDevExt The device extension.
380 */
381void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt);
382
383/**
384 * Hook for handling OS specfic options from the host.
385 *
386 * @returns true if handled, false if not.
387 * @param pDevExt The device extension.
388 * @param pszName The option name.
389 * @param pszValue The option value.
390 */
391bool VGDrvNativeProcessOption(PVBOXGUESTDEVEXT pDevExt, const char *pszName, const char *pszValue);
392
393
394#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
395int VGDrvNtIOCtl_DpcLatencyChecker(void);
396#endif
397
398#ifdef VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT
399int VGDrvNativeSetMouseNotifyCallback(PVBOXGUESTDEVEXT pDevExt, PVBGLIOCSETMOUSENOTIFYCALLBACK pNotify);
400#endif
401
402RT_C_DECLS_END
403
404#endif /* !GA_INCLUDED_SRC_common_VBoxGuest_VBoxGuestInternal_h */
405
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette