VirtualBox

Changeset 21456 in vbox


Ignore:
Timestamp:
Jul 9, 2009 8:09:23 PM (15 years ago)
Author:
vboxsync
Message:

HGCM&Co: physical page list.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxGuestLib.h

    r21260 r21456  
    225225 * @return VBox status code.
    226226 */
    227 DECLR0VBGL(int) VbglR0HGCMInternalCall (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t fFlags,
     227DECLR0VBGL(int) VbglR0HGCMInternalCall (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
    228228                                        VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
    229229
     
    242242 * @return VBox status code.
    243243 */
    244 DECLR0VBGL(int) VbglR0HGCMInternalCall32 (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t fFlags,
     244DECLR0VBGL(int) VbglR0HGCMInternalCall32 (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
    245245                                          VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
    246246
  • trunk/include/VBox/VMMDev.h

    r21227 r21456  
    105105 * Additions version is reported to host (VMMDev) by VMMDevReq_ReportGuestInfo.
    106106 *
    107  * @remark  These defines also live in the 16-bit and assembly versions of this header.
     107 * @remarks These defines also live in the 16-bit and assembly versions of this
     108 *          header.
    108109 */
    109110#define VMMDEV_VERSION                      0x00010004
     
    10051006    VMMDevHGCMParmType_64bit              = 2,
    10061007    VMMDevHGCMParmType_PhysAddr           = 3,
    1007     VMMDevHGCMParmType_LinAddr            = 4, /**< In and Out */
    1008     VMMDevHGCMParmType_LinAddr_In         = 5, /**< In  (read;  host<-guest) */
    1009     VMMDevHGCMParmType_LinAddr_Out        = 6, /**< Out (write; host->guest) */
    1010     VMMDevHGCMParmType_LinAddr_Locked     = 7, /**< Locked In and Out */
    1011     VMMDevHGCMParmType_LinAddr_Locked_In  = 8, /**< Locked In  (read;  host<-guest) */
    1012     VMMDevHGCMParmType_LinAddr_Locked_Out = 9, /**< Locked Out (write; host->guest) */
     1008    VMMDevHGCMParmType_LinAddr            = 4,  /**< In and Out */
     1009    VMMDevHGCMParmType_LinAddr_In         = 5,  /**< In  (read;  host<-guest) */
     1010    VMMDevHGCMParmType_LinAddr_Out        = 6,  /**< Out (write; host->guest) */
     1011    VMMDevHGCMParmType_LinAddr_Locked     = 7,  /**< Locked In and Out */
     1012    VMMDevHGCMParmType_LinAddr_Locked_In  = 8,  /**< Locked In  (read;  host<-guest) */
     1013    VMMDevHGCMParmType_LinAddr_Locked_Out = 9,  /**< Locked Out (write; host->guest) */
     1014    VMMDevHGCMParmType_PageList           = 10, /**< Physical addresses of locked pages for a buffer. */
    10131015    VMMDevHGCMParmType_SizeHack           = 0x7fffffff
    10141016} HGCMFunctionParameterType;
     
    10361038            } u;
    10371039        } Pointer;
     1040        struct
     1041        {
     1042            uint32_t size;   /**< Size of the buffer described by the page list. */
     1043            uint32_t offset; /**< Relative to the request header, valid if size != 0. */
     1044        } PageList;
    10381045    } u;
    10391046#  ifdef __cplusplus
     
    11011108            } u;
    11021109        } Pointer;
     1110        struct
     1111        {
     1112            uint32_t size;   /**< Size of the buffer described by the page list. */
     1113            uint32_t offset; /**< Relative to the request header, valid if size != 0. */
     1114        } PageList;
    11031115    } u;
    11041116#  ifdef __cplusplus
     
    11811193            } u;
    11821194        } Pointer;
     1195        struct
     1196        {
     1197            uint32_t size;   /**< Size of the buffer described by the page list. */
     1198            uint32_t offset; /**< Relative to the request header, valid if size != 0. */
     1199        } PageList;
    11831200    } u;
    11841201#  ifdef __cplusplus
     
    12461263} VMMDevHGCMCall;
    12471264AssertCompileSize(VMMDevHGCMCall, 32+12);
     1265
     1266/** @name Direction of data transfer (HGCMPageListInfo::flags). Bit flags.
     1267 * @{ */
     1268#define VBOX_HGCM_F_PARM_DIRECTION_NONE      UINT32_C(0x00000000)
     1269#define VBOX_HGCM_F_PARM_DIRECTION_TO_HOST   UINT32_C(0x00000001)
     1270#define VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST UINT32_C(0x00000002)
     1271#define VBOX_HGCM_F_PARM_DIRECTION_BOTH      UINT32_C(0x00000003)
     1272/** @} */
     1273
     1274/**
     1275 * VMMDevHGCMParmType_PageList points to this structure to actually describe the
     1276 * buffer.
     1277 */
     1278typedef struct _HGCMPageListInfo
     1279{
     1280    uint32_t flags;        /* VBOX_HGCM_F_PARM_*. */
     1281    uint16_t offFirstPage; /* Offset in the first page where data begins. */
     1282    uint16_t cPages;       /* Number of pages. */
     1283    RTGCPHYS64 aPages[1];  /* Page addesses. */
     1284} HGCMPageListInfo;
     1285AssertCompileSize(HGCMPageListInfo, 4+2+2+8);
    12481286
    12491287# pragma pack()
  • trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest.cpp

    r21260 r21456  
    11921192            uint32_t fFlags = pIrp->RequestorMode == KernelMode ? VBGLR0_HGCMCALL_F_KERNEL : VBGLR0_HGCMCALL_F_USER;
    11931193
    1194             rc = VbglR0HGCMInternalCall32(ptr, fFlags, pIrp->RequestorMode == KernelMode? VBoxHGCMCallbackKernelMode :VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT);
     1194            rc = VbglR0HGCMInternalCall32(ptr, pStack->Parameters.DeviceIoControl.InputBufferLength, fFlags,
     1195                                          pIrp->RequestorMode == KernelMode? VBoxHGCMCallbackKernelMode :VBoxHGCMCallback,
     1196                                          pDevExt, RT_INDEFINITE_WAIT);
    11951197
    11961198            if (RT_FAILURE(rc))
     
    12251227            uint32_t fFlags = pIrp->RequestorMode == KernelMode ? VBGLR0_HGCMCALL_F_KERNEL : VBGLR0_HGCMCALL_F_USER;
    12261228
    1227             rc = VbglR0HGCMInternalCall (ptr, fFlags, pIrp->RequestorMode == KernelMode? VBoxHGCMCallbackKernelMode :VBoxHGCMCallback,
     1229            rc = VbglR0HGCMInternalCall (ptr, pStack->Parameters.DeviceIoControl.InputBufferLength, fFlags,
     1230                                         pIrp->RequestorMode == KernelMode? VBoxHGCMCallbackKernelMode :VBoxHGCMCallback,
    12281231                                         pDevExt, RT_INDEFINITE_WAIT);
    12291232
     
    12631266                dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall interruptible, timeout %lu ms\n",
    12641267                         pInfo->u32Timeout));
    1265                 rc = VbglR0HGCMInternalCall (ptr, fFlags, VBoxHGCMCallbackInterruptible, pDevExt, pInfo->u32Timeout);
     1268                rc = VbglR0HGCMInternalCall (ptr, pStack->Parameters.DeviceIoControl.InputBufferLength, fFlags,
     1269                                             VBoxHGCMCallbackInterruptible, pDevExt, pInfo->u32Timeout);
    12661270            }
    12671271            else
     
    12691273                dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall, timeout %lu ms\n",
    12701274                         pInfo->u32Timeout));
    1271                 rc = VbglR0HGCMInternalCall (ptr, fFlags, VBoxHGCMCallback, pDevExt, pInfo->u32Timeout);
     1275                rc = VbglR0HGCMInternalCall (ptr, pStack->Parameters.DeviceIoControl.InputBufferLength, fFlags,
     1276                                             VBoxHGCMCallback, pDevExt, pInfo->u32Timeout);
    12721277            }
    12731278
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r21450 r21456  
    11261126    {
    11271127        if (fInterruptible)
    1128             rc = VbglR0HGCMInternalCall32(pInfo, fFlags, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
     1128            rc = VbglR0HGCMInternalCall32(pInfo, cbData - cbExtra, fFlags, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
    11291129        else
    1130             rc = VbglR0HGCMInternalCall32(pInfo, fFlags, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
     1130            rc = VbglR0HGCMInternalCall32(pInfo, cbData - cbExtra, fFlags, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
    11311131    }
    11321132    else
     
    11341134    {
    11351135        if (fInterruptible)
    1136             rc = VbglR0HGCMInternalCall(pInfo, fFlags, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
     1136            rc = VbglR0HGCMInternalCall(pInfo, cbData - cbExtra, fFlags, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
    11371137        else
    1138             rc = VbglR0HGCMInternalCall(pInfo, fFlags, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
     1138            rc = VbglR0HGCMInternalCall(pInfo, cbData - cbExtra, fFlags, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
    11391139    }
    11401140    if (RT_SUCCESS(rc))
  • trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp

    r21268 r21456  
    122122
    123123/** @todo merge with the one below (use a header file). Too lazy now. */
    124 DECLR0VBGL(int) VbglR0HGCMInternalCall (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t fFlags,
     124DECLR0VBGL(int) VbglR0HGCMInternalCall (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
    125125                                        VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
    126126{
     
    140140    pHGCMCall = NULL;
    141141
    142     cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter);
     142    if (cbCallInfo == 0)
     143    {
     144        /* Caller did not specify the size (a valid value should be at least sizeof(VBoxGuestHGCMCallInfo)).
     145         * Compute the size.
     146         */
     147        cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter32);
     148    }
     149    else if (cbCallInfo < sizeof (VBoxGuestHGCMCallInfo))
     150    {
     151        return VERR_INVALID_PARAMETER;
     152    }
     153    else
     154    {
     155        cbParms = cbCallInfo - sizeof (VBoxGuestHGCMCallInfo);
     156    }
    143157
    144158    /* Allocate request */
     
    195209                    else
    196210                        pParm->type = VMMDevHGCMParmType_LinAddr;
     211                    break;
     212
     213                case VMMDevHGCMParmType_PageList:
     214                    if ((fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER)
     215                        rc = VERR_INVALID_PARAMETER;
    197216                    break;
    198217
     
    307326# if ARCH_BITS == 64
    308327/** @todo merge with the one above (use a header file). Too lazy now. */
    309 DECLR0VBGL(int) VbglR0HGCMInternalCall32 (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t fFlags,
     328DECLR0VBGL(int) VbglR0HGCMInternalCall32 (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
    310329                                          VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
    311330{
     
    325344    pHGCMCall = NULL;
    326345
    327     cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter32);
     346    if (cbCallInfo == 0)
     347    {
     348        /* Caller did not specify the size (a valid value should be at least sizeof(VBoxGuestHGCMCallInfo)).
     349         * Compute the size.
     350         */
     351        cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter32);
     352    }
     353    else if (cbCallInfo < sizeof (VBoxGuestHGCMCallInfo))
     354    {
     355        return VERR_INVALID_PARAMETER;
     356    }
     357    else
     358    {
     359        cbParms = cbCallInfo - sizeof (VBoxGuestHGCMCallInfo);
     360    }
    328361
    329362    /* Allocate request */
     
    380413                    else
    381414                        pParm->type = VMMDevHGCMParmType_LinAddr;
     415                    break;
     416
     417                case VMMDevHGCMParmType_PageList:
     418                    if ((fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER)
     419                        rc = VERR_INVALID_PARAMETER;
    382420                    break;
    383421
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r21231 r21456  
    11081108#endif /* VBOX_WITH_64_BITS_GUESTS */
    11091109
    1110                 pRequestHeader->rc = vmmdevHGCMCall (pThis, pHGCMCall, (RTGCPHYS)u32, f64Bits);
     1110                pRequestHeader->rc = vmmdevHGCMCall (pThis, pHGCMCall, requestHeader.size, (RTGCPHYS)u32, f64Bits);
    11111111            }
    11121112            break;
  • trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp

    r21062 r21456  
    338338}
    339339
     340static int vmmdevHGCMPageListRead(PPDMDEVINSR3 pDevIns, void *pvDst, uint32_t cbDst, const HGCMPageListInfo *pPageListInfo)
     341{
     342    int rc = VINF_SUCCESS;
     343
     344    uint8_t *pu8Dst = (uint8_t *)pvDst;
     345    uint32_t offPage = pPageListInfo->offFirstPage;
     346    size_t cbRemaining = (size_t)cbDst;
     347
     348    uint32_t iPage;
     349    for (iPage = 0; iPage < pPageListInfo->cPages; iPage++)
     350    {
     351        if (cbRemaining == 0)
     352        {
     353            break;
     354        }
     355
     356        size_t cbChunk = PAGE_SIZE - offPage;
     357
     358        if (cbChunk > cbRemaining)
     359        {
     360            cbChunk = cbRemaining;
     361        }
     362
     363        rc = PDMDevHlpPhysRead(pDevIns,
     364                               pPageListInfo->aPages[iPage] + offPage,
     365                               pu8Dst, cbChunk);
     366
     367        AssertRCBreak(rc);
     368
     369        offPage = 0; /* A next page is read from 0 offset. */
     370        cbRemaining -= cbChunk;
     371        pu8Dst += cbChunk;
     372    }
     373
     374    return rc;
     375}
     376
     377static int vmmdevHGCMPageListWrite(PPDMDEVINSR3 pDevIns, const HGCMPageListInfo *pPageListInfo, const void *pvSrc, uint32_t cbSrc)
     378{
     379    int rc = VINF_SUCCESS;
     380
     381    uint8_t *pu8Src = (uint8_t *)pvSrc;
     382    uint32_t offPage = pPageListInfo->offFirstPage;
     383    size_t cbRemaining = (size_t)cbSrc;
     384
     385    uint32_t iPage;
     386    for (iPage = 0; iPage < pPageListInfo->cPages; iPage++)
     387    {
     388        if (cbRemaining == 0)
     389        {
     390            break;
     391        }
     392
     393        size_t cbChunk = PAGE_SIZE - offPage;
     394
     395        if (cbChunk > cbRemaining)
     396        {
     397            cbChunk = cbRemaining;
     398        }
     399
     400        rc = PDMDevHlpPhysWrite(pDevIns,
     401                                pPageListInfo->aPages[iPage] + offPage,
     402                                pu8Src, cbChunk);
     403
     404        AssertRCBreak(rc);
     405
     406        offPage = 0; /* A next page is read from 0 offset. */
     407        cbRemaining -= cbChunk;
     408        pu8Src += cbChunk;
     409    }
     410
     411    return rc;
     412}
     413
    340414static void logRelSavedCmdSizeMismatch (const char *pszFunction, uint32_t cbExpected, uint32_t cbCmdSize)
    341415{
     
    456530}
    457531
    458 
    459 int vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, RTGCPHYS GCPhys, bool f64Bits)
     532int vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, uint32_t cbHGCMCall, RTGCPHYS GCPhys, bool f64Bits)
    460533{
    461534    int rc = VINF_SUCCESS;
     
    516589                } break;
    517590
     591                case VMMDevHGCMParmType_PageList:
     592                {
     593                    cbCmdSize += pGuestParm->u.PageList.size;
     594                    Log(("vmmdevHGCMCall: pagelist size = %d\n", pGuestParm->u.PageList.size));
     595                } break;
     596
    518597                case VMMDevHGCMParmType_32bit:
    519598                case VMMDevHGCMParmType_64bit:
     
    560639
    561640                    Log(("vmmdevHGCMCall: linptr size = %d\n", pGuestParm->u.Pointer.size));
     641                } break;
     642
     643                case VMMDevHGCMParmType_PageList:
     644                {
     645                    cbCmdSize += pGuestParm->u.PageList.size;
     646                    Log(("vmmdevHGCMCall: pagelist size = %d\n", pGuestParm->u.PageList.size));
    562647                } break;
    563648
     
    727812                     }
    728813
     814                     case VMMDevHGCMParmType_PageList:
     815                     {
     816                         uint32_t size = pGuestParm->u.PageList.size;
     817
     818                         /* Check that the page list info is within the request. */
     819                         if (   cbHGCMCall < sizeof (HGCMPageListInfo)
     820                             || pGuestParm->u.PageList.offset > cbHGCMCall - sizeof (HGCMPageListInfo))
     821                         {
     822                             rc = VERR_INVALID_PARAMETER;
     823                             break;
     824                         }
     825
     826                         /* At least the structure is within. */
     827                         HGCMPageListInfo *pPageListInfo = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + pGuestParm->u.PageList.offset);
     828
     829                         uint32_t cbPageListInfo = sizeof (HGCMPageListInfo) + (pPageListInfo->cPages - 1) * sizeof (pPageListInfo->aPages[0]);
     830
     831                         if (   pPageListInfo->cPages == 0
     832                             || cbHGCMCall < pGuestParm->u.PageList.offset + cbPageListInfo)
     833                         {
     834                             rc = VERR_INVALID_PARAMETER;
     835                             break;
     836                         }
     837
     838                         pHostParm->type = VBOX_HGCM_SVC_PARM_PTR;
     839                         pHostParm->u.pointer.size = size;
     840
     841                         /* Copy guest data to an allocated buffer, so
     842                          * services can use the data.
     843                          */
     844
     845                         if (size == 0)
     846                         {
     847                             pHostParm->u.pointer.addr = NULL;
     848                         }
     849                         else
     850                         {
     851                             if (pPageListInfo->flags & VBOX_HGCM_F_PARM_DIRECTION_TO_HOST)
     852                             {
     853                                 /* Copy pages to the pcBuf[size]. */
     854                                 rc = vmmdevHGCMPageListRead(pVMMDevState->pDevIns, pcBuf, size, pPageListInfo);
     855                             }
     856                             else
     857                                 rc = VINF_SUCCESS;
     858
     859                             if (RT_SUCCESS(rc))
     860                             {
     861                                 pHostParm->u.pointer.addr = pcBuf;
     862                                 pcBuf += size;
     863                             }
     864                         }
     865
     866                         Log(("vmmdevHGCMCall: PageList guest parameter rc = %Rrc\n", rc));
     867                         break;
     868                     }
     869
    729870                    /* just to shut up gcc */
    730871                    default:
     
    828969                     }
    829970
     971                     case VMMDevHGCMParmType_PageList:
     972                     {
     973                         uint32_t size = pGuestParm->u.PageList.size;
     974
     975                         /* Check that the page list info is within the request. */
     976                         if (   cbHGCMCall < sizeof (HGCMPageListInfo)
     977                             || pGuestParm->u.PageList.offset > cbHGCMCall - sizeof (HGCMPageListInfo))
     978                         {
     979                             rc = VERR_INVALID_PARAMETER;
     980                             break;
     981                         }
     982
     983                         /* At least the structure is within. */
     984                         HGCMPageListInfo *pPageListInfo = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + pGuestParm->u.PageList.offset);
     985
     986                         uint32_t cbPageListInfo = sizeof (HGCMPageListInfo) + (pPageListInfo->cPages - 1) * sizeof (pPageListInfo->aPages[0]);
     987
     988                         if (   pPageListInfo->cPages == 0
     989                             || cbHGCMCall < pGuestParm->u.PageList.offset + cbPageListInfo)
     990                         {
     991                             rc = VERR_INVALID_PARAMETER;
     992                             break;
     993                         }
     994
     995                         pHostParm->type = VBOX_HGCM_SVC_PARM_PTR;
     996                         pHostParm->u.pointer.size = size;
     997
     998                         /* Copy guest data to an allocated buffer, so
     999                          * services can use the data.
     1000                          */
     1001
     1002                         if (size == 0)
     1003                         {
     1004                             pHostParm->u.pointer.addr = NULL;
     1005                         }
     1006                         else
     1007                         {
     1008                             if (pPageListInfo->flags & VBOX_HGCM_F_PARM_DIRECTION_TO_HOST)
     1009                             {
     1010                                 /* Copy pages to the pcBuf[size]. */
     1011                                 rc = vmmdevHGCMPageListRead(pVMMDevState->pDevIns, pcBuf, size, pPageListInfo);
     1012                             }
     1013                             else
     1014                                 rc = VINF_SUCCESS;
     1015
     1016                             if (RT_SUCCESS(rc))
     1017                             {
     1018                                 pHostParm->u.pointer.addr = pcBuf;
     1019                                 pcBuf += size;
     1020                             }
     1021                         }
     1022
     1023                         Log(("vmmdevHGCMCall: PageList guest parameter rc = %Rrc\n", rc));
     1024                         break;
     1025                     }
     1026
    8301027                    /* just to shut up gcc */
    8311028                    default:
     
    8691066
    8701067
    871 static int vmmdevHGCMCallSaved (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, bool f64Bits, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd)
     1068static int vmmdevHGCMCallSaved (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, uint32_t cbHGCMCall, bool f64Bits, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd)
    8721069{
    8731070    int rc = VINF_SUCCESS;
     
    10431240                     }
    10441241
     1242                     case VMMDevHGCMParmType_PageList:
     1243                     {
     1244                         uint32_t size = pGuestParm->u.PageList.size;
     1245
     1246                         /* Check that the page list info is within the request. */
     1247                         if (   cbHGCMCall < sizeof (HGCMPageListInfo)
     1248                             || pGuestParm->u.PageList.offset > cbHGCMCall - sizeof (HGCMPageListInfo))
     1249                         {
     1250                             rc = VERR_INVALID_PARAMETER;
     1251                             break;
     1252                         }
     1253
     1254                         /* At least the structure is within. */
     1255                         HGCMPageListInfo *pPageListInfo = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + pGuestParm->u.PageList.offset);
     1256
     1257                         uint32_t cbPageListInfo = sizeof (HGCMPageListInfo) + (pPageListInfo->cPages - 1) * sizeof (pPageListInfo->aPages[0]);
     1258
     1259                         if (   pPageListInfo->cPages == 0
     1260                             || cbHGCMCall < pGuestParm->u.PageList.offset + cbPageListInfo)
     1261                         {
     1262                             rc = VERR_INVALID_PARAMETER;
     1263                             break;
     1264                         }
     1265
     1266                         pHostParm->type = VBOX_HGCM_SVC_PARM_PTR;
     1267                         pHostParm->u.pointer.size = size;
     1268
     1269                         /* Copy guest data to an allocated buffer, so
     1270                          * services can use the data.
     1271                          */
     1272
     1273                         if (size == 0)
     1274                         {
     1275                             pHostParm->u.pointer.addr = NULL;
     1276                         }
     1277                         else
     1278                         {
     1279                             if (pPageListInfo->flags & VBOX_HGCM_F_PARM_DIRECTION_TO_HOST)
     1280                             {
     1281                                 /* Copy pages to the pcBuf[size]. */
     1282                                 rc = vmmdevHGCMPageListRead(pVMMDevState->pDevIns, pu8Buf, size, pPageListInfo);
     1283                             }
     1284                             else
     1285                                 rc = VINF_SUCCESS;
     1286
     1287                             if (RT_SUCCESS(rc))
     1288                             {
     1289                                 pHostParm->u.pointer.addr = pu8Buf;
     1290                                 pu8Buf += size;
     1291                             }
     1292                         }
     1293
     1294                         Log(("vmmdevHGCMCall: PageList guest parameter rc = %Rrc\n", rc));
     1295                         break;
     1296                     }
     1297
    10451298                    /* just to shut up gcc */
    10461299                    default:
     
    11831436                     }
    11841437
     1438                     case VMMDevHGCMParmType_PageList:
     1439                     {
     1440                         uint32_t size = pGuestParm->u.PageList.size;
     1441
     1442                         /* Check that the page list info is within the request. */
     1443                         if (   cbHGCMCall < sizeof (HGCMPageListInfo)
     1444                             || pGuestParm->u.PageList.offset > cbHGCMCall - sizeof (HGCMPageListInfo))
     1445                         {
     1446                             rc = VERR_INVALID_PARAMETER;
     1447                             break;
     1448                         }
     1449
     1450                         /* At least the structure is within. */
     1451                         HGCMPageListInfo *pPageListInfo = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + pGuestParm->u.PageList.offset);
     1452
     1453                         uint32_t cbPageListInfo = sizeof (HGCMPageListInfo) + (pPageListInfo->cPages - 1) * sizeof (pPageListInfo->aPages[0]);
     1454
     1455                         if (   pPageListInfo->cPages == 0
     1456                             || cbHGCMCall < pGuestParm->u.PageList.offset + cbPageListInfo)
     1457                         {
     1458                             rc = VERR_INVALID_PARAMETER;
     1459                             break;
     1460                         }
     1461
     1462                         pHostParm->type = VBOX_HGCM_SVC_PARM_PTR;
     1463                         pHostParm->u.pointer.size = size;
     1464
     1465                         /* Copy guest data to an allocated buffer, so
     1466                          * services can use the data.
     1467                          */
     1468
     1469                         if (size == 0)
     1470                         {
     1471                             pHostParm->u.pointer.addr = NULL;
     1472                         }
     1473                         else
     1474                         {
     1475                             if (pPageListInfo->flags & VBOX_HGCM_F_PARM_DIRECTION_TO_HOST)
     1476                             {
     1477                                 /* Copy pages to the pcBuf[size]. */
     1478                                 rc = vmmdevHGCMPageListRead(pVMMDevState->pDevIns, pu8Buf, size, pPageListInfo);
     1479                             }
     1480                             else
     1481                                 rc = VINF_SUCCESS;
     1482
     1483                             if (RT_SUCCESS(rc))
     1484                             {
     1485                                 pHostParm->u.pointer.addr = pu8Buf;
     1486                                 pu8Buf += size;
     1487                             }
     1488                         }
     1489
     1490                         Log(("vmmdevHGCMCall: PageList guest parameter rc = %Rrc\n", rc));
     1491                         break;
     1492                     }
     1493
    11851494                    /* just to shut up gcc */
    11861495                    default:
     
    14051714                        } break;
    14061715
     1716                        case VMMDevHGCMParmType_PageList:
     1717                        {
     1718                            uint32_t cbHGCMCall = pCmd->cbSize; /* Size of the request. */
     1719
     1720                            uint32_t size = pGuestParm->u.PageList.size;
     1721
     1722                            /* Check that the page list info is within the request. */
     1723                            if (   cbHGCMCall < sizeof (HGCMPageListInfo)
     1724                                || pGuestParm->u.PageList.offset > cbHGCMCall - sizeof (HGCMPageListInfo))
     1725                            {
     1726                                rc = VERR_INVALID_PARAMETER;
     1727                                break;
     1728                            }
     1729
     1730                            /* At least the structure is within. */
     1731                            HGCMPageListInfo *pPageListInfo = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + pGuestParm->u.PageList.offset);
     1732
     1733                            uint32_t cbPageListInfo = sizeof (HGCMPageListInfo) + (pPageListInfo->cPages - 1) * sizeof (pPageListInfo->aPages[0]);
     1734
     1735                            if (   pPageListInfo->cPages == 0
     1736                                || cbHGCMCall < pGuestParm->u.PageList.offset + cbPageListInfo)
     1737                            {
     1738                                rc = VERR_INVALID_PARAMETER;
     1739                                break;
     1740                            }
     1741
     1742                            if (size > 0)
     1743                            {
     1744                                if (pPageListInfo->flags & VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST)
     1745                                {
     1746                                    /* Copy pHostParm->u.pointer.addr[pHostParm->u.pointer.size] to pages. */
     1747                                    rc = vmmdevHGCMPageListWrite(pVMMDevState->pDevIns, pPageListInfo, pHostParm->u.pointer.addr, size);
     1748                                }
     1749                                else
     1750                                    rc = VINF_SUCCESS;
     1751                            }
     1752
     1753                            Log(("vmmdevHGCMCall: PageList guest parameter rc = %Rrc\n", rc));
     1754                        } break;
     1755
    14071756                        default:
    14081757                        {
     
    14661815                                iLinPtr++;
    14671816                            }
     1817                        } break;
     1818
     1819                        case VMMDevHGCMParmType_PageList:
     1820                        {
     1821                            uint32_t cbHGCMCall = pCmd->cbSize; /* Size of the request. */
     1822
     1823                            uint32_t size = pGuestParm->u.PageList.size;
     1824
     1825                            /* Check that the page list info is within the request. */
     1826                            if (   cbHGCMCall < sizeof (HGCMPageListInfo)
     1827                                || pGuestParm->u.PageList.offset > cbHGCMCall - sizeof (HGCMPageListInfo))
     1828                            {
     1829                                rc = VERR_INVALID_PARAMETER;
     1830                                break;
     1831                            }
     1832
     1833                            /* At least the structure is within. */
     1834                            HGCMPageListInfo *pPageListInfo = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + pGuestParm->u.PageList.offset);
     1835
     1836                            uint32_t cbPageListInfo = sizeof (HGCMPageListInfo) + (pPageListInfo->cPages - 1) * sizeof (pPageListInfo->aPages[0]);
     1837
     1838                            if (   pPageListInfo->cPages == 0
     1839                                || cbHGCMCall < pGuestParm->u.PageList.offset + cbPageListInfo)
     1840                            {
     1841                                rc = VERR_INVALID_PARAMETER;
     1842                                break;
     1843                            }
     1844
     1845                            if (size > 0)
     1846                            {
     1847                                if (pPageListInfo->flags & VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST)
     1848                                {
     1849                                    /* Copy pHostParm->u.pointer.addr[pHostParm->u.pointer.size] to pages. */
     1850                                    rc = vmmdevHGCMPageListWrite(pVMMDevState->pDevIns, pPageListInfo, pHostParm->u.pointer.addr, size);
     1851                                }
     1852                                else
     1853                                    rc = VINF_SUCCESS;
     1854                            }
     1855
     1856                            Log(("vmmdevHGCMCall: PageList guest parameter rc = %Rrc\n", rc));
    14681857                        } break;
    14691858
     
    15291918                                iLinPtr++;
    15301919                            }
     1920                        } break;
     1921
     1922                        case VMMDevHGCMParmType_PageList:
     1923                        {
     1924                            uint32_t cbHGCMCall = pCmd->cbSize; /* Size of the request. */
     1925
     1926                            uint32_t size = pGuestParm->u.PageList.size;
     1927
     1928                            /* Check that the page list info is within the request. */
     1929                            if (   cbHGCMCall < sizeof (HGCMPageListInfo)
     1930                                || pGuestParm->u.PageList.offset > cbHGCMCall - sizeof (HGCMPageListInfo))
     1931                            {
     1932                                rc = VERR_INVALID_PARAMETER;
     1933                                break;
     1934                            }
     1935
     1936                            /* At least the structure is within. */
     1937                            HGCMPageListInfo *pPageListInfo = (HGCMPageListInfo *)((uint8_t *)pHGCMCall + pGuestParm->u.PageList.offset);
     1938
     1939                            uint32_t cbPageListInfo = sizeof (HGCMPageListInfo) + (pPageListInfo->cPages - 1) * sizeof (pPageListInfo->aPages[0]);
     1940
     1941                            if (   pPageListInfo->cPages == 0
     1942                                || cbHGCMCall < pGuestParm->u.PageList.offset + cbPageListInfo)
     1943                            {
     1944                                rc = VERR_INVALID_PARAMETER;
     1945                                break;
     1946                            }
     1947
     1948                            if (size > 0)
     1949                            {
     1950                                if (pPageListInfo->flags & VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST)
     1951                                {
     1952                                    /* Copy pHostParm->u.pointer.addr[pHostParm->u.pointer.size] to pages. */
     1953                                    rc = vmmdevHGCMPageListWrite(pVMMDevState->pDevIns, pPageListInfo, pHostParm->u.pointer.addr, size);
     1954                                }
     1955                                else
     1956                                    rc = VINF_SUCCESS;
     1957                            }
     1958
     1959                            Log(("vmmdevHGCMCall: PageList guest parameter rc = %Rrc\n", rc));
    15311960                        } break;
    15321961
     
    20092438                                bool f64Bits = false;
    20102439#endif /* VBOX_WITH_64_BITS_GUESTS */
    2011                                 requestHeader->header.rc = vmmdevHGCMCallSaved (pVMMDevState, pHGCMCall, f64Bits, &fHGCMCalled, pIter);
     2440                                requestHeader->header.rc = vmmdevHGCMCallSaved (pVMMDevState, pHGCMCall, requestHeader->header.size, f64Bits, &fHGCMCalled, pIter);
    20122441                            }
    20132442                            break;
     
    20932522                                        bool f64Bits = false;
    20942523#endif /* VBOX_WITH_64_BITS_GUESTS */
    2095                                         requestHeader->header.rc = vmmdevHGCMCall (pVMMDevState, pHGCMCall, pIter->GCPhys, f64Bits);
     2524                                        requestHeader->header.rc = vmmdevHGCMCall (pVMMDevState, pHGCMCall, requestHeader->header.size, pIter->GCPhys, f64Bits);
    20962525                                    }
    20972526                                    break;
  • trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.h

    r21227 r21456  
    2828DECLCALLBACK(int) vmmdevHGCMConnect (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect, RTGCPHYS GCPtr);
    2929DECLCALLBACK(int) vmmdevHGCMDisconnect (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect, RTGCPHYS GCPtr);
    30 DECLCALLBACK(int) vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, RTGCPHYS GCPtr, bool f64Bits);
     30DECLCALLBACK(int) vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, uint32_t cbHGCMCall, RTGCPHYS GCPtr, bool f64Bits);
    3131DECLCALLBACK(int) vmmdevHGCMCancel (VMMDevState *pVMMDevState, VMMDevHGCMCancel *pHGCMCancel, RTGCPHYS GCPtr);
    3232
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette