VirtualBox

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

Last change on this file since 98103 was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use