VMMDev.cpp revision 0e4730a77d217b2b5a8743a9e9e1a731d5b75653
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * VMMDev - Guest <-> VMM/Host communication device.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Copyright (C) 2006-2014 Oracle Corporation
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * available from http://www.virtualbox.org. This file is free software;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * General Public License (GPL) as published by the Free Software
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/*******************************************************************************
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync* Header Files *
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync*******************************************************************************/
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/* Enable dev_vmm Log3 statements to get IRQ-related logging. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/*******************************************************************************
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync* Defined Constants And Macros *
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync*******************************************************************************/
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ( RT_HIWORD((s)->guestInfo.interfaceVersion) == 1 \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync && RT_LOWORD((s)->guestInfo.interfaceVersion) == 3 )
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync#define VBOX_GUEST_INTERFACE_VERSION_OK(additionsVersion) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ( RT_HIWORD(additionsVersion) == RT_HIWORD(VMMDEV_VERSION) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync && RT_LOWORD(additionsVersion) <= RT_LOWORD(VMMDEV_VERSION) )
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync#define VBOX_GUEST_INTERFACE_VERSION_OLD(additionsVersion) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ( (RT_HIWORD(additionsVersion) < RT_HIWORD(VMMDEV_VERSION) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync || ( RT_HIWORD(additionsVersion) == RT_HIWORD(VMMDEV_VERSION) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync && RT_LOWORD(additionsVersion) <= RT_LOWORD(VMMDEV_VERSION) ) )
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync#define VBOX_GUEST_INTERFACE_VERSION_TOO_OLD(additionsVersion) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ( RT_HIWORD(additionsVersion) < RT_HIWORD(VMMDEV_VERSION) )
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync#define VBOX_GUEST_INTERFACE_VERSION_NEW(additionsVersion) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ( RT_HIWORD(additionsVersion) > RT_HIWORD(VMMDEV_VERSION) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync || ( RT_HIWORD(additionsVersion) == RT_HIWORD(VMMDEV_VERSION) \
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync && RT_LOWORD(additionsVersion) > RT_LOWORD(VMMDEV_VERSION) ) )
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/** The saved state version. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/** The saved state version which is missing the guest facility statuses. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync#define VMMDEV_SAVED_STATE_VERSION_MISSING_FACILITY_STATUSES 14
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/** The saved state version which is missing the guestInfo2 bits. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync#define VMMDEV_SAVED_STATE_VERSION_MISSING_GUEST_INFO_2 13
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/** The saved state version used by VirtualBox 3.0.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * This doesn't have the config part. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/** Default interval in nanoseconds between guest heartbeats.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Used when no HeartbeatInterval is set in CFGM and for setting
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * HB check timer if the guest's heartbeat frequency is less than 1Hz. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync#define HEARTBEAT_DEFAULT_INTERVAL UINT64_C(2000000000)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/** @page pg_vmmdev VMMDev
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Whenever host wants to inform guest about something an IRQ notification will
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * be raised.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * VMMDev PDM interface will contain the guest notification method.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * There is a 32 bit event mask which will be read by guest on an interrupt. A
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * non zero bit in the mask means that the specific event occurred and requires
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * processing on guest side.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * After reading the event mask guest must issue a generic request
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * AcknowlegdeEvents.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * IRQ line is set to 1 (request) if there are unprocessed events, that is the
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * event mask is not zero.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * After receiving an interrupt and checking event mask, the guest must process
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * events using the event specific mechanism.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * That is if mouse capabilities were changed, guest will use
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * VMMDev_GetMouseStatus generic request.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Event mask is only a set of flags indicating that guest must proceed with a
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * procedure.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Unsupported events are therefore ignored. The guest additions must inform
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * host which events they want to receive, to avoid unnecessary IRQ processing.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * By default no events are signalled to guest.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * This seems to be fast method. It requires only one context switch for an
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * event processing.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/* -=-=-=-=- Misc Helpers -=-=-=-=- */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Sets the IRQ (raise it or lower it) for 1.03 additions.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev state.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @thread Any.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @remarks Must be called owning the critical section.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log(("vmmdevSetIRQ: IRQ is not generated, guest has not yet reported to us.\n"));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Filter unsupported events */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log(("vmmdevSetIRQ: u32EventFlags=%#010x, u32HostEventFlags=%#010x, u32GuestEventMask=%#010x.\n",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync u32EventFlags, pThis->u32HostEventFlags, pThis->pVMMDevRAMR3->V.V1_03.u32GuestEventMask));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Move event flags to VMMDev RAM */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->pVMMDevRAMR3->V.V1_03.u32HostEvents = u32EventFlags;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Clear host flags which will be delivered to guest. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log(("vmmdevSetIRQ: u32HostEventFlags=%#010x\n", pThis->u32HostEventFlags));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Set IRQ level for pin 0 (see NoWait comment in vmmdevMaybeSetIRQ). */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /** @todo make IRQ pin configurable, at least a symbolic constant */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Sets the IRQ if there are events to be delivered.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev state.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @thread Any.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @remarks Must be called owning the critical section.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log3(("vmmdevMaybeSetIRQ: u32HostEventFlags=%#010x, u32GuestFilterMask=%#010x.\n",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->u32HostEventFlags, pThis->u32GuestFilterMask));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->u32HostEventFlags & pThis->u32GuestFilterMask)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Note! No need to wait for the IRQs to be set (if we're not luck
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * with the locks, etc). It is a notification about something,
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * which has already happened.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Notifies the guest about new events (@a fAddEvents).
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev state.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param fAddEvents New events to add.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @thread Any.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @remarks Must be called owning the critical section.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic void vmmdevNotifyGuestWorker(PVMMDEV pThis, uint32_t fAddEvents)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log3(("vmmdevNotifyGuestWorker: fAddEvents=%#010x.\n", fAddEvents));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log3(("vmmdevNotifyGuestWorker: Old additions detected.\n"));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log3(("vmmdevNotifyGuestWorker: New additions detected.\n"));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log(("vmmdevNotifyGuestWorker: IRQ is not generated, guest has not yet reported to us.\n"));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync const bool fHadEvents = (pThis->u32HostEventFlags & pThis->u32GuestFilterMask) != 0;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log3(("vmmdevNotifyGuestWorker: fHadEvents=%d, u32HostEventFlags=%#010x, u32GuestFilterMask=%#010x.\n",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync fHadEvents, pThis->u32HostEventFlags, pThis->u32GuestFilterMask));
f4859dbc9e6e61d81adba530beddf0c374ac9011vboxsync/* -=-=-=-=- Interfaces shared with VMMDevHGCM.cpp -=-=-=-=- */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Notifies the guest about new events (@a fAddEvents).
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * This is used by VMMDev.cpp as well as VMMDevHGCM.cpp.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev state.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param fAddEvents New events to add.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @thread Any.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncvoid VMMDevNotifyGuest(PVMMDEV pThis, uint32_t fAddEvents)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log3(("VMMDevNotifyGuest: fAddEvents=%#010x\n", fAddEvents));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Drop notifications if the VM is not running yet/anymore.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync VMSTATE enmVMState = PDMDevHlpVMState(pThis->pDevIns);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Code shared by VMMDevReq_CtlGuestFilterMask and HGCM for controlling the
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * events the guest are interested in.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev state.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param fOrMask Events to add (VMMDEV_EVENT_XXX). Pass 0 for no
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param fNotMask Events to remove (VMMDEV_EVENT_XXX). Pass 0 for no
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @remarks When HGCM will automatically enable VMMDEV_EVENT_HGCM when the guest
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * starts submitting HGCM requests. Otherwise, the events are
7f17f0ea0209f234bdebdf0509c0e2b74e732f69vboxsync * controlled by the guest.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncvoid VMMDevCtlSetGuestFilterMask(PVMMDEV pThis, uint32_t fOrMask, uint32_t fNotMask)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync const bool fHadEvents = (pThis->u32HostEventFlags & pThis->u32GuestFilterMask) != 0;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync Log(("VMMDevCtlSetGuestFilterMask: fOrMask=%#010x, u32NotMask=%#010x, fHadEvents=%d.\n", fOrMask, fNotMask, fHadEvents));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->u32NewGuestFilterMask = pThis->u32GuestFilterMask;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync/* -=-=-=-=- Request processing functions. -=-=-=-=- */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Handles VMMDevReq_ReportGuestInfo.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code that the guest should see.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pRequestHeader The header of the request to handle.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic int vmmdevReqHandler_ReportGuestInfo(PVMMDEV pThis, VMMDevRequestHeader *pRequestHeader)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(pRequestHeader->size == sizeof(VMMDevReportGuestInfo), ("%u\n", pRequestHeader->size), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync VBoxGuestInfo const *pInfo = &((VMMDevReportGuestInfo *)pRequestHeader)->guestInfo;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (memcmp(&pThis->guestInfo, pInfo, sizeof(*pInfo)) != 0)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Make a copy of supplied information. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Check additions interface version. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->fu32AdditionsOk = VBOX_GUEST_INTERFACE_VERSION_OK(pThis->guestInfo.interfaceVersion);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("Guest Additions information report: Interface = 0x%08X osType = 0x%08X (%u-bit)\n",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->guestInfo.interfaceVersion, pThis->guestInfo.osType,
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync (pThis->guestInfo.osType & VBOXOSTYPE_x64) ? 64 : 32));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestInfo)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Clear our IRQ in case it was high for whatever reason. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Resets heartbeat timer.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev state.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync return TMTimerSetNano(pThis->pHBCheckTimer, pThis->u64HeartbeatTimeout);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Handles VMMDevReq_GuestHeartbeat.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code that the guest should see.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic int vmmDevReqHandler_GuestHeartbeat(PVMMDEV pThis)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ASMAtomicWriteU64(&pThis->uLastHBTime, TMTimerGetNano(pThis->pHBCheckTimer));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("vmmDevReqHandler_GuestHeartBeat: guest is alive\n"));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Guest heartbeat check timer. Fires if there are no heartbeats for certain time.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Timer is set in vmmDevHeartbeatTimerReset.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic DECLCALLBACK(void) vmmDevHeartBeatCheckTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync uint64_t interval = TMTimerGetNano(pTimer) - pThis->uLastHBTime;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (!pThis->fHasMissedHB && interval >= pThis->u64HeartbeatInterval)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("vmmDevHeartBeatCheckTimer: guest seems to be not responding, last heartbeat received %RU64 sec ago\n", interval / 1000000000));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Handles VMMDevReq_HeartbeatConfigure.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code that the guest should see.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pReqHdr The header of the request to handle.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic int vmmDevReqHandler_HeartbeatConfigure(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(pReqHdr->size == sizeof(VMMDevReqHeartbeat), ("%u\n", pReqHdr->size), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync VMMDevReqHeartbeat *pReq = (VMMDevReqHeartbeat *)pReqHdr;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ASMAtomicWriteBool(&pThis->fHBCheckEnabled, pReq->fEnabled);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* set first timer explicitly */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("Heartbeat checking timer has been set to trigger every %RU64 sec\n", pThis->u64HeartbeatInterval / 500000000));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("Cannot create heartbeat check timer, rc=%Rrc\n", rc));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("Heartbeat checking timer has been stopped, rc=%Rrc\n", rc));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("vmmDevReqHandler_HeartbeatConfigure: enabled=%d\n", pThis->fHBCheckEnabled));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Validates a publisher tag.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns true / false.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pszTag Tag to validate.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic bool vmmdevReqIsValidPublisherTag(const char *pszTag)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Note! This character set is also found in Config.kmk. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync static char const s_szValidChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz()[]{}+-.,";
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync return false;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync return true;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Validates a build tag.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns true / false.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pszTag Tag to validate.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic bool vmmdevReqIsValidBuildTag(const char *pszTag)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync return false;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync return true;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync int rc = RTStrToUInt8Full(&pszTag[cchPrefix], 10, &u8);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Handles VMMDevReq_ReportGuestInfo2.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code that the guest should see.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pReqHdr The header of the request to handle.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic int vmmdevReqHandler_ReportGuestInfo2(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(pReqHdr->size == sizeof(VMMDevReportGuestInfo2), ("%u\n", pReqHdr->size), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync VBoxGuestInfo2 const *pInfo2 = &((VMMDevReportGuestInfo2 *)pReqHdr)->guestInfo;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("Guest Additions information report: Version %d.%d.%d r%d '%.*s'\n",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild,
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pInfo2->additionsRevision, sizeof(pInfo2->szName), pInfo2->szName));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* The interface was introduced in 3.2 and will definitely not be
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync backported beyond 3.0 (bird). */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ("%u.%u.%u\n", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild),
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* The version must fit in a full version compression. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync uint32_t uFullVersion = VBOX_FULL_VERSION_MAKE(pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn( VBOX_FULL_VERSION_GET_MAJOR(uFullVersion) == pInfo2->additionsMajor
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync && VBOX_FULL_VERSION_GET_MINOR(uFullVersion) == pInfo2->additionsMinor
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync && VBOX_FULL_VERSION_GET_BUILD(uFullVersion) == pInfo2->additionsBuild,
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync ("%u.%u.%u\n", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild),
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Validate the name.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Be less strict towards older additions (< v4.1.50).
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertCompile(sizeof(pThis->guestInfo2.szName) == sizeof(pInfo2->szName));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertReturn(memchr(pInfo2->szName, '\0', sizeof(pInfo2->szName)) != NULL, VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* The version number which shouldn't be there. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync size_t cchStart = RTStrPrintf(szTmp, sizeof(szTmp), "%u.%u.%u", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(!strncmp(pszName, szTmp, cchStart), ("%s != %s\n", pszName, szTmp), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Now we can either have nothing or a build tag or/and a publisher tag. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync || (pInfo2->additionsMajor == 4 && pInfo2->additionsMinor > 1)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync || (pInfo2->additionsMajor == 4 && pInfo2->additionsMinor == 1 && pInfo2->additionsBuild >= 50);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync bool fOk = false;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertLogRelMsgReturn(!fStrict, ("%s", pszName), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* non-strict mode, just zap the extra stuff. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("ReportGuestInfo2: Ignoring unparsable version name bits: '%s' -> '%s'.\n", pszName, pszRelaxedName));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Save the info and tell Main or whoever is listening.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->guestInfo2.uRevision = pInfo2->additionsRevision;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->guestInfo2.fFeatures = pInfo2->additionsFeatures;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestInfo2)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, uFullVersion, pszName, pInfo2->additionsRevision, pInfo2->additionsFeatures);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Clear our IRQ in case it was high for whatever reason. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Allocates a new facility status entry, initializing it to inactive.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns Pointer to a facility status entry on success, NULL on failure
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * (table full).
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param uFacility The facility type code - VBoxGuestFacilityType.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param fFixed This is set when allocating the standard entries
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * from the constructor.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pTimeSpecNow Optionally giving the entry timestamp to use (ctor).
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncvmmdevAllocFacilityStatusEntry(PVMMDEV pThis, uint32_t uFacility, bool fFixed, PCRTTIMESPEC pTimeSpecNow)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* If full, expunge one inactive entry. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->cFacilityStatuses == RT_ELEMENTS(pThis->aFacilityStatuses))
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync while (i-- > 0)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if ( pThis->aFacilityStatuses[i].uStatus == VBoxGuestFacilityStatus_Inactive
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync memmove(&pThis->aFacilityStatuses[i], &pThis->aFacilityStatuses[i + 1],
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync RT_ZERO(pThis->aFacilityStatuses[pThis->cFacilityStatuses]);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->cFacilityStatuses == RT_ELEMENTS(pThis->aFacilityStatuses))
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Find location in array (it's sorted). */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync while (i-- > 0)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->aFacilityStatuses[i].uFacility < uFacility)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Move. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync memmove(&pThis->aFacilityStatuses[i + 1], &pThis->aFacilityStatuses[i],
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Initialize. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->aFacilityStatuses[i].uStatus = VBoxGuestFacilityStatus_Inactive;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->aFacilityStatuses[i].TimeSpecTS = *pTimeSpecNow;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync RTTimeSpecSetNano(&pThis->aFacilityStatuses[i].TimeSpecTS, 0);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Gets a facility status entry, allocating a new one if not already present.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns Pointer to a facility status entry on success, NULL on failure
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * (table full).
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param uFacility The facility type code - VBoxGuestFacilityType.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic PVMMDEVFACILITYSTATUSENTRY vmmdevGetFacilityStatusEntry(PVMMDEV pThis, uint32_t uFacility)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /** @todo change to binary search. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync while (i-- > 0)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->aFacilityStatuses[i].uFacility == uFacility)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->aFacilityStatuses[i].uFacility < uFacility)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync return vmmdevAllocFacilityStatusEntry(pThis, uFacility, false /*fFixed*/, NULL);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Handles VMMDevReq_ReportGuestStatus.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code that the guest should see.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pReqHdr The header of the request to handle.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic int vmmdevReqHandler_ReportGuestStatus(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Validate input.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(pReqHdr->size == sizeof(VMMDevReportGuestStatus), ("%u\n", pReqHdr->size), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync VBoxGuestStatus *pStatus = &((VMMDevReportGuestStatus *)pReqHdr)->guestStatus;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn( pStatus->facility > VBoxGuestFacilityType_Unknown
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(pStatus->status == (VBoxGuestFacilityStatus)(uint16_t)pStatus->status,
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Do the update.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pStatus->facility == VBoxGuestFacilityType_All)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync while (i-- > 0)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->aFacilityStatuses[i].uStatus = (uint16_t)pStatus->status;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->aFacilityStatuses[i].fFlags = pStatus->flags;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync PVMMDEVFACILITYSTATUSENTRY pEntry = vmmdevGetFacilityStatusEntry(pThis, pStatus->facility);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRelMax(10, ("VMM: Facility table is full - facility=%u status=%u.\n", pStatus->facility, pStatus->status));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pEntry->uStatus = (uint16_t)pStatus->status; /** @todo r=andy uint16_t vs. 32-bit enum. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestStatus)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, pStatus->facility, pStatus->status, pStatus->flags, &Now);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Handles VMMDevReq_ReportGuestUserState.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code that the guest should see.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pReqHdr The header of the request to handle.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic int vmmdevReqHandler_ReportGuestUserState(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Validate input.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(pReqHdr->size >= sizeof(VMMDevReportGuestUserState), ("%u\n", pReqHdr->size), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync VBoxGuestUserStatus *pStatus = &((VMMDevReportGuestUserState *)pReqHdr)->status;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* pyDynamic marks the beginning of the struct's dynamically
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * allocated data area. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync uint8_t *pvDynamic = (uint8_t *)pStatus + RT_OFFSETOF(VBoxGuestUserStatus, szUser);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pvDynamic += pStatus->cbUser; /* Advance to next field. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Note: pszDomain can be NULL. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pvDynamic += pStatus->cbDomain; /* Advance to next field. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Note: puDetails can be NULL. */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->pDrv->pfnUpdateGuestUserState(pThis->pDrv, pszUser, pszDomain,
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* State */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* State details */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Handles VMMDevReq_ReportGuestCapabilities.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code that the guest should see.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pReqHdr The header of the request to handle.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic int vmmdevReqHandler_ReportGuestCapabilities(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync VMMDevReqGuestCapabilities *pReq = (VMMDevReqGuestCapabilities *)pReqHdr;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* Enable VMMDEV_GUEST_SUPPORTS_GRAPHICS automatically for guests using the old
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * request to report their capabilities.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync const uint32_t fu32Caps = pReq->caps | VMMDEV_GUEST_SUPPORTS_GRAPHICS;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync /* make a copy of supplied information */
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("Guest Additions capability report (legacy): (0x%x) seamless: %s, hostWindowMapping: %s, graphics: yes\n",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync fu32Caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? "yes" : "no",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync fu32Caps & VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING ? "yes" : "no"));
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestCapabilities)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, fu32Caps);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * Handles VMMDevReq_SetGuestCapabilities.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @returns VBox status code that the guest should see.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pThis The VMMDev instance data.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync * @param pReqHdr The header of the request to handle.
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsyncstatic int vmmdevReqHandler_SetGuestCapabilities(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync VMMDevReqGuestCapabilities2 *pReq = (VMMDevReqGuestCapabilities2 *)pReqHdr;
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync LogRel(("Guest Additions capability report: (%#x -> %#x) seamless: %s, hostWindowMapping: %s, graphics: %s\n",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync fu32Caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? "yes" : "no",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync fu32Caps & VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING ? "yes" : "no",
e1fd337d575f2a4c053c6fe7a811e2fd1a31e874vboxsync fu32Caps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? "yes" : "no"));
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
bool fNotify = false;
fNotify = true;
if (fNotify)
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
AssertMsg(pReq->header.size == 0x10028 && pReq->header.version == 10000, /* don't complain about legacy!!! */
return VERR_INVALID_PARAMETER;
fShape = false;
if (fShape)
return rc;
NULL);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VERR_NOT_SUPPORTED;
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
int rc;
return rc;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VMMR3DeregisterPatchMemory(PDMDevHlpGetVM(pThis->pDevIns), pReq->pPatchMem, pReq->cbPatchMem);
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
case VMMDevPowerState_Pause:
return VERR_ACCESS_DENIED;
return VERR_INVALID_PARAMETER;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
Log(("VMMDev: returning display change request xres = %d, yres = %d, bpp = %d\n", pReq->xres, pReq->yres, pReq->bpp));
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
if (pDispRequest)
if (!pDispRequest)
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
if (pDispRequest)
if (!pDispRequest)
Log(("VMMDevEx: returning display change request xres = %d, yres = %d, bpp = %d id %d xPos = %d, yPos = %d & Enabled=%d\n",
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
LogRelFlowFunc(("VMMDevCtlGuestFilterMask: or mask: %#x, not mask: %#x\n", pReq->u32OrMask, pReq->u32NotMask));
return VINF_SUCCESS;
#ifdef VBOX_WITH_HGCM
static int vmmdevReqHandler_HGCMConnect(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr, RTGCPHYS GCPhysReqHdr)
AssertMsgReturn(pReq->header.header.size >= sizeof(*pReq), ("%u\n", pReq->header.header.size), VERR_INVALID_PARAMETER); /** @todo Not sure why this is >= ... */
return VERR_NOT_SUPPORTED;
static int vmmdevReqHandler_HGCMDisconnect(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr, RTGCPHYS GCPhysReqHdr)
AssertMsgReturn(pReq->header.header.size >= sizeof(*pReq), ("%u\n", pReq->header.header.size), VERR_INVALID_PARAMETER); /** @todo Not sure why this >= ... */
return VERR_NOT_SUPPORTED;
static int vmmdevReqHandler_HGCMCall(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr, RTGCPHYS GCPhysReqHdr)
AssertMsgReturn(pReq->header.header.size >= sizeof(*pReq), ("%u\n", pReq->header.header.size), VERR_INVALID_PARAMETER);
return VERR_NOT_SUPPORTED;
#ifdef VBOX_WITH_64_BITS_GUESTS
bool f64Bits = false;
static int vmmdevReqHandler_HGCMCancel(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr, RTGCPHYS GCPhysReqHdr)
AssertMsgReturn(pReq->header.header.size >= sizeof(*pReq), ("%u\n", pReq->header.header.size), VERR_INVALID_PARAMETER); /** @todo Not sure why this >= ... */
return VERR_NOT_SUPPORTED;
AssertMsgReturn(pReq->header.size >= sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER); /** @todo Not sure why this >= ... */
return VERR_NOT_SUPPORTED;
AssertMsgReturn(pReq->header.size >= sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER); /** @todo Not sure why this >= ... */
return VERR_NOT_SUPPORTED;
Log(("VMMDevReq_VideoAccelEnable guest ring buffer size %d, should be %d!!!\n", pReq->cbRingBuffer, VBVA_RING_BUFFER_SIZE));
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size >= sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER); /** @todo Not sure why this >= ... */
return VERR_NOT_SUPPORTED;
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size + sizeof(RTRECT) >= sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VERR_NOT_SUPPORTED;
|| pReq->header.size != sizeof(VMMDevVideoSetVisibleRegion) + pReq->cRect * sizeof(RTRECT) - sizeof(RTRECT))
return VERR_INVALID_PARAMETER;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
Log(("VMMDev: returning VRDP status %d level %d\n", pThis->fVRDPEnabled, pThis->uVRDPExperienceLevel));
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size >= sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
AssertMsgReturn(pReq->cPages == VMMDEV_MEMORY_BALLOON_CHUNK_PAGES, ("%u\n", pReq->cPages), VERR_INVALID_PARAMETER);
AssertMsgReturn(pReq->header.size == (uint32_t)RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[pReq->cPages]),
int rc = PGMR3PhysChangeMemBalloon(PDMDevHlpGetVM(pThis->pDevIns), !!pReq->fInflate, pReq->cPages, pReq->aPhysPage);
return rc;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
#ifdef LOG_ENABLED
Log(("CPU%u: Total physical memory %-4d MB\n", pGuestStats->u32CpuId, (pGuestStats->u32PhysMemTotal + (_1M/_4K)-1) / (_1M/_4K)));
Log(("CPU%u: Free physical memory %-4d MB\n", pGuestStats->u32CpuId, pGuestStats->u32PhysMemAvail / (_1M/_4K)));
Log(("CPU%u: Memory balloon size %-4d MB\n", pGuestStats->u32CpuId, pGuestStats->u32PhysMemBalloon / (_1M/_4K)));
Log(("CPU%u: Committed memory %-4d MB\n", pGuestStats->u32CpuId, pGuestStats->u32MemCommitTotal / (_1M/_4K)));
Log(("CPU%u: Total kernel memory %-4d MB\n", pGuestStats->u32CpuId, pGuestStats->u32MemKernelTotal / (_1M/_4K)));
Log(("CPU%u: Paged kernel memory %-4d MB\n", pGuestStats->u32CpuId, pGuestStats->u32MemKernelPaged / (_1M/_4K)));
Log(("CPU%u: Nonpaged kernel memory %-4d MB\n", pGuestStats->u32CpuId, pGuestStats->u32MemKernelNonPaged / (_1M/_4K)));
Log(("CPU%u: System cache size %-4d MB\n", pGuestStats->u32CpuId, pGuestStats->u32MemSystemCache / (_1M/_4K)));
Log(("CPU%u: Page file size %-4d MB\n", pGuestStats->u32CpuId, pGuestStats->u32PageFileSize / (_1M/_4K)));
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
#ifdef DEBUG
AssertMsgReturn(pReq->header.size >= sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
AssertMsgReturn(pReq->szString[pReq->header.size - RT_OFFSETOF(VMMDevReqLogString, szString) - 1] == '\0',
LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP_DEV_VMM_BACKDOOR, ("DEBUG LOG: %s", pReq->szString));
return VINF_SUCCESS;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
#ifdef VBOX_WITH_PAGE_SHARING
AssertMsgReturn(pReq->header.size == RT_UOFFSETOF(VMMDevSharedModuleRegistrationRequest, aRegions[pReq->cRegions]),
return PGMR3SharedModuleRegister(PDMDevHlpGetVM(pThis->pDevIns), pReq->enmGuestOS, pReq->szName, pReq->szVersion,
return VINF_SUCCESS;
# ifdef DEBUG
return PGMR3SharedModuleGetPageState(PDMDevHlpGetVM(pThis->pDevIns), pReq->GCPtrPage, &pReq->fShared, &pReq->uPageFlags);
return VERR_NOT_IMPLEMENTED;
AssertMsgReturn(pReq->header.size == sizeof(VMMDevReqWriteCoreDump), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
return VERR_ACCESS_DENIED;
return VERR_PATH_NOT_FOUND;
static int vmmdevReqDispatcher(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr, RTGCPHYS GCPhysReqHdr, bool *pfDelayedUnlock)
*pfDelayedUnlock = false;
case VMMDevReq_WriteCoreDump:
case VMMDevReq_GetMouseStatus:
case VMMDevReq_SetMouseStatus:
case VMMDevReq_GetHostTime:
case VMMDevReq_SetPowerStatus:
#ifdef VBOX_WITH_HGCM
case VMMDevReq_HGCMConnect:
*pfDelayedUnlock = true;
case VMMDevReq_HGCMDisconnect:
*pfDelayedUnlock = true;
# ifdef VBOX_WITH_64_BITS_GUESTS
case VMMDevReq_HGCMCall32:
case VMMDevReq_HGCMCall64:
case VMMDevReq_HGCMCall:
*pfDelayedUnlock = true;
case VMMDevReq_HGCMCancel:
*pfDelayedUnlock = true;
case VMMDevReq_HGCMCancel2:
case VMMDevReq_GetHostVersion:
#ifdef VBOX_WITH_PAGE_SHARING
#ifdef DEBUG
case VMMDevReq_LogString:
case VMMDevReq_GetSessionId:
case VMMDevReq_Idle:
case VMMDevReq_GuestHeartbeat:
return rcRet;
static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return VINF_SUCCESS;
Log(("VMMDev: guest header version (0x%08X) differs from ours (0x%08X)\n", requestHeader.version, VMMDEV_REQUEST_HEADER_VERSION));
return VINF_SUCCESS;
bool fDelayedUnlock = false;
if (pRequestHeader)
if (cbLeft)
cbLeft);
if (!fDelayedUnlock)
LogRelMax(10, ("VMMDev: the guest has not yet reported to us -- refusing operation of request #%d\n",
if (pRequestHeader)
if (fDelayedUnlock)
return rcRet;
static DECLCALLBACK(int)
vmmdevIORAMRegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
LogFlow(("vmmdevR3IORAMRegionMap: iRegion=%d GCPhysAddress=%RGp cb=%#x enmType=%d\n", iRegion, GCPhysAddress, cb, enmType));
int rc;
rc = PDMDevHlpRegisterVMMDevHeap(pPciDev->pDevIns, GCPhysAddress, pThis->pVMMDevHeapR3, VMMDEV_HEAP_SIZE);
return rc;
static DECLCALLBACK(int)
vmmdevIOPortRegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
int rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + VMMDEV_PORT_OFF_REQUEST, 1,
return rc;
static DECLCALLBACK(int) vmmdevBackdoorLog(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (u32)
case '\r': LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP_DEV_VMM_BACKDOOR, ("vmmdev: <return>\n")); break;
case '\n': LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP_DEV_VMM_BACKDOOR, ("vmmdev: <newline>\n")); break;
case '\t': LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP_DEV_VMM_BACKDOOR, ("vmmdev: <tab>\n")); break;
default: LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP_DEV_VMM_BACKDOOR, ("vmmdev: %c (%02x)\n", u32, u32)); break;
LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP_DEV_VMM_BACKDOOR, ("Guest Log: %s\n", pThis->szMsg));
LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP_DEV_VMM_BACKDOOR, ("Guest Log: %s\n", pThis->szMsg));
return VINF_SUCCESS;
#ifdef VMMDEV_WITH_ALT_TIMESYNC
static DECLCALLBACK(int) vmmdevAltTimeSyncWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (u32)
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevAltTimeSyncRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
int rc;
return rc;
#ifdef VBOX_WITH_HGCM
return NULL;
static DECLCALLBACK(int) vmmdevQueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
return VINF_SUCCESS;
return VERR_PDM_LUN_NOT_FOUND;
static DECLCALLBACK(int) vmmdevIPort_QueryAbsoluteMouse(PPDMIVMMDEVPORT pInterface, int32_t *pxAbs, int32_t *pyAbs)
if (pxAbs)
if (pyAbs)
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevIPort_SetAbsoluteMouse(PPDMIVMMDEVPORT pInterface, int32_t xAbs, int32_t yAbs)
Log2(("vmmdevIPort_SetAbsoluteMouse : settings absolute position to x = %d, y = %d\n", xAbs, yAbs));
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevIPort_QueryMouseCapabilities(PPDMIVMMDEVPORT pInterface, uint32_t *pfCapabilities)
return VINF_SUCCESS;
static DECLCALLBACK(int)
vmmdevIPort_UpdateMouseCapabilities(PPDMIVMMDEVPORT pInterface, uint32_t fCapsAdded, uint32_t fCapsRemoved)
LogRelFlowFunc(("fCapsAdded=0x%x, fCapsRemoved=0x%x, fNotify=%RTbool\n", fCapsAdded, fCapsRemoved, fNotify));
if (fNotify)
return VINF_SUCCESS;
static DECLCALLBACK(int)
vmmdevIPort_RequestDisplayChange(PPDMIVMMDEVPORT pInterface, uint32_t cx, uint32_t cy, uint32_t cBits, uint32_t idxDisplay,
return VERR_INVALID_PARAMETER;
fSameResolution = false;
if (!fSameResolution)
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevIPort_RequestSeamlessChange(PPDMIVMMDEVPORT pInterface, bool fEnabled)
if (!fSameMode)
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevIPort_SetMemoryBalloon(PPDMIVMMDEVPORT pInterface, uint32_t cMbBalloon)
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevIPort_VRDPChange(PPDMIVMMDEVPORT pInterface, bool fVRDPEnabled, uint32_t uVRDPExperienceLevel)
if (!fSame)
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevIPort_SetStatisticsInterval(PPDMIVMMDEVPORT pInterface, uint32_t cSecsStatInterval)
Log(("vmmdevIPort_SetStatisticsInterval: old=%d. new=%d\n", pThis->u32LastStatIntervalSize, cSecsStatInterval));
if (!fSame)
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevIPort_SetCredentials(PPDMIVMMDEVPORT pInterface, const char *pszUsername,
AssertReturn(fFlags & (VMMDEV_SETCREDENTIALS_GUESTLOGON | VMMDEV_SETCREDENTIALS_JUDGE), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevIPort_CpuHotUnplug(PPDMIVMMDEVPORT pInterface, uint32_t idCpuCore, uint32_t idCpuPackage)
return rc;
static DECLCALLBACK(int) vmmdevIPort_CpuHotPlug(PPDMIVMMDEVPORT pInterface, uint32_t idCpuCore, uint32_t idCpuPackage)
return rc;
return VINF_SSM_DONT_CALL_AGAIN;
/* The following is not strictly necessary as PGM restores MMIO2, keeping it for historical reasons. */
#ifdef VBOX_WITH_HGCM
return VINF_SUCCESS;
static DECLCALLBACK(int) vmmdevLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
int rc;
LogRel(("VMMDev: Config mismatch - fGetHostTimeDisabled: config=%RTbool saved=%RTbool\n", pThis->fGetHostTimeDisabled, f));
LogRel(("VMMDev: Config mismatch - fBackdoorLogDisabled: config=%RTbool saved=%RTbool\n", pThis->fBackdoorLogDisabled, f));
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - fKeepCredentials: config=%RTbool saved=%RTbool"),
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - fHeapEnabled: config=%RTbool saved=%RTbool"),
return VINF_SUCCESS;
#ifdef VBOX_WITH_HGCM
("VMMDev: Ran out of entries restoring the guest facility statuses. Saved state has %u.\n", cFacilityStatuses),
Log(("vmmdevLoadState: capabilities changed (%x), informing connector\n", pThis->mouseCapabilities));
LogRel(("Guest Additions information report: additionsVersion = 0x%08X, osType = 0x%08X (%u-bit)\n",
pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, pThis->guestInfo2.uFullVersion, pThis->guestInfo2.szName,
return VINF_SUCCESS;
#ifdef VBOX_WITH_HGCM
pThis->pDrv->pfnVideoAccelEnable(pThis->pDrv, !!pThis->u32VideoAccelEnabled, &pThis->pVMMDevRAMR3->vbvaMemory);
return VINF_SUCCESS;
if (fVersionChanged)
while (iFacility-- > 0)
memset (&pRequest->lastReadDisplayChangeRequest, 0, sizeof (pRequest->lastReadDisplayChangeRequest));
#ifdef VBOX_WITH_HGCM
#ifdef VBOX_WITH_HGCM
#ifndef VBOX_WITHOUT_TESTING_FEATURES
return VINF_SUCCESS;
int rc;
vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxGuestDriver, true /*fFixed*/, &TimeStampNow);
vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxService, true /*fFixed*/, &TimeStampNow);
vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxTrayClient, true /*fFixed*/, &TimeStampNow);
vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_Seamless, true /*fFixed*/, &TimeStampNow);
vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_Graphics, true /*fFixed*/, &TimeStampNow);
#ifdef VBOX_WITH_HGCM
return VERR_NO_MEMORY;
rc = CFGMR3QueryU64Def(pCfg, "HeartbeatInterval", &pThis->u64HeartbeatInterval, HEARTBEAT_DEFAULT_INTERVAL);
rc = CFGMR3QueryU64Def(pCfg, "HeartbeatTimeout", &pThis->u64HeartbeatTimeout, pThis->u64HeartbeatInterval * 2);
#ifndef VBOX_WITHOUT_TESTING_FEATURES
return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed querying \"TestintXmlOutputFile\" as a string"));
#ifdef VMMDEV_WITH_ALT_TIMESYNC
rc = PDMDevHlpMMIO2Register(pDevIns, 1 /*iRegion*/, VMMDEV_RAM_SIZE, 0 /*fFlags*/, (void **)&pThis->pVMMDevRAMR3, "VMMDev");
rc = PDMDevHlpMMIO2Register(pDevIns, 2 /*iRegion*/, VMMDEV_HEAP_SIZE, 0 /*fFlags*/, (void **)&pThis->pVMMDevHeapR3, "VMMDev Heap");
return rc;
Log(("!!WARNING!!: pThis->PciDev.devfn=%d (ignore if testcase or no started by Main)\n", pThis->PciDev.devfn));
return rc;
rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1, VMMDEV_RAM_SIZE, PCI_ADDRESS_SPACE_MEM, vmmdevIORAMRegionMap);
return rc;
rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2, VMMDEV_HEAP_SIZE, PCI_ADDRESS_SPACE_MEM_PREFETCH, vmmdevIORAMRegionMap);
return rc;
#ifndef VBOX_WITHOUT_TESTING_FEATURES
return rc;
AssertMsgReturn(pThis->pDrv, ("LUN #0 doesn't have a VMMDev connector interface!\n"), VERR_PDM_MISSING_INTERFACE);
#ifdef VBOX_WITH_HGCM
Log(("%s/%d: warning: no driver attached to LUN #0!\n", pDevIns->pReg->szName, pDevIns->iInstance));
return rc;
#ifdef VBOX_WITH_HGCM
PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatMemBalloonChunks, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Memory balloon size", "/Devices/VMMDev/BalloonChunks");
return rc;
PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
sizeof(VMMDevState),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,