VBoxGuestInternal.h revision 2088c1e27f998c40ba40e69e9862cf43d88e80d5
/* $Id$ */
/** @file
* VBoxGuest - Guest Additions Driver.
*/
/*
* Copyright (C) 2010-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef ___VBoxGuestInternal_h
#define ___VBoxGuestInternal_h
#include <iprt/semaphore.h>
#include <iprt/spinlock.h>
#include <VBox/VBoxGuest.h>
#include <VBox/VBoxGuestLib.h>
/** @def VBOXGUEST_USE_WAKE_UP_LIST
* Defer wake-up of waiting thread when defined. */
#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
# define VBOXGUEST_USE_DEFERRED_WAKE_UP
#endif
/** Pointer to the VBoxGuest per session data. */
typedef struct VBOXGUESTSESSION *PVBOXGUESTSESSION;
/** Pointer to a wait-for-event entry. */
typedef struct VBOXGUESTWAIT *PVBOXGUESTWAIT;
/**
* VBox guest wait for event entry.
*
* Each waiting thread allocates one of these items and adds
* it to the wait list before going to sleep on the event sem.
*/
typedef struct VBOXGUESTWAIT
{
/** The list node. */
/** The events we are waiting on. */
/** The events we received. */
uint32_t volatile fResEvents;
/** Set by VBoxGuestWaitDoWakeUps before leaving the spinlock to call
* RTSemEventMultiSignal. */
bool volatile fPendingWakeUp;
/** Set by the requestor thread if it got the spinlock before the
* signaller. Deals with the race in VBoxGuestWaitDoWakeUps. */
bool volatile fFreeMe;
#endif
/** The event semaphore. */
/** The session that's waiting. */
#ifdef VBOX_WITH_HGCM
/** The HGCM request we're waiting for to complete. */
VMMDevHGCMRequestHeader volatile *pHGCMReq;
#endif
/**
* VBox guest memory balloon.
*/
typedef struct VBOXGUESTMEMBALLOON
{
/** Mutex protecting the members below from concurrent access.. */
/** The current number of chunks in the balloon. */
/** The maximum number of chunks in the balloon (typically the amount of guest
* memory / chunksize). */
/** This is true if we are using RTR0MemObjAllocPhysNC() / RTR0MemObjGetPagePhysAddr()
* and false otherwise. */
bool fUseKernelAPI;
/** The current owner of the balloon.
* This is automatically assigned to the first session using the ballooning
* API and first released when the session closes. */
/** The pointer to the array of memory objects holding the chunks of the
* balloon. This array is cMaxChunks in size when present. */
/** Pointer to a memory balloon. */
typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON;
/**
* Per bit usage tracker for a uint32_t mask.
*
* Used for optimal handling of guest properties, mouse status and event filter.
*/
typedef struct VBOXGUESTBITUSAGETRACER
{
/** Per bit usage counters. */
/** The current mask according to acPerBitUsage. */
/** Pointer to a per bit usage tracker. */
/** Pointer to a const per bit usage tracker. */
typedef VBOXGUESTBITUSAGETRACER const *PCVBOXGUESTBITUSAGETRACER;
/**
* VBox guest device (data) extension.
*/
typedef struct VBOXGUESTDEVEXT
{
/** The base of the adapter I/O ports. */
/** Pointer to the mapping of the VMMDev adapter memory. */
VMMDevMemory volatile *pVMMDevMemory;
/** The memory object reserving space for the guest mappings. */
/** Spinlock protecting the signaling and resetting of the wait-for-event
* semaphores as well as the event acking in the ISR. */
/** Preallocated VMMDevEvents for the IRQ handler. */
/** The physical address of pIrqAckEvents. */
/** Wait-for-event list for threads waiting for multiple events
* (VBOXGUESTWAIT). */
#ifdef VBOX_WITH_HGCM
/** Wait-for-event list for threads waiting on HGCM async completion
* (VBOXGUESTWAIT).
*
* The entire list is evaluated upon the arrival of an HGCM event, unlike
* the other lists which are only evaluated till the first thread has
* been woken up. */
#endif
/** List of wait-for-event entries that needs waking up
* (VBOXGUESTWAIT). */
#endif
/** List of wait-for-event entries that has been woken up
* (VBOXGUESTWAIT). */
/** List of free wait-for-event entries (VBOXGUESTWAIT). */
/** Mask of pending events. */
uint32_t volatile f32PendingEvents;
/** Current VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
* Used to implement polling. */
uint32_t volatile u32MousePosChangedSeq;
/** Spinlock various items in the VBOXGUESTSESSION. */
/** List of guest sessions (VBOXGUESTSESSION). We currently traverse this
* but do not search it, so a list data type should be fine. Use under the
* #SessionSpinlock lock. */
/** Number of session. */
/** Flag indicating whether logging to the release log
* is enabled. */
bool fLoggingEnabled;
/** Memory balloon information for RTR0MemObjAllocPhysNC(). */
/** Callback and user data for a kernel mouse handler. */
/** @name Host Event Filtering
* @{ */
/** Events we won't permit anyone to filter out. */
/** Usage counters for the host events. (Fixed events are not included.) */
/** The event filter last reported to the host (UINT32_MAX on failure). */
/** @} */
/** @name Mouse Status
* @{ */
/** Usage counters for the mouse statuses (VMMDEV_MOUSE_XXX). */
/** The mouse status last reported to the host (UINT32_MAX on failure). */
/** @} */
/** @name Guest Capabilities
* @{ */
/** Guest capabilities which have been set to "acquire" mode. This means
* that only one session can use them at a time, and that they will be
* automatically cleaned up if that session exits without doing so.
*
* Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
* without holding the lock in a couple of places. */
uint32_t volatile u32AcquireModeGuestCaps;
/** Guest capabilities which have been set to "set" mode. This just means
* that they have been blocked from ever being set to "acquire" mode. */
/** Mask of all capabilities which are currently acquired by some session
* and as such reported to the host. */
/** Usage counters for guest capabilities in "set" mode. Indexed by
* capability bit number, one count per session using a capability. */
/** The guest capabilities last reported to the host (UINT32_MAX on failure). */
/** @} */
/** Heartbeat timer which fires with interval
* cNsHearbeatInterval and its handler sends
* VMMDevReq_GuestHeartbeat to VMMDev. */
/** Heartbeat timer interval in nanoseconds. */
/** Preallocated VMMDevReq_GuestHeartbeat request. */
/** Pointer to the VBoxGuest driver data. */
typedef VBOXGUESTDEVEXT *PVBOXGUESTDEVEXT;
/**
* The VBoxGuest per session data.
*/
typedef struct VBOXGUESTSESSION
{
/** The list node. */
/** Pointer to the next session with the same hash. */
#endif
#if defined(RT_OS_OS2)
/** The system file number of this session. */
#endif
/** The process (id) of the session.
* This is NIL if it's a kernel session. */
/** Which process this session is associated with.
* This is NIL if it's a kernel session. */
/** Pointer to the device extension. */
#ifdef VBOX_WITH_HGCM
/** Array containing HGCM client IDs associated with this session.
* This will be automatically disconnected when the session is closed. */
#endif
/** The last consumed VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
* Used to implement polling. */
uint32_t volatile u32MousePosChangedSeq;
/** Host events requested by the session.
* An event type requested in any guest session will be added to the host
* filter. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */
/** Guest capabilities held in "acquired" by this session.
* Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
* without holding the lock in a couple of places. */
uint32_t volatile u32AquiredGuestCaps;
/** Guest capabilities in "set" mode for this session.
* These accumulated for sessions via VBOXGUESTDEVEXT::acGuestCapsSet and
* reported to the host. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */
/** Mouse features supported. A feature enabled in any guest session will
* be enabled for the host.
* @note We invert the VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR feature in this
* bitmap. The logic of this is that the real feature is when the host
* cursor is not needed, and we tell the host it is not needed if any
* session explicitly fails to assert it. Storing it inverted simplifies
* the checks.
* Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
#ifdef RT_OS_DARWIN
/** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
void *pvVBoxGuestClient;
/** Whether this session has been opened or not. */
bool fOpened;
#endif
/** Whether a CANCEL_ALL_WAITEVENTS is pending. This happens when
* CANCEL_ALL_WAITEVENTS is called, but no call to WAITEVENT is in process
* in the current session. In that case the next call will be interrupted
* at once. */
bool volatile fPendingCancelWaitEvents;
/** Does this session belong to a root process or a user one? */
bool fUserSession;
int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase, void *pvMMIOBase, uint32_t cbMMIO, VBOXOSTYPE enmOSType, uint32_t fEvents);
#endif
int VBoxGuestCommonIOCtlFast(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
#if defined(RT_OS_SOLARIS) \
|| defined(RT_OS_FREEBSD) \
|| defined(RT_OS_LINUX)
DECLVBGL(int) VBoxGuestNativeServiceCall(void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
#endif
/**
* ISR callback for notifying threads polling for mouse events.
*
* This is called at the end of the ISR, after leaving the event spinlock, if
* VMMDEV_EVENT_MOUSE_POSITION_CHANGED was raised by the host.
*
* @param pDevExt The device extension.
*/
int VbgdNtIOCtl_DpcLatencyChecker(void);
#endif
#endif