VirtualBox

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

Last change on this file was 100267, checked in by vboxsync, 10 months ago

Additions: Make the R0 physical heap configurable to allow for allocations >= 4GiB if supported by the VBox device (the MMIO request path is available), add support for the MMIO request path required for ARM, bugref:10457

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.3 KB
Line 
1/* $Id: VBoxGuestInternal.h 100267 2023-06-23 14:57:53Z 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 MMIO request region if available. */
160 uintptr_t volatile *pMmioReq;
161 /** Pointer to the fast request register in the MMIO region if available. */
162 uint32_t volatile *pMmioReqFast;
163 /** Pointer to the mapping of the VMMDev adapter memory. */
164 VMMDevMemory volatile *pVMMDevMemory;
165 /** The memory object reserving space for the guest mappings. */
166 RTR0MEMOBJ hGuestMappings;
167 /** Spinlock protecting the signaling and resetting of the wait-for-event
168 * semaphores as well as the event acking in the ISR. */
169 RTSPINLOCK EventSpinlock;
170 /** Host feature flags (VMMDEV_HVF_XXX). */
171 uint32_t fHostFeatures;
172 /** Preallocated VMMDevEvents for the IRQ handler. */
173 VMMDevEvents *pIrqAckEvents;
174 /** The physical address of pIrqAckEvents. */
175 RTCCPHYS PhysIrqAckEvents;
176 /** Wait-for-event list for threads waiting for multiple events
177 * (VBOXGUESTWAIT). */
178 RTLISTANCHOR WaitList;
179#ifdef VBOX_WITH_HGCM
180 /** Wait-for-event list for threads waiting on HGCM async completion
181 * (VBOXGUESTWAIT).
182 *
183 * The entire list is evaluated upon the arrival of an HGCM event, unlike
184 * the other lists which are only evaluated till the first thread has
185 * been woken up. */
186 RTLISTANCHOR HGCMWaitList;
187#endif
188#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
189 /** List of wait-for-event entries that needs waking up
190 * (VBOXGUESTWAIT). */
191 RTLISTANCHOR WakeUpList;
192#endif
193 /** List of wait-for-event entries that has been woken up
194 * (VBOXGUESTWAIT). */
195 RTLISTANCHOR WokenUpList;
196 /** List of free wait-for-event entries (VBOXGUESTWAIT). */
197 RTLISTANCHOR FreeList;
198 /** Mask of pending events. */
199 uint32_t volatile f32PendingEvents;
200 /** Current VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
201 * Used to implement polling. */
202 uint32_t volatile u32MousePosChangedSeq;
203
204 /** Spinlock various items in the VBOXGUESTSESSION. */
205 RTSPINLOCK SessionSpinlock;
206 /** List of guest sessions (VBOXGUESTSESSION). We currently traverse this
207 * but do not search it, so a list data type should be fine. Use under the
208 * #SessionSpinlock lock. */
209 RTLISTANCHOR SessionList;
210 /** Number of session. */
211 uint32_t cSessions;
212 /** Flag indicating whether logging to the release log
213 * is enabled. */
214 bool fLoggingEnabled;
215 /** Memory balloon information for RTR0MemObjAllocPhysNC(). */
216 VBOXGUESTMEMBALLOON MemBalloon;
217 /** Mouse notification callback function. */
218 PFNVBOXGUESTMOUSENOTIFY pfnMouseNotifyCallback;
219 /** The callback argument for the mouse ntofication callback. */
220 void *pvMouseNotifyCallbackArg;
221
222 /** @name Host Event Filtering
223 * @{ */
224 /** Events we won't permit anyone to filter out. */
225 uint32_t fFixedEvents;
226 /** Usage counters for the host events. (Fixed events are not included.) */
227 VBOXGUESTBITUSAGETRACER EventFilterTracker;
228 /** The event filter last reported to the host (UINT32_MAX on failure). */
229 uint32_t fEventFilterHost;
230 /** @} */
231
232 /** @name Mouse Status
233 * @{ */
234 /** Usage counters for the mouse statuses (VMMDEV_MOUSE_XXX). */
235 VBOXGUESTBITUSAGETRACER MouseStatusTracker;
236 /** The mouse status last reported to the host (UINT32_MAX on failure). */
237 uint32_t fMouseStatusHost;
238 /** @} */
239
240 /** @name Guest Capabilities
241 * @{ */
242 /** Guest capabilities which have been set to "acquire" mode. This means
243 * that only one session can use them at a time, and that they will be
244 * automatically cleaned up if that session exits without doing so.
245 *
246 * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
247 * without holding the lock in a couple of places. */
248 uint32_t volatile fAcquireModeGuestCaps;
249 /** Guest capabilities which have been set to "set" mode. This just means
250 * that they have been blocked from ever being set to "acquire" mode. */
251 uint32_t fSetModeGuestCaps;
252 /** Mask of all capabilities which are currently acquired by some session
253 * and as such reported to the host. */
254 uint32_t fAcquiredGuestCaps;
255 /** Usage counters for guest capabilities in "set" mode. Indexed by
256 * capability bit number, one count per session using a capability. */
257 VBOXGUESTBITUSAGETRACER SetGuestCapsTracker;
258 /** The guest capabilities last reported to the host (UINT32_MAX on failure). */
259 uint32_t fGuestCapsHost;
260 /** @} */
261
262 /** Heartbeat timer which fires with interval
263 * cNsHearbeatInterval and its handler sends
264 * VMMDevReq_GuestHeartbeat to VMMDev. */
265 PRTTIMER pHeartbeatTimer;
266 /** Heartbeat timer interval in nanoseconds. */
267 uint64_t cNsHeartbeatInterval;
268 /** Preallocated VMMDevReq_GuestHeartbeat request. */
269 VMMDevRequestHeader *pReqGuestHeartbeat;
270} VBOXGUESTDEVEXT;
271/** Pointer to the VBoxGuest driver data. */
272typedef VBOXGUESTDEVEXT *PVBOXGUESTDEVEXT;
273
274/** @name VBOXGUESTDEVEXT_INIT_STATE_XXX - magic values for validating init
275 * state of the device extension structur.
276 * @{ */
277#define VBOXGUESTDEVEXT_INIT_STATE_FUNDAMENT UINT32_C(0x0badcafe)
278#define VBOXGUESTDEVEXT_INIT_STATE_RESOURCES UINT32_C(0xcafebabe)
279#define VBOXGUESTDEVEXT_INIT_STATE_DELETED UINT32_C(0xdeadd0d0)
280/** @} */
281
282/**
283 * The VBoxGuest per session data.
284 */
285typedef struct VBOXGUESTSESSION
286{
287 /** The list node. */
288 RTLISTNODE ListNode;
289#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
290 /** Pointer to the next session with the same hash. */
291 PVBOXGUESTSESSION pNextHash;
292#endif
293#if defined(RT_OS_OS2)
294 /** The system file number of this session. */
295 uint16_t sfn;
296 uint16_t Alignment; /**< Alignment */
297#endif
298 /** The requestor information to pass to the host for this session.
299 * @sa VMMDevRequestHeader::fRequestor */
300 uint32_t fRequestor;
301 /** The process (id) of the session.
302 * This is NIL if it's a kernel session. */
303 RTPROCESS Process;
304 /** Which process this session is associated with.
305 * This is NIL if it's a kernel session. */
306 RTR0PROCESS R0Process;
307 /** Pointer to the device extension. */
308 PVBOXGUESTDEVEXT pDevExt;
309
310#ifdef VBOX_WITH_HGCM
311 /** Array containing HGCM client IDs associated with this session.
312 * This will be automatically disconnected when the session is closed. */
313 uint32_t volatile aHGCMClientIds[64];
314#endif
315 /** The last consumed VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
316 * Used to implement polling. */
317 uint32_t volatile u32MousePosChangedSeq;
318 /** Host events requested by the session.
319 * An event type requested in any guest session will be added to the host
320 * filter. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */
321 uint32_t fEventFilter;
322 /** Guest capabilities held in "acquired" by this session.
323 * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
324 * without holding the lock in a couple of places. */
325 uint32_t volatile fAcquiredGuestCaps;
326 /** Guest capabilities in "set" mode for this session.
327 * These accumulated for sessions via VBOXGUESTDEVEXT::acGuestCapsSet and
328 * reported to the host. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */
329 uint32_t fCapabilities;
330 /** Mouse features supported. A feature enabled in any guest session will
331 * be enabled for the host.
332 * @note We invert the VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR feature in this
333 * bitmap. The logic of this is that the real feature is when the host
334 * cursor is not needed, and we tell the host it is not needed if any
335 * session explicitly fails to assert it. Storing it inverted simplifies
336 * the checks.
337 * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
338 uint32_t fMouseStatus;
339#ifdef RT_OS_DARWIN
340 /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
341 void *pvVBoxGuestClient;
342 /** Whether this session has been opened or not. */
343 bool fOpened;
344#endif
345 /** Whether a CANCEL_ALL_WAITEVENTS is pending. This happens when
346 * CANCEL_ALL_WAITEVENTS is called, but no call to WAITEVENT is in process
347 * in the current session. In that case the next call will be interrupted
348 * at once. */
349 bool volatile fPendingCancelWaitEvents;
350 /** Does this session belong to a root process or a user one? */
351 bool fUserSession;
352} VBOXGUESTSESSION;
353
354RT_C_DECLS_BEGIN
355
356int VGDrvCommonInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase, void *pvMmioReq,
357 void *pvMMIOBase, uint32_t cbMMIO,
358 VBOXOSTYPE enmOSType, uint32_t fEvents);
359void VGDrvCommonDeleteDevExt(PVBOXGUESTDEVEXT pDevExt);
360
361int VGDrvCommonInitLoggers(void);
362void VGDrvCommonDestroyLoggers(void);
363int VGDrvCommonInitDevExtFundament(PVBOXGUESTDEVEXT pDevExt);
364void VGDrvCommonDeleteDevExtFundament(PVBOXGUESTDEVEXT pDevExt);
365int VGDrvCommonInitDevExtResources(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
366 void *pvMmioReq, void *pvMMIOBase, uint32_t cbMMIO,
367 VBOXOSTYPE enmOSType, uint32_t fFixedEvents);
368void VGDrvCommonDeleteDevExtResources(PVBOXGUESTDEVEXT pDevExt);
369int VGDrvCommonReinitDevExtAfterHibernation(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enmOSType);
370
371bool VBDrvCommonIsOptionValueTrue(const char *pszValue);
372void VGDrvCommonProcessOption(PVBOXGUESTDEVEXT pDevExt, const char *pszName, const char *pszValue);
373void VGDrvCommonProcessOptionsFromHost(PVBOXGUESTDEVEXT pDevExt);
374bool VGDrvCommonIsOurIRQ(PVBOXGUESTDEVEXT pDevExt);
375bool VGDrvCommonISR(PVBOXGUESTDEVEXT pDevExt);
376
377#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
378void VGDrvCommonWaitDoWakeUps(PVBOXGUESTDEVEXT pDevExt);
379#endif
380
381int VGDrvCommonCreateUserSession(PVBOXGUESTDEVEXT pDevExt, uint32_t fRequestor, PVBOXGUESTSESSION *ppSession);
382int VGDrvCommonCreateKernelSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession);
383void VGDrvCommonCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
384
385int VGDrvCommonIoCtlFast(uintptr_t iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
386int VGDrvCommonIoCtl(uintptr_t iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
387 PVBGLREQHDR pReqHdr, size_t cbReq);
388
389/**
390 * ISR callback for notifying threads polling for mouse events.
391 *
392 * This is called at the end of the ISR, after leaving the event spinlock, if
393 * VMMDEV_EVENT_MOUSE_POSITION_CHANGED was raised by the host.
394 *
395 * @param pDevExt The device extension.
396 */
397void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt);
398
399/**
400 * Hook for handling OS specfic options from the host.
401 *
402 * @returns true if handled, false if not.
403 * @param pDevExt The device extension.
404 * @param pszName The option name.
405 * @param pszValue The option value.
406 */
407bool VGDrvNativeProcessOption(PVBOXGUESTDEVEXT pDevExt, const char *pszName, const char *pszValue);
408
409
410#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
411int VGDrvNtIOCtl_DpcLatencyChecker(void);
412#endif
413
414#ifdef VBOXGUEST_MOUSE_NOTIFY_CAN_PREEMPT
415int VGDrvNativeSetMouseNotifyCallback(PVBOXGUESTDEVEXT pDevExt, PVBGLIOCSETMOUSENOTIFYCALLBACK pNotify);
416#endif
417
418RT_C_DECLS_END
419
420#endif /* !GA_INCLUDED_SRC_common_VBoxGuest_VBoxGuestInternal_h */
421
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use