VirtualBox

Changeset 56036 in vbox for trunk/src


Ignore:
Timestamp:
May 22, 2015 4:29:25 PM (10 years ago)
Author:
vboxsync
Message:

DevVGA_VBVA: HGSMI and VBVA cleanup, logging

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r55844 r56036  
    5353} VBVAPARTIALRECORD;
    5454
     55typedef struct VBVADATA
     56{
     57    struct
     58    {
     59        VBVABUFFER *pVBVA;           /* Pointer to the guest memory with the VBVABUFFER. */
     60        uint8_t *pu8Data;            /* For convenience, pointer to the guest ring buffer (VBVABUFFER::au8Data). */
     61    } guest;
     62    uint32_t u32VBVAOffset;          /* VBVABUFFER offset in the guest VRAM. */
     63    VBVAPARTIALRECORD partialRecord; /* Partial record temporary storage. */
     64    uint32_t off32Data;              /* The offset where the data starts in the VBVABUFFER.
     65                                      * The host code uses it instead of VBVABUFFER::off32Data.
     66                                      */
     67    uint32_t indexRecordFirst;       /* Index of the first filled record in VBVABUFFER::aRecords. */
     68    uint32_t cbPartialWriteThreshold; /* Copy of VBVABUFFER::cbPartialWriteThreshold used by host code. */
     69    uint32_t cbData;                 /* Copy of VBVABUFFER::cbData used by host code. */
     70} VBVADATA;
     71
    5572typedef struct VBVAVIEW
    5673{
    5774    VBVAINFOVIEW    view;
    5875    VBVAINFOSCREEN  screen;
    59     VBVABUFFER     *pVBVA;
    60     uint32_t        u32VBVAOffset;
    61     VBVAPARTIALRECORD partialRecord;
     76    VBVADATA        vbva;
    6277} VBVAVIEW;
    6378
     
    8095{
    8196    uint32_t cViews;
    82     VBVAVIEW aViews[64 /* @todo SchemaDefs::MaxGuestMonitors*/];
     97    VBVAVIEW aViews[VBOX_VIDEO_MAX_SCREENS];
    8398    VBVAMOUSESHAPEINFO mouseShapeInfo;
    8499    bool fPaused;
     
    89104
    90105
     106static void vbvaDataCleanup(VBVADATA *pVBVAData)
     107{
     108    if (pVBVAData->guest.pVBVA)
     109    {
     110        RT_ZERO(pVBVAData->guest.pVBVA->hostFlags);
     111    }
     112   
     113    RTMemFree(pVBVAData->partialRecord.pu8);
     114
     115    RT_ZERO(*pVBVAData);
     116    pVBVAData->u32VBVAOffset = HGSMIOFFSET_VOID;
     117}
    91118
    92119/** Copies @a cb bytes from the VBVA ring buffer to the @a pu8Dst.
    93120 * Used for partial records or for records which cross the ring boundary.
    94121 */
    95 static void vbvaFetchBytes (VBVABUFFER *pVBVA, uint8_t *pu8Dst, uint32_t cb)
    96 {
    97     /** @todo replace the 'if' with an assert. The caller must ensure this condition. */
    98     if (cb >= pVBVA->cbData)
    99     {
    100         AssertMsgFailed (("cb = 0x%08X, ring buffer size 0x%08X", cb, pVBVA->cbData));
    101         return;
    102     }
    103 
    104     const uint32_t u32BytesTillBoundary = pVBVA->cbData - pVBVA->off32Data;
    105     const uint8_t  *src                 = &pVBVA->au8Data[pVBVA->off32Data];
     122static bool vbvaFetchBytes(VBVADATA *pVBVAData, uint8_t *pu8Dst, uint32_t cb)
     123{
     124    if (cb >= pVBVAData->cbData)
     125    {
     126        AssertMsgFailed(("cb = 0x%08X, ring buffer size 0x%08X", cb, pVBVAData->cbData));
     127        return false;
     128    }
     129
     130    const uint32_t u32BytesTillBoundary = pVBVAData->cbData - pVBVAData->off32Data;
     131    const uint8_t  *pu8Src              = &pVBVAData->guest.pu8Data[pVBVAData->off32Data];
    106132    const int32_t i32Diff               = cb - u32BytesTillBoundary;
    107133
     
    109135    {
    110136        /* Chunk will not cross buffer boundary. */
    111         memcpy (pu8Dst, src, cb);
     137        memcpy(pu8Dst, pu8Src, cb);
    112138    }
    113139    else
    114140    {
    115141        /* Chunk crosses buffer boundary. */
    116         memcpy (pu8Dst, src, u32BytesTillBoundary);
    117         memcpy (pu8Dst + u32BytesTillBoundary, &pVBVA->au8Data[0], i32Diff);
    118     }
    119 
    120     /* Advance data offset. */
    121     pVBVA->off32Data = (pVBVA->off32Data + cb) % pVBVA->cbData;
    122 
    123     return;
    124 }
    125 
    126 
    127 static bool vbvaPartialRead (VBVAPARTIALRECORD *pPartialRecord, uint32_t cbRecord, VBVABUFFER *pVBVA)
    128 {
     142        memcpy(pu8Dst, pu8Src, u32BytesTillBoundary);
     143        memcpy(pu8Dst + u32BytesTillBoundary, &pVBVAData->guest.pu8Data[0], i32Diff);
     144    }
     145
     146    /* Advance data offset and sync with guest. */
     147    pVBVAData->off32Data = (pVBVAData->off32Data + cb) % pVBVAData->cbData;
     148    pVBVAData->guest.pVBVA->off32Data = pVBVAData->off32Data;
     149    return true;
     150}
     151
     152
     153static bool vbvaPartialRead(uint32_t cbRecord, VBVADATA *pVBVAData)
     154{
     155    VBVAPARTIALRECORD *pPartialRecord = &pVBVAData->partialRecord;
    129156    uint8_t *pu8New;
    130157
     
    132159                   pPartialRecord->pu8, pPartialRecord->cb, cbRecord));
    133160
     161    Assert(cbRecord > pPartialRecord->cb); /* Caller ensures this. */
     162
     163    const uint32_t cbChunk = cbRecord - pPartialRecord->cb;
     164    if (cbChunk >= pVBVAData->cbData)
     165    {
     166        return false;
     167    }
     168
    134169    if (pPartialRecord->pu8)
    135170    {
    136         Assert (pPartialRecord->cb);
    137         pu8New = (uint8_t *)RTMemRealloc (pPartialRecord->pu8, cbRecord);
     171        Assert(pPartialRecord->cb);
     172        pu8New = (uint8_t *)RTMemRealloc(pPartialRecord->pu8, cbRecord);
    138173    }
    139174    else
    140175    {
    141         Assert (!pPartialRecord->cb);
    142         pu8New = (uint8_t *)RTMemAlloc (cbRecord);
     176        Assert(!pPartialRecord->cb);
     177        pu8New = (uint8_t *)RTMemAlloc(cbRecord);
    143178    }
    144179
     
    149184             cbRecord));
    150185
    151         if (pPartialRecord->pu8)
    152         {
    153             RTMemFree (pPartialRecord->pu8);
    154         }
    155 
    156         pPartialRecord->pu8 = NULL;
    157         pPartialRecord->cb = 0;
    158 
    159186        return false;
    160187    }
    161188
    162189    /* Fetch data from the ring buffer. */
    163     vbvaFetchBytes (pVBVA, pu8New + pPartialRecord->cb, cbRecord - pPartialRecord->cb);
     190    if (!vbvaFetchBytes(pVBVAData, pu8New + pPartialRecord->cb, cbChunk))
     191    {
     192        return false;
     193    }
    164194
    165195    pPartialRecord->pu8 = pu8New;
     
    172202 * For crossing boundary - allocate a buffer from heap.
    173203 */
    174 static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA, VBVACMDHDR **ppHdr, uint32_t *pcbCmd)
    175 {
    176     uint32_t indexRecordFirst = pVBVA->indexRecordFirst;
    177     uint32_t indexRecordFree = pVBVA->indexRecordFree;
     204static bool vbvaFetchCmd(VBVADATA *pVBVAData, VBVACMDHDR **ppHdr, uint32_t *pcbCmd)
     205{
     206    VBVAPARTIALRECORD *pPartialRecord = &pVBVAData->partialRecord;
     207    uint32_t indexRecordFirst = pVBVAData->indexRecordFirst;
     208    const uint32_t indexRecordFree = ASMAtomicReadU32(&pVBVAData->guest.pVBVA->indexRecordFree);
    178209
    179210    LOGVBVABUFFER(("first = %d, free = %d\n",
    180211                   indexRecordFirst, indexRecordFree));
    181212
     213    if (indexRecordFree >= RT_ELEMENTS(pVBVAData->guest.pVBVA->aRecords))
     214    {
     215        return false;
     216    }
     217
    182218    if (indexRecordFirst == indexRecordFree)
    183219    {
     
    186222    }
    187223
    188     uint32_t cbRecordCurrent = ASMAtomicReadU32(&pVBVA->aRecords[indexRecordFirst].cbRecord);
     224    uint32_t cbRecordCurrent = ASMAtomicReadU32(&pVBVAData->guest.pVBVA->aRecords[indexRecordFirst].cbRecord);
    189225
    190226    LOGVBVABUFFER(("cbRecord = 0x%08X, pPartialRecord->cb = 0x%08X\n", cbRecordCurrent, pPartialRecord->cb));
    191227
    192228    uint32_t cbRecord = cbRecordCurrent & ~VBVA_F_RECORD_PARTIAL;
     229
     230    if (cbRecord > VBVA_MAX_RECORD_SIZE)
     231    {
     232        return false;
     233    }
    193234
    194235    if (pPartialRecord->cb)
     
    203244        {
    204245            /* New data has been added to the record. */
    205             if (!vbvaPartialRead (pPartialRecord, cbRecord, pVBVA))
     246            if (!vbvaPartialRead(cbRecord, pVBVAData))
    206247            {
    207248                return false;
     
    218259            pPartialRecord->cb = 0;
    219260
    220             /* Advance the record index. */
    221             pVBVA->indexRecordFirst = (indexRecordFirst + 1) % RT_ELEMENTS(pVBVA->aRecords);
     261            /* Advance the record index and sync with guest. */
     262            pVBVAData->indexRecordFirst = (indexRecordFirst + 1) % RT_ELEMENTS(pVBVAData->guest.pVBVA->aRecords);
     263            pVBVAData->guest.pVBVA->indexRecordFirst = pVBVAData->indexRecordFirst;
    222264
    223265            LOGVBVABUFFER(("partial done ok, data = %d, free = %d\n",
    224                           pVBVA->off32Data, pVBVA->off32Free));
     266                          pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free));
    225267        }
    226268
     
    236278         * be accumulated in an allocated buffer.
    237279         */
    238         if (cbRecord >= pVBVA->cbData - pVBVA->cbPartialWriteThreshold)
     280        if (cbRecord >= pVBVAData->cbData - pVBVAData->cbPartialWriteThreshold)
    239281        {
    240282            /* Partial read must be started. */
    241             if (!vbvaPartialRead (pPartialRecord, cbRecord, pVBVA))
     283            if (!vbvaPartialRead(cbRecord, pVBVAData))
    242284            {
    243285                return false;
     
    252294
    253295    /* Current record is complete. If it is not empty, process it. */
     296    if (cbRecord >= pVBVAData->cbData)
     297    {
     298        return false;
     299    }
     300
    254301    if (cbRecord)
    255302    {
    256         /* The size of largest contiguous chunk in the ring biffer. */
    257         uint32_t u32BytesTillBoundary = pVBVA->cbData - pVBVA->off32Data;
     303        /* The size of largest contiguous chunk in the ring buffer. */
     304        uint32_t u32BytesTillBoundary = pVBVAData->cbData - pVBVAData->off32Data;
    258305
    259306        /* The pointer to data in the ring buffer. */
    260         uint8_t *src = &pVBVA->au8Data[pVBVA->off32Data];
     307        uint8_t *pu8Src = &pVBVAData->guest.pu8Data[pVBVAData->off32Data];
    261308
    262309        /* Fetch or point the data. */
     
    264311        {
    265312            /* The command does not cross buffer boundary. Return address in the buffer. */
    266             *ppHdr = (VBVACMDHDR *)src;
    267 
    268             /* Advance data offset. */
    269             pVBVA->off32Data = (pVBVA->off32Data + cbRecord) % pVBVA->cbData;
     313            *ppHdr = (VBVACMDHDR *)pu8Src;
     314
     315            /* Advance data offset and sync with guest. */
     316            pVBVAData->off32Data = (pVBVAData->off32Data + cbRecord) % pVBVAData->cbData;
     317            pVBVAData->guest.pVBVA->off32Data = pVBVAData->off32Data;
    270318        }
    271319        else
    272320        {
    273321            /* The command crosses buffer boundary. Rare case, so not optimized. */
    274             uint8_t *dst = (uint8_t *)RTMemAlloc (cbRecord);
    275 
    276             if (!dst)
     322            uint8_t *pu8Dst = (uint8_t *)RTMemAlloc(cbRecord);
     323
     324            if (!pu8Dst)
    277325            {
    278326                LogFlowFunc (("could not allocate %d bytes from heap!!!\n", cbRecord));
    279                 pVBVA->off32Data = (pVBVA->off32Data + cbRecord) % pVBVA->cbData;
    280327                return false;
    281328            }
    282329
    283             vbvaFetchBytes (pVBVA, dst, cbRecord);
    284 
    285             *ppHdr = (VBVACMDHDR *)dst;
    286 
    287             LOGVBVABUFFER(("Allocated from heap %p\n", dst));
     330            vbvaFetchBytes(pVBVAData, pu8Dst, cbRecord);
     331
     332            *ppHdr = (VBVACMDHDR *)pu8Dst;
     333
     334            LOGVBVABUFFER(("Allocated from heap %p\n", pu8Dst));
    288335        }
    289336    }
     
    291338    *pcbCmd = cbRecord;
    292339
    293     /* Advance the record index. */
    294     pVBVA->indexRecordFirst = (indexRecordFirst + 1) % RT_ELEMENTS(pVBVA->aRecords);
     340    /* Advance the record index and sync with guest. */
     341    pVBVAData->indexRecordFirst = (indexRecordFirst + 1) % RT_ELEMENTS(pVBVAData->guest.pVBVA->aRecords);
     342    pVBVAData->guest.pVBVA->indexRecordFirst = pVBVAData->indexRecordFirst;
    295343
    296344    LOGVBVABUFFER(("done ok, data = %d, free = %d\n",
    297                   pVBVA->off32Data, pVBVA->off32Free));
     345                  pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free));
    298346
    299347    return true;
    300348}
    301349
    302 static void vbvaReleaseCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA, VBVACMDHDR *pHdr, uint32_t cbCmd)
    303 {
    304     uint8_t *au8RingBuffer = &pVBVA->au8Data[0];
     350static void vbvaReleaseCmd(VBVADATA *pVBVAData, VBVACMDHDR *pHdr, uint32_t cbCmd)
     351{
     352    VBVAPARTIALRECORD *pPartialRecord = &pVBVAData->partialRecord;
     353    uint8_t *au8RingBuffer = pVBVAData->guest.pu8Data;
    305354
    306355    if (   (uint8_t *)pHdr >= au8RingBuffer
    307         && (uint8_t *)pHdr < &au8RingBuffer[pVBVA->cbData])
     356        && (uint8_t *)pHdr < &au8RingBuffer[pVBVAData->cbData])
    308357    {
    309358        /* The pointer is inside ring buffer. Must be continuous chunk. */
    310         Assert (pVBVA->cbData - ((uint8_t *)pHdr - au8RingBuffer) >= cbCmd);
     359        Assert(pVBVAData->cbData - ((uint8_t *)pHdr - au8RingBuffer) >= cbCmd);
    311360
    312361        /* Do nothing. */
     
    326375        else
    327376        {
    328             Assert (!pPartialRecord->pu8 && pPartialRecord->cb == 0);
    329         }
    330 
    331         RTMemFree (pHdr);
    332     }
    333 
    334     return;
    335 }
    336 
    337 static int vbvaFlushProcess (unsigned uScreenId, PVGASTATE pVGAState, VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA)
     377            Assert(!pPartialRecord->pu8 && pPartialRecord->cb == 0);
     378        }
     379
     380        RTMemFree(pHdr);
     381    }
     382}
     383
     384static int vbvaFlushProcess(unsigned uScreenId, PVGASTATE pVGAState, VBVADATA *pVBVAData)
    338385{
    339386    LOGVBVABUFFER(("uScreenId %d, indexRecordFirst = %d, indexRecordFree = %d, off32Data = %d, off32Free = %d\n",
    340                   uScreenId, pVBVA->indexRecordFirst, pVBVA->indexRecordFree, pVBVA->off32Data, pVBVA->off32Free));
     387                  uScreenId, pVBVAData->indexRecordFirst, pVBVAData->guest.pVBVA->indexRecordFree,
     388                  pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free));
    341389    struct {
    342390        /* The rectangle that includes all dirty rectangles. */
     
    357405
    358406        /* Fetch the command data. */
    359         if (!vbvaFetchCmd (pPartialRecord, pVBVA, &phdr, &cbCmd))
     407        if (!vbvaFetchCmd(pVBVAData, &phdr, &cbCmd))
    360408        {
    361409            LogFunc(("unable to fetch command. off32Data = %d, off32Free = %d!!!\n",
    362                   pVBVA->off32Data, pVBVA->off32Free));
    363 
    364             /* @todo old code disabled VBVA processing here. */
     410                  pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free));
     411
    365412            return VERR_NOT_SUPPORTED;
    366413        }
     
    372419        }
    373420
     421        if (cbCmd < sizeof(VBVACMDHDR))
     422        {
     423            LogFunc(("short command. off32Data = %d, off32Free = %d, cbCmd %d!!!\n",
     424                  pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free, cbCmd));
     425
     426            return VERR_NOT_SUPPORTED;
     427        }
     428
    374429        if (cbCmd != 0)
    375430        {
    376431            if (!fUpdate)
    377432            {
    378                 pVGAState->pDrv->pfnVBVAUpdateBegin (pVGAState->pDrv, uScreenId);
     433                pVGAState->pDrv->pfnVBVAUpdateBegin(pVGAState->pDrv, uScreenId);
    379434                fUpdate = true;
    380435            }
    381436
    382437            /* Updates the rectangle and sends the command to the VRDP server. */
    383             pVGAState->pDrv->pfnVBVAUpdateProcess (pVGAState->pDrv, uScreenId, phdr, cbCmd);
     438            pVGAState->pDrv->pfnVBVAUpdateProcess(pVGAState->pDrv, uScreenId, phdr, cbCmd);
    384439
    385440            int32_t xRight  = phdr->x + phdr->w;
     
    391446                           cbCmd, phdr->x, phdr->y, phdr->w, phdr->h));
    392447            LogRel3(("%s: update command cbCmd = %d, x=%d, y=%d, w=%d, h=%d\n",
    393                      __PRETTY_FUNCTION__, cbCmd, phdr->x, phdr->y, phdr->w,
    394                      phdr->h));
     448                     __FUNCTION__, cbCmd, phdr->x, phdr->y, phdr->w, phdr->h));
    395449
    396450            /* Collect all rects into one. */
     
    429483        }
    430484
    431         vbvaReleaseCmd (pPartialRecord, pVBVA, phdr, cbCmd);
     485        vbvaReleaseCmd(pVBVAData, phdr, cbCmd);
    432486    }
    433487
     
    437491        {
    438492            LogRel3(("%s: sending update screen=%d, x=%d, y=%d, w=%d, h=%d\n",
    439                      __PRETTY_FUNCTION__, uScreenId, dirtyRect.xLeft,
     493                     __FUNCTION__, uScreenId, dirtyRect.xLeft,
    440494                     dirtyRect.yTop, dirtyRect.xRight - dirtyRect.xLeft,
    441495                     dirtyRect.yBottom - dirtyRect.yTop));
    442             pVGAState->pDrv->pfnVBVAUpdateEnd (pVGAState->pDrv, uScreenId, dirtyRect.xLeft, dirtyRect.yTop,
    443                                                dirtyRect.xRight - dirtyRect.xLeft, dirtyRect.yBottom - dirtyRect.yTop);
     496            pVGAState->pDrv->pfnVBVAUpdateEnd(pVGAState->pDrv, uScreenId, dirtyRect.xLeft, dirtyRect.yTop,
     497                                              dirtyRect.xRight - dirtyRect.xLeft, dirtyRect.yBottom - dirtyRect.yTop);
    444498        }
    445499        else
    446500        {
    447             pVGAState->pDrv->pfnVBVAUpdateEnd (pVGAState->pDrv, uScreenId, 0, 0, 0, 0);
     501            pVGAState->pDrv->pfnVBVAUpdateEnd(pVGAState->pDrv, uScreenId, 0, 0, 0, 0);
    448502        }
    449503    }
     
    452506}
    453507
    454 static int vbvaFlush (PVGASTATE pVGAState, VBVACONTEXT *pCtx)
    455 {
     508static int vbvaFlush(PVGASTATE pVGAState, VBVACONTEXT *pCtx)
     509{
     510    int rc = VINF_SUCCESS;
     511
    456512    unsigned uScreenId;
    457 
    458513    for (uScreenId = 0; uScreenId < pCtx->cViews; uScreenId++)
    459514    {
    460         VBVAPARTIALRECORD *pPartialRecord = &pCtx->aViews[uScreenId].partialRecord;
    461         VBVABUFFER *pVBVA = pCtx->aViews[uScreenId].pVBVA;
    462 
    463         if (pVBVA)
    464         {
    465             vbvaFlushProcess (uScreenId, pVGAState, pPartialRecord, pVBVA);
    466         }
    467     }
    468 
    469     /* @todo rc */
    470     return VINF_SUCCESS;
    471 }
    472 
    473 static int vbvaResize (PVGASTATE pVGAState, VBVAVIEW *pView, const VBVAINFOSCREEN *pNewScreen)
    474 {
    475     /* Verify pNewScreen. */
    476     /* @todo */
     515        VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva;
     516
     517        if (pVBVAData->guest.pVBVA)
     518        {
     519            rc = vbvaFlushProcess(uScreenId, pVGAState, pVBVAData);
     520            if (RT_FAILURE(rc))
     521            {
     522                break;
     523            }
     524        }
     525    }
     526
     527    if (RT_FAILURE(rc))
     528    {
     529        /* Turn off VBVA processing. */
     530        LogRel(("VBVA: disabling\n", rc));
     531        for (uScreenId = 0; uScreenId < pCtx->cViews; uScreenId++)
     532        {
     533            VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva;
     534            if (pVBVAData->guest.pVBVA)
     535            {
     536                vbvaDataCleanup(pVBVAData);
     537                pVGAState->pDrv->pfnVBVADisable(pVGAState->pDrv, uScreenId);
     538            }
     539        }
     540    }
     541
     542    return rc;
     543}
     544
     545static int vbvaResize(PVGASTATE pVGAState, VBVAVIEW *pView, const VBVAINFOSCREEN *pNewScreen)
     546{
     547    /* Callers ensure that pNewScreen contains valid data. */
    477548
    478549    /* Apply these changes. */
     
    480551
    481552    uint8_t *pu8VRAM = pVGAState->vram_ptrR3 + pView->view.u32ViewOffset;
    482 
    483     int rc = pVGAState->pDrv->pfnVBVAResize (pVGAState->pDrv, &pView->view, &pView->screen, pu8VRAM);
    484 
    485     /* @todo process VINF_VGA_RESIZE_IN_PROGRESS? */
    486 
    487     return rc;
    488 }
    489 
    490 static int vbvaEnable (unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx, VBVABUFFER *pVBVA, uint32_t u32Offset, bool fRestored)
    491 {
    492     /* @todo old code did a UpdateDisplayAll at this place. */
    493 
     553    return pVGAState->pDrv->pfnVBVAResize (pVGAState->pDrv, &pView->view, &pView->screen, pu8VRAM);
     554}
     555
     556static int vbvaEnable(unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx, VBVABUFFER *pVBVA, uint32_t u32Offset, bool fRestored)
     557{
    494558    int rc;
    495559
     560    /* Check if VBVABUFFER content makes sense. */
     561    const VBVABUFFER parms = *pVBVA;
     562
     563    uint32_t cbVBVABuffer = RT_UOFFSETOF(VBVABUFFER, au8Data) + parms.cbData;
     564    if (   parms.cbData > UINT32_MAX - RT_UOFFSETOF(VBVABUFFER, au8Data)
     565        || cbVBVABuffer > pVGAState->vram_size
     566        || u32Offset > pVGAState->vram_size - cbVBVABuffer)
     567    {
     568        return VERR_INVALID_PARAMETER;
     569    }
     570
     571    if (   parms.off32Data != 0
     572        || parms.off32Free != 0
     573        || parms.indexRecordFirst != 0
     574        || parms.indexRecordFree != 0
     575        || parms.cbPartialWriteThreshold >= parms.cbData
     576        || parms.cbPartialWriteThreshold == 0)
     577    {
     578        return VERR_INVALID_PARAMETER;
     579    }
     580
    496581    if (pVGAState->pDrv->pfnVBVAEnable)
    497582    {
    498         pVBVA->hostFlags.u32HostEvents = 0;
    499         pVBVA->hostFlags.u32SupportedOrders = 0;
    500 
    501         rc = pVGAState->pDrv->pfnVBVAEnable (pVGAState->pDrv, uScreenId, &pVBVA->hostFlags, false);
     583        RT_ZERO(pVBVA->hostFlags);
     584        rc = pVGAState->pDrv->pfnVBVAEnable(pVGAState->pDrv, uScreenId, &pVBVA->hostFlags, false);
    502585    }
    503586    else
     
    506589    }
    507590
    508     if (RT_SUCCESS (rc))
     591    if (RT_SUCCESS(rc))
    509592    {
    510593        /* pVBVA->hostFlags has been set up by pfnVBVAEnable. */
    511594        LogFlowFunc(("u32HostEvents 0x%08X, u32SupportedOrders 0x%08X\n",
    512595                     pVBVA->hostFlags.u32HostEvents, pVBVA->hostFlags.u32SupportedOrders));
     596
     597        VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva;
     598        pVBVAData->guest.pVBVA             = pVBVA;
     599        pVBVAData->guest.pu8Data           = &pVBVA->au8Data[0];
     600        pVBVAData->u32VBVAOffset           = u32Offset;
     601        pVBVAData->off32Data               = 0;
     602        pVBVAData->indexRecordFirst        = 0;
     603        pVBVAData->cbPartialWriteThreshold = parms.cbPartialWriteThreshold;
     604        pVBVAData->cbData                  = parms.cbData;
    513605
    514606        if (!fRestored)
     
    520612             * when partialRecord might be loaded already from the saved state.
    521613             */
    522             pCtx->aViews[uScreenId].partialRecord.pu8 = NULL;
    523             pCtx->aViews[uScreenId].partialRecord.cb = 0;
    524         }
    525 
    526         pCtx->aViews[uScreenId].pVBVA = pVBVA;
    527         pCtx->aViews[uScreenId].u32VBVAOffset = u32Offset;
     614            pVBVAData->partialRecord.pu8 = NULL;
     615            pVBVAData->partialRecord.cb = 0;
     616        }
    528617
    529618        /* VBVA is working so disable the pause. */
     
    539628    vbvaFlush (pVGAState, pCtx);
    540629
    541     VBVAVIEW *pView = &pCtx->aViews[uScreenId];
    542 
    543     if (pView->pVBVA)
    544     {
    545         pView->pVBVA->hostFlags.u32HostEvents = 0;
    546         pView->pVBVA->hostFlags.u32SupportedOrders = 0;
    547 
    548         pView->partialRecord.pu8 = NULL;
    549         pView->partialRecord.cb = 0;
    550 
    551         pView->pVBVA = NULL;
    552         pView->u32VBVAOffset = HGSMIOFFSET_VOID;
    553     }
    554 
    555     pVGAState->pDrv->pfnVBVADisable (pVGAState->pDrv, uScreenId);
     630    VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva;
     631    vbvaDataCleanup(pVBVAData);
     632
     633    pVGAState->pDrv->pfnVBVADisable(pVGAState->pDrv, uScreenId);
    556634    return VINF_SUCCESS;
    557635}
     
    568646            {
    569647                VBVAVIEW * pView = &pCtx->aViews[0];
    570                 if (pView->pVBVA)
     648                if (pView->vbva.guest.pVBVA)
    571649                    return true;
    572650            }
     
    594672#endif
    595673
    596 static int vbvaUpdateMousePointerShape(PVGASTATE pVGAState, VBVAMOUSESHAPEINFO *pMouseShapeInfo, bool fShape, const uint8_t *pu8Shape)
    597 {
    598     int rc;
    599     LogFlowFunc(("pVGAState %p, pMouseShapeInfo %p, fShape %d, pu8Shape %p\n",
    600                   pVGAState, pMouseShapeInfo, fShape, pu8Shape));
     674static int vbvaUpdateMousePointerShape(PVGASTATE pVGAState, VBVAMOUSESHAPEINFO *pMouseShapeInfo, bool fShape)
     675{
     676    LogFlowFunc(("pVGAState %p, pMouseShapeInfo %p, fShape %d\n",
     677                  pVGAState, pMouseShapeInfo, fShape));
    601678#ifdef DEBUG_sunlover
    602679    dumpMouseShapeInfo(pMouseShapeInfo);
    603680#endif
    604681
    605     if (fShape && pu8Shape != NULL)
     682    if (pVGAState->pDrv->pfnVBVAMousePointerShape == NULL)
     683    {
     684        return VERR_NOT_SUPPORTED;
     685    }
     686
     687    int rc;
     688    if (fShape && pMouseShapeInfo->pu8Shape != NULL)
    606689    {
    607690        rc = pVGAState->pDrv->pfnVBVAMousePointerShape (pVGAState->pDrv,
     
    612695                                                        pMouseShapeInfo->u32Width,
    613696                                                        pMouseShapeInfo->u32Height,
    614                                                         pu8Shape);
     697                                                        pMouseShapeInfo->pu8Shape);
    615698    }
    616699    else
     
    627710}
    628711
    629 static int vbvaMousePointerShape (PVGASTATE pVGAState, VBVACONTEXT *pCtx, const VBVAMOUSEPOINTERSHAPE *pShape, HGSMISIZE cbShape)
    630 {
    631     bool fVisible = (pShape->fu32Flags & VBOX_MOUSE_POINTER_VISIBLE) != 0;
    632     bool fAlpha =   (pShape->fu32Flags & VBOX_MOUSE_POINTER_ALPHA) != 0;
    633     bool fShape =   (pShape->fu32Flags & VBOX_MOUSE_POINTER_SHAPE) != 0;
     712static int vbvaMousePointerShape(PVGASTATE pVGAState, VBVACONTEXT *pCtx, const VBVAMOUSEPOINTERSHAPE *pShape, HGSMISIZE cbShape)
     713{
     714    const VBVAMOUSEPOINTERSHAPE parms = *pShape;
     715
     716    LogFlowFunc(("VBVA_MOUSE_POINTER_SHAPE: i32Result 0x%x, fu32Flags 0x%x, hot spot %d,%d, size %dx%d\n",
     717                 parms.i32Result,
     718                 parms.fu32Flags,
     719                 parms.u32HotX,
     720                 parms.u32HotY,
     721                 parms.u32Width,
     722                 parms.u32Height));
     723
     724    const bool fVisible = RT_BOOL(parms.fu32Flags & VBOX_MOUSE_POINTER_VISIBLE);
     725    const bool fAlpha =   RT_BOOL(parms.fu32Flags & VBOX_MOUSE_POINTER_ALPHA);
     726    const bool fShape =   RT_BOOL(parms.fu32Flags & VBOX_MOUSE_POINTER_SHAPE);
    634727
    635728    HGSMISIZE cbPointerData = 0;
     
    637730    if (fShape)
    638731    {
    639          if (pShape->u32Width > 8192 || pShape->u32Height > 8192)
     732         if (parms.u32Width > 8192 || parms.u32Height > 8192)
    640733         {
    641734             Log(("vbvaMousePointerShape: unsupported size %ux%u\n",
    642                    pShape->u32Width, pShape->u32Height));
     735                   parms.u32Width, parms.u32Height));
    643736             return VERR_INVALID_PARAMETER;
    644737         }
    645738
    646          cbPointerData = ((((pShape->u32Width + 7) / 8) * pShape->u32Height + 3) & ~3)
    647                          + pShape->u32Width * 4 * pShape->u32Height;
    648     }
    649 
    650     if (cbPointerData > cbShape - RT_OFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data))
     739         cbPointerData = ((((parms.u32Width + 7) / 8) * parms.u32Height + 3) & ~3)
     740                         + parms.u32Width * 4 * parms.u32Height;
     741    }
     742
     743    if (cbPointerData > cbShape - RT_UOFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data))
    651744    {
    652745        Log(("vbvaMousePointerShape: calculated pointer data size is too big (%d bytes, limit %d)\n",
    653               cbPointerData, cbShape - RT_OFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data)));
     746              cbPointerData, cbShape - RT_UOFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data)));
    654747        return VERR_INVALID_PARAMETER;
    655748    }
     
    662755    {
    663756        /* Data related to shape. */
    664         pCtx->mouseShapeInfo.u32HotX = pShape->u32HotX;
    665         pCtx->mouseShapeInfo.u32HotY = pShape->u32HotY;
    666         pCtx->mouseShapeInfo.u32Width = pShape->u32Width;
    667         pCtx->mouseShapeInfo.u32Height = pShape->u32Height;
     757        pCtx->mouseShapeInfo.u32HotX = parms.u32HotX;
     758        pCtx->mouseShapeInfo.u32HotY = parms.u32HotY;
     759        pCtx->mouseShapeInfo.u32Width = parms.u32Width;
     760        pCtx->mouseShapeInfo.u32Height = parms.u32Height;
    668761
    669762        /* Reallocate memory buffer if necessary. */
     
    685778        if (pCtx->mouseShapeInfo.pu8Shape)
    686779        {
    687             memcpy (pCtx->mouseShapeInfo.pu8Shape, &pShape->au8Data[0], cbPointerData);
     780            memcpy(pCtx->mouseShapeInfo.pu8Shape, &pShape->au8Data[0], cbPointerData);
    688781            pCtx->mouseShapeInfo.cbShape = cbPointerData;
    689782        }
    690783    }
    691784
    692     if (pVGAState->pDrv->pfnVBVAMousePointerShape == NULL)
    693     {
    694         return VERR_NOT_SUPPORTED;
    695     }
    696 
    697     int rc = vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, fShape, &pShape->au8Data[0]);
     785    int rc = vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, fShape);
    698786
    699787    return rc;
    700788}
    701789
    702 static unsigned vbvaViewFromOffset (PHGSMIINSTANCE pIns, VBVACONTEXT *pCtx, const void *pvBuffer)
     790static uint32_t vbvaViewFromBufferPtr(PHGSMIINSTANCE pIns, const VBVACONTEXT *pCtx, const void *pvBuffer)
    703791{
    704792    /* Check which view contains the buffer. */
    705     HGSMIOFFSET offBuffer = HGSMIPointerToOffsetHost (pIns, pvBuffer);
     793    HGSMIOFFSET offBuffer = HGSMIPointerToOffsetHost(pIns, pvBuffer);
    706794
    707795    if (offBuffer != HGSMIOFFSET_VOID)
    708796    {
    709797        unsigned uScreenId;
    710 
    711798        for (uScreenId = 0; uScreenId < pCtx->cViews; uScreenId++)
    712799        {
    713             VBVAINFOVIEW *pView = &pCtx->aViews[uScreenId].view;
     800            const VBVAINFOVIEW *pView = &pCtx->aViews[uScreenId].view;
    714801
    715802            if (   pView->u32ViewSize > 0
     
    722809    }
    723810
    724     return ~0U;
     811    return UINT32_C(~0);
    725812}
    726813
     
    754841        Log(("                  VBVA o 0x%x p %p\n",
    755842              pView->u32VBVAOffset,
    756               pView->pVBVA));
     843              pView->vbva.guest.pVBVA));
    757844
    758845        Log(("                  PR cb 0x%x p %p\n",
     
    15551642                AssertRCReturn(rc, rc);
    15561643
    1557                 rc = SSMR3PutU32 (pSSM, pView->pVBVA? pView->u32VBVAOffset: HGSMIOFFSET_VOID);
    1558                 AssertRCReturn(rc, rc);
    1559 
    1560                 rc = SSMR3PutU32 (pSSM, pView->partialRecord.cb);
    1561                 AssertRCReturn(rc, rc);
    1562 
    1563                 if (pView->partialRecord.cb > 0)
    1564                 {
    1565                     rc = SSMR3PutMem (pSSM, pView->partialRecord.pu8, pView->partialRecord.cb);
     1644                rc = SSMR3PutU32 (pSSM, pView->vbva.guest.pVBVA? pView->vbva.u32VBVAOffset: HGSMIOFFSET_VOID);
     1645                AssertRCReturn(rc, rc);
     1646
     1647                rc = SSMR3PutU32 (pSSM, pView->vbva.partialRecord.cb);
     1648                AssertRCReturn(rc, rc);
     1649
     1650                if (pView->vbva.partialRecord.cb > 0)
     1651                {
     1652                    rc = SSMR3PutMem (pSSM, pView->vbva.partialRecord.pu8, pView->vbva.partialRecord.cb);
    15661653                    AssertRCReturn(rc, rc);
    15671654                }
     
    17411828                AssertRCReturn(rc, rc);
    17421829
    1743                 rc = SSMR3GetU32 (pSSM, &pView->u32VBVAOffset);
    1744                 AssertRCReturn(rc, rc);
    1745 
    1746                 rc = SSMR3GetU32 (pSSM, &pView->partialRecord.cb);
    1747                 AssertRCReturn(rc, rc);
    1748 
    1749                 if (pView->partialRecord.cb == 0)
    1750                 {
    1751                     pView->partialRecord.pu8 = NULL;
     1830                rc = SSMR3GetU32 (pSSM, &pView->vbva.u32VBVAOffset);
     1831                AssertRCReturn(rc, rc);
     1832
     1833                rc = SSMR3GetU32 (pSSM, &pView->vbva.partialRecord.cb);
     1834                AssertRCReturn(rc, rc);
     1835
     1836                if (pView->vbva.partialRecord.cb == 0)
     1837                {
     1838                    pView->vbva.partialRecord.pu8 = NULL;
    17521839                }
    17531840                else
    17541841                {
    1755                     Assert(pView->partialRecord.pu8 == NULL); /* Should be it. */
    1756 
    1757                     uint8_t *pu8 = (uint8_t *)RTMemAlloc (pView->partialRecord.cb);
     1842                    Assert(pView->vbva.partialRecord.pu8 == NULL); /* Should be it. */
     1843
     1844                    uint8_t *pu8 = (uint8_t *)RTMemAlloc(pView->vbva.partialRecord.cb);
    17581845
    17591846                    if (!pu8)
     
    17621849                    }
    17631850
    1764                     pView->partialRecord.pu8 = pu8;
    1765 
    1766                     rc = SSMR3GetMem (pSSM, pView->partialRecord.pu8, pView->partialRecord.cb);
     1851                    pView->vbva.partialRecord.pu8 = pu8;
     1852
     1853                    rc = SSMR3GetMem (pSSM, pView->vbva.partialRecord.pu8, pView->vbva.partialRecord.cb);
    17671854                    AssertRCReturn(rc, rc);
    17681855                }
    17691856
    1770                 if (pView->u32VBVAOffset == HGSMIOFFSET_VOID)
    1771                 {
    1772                     pView->pVBVA = NULL;
     1857                if (pView->vbva.u32VBVAOffset == HGSMIOFFSET_VOID)
     1858                {
     1859                    pView->vbva.guest.pVBVA = NULL;
    17731860                }
    17741861                else
    17751862                {
    1776                     pView->pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost (pIns, pView->u32VBVAOffset);
     1863                    pView->vbva.guest.pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pIns, pView->vbva.u32VBVAOffset);
    17771864                }
    17781865            }
     
    19452032            VBVAVIEW *pView = &pCtx->aViews[iView];
    19462033
    1947             if (pView->pVBVA)
     2034            if (pView->vbva.guest.pVBVA)
    19482035            {
    19492036#ifdef VBOX_WITH_CRHGSMI
    19502037                Assert(!vboxCmdVBVAIsEnabled(pVGAState));
    19512038#endif
    1952                 vbvaEnable (iView, pVGAState, pCtx, pView->pVBVA, pView->u32VBVAOffset, true /* fRestored */);
     2039                vbvaEnable (iView, pVGAState, pCtx, pView->vbva.guest.pVBVA, pView->vbva.u32VBVAOffset, true /* fRestored */);
    19532040                vbvaResize (pVGAState, pView, &pView->screen);
    19542041            }
     
    19572044        if (pCtx->mouseShapeInfo.fSet)
    19582045        {
    1959             vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, true, pCtx->mouseShapeInfo.pu8Shape);
     2046            vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, true);
    19602047        }
    19612048    }
     
    19912078}
    19922079
    1993 int VBVAInfoView(PVGASTATE pVGAState, const VBVAINFOVIEW *pView)
    1994 {
    1995     LogFlowFunc(("VBVA_INFO_VIEW: u32ViewIndex %d, u32ViewOffset 0x%x, u32ViewSize 0x%x, u32MaxScreenSize 0x%x\n",
    1996                  pView->u32ViewIndex, pView->u32ViewOffset, pView->u32ViewSize, pView->u32MaxScreenSize));
    1997 
     2080static int vbvaHandleQueryConf32(PVGASTATE pVGAState, VBVACONF32 *pConf32)
     2081{
     2082    int rc = VINF_SUCCESS;
    19982083    PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
    19992084    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
    20002085
    2001     if (   pView->u32ViewIndex < pCtx->cViews
    2002         && pView->u32ViewOffset <= pVGAState->vram_size
    2003         && pView->u32ViewSize <= pVGAState->vram_size
    2004         && pView->u32ViewOffset <= pVGAState->vram_size - pView->u32ViewSize
    2005         && pView->u32MaxScreenSize <= pView->u32ViewSize)
    2006     {
    2007         pCtx->aViews[pView->u32ViewIndex].view = *pView;
    2008         return VINF_SUCCESS;
    2009     }
    2010 
    2011     LogRelFlow(("VBVA_INFO_VIEW: invalid data: index %d(%d), offset 0x%x, size 0x%x, max 0x%x, vram size 0x%x\n",
    2012                 pView->u32ViewIndex, pCtx->cViews, pView->u32ViewOffset, pView->u32ViewSize,
    2013                 pView->u32MaxScreenSize, pVGAState->vram_size));
    2014     return VERR_INVALID_PARAMETER;
    2015 }
    2016 
    2017 int VBVAInfoScreen(PVGASTATE pVGAState, const VBVAINFOSCREEN *pScreen)
    2018 {
    2019     LogRel(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n",
    2020             pScreen->u32ViewIndex, pScreen->i32OriginX, pScreen->i32OriginY,
    2021             pScreen->u32Width, pScreen->u32Height,
    2022             pScreen->u32LineSize, pScreen->u16BitsPerPixel, pScreen->u16Flags));
     2086    const uint32_t u32Index = pConf32->u32Index;
     2087
     2088    LogFlowFunc(("VBVA_QUERY_CONF32: u32Index %d, u32Value 0x%x\n",
     2089                 u32Index, pConf32->u32Value));
     2090
     2091    if (u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT)
     2092    {
     2093        pConf32->u32Value = pCtx->cViews;
     2094    }
     2095    else if (u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE)
     2096    {
     2097        /* @todo a value calculated from the vram size */
     2098        pConf32->u32Value = 64*_1K;
     2099    }
     2100    else if (   u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING
     2101             || u32Index == VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING)
     2102    {
     2103        pConf32->u32Value = VINF_SUCCESS;
     2104    }
     2105    else if (u32Index == VBOX_VBVA_CONF32_CURSOR_CAPABILITIES)
     2106    {
     2107        pConf32->u32Value = pVGAState->fHostCursorCapabilities;
     2108    }
     2109    else if (u32Index == VBOX_VBVA_CONF32_SCREEN_FLAGS)
     2110    {
     2111        pConf32->u32Value = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED | VBVA_SCREEN_F_BLANK;
     2112    }
     2113    else if (u32Index == VBOX_VBVA_CONF32_MAX_RECORD_SIZE)
     2114    {
     2115        pConf32->u32Value = VBVA_MAX_RECORD_SIZE;
     2116    }
     2117    else
     2118    {
     2119        Log(("Unsupported VBVA_QUERY_CONF32 index %d!!!\n",
     2120             u32Index));
     2121        rc = VERR_INVALID_PARAMETER;
     2122    }
     2123
     2124    return rc;
     2125}
     2126
     2127static int vbvaHandleSetConf32(PVGASTATE pVGAState, VBVACONF32 *pConf32)
     2128{
     2129    NOREF(pVGAState);
     2130
     2131    int rc = VINF_SUCCESS;
     2132    const VBVACONF32 parms = *pConf32;
     2133
     2134    LogFlowFunc(("VBVA_SET_CONF32: u32Index %d, u32Value 0x%x\n",
     2135                 parms.u32Index, parms.u32Value));
     2136
     2137    if (parms.u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT)
     2138    {
     2139        /* do nothing. this is a const. */
     2140    }
     2141    else if (parms.u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE)
     2142    {
     2143        /* do nothing. this is a const. */
     2144    }
     2145    else
     2146    {
     2147        Log(("Unsupported VBVA_SET_CONF32 index %d!!!\n",
     2148             parms.u32Index));
     2149        rc = VERR_INVALID_PARAMETER;
     2150    }
     2151
     2152    return rc;
     2153}
     2154
     2155static int vbvaHandleInfoHeap(PVGASTATE pVGAState, const VBVAINFOHEAP *pInfoHeap)
     2156{
     2157    PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
     2158
     2159    const VBVAINFOHEAP parms = *pInfoHeap;
     2160    LogFlowFunc(("VBVA_INFO_HEAP: offset 0x%x, size 0x%x\n",
     2161                 parms.u32HeapOffset, parms.u32HeapSize));
     2162
     2163    return HGSMIHostHeapSetup(pIns, parms.u32HeapOffset, parms.u32HeapSize);
     2164}
     2165
     2166int VBVAInfoView(PVGASTATE pVGAState, const VBVAINFOVIEW *pView)
     2167{
     2168    const VBVAINFOVIEW view = *pView;
     2169
     2170    LogFlowFunc(("VBVA_INFO_VIEW: u32ViewIndex %d, u32ViewOffset 0x%x, u32ViewSize 0x%x, u32MaxScreenSize 0x%x\n",
     2171                 view.u32ViewIndex, view.u32ViewOffset, view.u32ViewSize, view.u32MaxScreenSize));
    20232172
    20242173    PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
    20252174    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
    20262175
    2027     /* Allow pScreen->u16BitsPerPixel == 0 because legacy guest code used it for screen blanking. */
    2028     if (   pScreen->u32ViewIndex < pCtx->cViews
    2029         && pScreen->u16BitsPerPixel <= 32
    2030         && pScreen->u32Width <= UINT16_MAX
    2031         && pScreen->u32Height <= UINT16_MAX
    2032         && pScreen->u32LineSize <= UINT16_MAX * 4)
    2033     {
    2034         const VBVAINFOVIEW *pView = &pCtx->aViews[pScreen->u32ViewIndex].view;
    2035         const uint32_t u32BytesPerPixel = (pScreen->u16BitsPerPixel + 7) / 8;
    2036         if (pScreen->u32Width <= pScreen->u32LineSize / (u32BytesPerPixel? u32BytesPerPixel: 1))
    2037         {
    2038             const uint64_t u64ScreenSize = (uint64_t)pScreen->u32LineSize * pScreen->u32Height;
    2039             if (   pScreen->u32StartOffset <= pView->u32ViewSize
     2176    if (   view.u32ViewIndex < pCtx->cViews
     2177        && view.u32ViewOffset <= pVGAState->vram_size
     2178        && view.u32ViewSize <= pVGAState->vram_size
     2179        && view.u32ViewOffset <= pVGAState->vram_size - view.u32ViewSize
     2180        && view.u32MaxScreenSize <= view.u32ViewSize)
     2181    {
     2182        pCtx->aViews[view.u32ViewIndex].view = view;
     2183        return VINF_SUCCESS;
     2184    }
     2185
     2186    LogRelFlow(("VBVA_INFO_VIEW: invalid data: index %d(%d), offset 0x%x, size 0x%x, max 0x%x, vram size 0x%x\n",
     2187                view.u32ViewIndex, pCtx->cViews, view.u32ViewOffset, view.u32ViewSize,
     2188                view.u32MaxScreenSize, pVGAState->vram_size));
     2189    return VERR_INVALID_PARAMETER;
     2190}
     2191
     2192int VBVAInfoScreen(PVGASTATE pVGAState, const VBVAINFOSCREEN *pScreen)
     2193{
     2194    const VBVAINFOSCREEN screen = *pScreen;
     2195
     2196    LogRel(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n",
     2197            screen.u32ViewIndex, screen.i32OriginX, screen.i32OriginY,
     2198            screen.u32Width, screen.u32Height,
     2199            screen.u32LineSize, screen.u16BitsPerPixel, screen.u16Flags));
     2200
     2201    PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
     2202    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
     2203
     2204    /* Allow screen.u16BitsPerPixel == 0 because legacy guest code used it for screen blanking. */
     2205    if (   screen.u32ViewIndex < pCtx->cViews
     2206        && screen.u16BitsPerPixel <= 32
     2207        && screen.u32Width <= UINT16_MAX
     2208        && screen.u32Height <= UINT16_MAX
     2209        && screen.u32LineSize <= UINT16_MAX * 4)
     2210    {
     2211        const VBVAINFOVIEW *pView = &pCtx->aViews[screen.u32ViewIndex].view;
     2212        const uint32_t u32BytesPerPixel = (screen.u16BitsPerPixel + 7) / 8;
     2213        if (screen.u32Width <= screen.u32LineSize / (u32BytesPerPixel? u32BytesPerPixel: 1))
     2214        {
     2215            const uint64_t u64ScreenSize = (uint64_t)screen.u32LineSize * screen.u32Height;
     2216            if (   screen.u32StartOffset <= pView->u32ViewSize
    20402217                && u64ScreenSize <= pView->u32MaxScreenSize
    2041                 && pScreen->u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize)
    2042             {
    2043                 vbvaResize(pVGAState, &pCtx->aViews[pScreen->u32ViewIndex], pScreen);
     2218                && screen.u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize)
     2219            {
     2220                vbvaResize(pVGAState, &pCtx->aViews[screen.u32ViewIndex], &screen);
    20442221                return VINF_SUCCESS;
    20452222            }
     
    20522229    {
    20532230        LogRelFlow(("VBVA_INFO_SCREEN: invalid data: index %RU32(%RU32)\n",
    2054                      pScreen->u32ViewIndex, pCtx->cViews));
     2231                     screen.u32ViewIndex, pCtx->cViews));
    20552232    }
    20562233
     
    20752252}
    20762253
     2254static int vbvaHandleEnable(PVGASTATE pVGAState, const VBVAENABLE *pVbvaEnable, uint32_t u32ScreenId)
     2255{
     2256    int rc = VINF_SUCCESS;
     2257    PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
     2258    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
     2259
     2260    if (u32ScreenId > pCtx->cViews)
     2261    {
     2262        return VERR_INVALID_PARAMETER;
     2263    }
     2264
     2265    const VBVAENABLE parms = *pVbvaEnable;
     2266
     2267    LogFlowFunc(("VBVA_ENABLE[%d]: u32Flags 0x%x u32Offset 0x%x\n",
     2268                 u32ScreenId, parms.u32Flags, parms.u32Offset));
     2269
     2270    if ((parms.u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_ENABLE)
     2271    {
     2272        uint32_t u32Offset = parms.u32Offset;
     2273        if (u32Offset < pVGAState->vram_size)
     2274        {
     2275            /* Guest reported offset either absolute or relative to view. */
     2276            if (parms.u32Flags & VBVA_F_ABSOFFSET)
     2277            {
     2278                /* Offset from VRAM start. */
     2279                if (   pVGAState->vram_size < RT_UOFFSETOF(VBVABUFFER, au8Data)
     2280                    || u32Offset > pVGAState->vram_size - RT_UOFFSETOF(VBVABUFFER, au8Data))
     2281                {
     2282                    rc = VERR_INVALID_PARAMETER;
     2283                }
     2284            }
     2285            else
     2286            {
     2287                /* Offset from the view start. */
     2288                const VBVAINFOVIEW *pView = &pCtx->aViews[u32ScreenId].view;
     2289                if (   pVGAState->vram_size - u32Offset < pView->u32ViewOffset
     2290                    || pView->u32ViewSize < RT_UOFFSETOF(VBVABUFFER, au8Data)
     2291                    || u32Offset > pView->u32ViewSize - RT_UOFFSETOF(VBVABUFFER, au8Data))
     2292                {
     2293                    rc = VERR_INVALID_PARAMETER;
     2294                }
     2295                else
     2296                {
     2297                    u32Offset += pView->u32ViewOffset;
     2298                }
     2299            }
     2300        }
     2301        else
     2302        {
     2303            rc = VERR_INVALID_PARAMETER;
     2304        }
     2305
     2306        if (RT_SUCCESS(rc))
     2307        {
     2308            VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pIns, u32Offset);
     2309            if (pVBVA)
     2310            {
     2311                /* Process any pending orders and empty the VBVA ring buffer. */
     2312                vbvaFlush(pVGAState, pCtx);
     2313
     2314                rc = vbvaEnable(u32ScreenId, pVGAState, pCtx, pVBVA, u32Offset, false /* fRestored */);
     2315            }
     2316            else
     2317            {
     2318                Log(("Invalid VBVABUFFER offset 0x%x!!!\n",
     2319                     parms.u32Offset));
     2320                rc = VERR_INVALID_PARAMETER;
     2321            }
     2322        }
     2323    }
     2324    else if ((parms.u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_DISABLE)
     2325    {
     2326        rc = vbvaDisable(u32ScreenId, pVGAState, pCtx);
     2327    }
     2328    else
     2329    {
     2330        Log(("Invalid VBVA_ENABLE flags 0x%x!!!\n",
     2331             parms.u32Flags));
     2332        rc = VERR_INVALID_PARAMETER;
     2333    }
     2334
     2335    return rc;
     2336}
     2337
     2338static int vbvaHandleQueryModeHints(PVGASTATE pVGAState, const VBVAQUERYMODEHINTS *pQueryModeHints, HGSMISIZE cbBuffer)
     2339{
     2340    PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
     2341    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
     2342
     2343    const VBVAQUERYMODEHINTS parms = *pQueryModeHints;
     2344
     2345    LogRelFlowFunc(("VBVA_QUERY_MODE_HINTS: cHintsQueried=%RU16, cbHintStructureGuest=%RU16\n",
     2346                    parms.cHintsQueried, parms.cbHintStructureGuest));
     2347
     2348    if (cbBuffer <   sizeof(VBVAQUERYMODEHINTS)
     2349                   + (uint64_t)parms.cHintsQueried * parms.cbHintStructureGuest)
     2350    {
     2351        return VERR_INVALID_PARAMETER;
     2352    }
     2353
     2354    uint8_t *pbHint = (uint8_t *)pQueryModeHints + sizeof(VBVAQUERYMODEHINTS);
     2355    memset(pbHint, ~0, cbBuffer - sizeof(VBVAQUERYMODEHINTS));
     2356
     2357    unsigned iHint;
     2358    for (iHint = 0;    iHint < parms.cHintsQueried
     2359                    && iHint < VBOX_VIDEO_MAX_SCREENS; ++iHint)
     2360    {
     2361        memcpy(pbHint, &pCtx->aModeHints[iHint],
     2362               RT_MIN(parms.cbHintStructureGuest, sizeof(VBVAMODEHINT)));
     2363        pbHint += parms.cbHintStructureGuest;
     2364        Assert(pbHint - (uint8_t *)pQueryModeHints <= cbBuffer);
     2365    }
     2366
     2367    return VINF_SUCCESS;
     2368}
    20772369
    20782370/*
     
    20982390}
    20992391
    2100 /* The guest submitted a buffer. @todo Verify all guest data. */
    2101 static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer)
     2392/** The guest submitted a command buffer. Verify the buffer size and invoke corresponding handler.
     2393 *
     2394 * @return VBox status.
     2395 * @param pvHandler      The VBVA channel context.
     2396 * @param u16ChannelInfo Command code.
     2397 * @param pvBuffer       HGSMI buffer with command data.
     2398 * @param cbBuffer       Size of command data.
     2399 */
     2400static DECLCALLBACK(int) vbvaChannelHandler(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer)
    21022401{
    21032402    int rc = VINF_SUCCESS;
    21042403
    21052404    LogFlowFunc(("pvHandler %p, u16ChannelInfo %d, pvBuffer %p, cbBuffer %u\n",
    2106             pvHandler, u16ChannelInfo, pvBuffer, cbBuffer));
     2405                 pvHandler, u16ChannelInfo, pvBuffer, cbBuffer));
    21072406
    21082407    PVGASTATE pVGAState = (PVGASTATE)pvHandler;
    21092408    PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
    2110     VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext (pIns);
     2409    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
    21112410
    21122411    switch (u16ChannelInfo)
    21132412    {
     2413#ifdef VBOX_WITH_CRHGSMI
    21142414        case VBVA_CMDVBVA_SUBMIT:
    21152415        {
    2116 # ifdef VBOX_WITH_CRHGSMI
    21172416            rc = vboxCmdVBVACmdSubmit(pVGAState);
    2118 #endif
    2119             break;
    2120         }
     2417        } break;
     2418
    21212419        case VBVA_CMDVBVA_FLUSH:
    21222420        {
    2123 # ifdef VBOX_WITH_CRHGSMI
    2124             rc =vboxCmdVBVACmdFlush(pVGAState);
    2125 #endif
    2126             break;
    2127         }
     2421            rc = vboxCmdVBVACmdFlush(pVGAState);
     2422        } break;
     2423
    21282424        case VBVA_CMDVBVA_CTL:
    21292425        {
    2130 #ifdef VBOX_WITH_CRHGSMI
    2131             if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof (VBOXCMDVBVA_CTL))
    2132             {
    2133                 Log(("buffer too small\n"));
    2134 #ifdef DEBUG_misha
    2135                 AssertMsgFailed(("buffer too small\n"));
    2136 #endif
     2426            if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof(VBOXCMDVBVA_CTL))
     2427            {
    21372428                rc = VERR_INVALID_PARAMETER;
    21382429                break;
    21392430            }
     2431
    21402432            VBOXCMDVBVA_CTL *pCtl = (VBOXCMDVBVA_CTL*)VBoxSHGSMIBufferData((PVBOXSHGSMIHEADER)pvBuffer);
    21412433            rc = vboxCmdVBVACmdCtl(pVGAState, pCtl, cbBuffer - VBoxSHGSMIBufferHeaderSize());
    2142 #endif
    2143             break;
    2144         }
     2434        } break;
     2435#endif /* VBOX_WITH_CRHGSMI */
     2436
    21452437#ifdef VBOX_WITH_VDMA
    21462438        case VBVA_VDMA_CMD:
    21472439        {
    2148             if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof (VBOXVDMACBUF_DR))
     2440            if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof(VBOXVDMACBUF_DR))
    21492441            {
    21502442                rc = VERR_INVALID_PARAMETER;
    21512443                break;
    21522444            }
    2153             PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)VBoxSHGSMIBufferData ((PVBOXSHGSMIHEADER)pvBuffer);
     2445
     2446            PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)VBoxSHGSMIBufferData((PVBOXSHGSMIHEADER)pvBuffer);
    21542447            vboxVDMACommand(pVGAState->pVdma, pCmd, cbBuffer - VBoxSHGSMIBufferHeaderSize());
    2155             rc = VINF_SUCCESS;
    2156             break;
    2157         }
     2448        } break;
     2449
    21582450        case VBVA_VDMA_CTL:
    21592451        {
    2160             if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof (VBOXVDMA_CTL))
     2452            if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof(VBOXVDMA_CTL))
    21612453            {
    21622454                rc = VERR_INVALID_PARAMETER;
    21632455                break;
    21642456            }
    2165             PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMIBufferData ((PVBOXSHGSMIHEADER)pvBuffer);
     2457
     2458            PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMIBufferData((PVBOXSHGSMIHEADER)pvBuffer);
    21662459            vboxVDMAControl(pVGAState->pVdma, pCmd, cbBuffer - VBoxSHGSMIBufferHeaderSize());
    2167             rc = VINF_SUCCESS;
    2168             break;
    2169         }
    2170 #endif
     2460        } break;
     2461#endif /* VBOX_WITH_VDMA */
     2462
    21712463        case VBVA_QUERY_CONF32:
    21722464        {
    2173             if (cbBuffer < sizeof (VBVACONF32))
     2465            if (cbBuffer < sizeof(VBVACONF32))
    21742466            {
    21752467                rc = VERR_INVALID_PARAMETER;
     
    21782470
    21792471            VBVACONF32 *pConf32 = (VBVACONF32 *)pvBuffer;
    2180             LogFlowFunc(("VBVA_QUERY_CONF32: u32Index %d, u32Value 0x%x\n",
    2181                          pConf32->u32Index, pConf32->u32Value));
    2182 
    2183             if (pConf32->u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT)
    2184             {
    2185                 pConf32->u32Value = pCtx->cViews;
    2186             }
    2187             else if (pConf32->u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE)
    2188             {
    2189                 /* @todo a value calculated from the vram size */
    2190                 pConf32->u32Value = 64*_1K;
    2191             }
    2192             else if (   pConf32->u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING
    2193                      || pConf32->u32Index == VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING)
    2194             {
    2195                 pConf32->u32Value = VINF_SUCCESS;
    2196             }
    2197             else if (pConf32->u32Index == VBOX_VBVA_CONF32_CURSOR_CAPABILITIES)
    2198             {
    2199                 pConf32->u32Value = pVGAState->fHostCursorCapabilities;
    2200             }
    2201             else if (pConf32->u32Index == VBOX_VBVA_CONF32_SCREEN_FLAGS)
    2202             {
    2203                 pConf32->u32Value = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED | VBVA_SCREEN_F_BLANK;
    2204             }
    2205             else
    2206             {
    2207                 Log(("Unsupported VBVA_QUERY_CONF32 index %d!!!\n",
    2208                      pConf32->u32Index));
    2209                 rc = VERR_INVALID_PARAMETER;
    2210             }
     2472            rc = vbvaHandleQueryConf32(pVGAState, pConf32);
    22112473        } break;
    22122474
    22132475        case VBVA_SET_CONF32:
    22142476        {
    2215             if (cbBuffer < sizeof (VBVACONF32))
     2477            if (cbBuffer < sizeof(VBVACONF32))
    22162478            {
    22172479                rc = VERR_INVALID_PARAMETER;
     
    22202482
    22212483            VBVACONF32 *pConf32 = (VBVACONF32 *)pvBuffer;
    2222             LogFlowFunc(("VBVA_SET_CONF32: u32Index %d, u32Value 0x%x\n",
    2223                          pConf32->u32Index, pConf32->u32Value));
    2224 
    2225             if (pConf32->u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT)
    2226             {
    2227                 /* do nothing. this is a const. */
    2228             }
    2229             else if (pConf32->u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE)
    2230             {
    2231                 /* do nothing. this is a const. */
    2232             }
    2233             else
    2234             {
    2235                 Log(("Unsupported VBVA_SET_CONF32 index %d!!!\n",
    2236                      pConf32->u32Index));
    2237                 rc = VERR_INVALID_PARAMETER;
    2238             }
     2484            rc = vbvaHandleSetConf32(pVGAState, pConf32);
    22392485        } break;
    22402486
     
    22482494                break;
    22492495            }
    2250 #endif
     2496#endif /* VBOX_WITH_CRHGSMI */
    22512497
    22522498            /* Expect at least one VBVAINFOVIEW structure. */
     
    22632509                 ++pView, cbBuffer -= sizeof(VBVAINFOVIEW))
    22642510            {
    2265                 VBVAINFOVIEW view = *pView;
    2266                 rc = VBVAInfoView(pVGAState, &view);
     2511                rc = VBVAInfoView(pVGAState, pView);
    22672512                if (RT_FAILURE(rc))
    22682513                    break;
     
    22722517        case VBVA_INFO_HEAP:
    22732518        {
    2274             if (cbBuffer < sizeof (VBVAINFOHEAP))
     2519            if (cbBuffer < sizeof(VBVAINFOHEAP))
    22752520            {
    22762521                rc = VERR_INVALID_PARAMETER;
     
    22782523            }
    22792524
    2280             VBVAINFOHEAP *pHeap = (VBVAINFOHEAP *)pvBuffer;
    2281             LogFlowFunc(("VBVA_INFO_HEAP: offset 0x%x, size 0x%x\n",
    2282                          pHeap->u32HeapOffset, pHeap->u32HeapSize));
    2283 
    2284             rc = HGSMIHostHeapSetup(pIns, pHeap->u32HeapOffset, pHeap->u32HeapSize);
     2525            const VBVAINFOHEAP *pInfoHeap = (VBVAINFOHEAP *)pvBuffer;
     2526            rc = vbvaHandleInfoHeap(pVGAState, pInfoHeap);
    22852527        } break;
    22862528
    22872529        case VBVA_FLUSH:
    22882530        {
    2289             if (cbBuffer < sizeof (VBVAFLUSH))
     2531            if (cbBuffer < sizeof(VBVAFLUSH))
    22902532            {
    22912533                rc = VERR_INVALID_PARAMETER;
     
    22932535            }
    22942536
    2295             VBVAFLUSH *pFlush = (VBVAFLUSH *)pvBuffer;
    2296             LogFlowFunc(("VBVA_FLUSH: u32Reserved 0x%x\n",
    2297                          pFlush->u32Reserved));
    2298 
    2299             rc = vbvaFlush (pVGAState, pCtx);
     2537            // const VBVAFLUSH *pVbvaFlush = (VBVAFLUSH *)pvBuffer;
     2538            rc = vbvaFlush(pVGAState, pCtx);
    23002539        } break;
    23012540
     
    23092548                break;
    23102549            }
    2311 #endif
     2550#endif /* VBOX_WITH_CRHGSMI */
    23122551
    23132552            if (cbBuffer < sizeof(VBVAINFOSCREEN))
     
    23172556            }
    23182557
    2319             VBVAINFOSCREEN Screen = *(VBVAINFOSCREEN *)pvBuffer;
    2320             rc = VBVAInfoScreen(pVGAState, &Screen);
     2558            const VBVAINFOSCREEN *pInfoScreen = (VBVAINFOSCREEN *)pvBuffer;
     2559            rc = VBVAInfoScreen(pVGAState, pInfoScreen);
    23212560        } break;
    23222561
     
    23302569                break;
    23312570            }
    2332 #endif
    2333 
    2334             if (cbBuffer < sizeof (VBVAENABLE))
     2571#endif /* VBOX_WITH_CRHGSMI */
     2572
     2573            if (cbBuffer < sizeof(VBVAENABLE))
    23352574            {
    23362575                rc = VERR_INVALID_PARAMETER;
     
    23382577            }
    23392578
    2340             VBVAENABLE *pEnable = (VBVAENABLE *)pvBuffer;
    2341             unsigned uScreenId;
    2342             if (pEnable->u32Flags & VBVA_F_EXTENDED)
    2343             {
    2344                 if (cbBuffer < sizeof (VBVAENABLE_EX))
     2579            VBVAENABLE *pVbvaEnable = (VBVAENABLE *)pvBuffer;
     2580
     2581            uint32_t u32ScreenId;
     2582            const uint32_t u32Flags = pVbvaEnable->u32Flags;
     2583            if (u32Flags & VBVA_F_EXTENDED)
     2584            {
     2585                if (cbBuffer < sizeof(VBVAENABLE_EX))
    23452586                {
    23462587                    rc = VERR_INVALID_PARAMETER;
     
    23482589                }
    23492590
    2350                 VBVAENABLE_EX *pEnableEx = (VBVAENABLE_EX *)pvBuffer;
    2351                 uScreenId = pEnableEx->u32ScreenId;
     2591                const VBVAENABLE_EX *pEnableEx = (VBVAENABLE_EX *)pvBuffer;
     2592                u32ScreenId = pEnableEx->u32ScreenId;
    23522593            }
    23532594            else
    23542595            {
    2355                 uScreenId = vbvaViewFromOffset (pIns, pCtx, pvBuffer);
    2356             }
    2357 
    2358             if (uScreenId == ~0U)
     2596                u32ScreenId = vbvaViewFromBufferPtr(pIns, pCtx, pvBuffer);
     2597            }
     2598
     2599            rc = vbvaHandleEnable(pVGAState, pVbvaEnable, u32ScreenId);
     2600
     2601            pVbvaEnable->i32Result = rc;
     2602        } break;
     2603
     2604        case VBVA_MOUSE_POINTER_SHAPE:
     2605        {
     2606            if (cbBuffer < sizeof(VBVAMOUSEPOINTERSHAPE))
    23592607            {
    23602608                rc = VERR_INVALID_PARAMETER;
     
    23622610            }
    23632611
    2364             LogFlowFunc(("VBVA_ENABLE[%d]: u32Flags 0x%x u32Offset 0x%x\n",
    2365                          uScreenId, pEnable->u32Flags, pEnable->u32Offset));
    2366 
    2367             if ((pEnable->u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_ENABLE)
    2368             {
    2369                 /* Guest reported offset relative to view. */
    2370                 uint32_t u32Offset = pEnable->u32Offset;
    2371                 if (!(pEnable->u32Flags & VBVA_F_ABSOFFSET))
    2372                 {
    2373                     u32Offset += pCtx->aViews[uScreenId].view.u32ViewOffset;
    2374                 }
    2375 
    2376                 VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost (pIns, u32Offset);
    2377 
    2378                 if (pVBVA)
    2379                 {
    2380                     /* Process any pending orders and empty the VBVA ring buffer. */
    2381                     vbvaFlush (pVGAState, pCtx);
    2382 
    2383                     rc = vbvaEnable (uScreenId, pVGAState, pCtx, pVBVA, u32Offset, false /* fRestored */);
    2384                 }
    2385                 else
    2386                 {
    2387                     Log(("Invalid VBVABUFFER offset 0x%x!!!\n",
    2388                          pEnable->u32Offset));
    2389                     rc = VERR_INVALID_PARAMETER;
    2390                 }
    2391             }
    2392             else if ((pEnable->u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_DISABLE)
    2393             {
    2394                 rc = vbvaDisable (uScreenId, pVGAState, pCtx);
    2395             }
    2396             else
    2397             {
    2398                 Log(("Invalid VBVA_ENABLE flags 0x%x!!!\n",
    2399                      pEnable->u32Flags));
    2400                 rc = VERR_INVALID_PARAMETER;
    2401             }
    2402 
    2403             pEnable->i32Result = rc;
     2612            VBVAMOUSEPOINTERSHAPE *pShape = (VBVAMOUSEPOINTERSHAPE *)pvBuffer;
     2613            rc = vbvaMousePointerShape(pVGAState, pCtx, pShape, cbBuffer);
     2614
     2615            pShape->i32Result = rc;
    24042616        } break;
    24052617
    2406         case VBVA_MOUSE_POINTER_SHAPE:
    2407         {
    2408             if (cbBuffer < sizeof (VBVAMOUSEPOINTERSHAPE))
     2618
     2619#ifdef VBOX_WITH_VIDEOHWACCEL
     2620        case VBVA_VHWA_CMD:
     2621        {
     2622            if (cbBuffer < sizeof(VBOXVHWACMD))
    24092623            {
    24102624                rc = VERR_INVALID_PARAMETER;
    24112625                break;
    24122626            }
    2413 
    2414             VBVAMOUSEPOINTERSHAPE *pShape = (VBVAMOUSEPOINTERSHAPE *)pvBuffer;
    2415 
    2416             LogFlowFunc(("VBVA_MOUSE_POINTER_SHAPE: i32Result 0x%x, fu32Flags 0x%x, hot spot %d,%d, size %dx%d\n",
    2417                          pShape->i32Result,
    2418                          pShape->fu32Flags,
    2419                          pShape->u32HotX,
    2420                          pShape->u32HotY,
    2421                          pShape->u32Width,
    2422                          pShape->u32Height));
    2423 
    2424             rc = vbvaMousePointerShape (pVGAState, pCtx, pShape, cbBuffer);
    2425 
    2426             pShape->i32Result = rc;
     2627            vbvaVHWAHandleCommand(pVGAState, (PVBOXVHWACMD)pvBuffer);
    24272628        } break;
    2428 
    2429 
    2430 #ifdef VBOX_WITH_VIDEOHWACCEL
    2431         case VBVA_VHWA_CMD:
    2432         {
    2433             if (cbBuffer < sizeof (VBOXVHWACMD))
    2434             {
    2435                 rc = VERR_INVALID_PARAMETER;
    2436                 break;
    2437             }
    2438             vbvaVHWAHandleCommand(pVGAState, (PVBOXVHWACMD)pvBuffer);
    2439             rc = VINF_SUCCESS;
    2440             break;
    2441         } break;
    2442 #endif
     2629#endif /* VBOX_WITH_VIDEOHWACCEL */
    24432630
    24442631#ifdef VBOX_WITH_WDDM
    24452632        case VBVA_INFO_CAPS:
    24462633        {
    2447             if (cbBuffer < sizeof (VBVACAPS))
     2634            if (cbBuffer < sizeof(VBVACAPS))
    24482635            {
    24492636                rc = VERR_INVALID_PARAMETER;
     
    24542641            pVGAState->fGuestCaps = pCaps->fCaps;
    24552642            pVGAState->pDrv->pfnVBVAGuestCapabilityUpdate(pVGAState->pDrv,
    2456                                                           pCaps->fCaps);
     2643                                                          pVGAState->fGuestCaps);
    24572644            pCaps->rc = VINF_SUCCESS;
    24582645        } break;
    2459 #endif
     2646#endif /* VBOX_WITH_WDDM */
     2647
    24602648        case VBVA_SCANLINE_CFG:
    24612649        {
    2462             if (cbBuffer < sizeof (VBVASCANLINECFG))
     2650            if (cbBuffer < sizeof(VBVASCANLINECFG))
    24632651            {
    24642652                rc = VERR_INVALID_PARAMETER;
     
    24782666                break;
    24792667            }
    2480             VBVAQUERYMODEHINTS *pModeHintQuery = (VBVAQUERYMODEHINTS*)pvBuffer;
    2481             LogRelFlowFunc(("VBVA_QUERY_MODE_HINTS: cHintsQueried=%u, cbHintStructureGuest=%u\n",
    2482                             (unsigned)pModeHintQuery->cHintsQueried,
    2483                             (unsigned)pModeHintQuery->cbHintStructureGuest));
    2484             if (cbBuffer <   sizeof (VBVAQUERYMODEHINTS)
    2485                            +   (uint64_t)pModeHintQuery->cHintsQueried
    2486                              * pModeHintQuery->cbHintStructureGuest)
    2487             {
    2488                 pModeHintQuery->rc = VERR_INVALID_PARAMETER;
    2489                 break;
    2490             }
    2491             pModeHintQuery->rc = VINF_SUCCESS;
    2492             uint8_t *pbHint = (uint8_t *)pvBuffer + sizeof(VBVAQUERYMODEHINTS);
    2493             memset(pbHint, ~0, cbBuffer - sizeof(VBVAQUERYMODEHINTS));
    2494             unsigned iHint;
    2495             for (iHint = 0;    iHint < pModeHintQuery->cHintsQueried
    2496                             && iHint < VBOX_VIDEO_MAX_SCREENS; ++iHint)
    2497             {
    2498                 memcpy(pbHint, &pCtx->aModeHints[iHint],
    2499                        RT_MIN(pModeHintQuery->cbHintStructureGuest,
    2500                               sizeof(VBVAMODEHINT)));
    2501                 pbHint += pModeHintQuery->cbHintStructureGuest;
    2502                 Assert(pbHint - (uint8_t *)pvBuffer <= cbBuffer);
    2503             }
     2668
     2669            VBVAQUERYMODEHINTS *pQueryModeHints = (VBVAQUERYMODEHINTS*)pvBuffer;
     2670            rc = vbvaHandleQueryModeHints(pVGAState, pQueryModeHints, cbBuffer);
     2671            pQueryModeHints->rc = rc;
    25042672        } break;
    25052673
    25062674        case VBVA_REPORT_INPUT_MAPPING:
    25072675        {
    2508             if (cbBuffer != sizeof(VBVAREPORTINPUTMAPPING))
     2676            if (cbBuffer < sizeof(VBVAREPORTINPUTMAPPING))
    25092677            {
    25102678                rc = VERR_INVALID_PARAMETER;
    25112679                break;
    25122680            }
    2513             VBVAREPORTINPUTMAPPING *pReport = (VBVAREPORTINPUTMAPPING *)pvBuffer;
    2514             LogRelFlowFunc(("VBVA_REPORT_INPUT_MAPPING: x=%u, y=%u, cx=%u, cy=%u\n", (unsigned)pReport->x, (unsigned)pReport->y,
    2515                             (unsigned)pReport->cx, (unsigned)pReport->cy));
    2516             pVGAState->pDrv->pfnVBVAInputMappingUpdate(pVGAState->pDrv, pReport->x, pReport->y, pReport->cx, pReport->cy);
     2681
     2682            const VBVAREPORTINPUTMAPPING inputMapping = *(VBVAREPORTINPUTMAPPING *)pvBuffer;
     2683            LogRelFlowFunc(("VBVA_REPORT_INPUT_MAPPING: x=%RI32, y=%RI32, cx=%RU32, cy=%RU32\n",
     2684                            inputMapping.x, inputMapping.y, inputMapping.cx, inputMapping.cy));
     2685            pVGAState->pDrv->pfnVBVAInputMappingUpdate(pVGAState->pDrv,
     2686                                                       inputMapping.x, inputMapping.y,
     2687                                                       inputMapping.cx, inputMapping.cy);
    25172688        } break;
    25182689
    25192690        case VBVA_CURSOR_POSITION:
    25202691        {
    2521             if (cbBuffer != sizeof(VBVACURSORPOSITION))
     2692            if (cbBuffer < sizeof(VBVACURSORPOSITION))
    25222693            {
    25232694                rc = VERR_INVALID_PARAMETER;
    25242695                break;
    25252696            }
    2526             VBVACURSORPOSITION *pReport
    2527                 = (VBVACURSORPOSITION *)pvBuffer;
    2528             LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=%RTbool",
    2529                             RT_BOOL(pReport->fReportPosition)));
    2530             if (RT_BOOL(pReport->fReportPosition))
    2531                 LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=true, x=%u, y=%u\n",
    2532                                (unsigned)pReport->x, (unsigned)pReport->y));
    2533             else
    2534                 LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=false\n"));
     2697
     2698            VBVACURSORPOSITION *pReport = (VBVACURSORPOSITION *)pvBuffer;
     2699
     2700            LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=%RTbool, x=%RU32, y=%RU32\n",
     2701                            RT_BOOL(pReport->fReportPosition), pReport->x, pReport->y));
     2702
    25352703            pReport->x = pCtx->xCursor;
    25362704            pReport->y = pCtx->yCursor;
     
    26182786            if (RT_SUCCESS (rc))
    26192787            {
    2620                 if (!pCtx->aViews[0].pVBVA)
     2788                if (!pCtx->aViews[0].vbva.guest.pVBVA)
    26212789                {
    26222790                    /* VBVA is not enabled for the first view, so VGA device must do updates. */
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