VMMDevHGCM.cpp revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/** @file
*
* HGCM - Host-Guest Communication Manager device
*/
/*
* Copyright (C) 2006 InnoTek Systemberatung GmbH
*
* 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 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.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
#define LOG_GROUP LOG_GROUP_DEV_VMM
#include "VMMDevHGCM.h"
/* Information about a linear ptr parameter. */
typedef struct _VBOXHGCMLINPTR
{
/* Index of the parameter. */
int iParm;
/* Offset in the first physical page of the region. */
/* How many pages. */
/* Pointer to array of the HC addresses for these pages.
* It is assumed that the HC address of the locked resident
* guest physical page does not change.
*/
struct VBOXHGCMCMD
{
/* Pointer to guest request. */
/* Pointer to converted host parameters in case of a Call request. */
/* Linear pointer parameters information. */
int cLinPtrs;
/* Pointer to descriptions of linear pointers. */
};
{
int rc = VINF_SUCCESS;
AssertRelease (u32Size > 0);
/* Gonvert the guest linear pointers of pages to HC addresses. */
{
/* convert */
// rc = PGMPhysGCPtr2HCPtr (pVM, GCPtr, &HCPtr);
if (VBOX_FAILURE (rc))
{
break;
}
/* store */
/* next */
}
return rc;
}
void *pvHost,
{
int rc = VINF_SUCCESS;
{
/* copy */
Log(("vmmdevHGCMWriteLinPtr: page %d: dst %p, src %p, cbWrite %d\n", iPage, pu8Dst, pu8Src, cbWrite));
iPage++;
{
break;
}
/* next */
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (pCmd)
{
/* Only allow the guest to use existing services! */
rc = pVMMDevState->pHGCMDrv->pfnConnect (pVMMDevState->pHGCMDrv, pCmd, &pHGCMConnect->loc, &pHGCMConnect->u32ClientID);
}
else
{
rc = VERR_NO_MEMORY;
}
return rc;
}
{
int rc = VINF_SUCCESS;
if (pCmd)
{
rc = pVMMDevState->pHGCMDrv->pfnDisconnect (pVMMDevState->pHGCMDrv, pCmd, pHGCMDisconnect->u32ClientID);
}
else
{
rc = VERR_NO_MEMORY;
}
return rc;
}
{
int rc = VINF_SUCCESS;
Log(("vmmdevHGCMCall: client id = %d, function = %d\n", pHGCMCall->u32ClientID, pHGCMCall->u32Function));
/* Compute size and allocate memory block to hold:
* struct VBOXHGCMCMD
* VBOXHGCMSVCPARM[cParms]
* memory buffers for pointer parameters.
*/
/*
* Compute size of required memory buffer.
*/
/* Look for pointer parameters, which require a host buffer. */
uint32_t i;
uint32_t cLinPtrPages = 0;
{
switch (pGuestParm->type)
{
case VMMDevHGCMParmType_LinAddr_In: /* In (read) */
case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
case VMMDevHGCMParmType_LinAddr: /* In & Out */
#if 0
#endif
{
{
cLinPtrs++;
}
} break;
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
{
} break;
default:
{
break;
}
}
}
if (VBOX_FAILURE (rc))
{
return rc;
}
{
return VERR_NO_MEMORY;
}
if (cLinPtrs > 0)
{
+ sizeof (RTHCPTR) * cLinPtrPages);
{
return VERR_NO_MEMORY;
}
}
else
{
}
/* Process parameters, changing them to host context pointers for easy
* processing by connector. Guest must insure that the pointed data is actually
* in the guest RAM and remains locked there for entire request processing.
*/
if (cParms != 0)
{
/* Compute addresses of host parms array and first memory buffer. */
{
switch (pGuestParm->type)
{
case VMMDevHGCMParmType_32bit:
{
} break;
case VMMDevHGCMParmType_64bit:
{
} break;
{
} break;
case VMMDevHGCMParmType_LinAddr_In: /* In (read) */
case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
case VMMDevHGCMParmType_LinAddr: /* In & Out */
{
/* Copy guest data to an allocated buffer, so
* services can use the data.
*/
if (size == 0)
{
}
else
{
/* Don't overdo it */
{
linearAddr, size);
}
else
rc = VINF_SUCCESS;
if (VBOX_SUCCESS(rc))
{
{
/* Remember the guest physical pages those belongs to the virtual address
* region.
*/
rc = vmmdevHGCMSaveLinPtr (pVMMDevState->pDevIns, i, linearAddr, size, iLinPtr++, pCmd->paLinPtrs, &pPages);
}
}
}
} break;
/* just to shut up gcc */
default:
break;
}
}
}
if (VBOX_SUCCESS (rc))
{
/* Pass the function call to HGCM connector for actual processing */
rc = pVMMDevState->pHGCMDrv->pfnCall (pVMMDevState->pHGCMDrv, pCmd, pHGCMCall->u32ClientID, pHGCMCall->u32Function, cParms, pCmd->paHostParms);
}
else
{
{
}
}
return rc;
}
#define PDMIHGCMPORT_2_VMMDEVSTATE(pInterface) ( (VMMDevState *) ((uintptr_t)pInterface - RT_OFFSETOF(VMMDevState, HGCMPort)) )
{
int rc = VINF_SUCCESS;
/* Setup return codes. */
/* Update parameters and data buffers. */
{
uint32_t i;
{
switch (pGuestParm->type)
{
case VMMDevHGCMParmType_32bit:
{
} break;
case VMMDevHGCMParmType_64bit:
{
} break;
{
/* do nothing */
} break;
case VMMDevHGCMParmType_LinAddr_In: /* In (read) */
case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
case VMMDevHGCMParmType_LinAddr: /* In & Out */
{
/* Copy buffer back to guest memory. */
{
/* Use the saved page list. */
rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs);
// RTGCPTR linearAddr = pGuestParm->u.Pointer.u.linearAddr;
//
// rc = pVMMDevState->pDevIns->pDevHlp->pfnPhysWriteGCVirt (pVMMDevState->pDevIns,
// linearAddr,
// pHostParm->u.pointer.addr,
// size);
}
} break;
default:
{
/* This indicates that the guest request memory was corrupted. */
}
}
}
}
/* Mark request as processed*/
{
}
return;
}