VMMDevHGCM.cpp revision 4e70517ea7c253ad227af80a841e38adb5420203
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * VBox Guest/VMM/host communication:
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * HGCM - Host-Guest Communication Manager device
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * Copyright (C) 2006-2007 Sun Microsystems, Inc.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * This file is part of VirtualBox Open Source Edition (OSE), as
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * available from http://www.virtualbox.org. This file is free software;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * you can redistribute it and/or modify it under the terms of the GNU
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * General Public License (GPL) as published by the Free Software
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * Foundation, in version 2 as it comes in the "COPYING" file of the
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * Clara, CA 95054 USA or visit http://www.sun.com if you need
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * additional information or have any questions.
#include "VMMDevHGCM.h"
typedef enum _VBOXHGCMCMDTYPE
typedef struct _VBOXHGCMLINPTR
int iParm;
struct VBOXHGCMCMD
int cLinPtrs;
return rc;
static int vmmdevHGCMAddCommand (VMMDevState *pVMMDevState, PVBOXHGCMCMD pCmd, RTGCPHYS GCPhys, uint32_t cbSize, VBOXHGCMCMDTYPE enmCmdType)
return rc;
return rc;
return rc;
void *pvHost,
Log(("vmmdevHGCMWriteLinPtr: page %d: dst %VGp, src %p, cbWrite %d\n", iPage, GCPhysDst, pu8Src, cbWrite));
iPage++;
u32Size = 0;
return rc;
PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (struct VBOXHGCMCMD) + pHGCMConnect->header.header.size);
if (pCmd)
vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, pHGCMConnect->header.header.size, VBOXHGCMCMDTYPE_CONNECT);
rc = pVMMDevState->pHGCMDrv->pfnConnect (pVMMDevState->pHGCMDrv, pCmd, &pHGCMConnectCopy->loc, &pHGCMConnectCopy->u32ClientID);
return rc;
int vmmdevHGCMDisconnect (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect, RTGCPHYS GCPhys)
if (pCmd)
vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, pHGCMDisconnect->header.header.size, VBOXHGCMCMDTYPE_DISCONNECT);
rc = pVMMDevState->pHGCMDrv->pfnDisconnect (pVMMDevState->pHGCMDrv, pCmd, pHGCMDisconnect->u32ClientID);
return rc;
int vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, RTGCPHYS GCPhys, bool f64Bits)
Log(("vmmdevHGCMCall: client id = %d, function = %d, %s bit\n", pHGCMCall->u32ClientID, pHGCMCall->u32Function, f64Bits? "64": "32"));
uint32_t i;
if (f64Bits)
#ifdef VBOX_WITH_64_BITS_GUESTS
cLinPtrs++;
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
#ifdef VBOX_WITH_64_BITS_GUESTS
cLinPtrs++;
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
return rc;
return VERR_NO_MEMORY;
if (cLinPtrs > 0)
return VERR_NO_MEMORY;
if (cParms != 0)
if (f64Bits)
#ifdef VBOX_WITH_64_BITS_GUESTS
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
#ifdef LOG_ENABLED
AssertFailed();
/* rc = PDMDevHlpPhys2HCVirt (pVMMDevState->pDevIns, physAddr, size, &pHostParm->u.pointer.addr); */
if (size == 0)
rc = vmmdevHGCMSaveLinPtr (pVMMDevState->pDevIns, i, linearAddr, size, iLinPtr++, pCmd->paLinPtrs, &pPages);
#ifdef VBOX_WITH_64_BITS_GUESTS
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
#ifdef LOG_ENABLED
AssertFailed();
/* rc = PDMDevHlpPhys2HCVirt (pVMMDevState->pDevIns, physAddr, size, &pHostParm->u.pointer.addr); */
if (size == 0)
rc = vmmdevHGCMSaveLinPtr (pVMMDevState->pDevIns, i, linearAddr, size, iLinPtr++, pCmd->paLinPtrs, &pPages);
vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, pHGCMCall->header.header.size, VBOXHGCMCMDTYPE_CALL);
rc = pVMMDevState->pHGCMDrv->pfnCall (pVMMDevState->pHGCMDrv, pCmd, pHGCMCall->u32ClientID, pHGCMCall->u32Function, cParms, pCmd->paHostParms);
return rc;
case VBOXHGCMCMDTYPE_CONNECT:
case VBOXHGCMCMDTYPE_CALL:
#ifdef VBOX_WITH_64_BITS_GUESTS
AssertFailed ();
LogRel(("VMMDEV: Invalid HGCM command: pCmd->enmCmdType = 0x%08X, pHeader->header.requestType = 0x%08X\n",
return VERR_INVALID_PARAMETER;
#define PDMIHGCMPORT_2_VMMDEVSTATE(pInterface) ( (VMMDevState *) ((uintptr_t)pInterface - RT_OFFSETOF(VMMDevState, HGCMPort)) )
DECLCALLBACK(void) hgcmCompletedWorker (PPDMIHGCMPORT pInterface, int32_t result, PVBOXHGCMCMD pCmd)
#ifdef VBOX_WITH_64_BITS_GUESTS
case VMMDevReq_HGCMCall64:
uint32_t i;
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs);
case VMMDevReq_HGCMCall32:
uint32_t i;
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs);
case VMMDevReq_HGCMCall:
uint32_t i;
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs);
case VMMDevReq_HGCMConnect:
int rc = VMR3ReqCallEx(PDMDevHlpGetVM(pVMMDevState->pDevIns), NULL, 0, VMREQFLAGS_NO_WAIT | VMREQFLAGS_VOID,
while (pIter)
cCmds++;
if (cCmds > 0)
while (pIter)
return rc;
while (cCmds--)
return rc;
while (pIter)
return VERR_NO_MEMORY;
Log(("VMMDev: guest header version (0x%08X) differs from ours (0x%08X)\n", requestHeader->version, VMMDEV_REQUEST_HEADER_VERSION));
case VMMDevReq_HGCMConnect:
case VMMDevReq_HGCMDisconnect:
#ifdef VBOX_WITH_64_BITS_GUESTS
case VMMDevReq_HGCMCall64:
case VMMDevReq_HGCMCall32:
case VMMDevReq_HGCMCall:
#ifdef VBOX_WITH_64_BITS_GUESTS
bool f64Bits = false;
LogRel(("VMMDEV: Ignoring unknown request type %x during LoadState\n", requestHeader->requestType));
return rc;