VirtualBox

Changeset 71619 in vbox


Ignore:
Timestamp:
Apr 2, 2018 5:11:37 PM (7 years ago)
Author:
vboxsync
Message:

DevVGA,VBoxC: Code cleanup in progress. bugref:9094

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/Graphics/VBoxVideoHost3D.h

    r71607 r71619  
    4242typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_BEGIN)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen);
    4343typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_END)(HVBOXCRCMDCLTSCR hClt, unsigned uScreenId, int32_t x, int32_t y, uint32_t cx, uint32_t cy);
    44 typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_PROCESS)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen, const struct VBVACMDHDR *pCmd, size_t cbCmd);
     44typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_PROCESS)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen,
     45                                                                  struct VBVACMDHDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmd,
     46                                                                  size_t cbCmd);
    4547
    4648/*client callbacks to be used by the server
  • trunk/include/VBox/vmm/pdmifs.h

    r71597 r71619  
    903903     */
    904904    DECLR3CALLBACKMEMBER(int, pfnVBVAEnable,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId,
    905                                              PVBVAHOSTFLAGS pHostFlags, bool fRenderThreadMode));
     905                                             struct VBVAHOSTFLAGS RT_UNTRUSTED_VOLATILE_GUEST *pHostFlags, bool fRenderThreadMode));
    906906
    907907    /**
     
    936936     */
    937937    DECLR3CALLBACKMEMBER(void, pfnVBVAUpdateProcess,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId,
    938                                                      PCVBVACMDHDR pCmd, size_t cbCmd));
     938                                                     struct VBVACMDHDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmd, size_t cbCmd));
    939939
    940940    /**
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r71612 r71619  
    2626#include <VBox/vmm/ssm.h>
    2727#include <VBox/VMMDev.h>
     28#include <VBox/AssertGuest.h>
    2829#include <VBoxVideo.h>
    2930#include <iprt/alloc.h>
     
    5960    struct
    6061    {
    61         VBVABUFFER *pVBVA;           /* Pointer to the guest memory with the VBVABUFFER. */
    62         uint8_t *pu8Data;            /* For convenience, pointer to the guest ring buffer (VBVABUFFER::au8Data). */
     62        VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA;   /**< Pointer to the guest memory with the VBVABUFFER. */
     63        uint8_t RT_UNTRUSTED_VOLATILE_GUEST    *pu8Data; /**< For convenience, pointer to the guest ring buffer (VBVABUFFER::au8Data). */
    6364    } guest;
    64     uint32_t u32VBVAOffset;          /* VBVABUFFER offset in the guest VRAM. */
    65     VBVAPARTIALRECORD partialRecord; /* Partial record temporary storage. */
    66     uint32_t off32Data;              /* The offset where the data starts in the VBVABUFFER.
    67                                       * The host code uses it instead of VBVABUFFER::off32Data.
    68                                       */
    69     uint32_t indexRecordFirst;       /* Index of the first filled record in VBVABUFFER::aRecords. */
    70     uint32_t cbPartialWriteThreshold; /* Copy of VBVABUFFER::cbPartialWriteThreshold used by host code. */
    71     uint32_t cbData;                 /* Copy of VBVABUFFER::cbData used by host code. */
     65    uint32_t u32VBVAOffset;           /**< VBVABUFFER offset in the guest VRAM. */
     66    VBVAPARTIALRECORD partialRecord;  /**< Partial record temporary storage. */
     67    uint32_t off32Data;               /**< The offset where the data starts in the VBVABUFFER.
     68                                       * The host code uses it instead of VBVABUFFER::off32Data. */
     69    uint32_t indexRecordFirst;        /**< Index of the first filled record in VBVABUFFER::aRecords. */
     70    uint32_t cbPartialWriteThreshold; /**< Copy of VBVABUFFER::cbPartialWriteThreshold used by host code. */
     71    uint32_t cbData;                  /**< Copy of VBVABUFFER::cbData used by host code. */
    7272} VBVADATA;
    7373
     
    110110    if (pVBVAData->guest.pVBVA)
    111111    {
    112         RT_ZERO(pVBVAData->guest.pVBVA->hostFlags);
     112        pVBVAData->guest.pVBVA->hostFlags.u32HostEvents      = 0;
     113        pVBVAData->guest.pVBVA->hostFlags.u32SupportedOrders = 0;
    113114    }
    114115
     
    119120}
    120121
    121 /** Copies @a cb bytes from the VBVA ring buffer to the @a pu8Dst.
     122/** Copies @a cb bytes from the VBVA ring buffer to the @a pbDst.
    122123 * Used for partial records or for records which cross the ring boundary.
    123124 */
    124 static bool vbvaFetchBytes(VBVADATA *pVBVAData, uint8_t *pu8Dst, uint32_t cb)
     125static bool vbvaFetchBytes(VBVADATA *pVBVAData, uint8_t *pbDst, uint32_t cb)
    125126{
    126127    if (cb >= pVBVAData->cbData)
     
    130131    }
    131132
     133    const uint8_t RT_UNTRUSTED_VOLATILE_GUEST *pbSrc = &pVBVAData->guest.pu8Data[pVBVAData->off32Data];
    132134    const uint32_t u32BytesTillBoundary = pVBVAData->cbData - pVBVAData->off32Data;
    133     const uint8_t  *pu8Src              = &pVBVAData->guest.pu8Data[pVBVAData->off32Data];
    134     const int32_t i32Diff               = cb - u32BytesTillBoundary;
     135    const int32_t  i32Diff              = cb - u32BytesTillBoundary;
    135136
    136137    if (i32Diff <= 0)
    137138    {
    138139        /* Chunk will not cross buffer boundary. */
    139         memcpy(pu8Dst, pu8Src, cb);
     140        RT_BCOPY_VOLATILE(pbDst, pbSrc, cb);
    140141    }
    141142    else
    142143    {
    143144        /* Chunk crosses buffer boundary. */
    144         memcpy(pu8Dst, pu8Src, u32BytesTillBoundary);
    145         memcpy(pu8Dst + u32BytesTillBoundary, &pVBVAData->guest.pu8Data[0], i32Diff);
     145        RT_BCOPY_VOLATILE(pbDst, pbSrc, u32BytesTillBoundary);
     146        RT_BCOPY_VOLATILE(pbDst + u32BytesTillBoundary, &pVBVAData->guest.pu8Data[0], i32Diff);
    146147    }
    147148
     
    201202}
    202203
    203 /* For contiguous chunks just return the address in the buffer.
    204  * For crossing boundary - allocate a buffer from heap.
     204/**
     205 * For contiguous chunks just return the address in the buffer. For crossing
     206 * boundary - allocate a buffer from heap.
    205207 */
    206 static bool vbvaFetchCmd(VBVADATA *pVBVAData, VBVACMDHDR **ppHdr, uint32_t *pcbCmd)
     208static bool vbvaFetchCmd(VBVADATA *pVBVAData, VBVACMDHDR RT_UNTRUSTED_VOLATILE_GUEST **ppHdr, uint32_t *pcbCmd)
    207209{
    208210    VBVAPARTIALRECORD *pPartialRecord = &pVBVAData->partialRecord;
     
    307309
    308310        /* The pointer to data in the ring buffer. */
    309         uint8_t *pu8Src = &pVBVAData->guest.pu8Data[pVBVAData->off32Data];
     311        uint8_t RT_UNTRUSTED_VOLATILE_GUEST *pbSrc = &pVBVAData->guest.pu8Data[pVBVAData->off32Data];
    310312
    311313        /* Fetch or point the data. */
     
    313315        {
    314316            /* The command does not cross buffer boundary. Return address in the buffer. */
    315             *ppHdr = (VBVACMDHDR *)pu8Src;
     317            *ppHdr = (VBVACMDHDR RT_UNTRUSTED_VOLATILE_GUEST *)pbSrc;
    316318
    317319            /* The data offset will be updated in vbvaReleaseCmd. */
     
    320322        {
    321323            /* The command crosses buffer boundary. Rare case, so not optimized. */
    322             uint8_t *pu8Dst = (uint8_t *)RTMemAlloc(cbRecord);
    323 
    324             if (!pu8Dst)
     324            uint8_t *pbDst = (uint8_t *)RTMemAlloc(cbRecord);
     325            if (!pbDst)
    325326            {
    326327                LogFlowFunc (("could not allocate %d bytes from heap!!!\n", cbRecord));
     
    328329            }
    329330
    330             vbvaFetchBytes(pVBVAData, pu8Dst, cbRecord);
    331 
    332             *ppHdr = (VBVACMDHDR *)pu8Dst;
    333 
    334             LOGVBVABUFFER(("Allocated from heap %p\n", pu8Dst));
     331            vbvaFetchBytes(pVBVAData, pbDst, cbRecord);
     332
     333            *ppHdr = (VBVACMDHDR *)pbDst;
     334
     335            LOGVBVABUFFER(("Allocated from heap %p\n", pbDst));
    335336        }
    336337    }
     
    348349}
    349350
    350 static void vbvaReleaseCmd(VBVADATA *pVBVAData, VBVACMDHDR *pHdr, uint32_t cbCmd)
    351 {
    352     VBVAPARTIALRECORD *pPartialRecord = &pVBVAData->partialRecord;
    353     const uint8_t *au8RingBuffer = pVBVAData->guest.pu8Data;
    354 
    355     if (   (uintptr_t)pHdr >= (uintptr_t)au8RingBuffer
    356         && (uintptr_t)pHdr < (uintptr_t)&au8RingBuffer[pVBVAData->cbData])
     351static void vbvaReleaseCmd(VBVADATA *pVBVAData, VBVACMDHDR RT_UNTRUSTED_VOLATILE_GUEST *pHdr, uint32_t cbCmd)
     352{
     353    VBVAPARTIALRECORD                          *pPartialRecord = &pVBVAData->partialRecord;
     354    const uint8_t RT_UNTRUSTED_VOLATILE_GUEST  *pbRingBuffer  = pVBVAData->guest.pu8Data;
     355
     356    if (   (uintptr_t)pHdr >= (uintptr_t)pbRingBuffer
     357        && (uintptr_t)pHdr < (uintptr_t)&pbRingBuffer[pVBVAData->cbData])
    357358    {
    358359        /* The pointer is inside ring buffer. Must be continuous chunk. */
    359         Assert(pVBVAData->cbData - (uint32_t)((uint8_t *)pHdr - au8RingBuffer) >= cbCmd);
     360        Assert(pVBVAData->cbData - (uint32_t)((uint8_t *)pHdr - pbRingBuffer) >= cbCmd);
    360361
    361362        /* Advance data offset and sync with guest. */
     
    380381        }
    381382
    382         RTMemFree(pHdr);
     383        RTMemFree((void *)pHdr);
    383384    }
    384385}
     
    403404    for (;;)
    404405    {
    405         VBVACMDHDR *phdr = NULL;
    406         uint32_t cbCmd = UINT32_MAX;
    407 
    408406        /* Fetch the command data. */
    409         if (!vbvaFetchCmd(pVBVAData, &phdr, &cbCmd))
     407        VBVACMDHDR RT_UNTRUSTED_VOLATILE_GUEST *pHdr  = NULL;
     408        uint32_t                                cbCmd = UINT32_MAX;
     409        if (!vbvaFetchCmd(pVBVAData, &pHdr, &cbCmd))
    410410        {
    411411            LogFunc(("unable to fetch command. off32Data = %d, off32Free = %d!!!\n",
    412                   pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free));
    413 
     412                     pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free));
    414413            return VERR_NOT_SUPPORTED;
    415414        }
     
    438437
    439438            /* Updates the rectangle and sends the command to the VRDP server. */
    440             pVGAState->pDrv->pfnVBVAUpdateProcess(pVGAState->pDrv, uScreenId, phdr, cbCmd);
    441 
    442             int32_t xRight  = phdr->x + phdr->w;
    443             int32_t yBottom = phdr->y + phdr->h;
     439            pVGAState->pDrv->pfnVBVAUpdateProcess(pVGAState->pDrv, uScreenId, pHdr, cbCmd);
     440
     441            int32_t xRight  = pHdr->x + pHdr->w;
     442            int32_t yBottom = pHdr->y + pHdr->h;
    444443
    445444            /* These are global coords, relative to the primary screen. */
    446445
    447446            LOGVBVABUFFER(("cbCmd = %d, x=%d, y=%d, w=%d, h=%d\n",
    448                            cbCmd, phdr->x, phdr->y, phdr->w, phdr->h));
     447                           cbCmd, pHdr->x, pHdr->y, pHdr->w, pHdr->h));
    449448            LogRel3(("%s: update command cbCmd = %d, x=%d, y=%d, w=%d, h=%d\n",
    450                      __FUNCTION__, cbCmd, phdr->x, phdr->y, phdr->w, phdr->h));
     449                     __FUNCTION__, cbCmd, pHdr->x, pHdr->y, pHdr->w, pHdr->h));
    451450
    452451            /* Collect all rects into one. */
     
    454453            {
    455454                /* This is the first rectangle to be added. */
    456                 dirtyRect.xLeft   = phdr->x;
    457                 dirtyRect.yTop    = phdr->y;
     455                dirtyRect.xLeft   = pHdr->x;
     456                dirtyRect.yTop    = pHdr->y;
    458457                dirtyRect.xRight  = xRight;
    459458                dirtyRect.yBottom = yBottom;
     
    463462            {
    464463                /* Adjust region coordinates. */
    465                 if (dirtyRect.xLeft > phdr->x)
     464                if (dirtyRect.xLeft > pHdr->x)
    466465                {
    467                     dirtyRect.xLeft = phdr->x;
     466                    dirtyRect.xLeft = pHdr->x;
    468467                }
    469468
    470                 if (dirtyRect.yTop > phdr->y)
     469                if (dirtyRect.yTop > pHdr->y)
    471470                {
    472                     dirtyRect.yTop = phdr->y;
     471                    dirtyRect.yTop = pHdr->y;
    473472                }
    474473
     
    485484        }
    486485
    487         vbvaReleaseCmd(pVBVAData, phdr, cbCmd);
     486        vbvaReleaseCmd(pVBVAData, pHdr, cbCmd);
    488487    }
    489488
     
    516515    {
    517516        VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva;
    518 
    519517        if (pVBVAData->guest.pVBVA)
    520518        {
    521519            rc = vbvaFlushProcess(uScreenId, pVGAState, pVBVAData);
    522520            if (RT_FAILURE(rc))
    523             {
    524521                break;
    525             }
    526522        }
    527523    }
     
    558554}
    559555
    560 static int vbvaEnable(unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx, VBVABUFFER *pVBVA, uint32_t u32Offset, bool fRestored)
    561 {
     556static int vbvaEnable(unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx,
     557                      VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA, uint32_t u32Offset, bool fRestored)
     558{
     559    /*
     560     * Copy into non-volatile memory and validate its content.
     561     */
     562    VBVABUFFER VbgaSafe;
     563    RT_COPY_VOLATILE(VbgaSafe, *pVBVA);
     564    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     565
     566    uint32_t const cbVBVABuffer = RT_UOFFSETOF(VBVABUFFER, au8Data) + VbgaSafe.cbData;
     567    ASSERT_GUEST_RETURN(   VbgaSafe.cbData <= UINT32_MAX - RT_UOFFSETOF(VBVABUFFER, au8Data)
     568                        && cbVBVABuffer <= pVGAState->vram_size
     569                        && u32Offset > pVGAState->vram_size - cbVBVABuffer,
     570                        VERR_INVALID_PARAMETER);
     571    if (!fRestored)
     572    {
     573        ASSERT_GUEST_RETURN(VbgaSafe.off32Data        == 0, VERR_INVALID_PARAMETER);
     574        ASSERT_GUEST_RETURN(VbgaSafe.off32Free        == 0, VERR_INVALID_PARAMETER);
     575        ASSERT_GUEST_RETURN(VbgaSafe.indexRecordFirst == 0, VERR_INVALID_PARAMETER);
     576        ASSERT_GUEST_RETURN(VbgaSafe.indexRecordFree  == 0, VERR_INVALID_PARAMETER);
     577    }
     578    ASSERT_GUEST_RETURN(   VbgaSafe.cbPartialWriteThreshold < VbgaSafe.cbData
     579                        && VbgaSafe.cbPartialWriteThreshold != 0,
     580                        VERR_INVALID_PARAMETER);
     581    RT_UNTRUSTED_VALIDATED_FENCE();
     582
     583    /*
     584     * Okay, try do the job.
     585     */
    562586    int rc;
    563 
    564     /* Check if VBVABUFFER content makes sense. */
    565     const VBVABUFFER parms = *pVBVA;
    566 
    567     uint32_t cbVBVABuffer = RT_UOFFSETOF(VBVABUFFER, au8Data) + parms.cbData;
    568     if (   parms.cbData > UINT32_MAX - RT_UOFFSETOF(VBVABUFFER, au8Data)
    569         || cbVBVABuffer > pVGAState->vram_size
    570         || u32Offset > pVGAState->vram_size - cbVBVABuffer)
    571     {
    572         return VERR_INVALID_PARAMETER;
    573     }
    574 
    575     if (!fRestored)
    576     {
    577         if (   parms.off32Data != 0
    578             || parms.off32Free != 0
    579             || parms.indexRecordFirst != 0
    580             || parms.indexRecordFree != 0)
    581         {
    582             return VERR_INVALID_PARAMETER;
    583         }
    584     }
    585 
    586     if (   parms.cbPartialWriteThreshold >= parms.cbData
    587         || parms.cbPartialWriteThreshold == 0)
    588     {
    589         return VERR_INVALID_PARAMETER;
    590     }
    591 
    592587    if (pVGAState->pDrv->pfnVBVAEnable)
    593588    {
    594         RT_ZERO(pVBVA->hostFlags);
     589        pVBVA->hostFlags.u32HostEvents      = 0;
     590        pVBVA->hostFlags.u32SupportedOrders = 0;
    595591        rc = pVGAState->pDrv->pfnVBVAEnable(pVGAState->pDrv, uScreenId, &pVBVA->hostFlags, false);
     592        if (RT_SUCCESS(rc))
     593        {
     594            /* pVBVA->hostFlags has been set up by pfnVBVAEnable. */
     595            LogFlowFunc(("u32HostEvents=0x%08x  u32SupportedOrders=0x%08x\n",
     596                         pVBVA->hostFlags.u32HostEvents, pVBVA->hostFlags.u32SupportedOrders));
     597
     598            VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva;
     599            pVBVAData->guest.pVBVA             = pVBVA;
     600            pVBVAData->guest.pu8Data           = &pVBVA->au8Data[0];
     601            pVBVAData->u32VBVAOffset           = u32Offset;
     602            pVBVAData->off32Data               = VbgaSafe.off32Data;
     603            pVBVAData->indexRecordFirst        = VbgaSafe.indexRecordFirst;
     604            pVBVAData->cbPartialWriteThreshold = VbgaSafe.cbPartialWriteThreshold;
     605            pVBVAData->cbData                  = VbgaSafe.cbData;
     606
     607            if (!fRestored)
     608            {
     609                /** @todo Actually this function must not touch the partialRecord structure at all,
     610                 * because initially it is a zero and when VBVA is disabled this should be set to zero.
     611                 * But I'm not sure that no code depends on zeroing partialRecord here.
     612                 * So for now (a quick fix for 4.1) just do not do this if the VM was restored,
     613                 * when partialRecord might be loaded already from the saved state.
     614                 */
     615                pVBVAData->partialRecord.pu8 = NULL;
     616                pVBVAData->partialRecord.cb = 0;
     617            }
     618
     619            /* VBVA is working so disable the pause. */
     620            pCtx->fPaused = false;
     621        }
    596622    }
    597623    else
    598     {
    599624        rc = VERR_NOT_SUPPORTED;
    600     }
    601 
    602     if (RT_SUCCESS(rc))
    603     {
    604         /* pVBVA->hostFlags has been set up by pfnVBVAEnable. */
    605         LogFlowFunc(("u32HostEvents 0x%08X, u32SupportedOrders 0x%08X\n",
    606                      pVBVA->hostFlags.u32HostEvents, pVBVA->hostFlags.u32SupportedOrders));
    607 
    608         VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva;
    609         pVBVAData->guest.pVBVA             = pVBVA;
    610         pVBVAData->guest.pu8Data           = &pVBVA->au8Data[0];
    611         pVBVAData->u32VBVAOffset           = u32Offset;
    612         pVBVAData->off32Data               = parms.off32Data;
    613         pVBVAData->indexRecordFirst        = parms.indexRecordFirst;
    614         pVBVAData->cbPartialWriteThreshold = parms.cbPartialWriteThreshold;
    615         pVBVAData->cbData                  = parms.cbData;
    616 
    617         if (!fRestored)
    618         {
    619             /** @todo Actually this function must not touch the partialRecord structure at all,
    620              * because initially it is a zero and when VBVA is disabled this should be set to zero.
    621              * But I'm not sure that no code depends on zeroing partialRecord here.
    622              * So for now (a quick fix for 4.1) just do not do this if the VM was restored,
    623              * when partialRecord might be loaded already from the saved state.
    624              */
    625             pVBVAData->partialRecord.pu8 = NULL;
    626             pVBVAData->partialRecord.cb = 0;
    627         }
    628 
    629         /* VBVA is working so disable the pause. */
    630         pCtx->fPaused = false;
    631     }
    632 
    633625    return rc;
    634626}
     
    811803    /* Check which view contains the buffer. */
    812804    HGSMIOFFSET offBuffer = HGSMIPointerToOffsetHost(pIns, pvBuffer);
    813 
    814805    if (offBuffer != HGSMIOFFSET_VOID)
    815806    {
     
    818809        {
    819810            const VBVAINFOVIEW *pView = &pCtx->aViews[uScreenId].view;
    820 
    821             if (   pView->u32ViewSize > 0
    822                 && pView->u32ViewOffset <= offBuffer
    823                 && offBuffer <= pView->u32ViewOffset + pView->u32ViewSize - 1)
    824             {
     811            if ((uint32_t)(offBuffer - pView->u32ViewOffset) < pView->u32ViewSize)
    825812                return pView->u32ViewIndex;
    826             }
    827         }
    828     }
    829 
     813        }
     814    }
    830815    return UINT32_MAX;
    831816}
     
    21162101static int vbvaHandleQueryConf32(PVGASTATE pVGAState, VBVACONF32 RT_UNTRUSTED_VOLATILE_GUEST *pConf32)
    21172102{
    2118     int rc = VINF_SUCCESS;
    2119     PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
    2120     VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
    2121 
    2122     const uint32_t u32Index = pConf32->u32Index;
    2123     ASMCompilerBarrier();
    2124 
    2125     LogFlowFunc(("VBVA_QUERY_CONF32: u32Index %d, u32Value 0x%x\n",
    2126                  u32Index, pConf32->u32Value));
    2127 
    2128     if (u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT)
    2129     {
    2130         pConf32->u32Value = pCtx->cViews;
    2131     }
    2132     else if (u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE)
    2133     {
    2134         /** @todo a value calculated from the vram size */
    2135         pConf32->u32Value = _64K;
    2136     }
    2137     else if (   u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING
    2138              || u32Index == VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING)
    2139     {
    2140         pConf32->u32Value = VINF_SUCCESS;
    2141     }
    2142     else if (u32Index == VBOX_VBVA_CONF32_CURSOR_CAPABILITIES)
    2143     {
    2144         pConf32->u32Value = pVGAState->fHostCursorCapabilities;
    2145     }
    2146     else if (u32Index == VBOX_VBVA_CONF32_SCREEN_FLAGS)
    2147     {
    2148         pConf32->u32Value =  VBVA_SCREEN_F_ACTIVE
    2149                            | VBVA_SCREEN_F_DISABLED
    2150                            | VBVA_SCREEN_F_BLANK
    2151                            | VBVA_SCREEN_F_BLANK2;
    2152     }
    2153     else if (u32Index == VBOX_VBVA_CONF32_MAX_RECORD_SIZE)
    2154     {
    2155         pConf32->u32Value = VBVA_MAX_RECORD_SIZE;
    2156     }
     2103    uint32_t const idxQuery = pConf32->u32Index;
     2104    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     2105    LogFlowFunc(("VBVA_QUERY_CONF32: u32Index %d, u32Value 0x%x\n", idxQuery, pConf32->u32Value));
     2106
     2107    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pVGAState->pHGSMI);
     2108    uint32_t     uValue;
     2109    if (idxQuery == VBOX_VBVA_CONF32_MONITOR_COUNT)
     2110        uValue = pCtx->cViews;
     2111    else if (idxQuery == VBOX_VBVA_CONF32_HOST_HEAP_SIZE)
     2112        uValue = _64K; /** @todo a value calculated from the vram size */
     2113    else if (   idxQuery == VBOX_VBVA_CONF32_MODE_HINT_REPORTING
     2114             || idxQuery == VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING)
     2115        uValue = VINF_SUCCESS;
     2116    else if (idxQuery == VBOX_VBVA_CONF32_CURSOR_CAPABILITIES)
     2117        uValue = pVGAState->fHostCursorCapabilities;
     2118    else if (idxQuery == VBOX_VBVA_CONF32_SCREEN_FLAGS)
     2119        uValue = VBVA_SCREEN_F_ACTIVE
     2120               | VBVA_SCREEN_F_DISABLED
     2121               | VBVA_SCREEN_F_BLANK
     2122               | VBVA_SCREEN_F_BLANK2;
     2123    else if (idxQuery == VBOX_VBVA_CONF32_MAX_RECORD_SIZE)
     2124        uValue = VBVA_MAX_RECORD_SIZE;
    21572125    else
    2158     {
    2159         Log(("Unsupported VBVA_QUERY_CONF32 index %d!!!\n",
    2160              u32Index));
    2161         rc = VERR_INVALID_PARAMETER;
    2162     }
    2163 
    2164     return rc;
    2165 }
    2166 
    2167 static int vbvaHandleSetConf32(PVGASTATE pVGAState, VBVACONF32 RT_UNTRUSTED_VOLATILE_GUEST *pConf32)
    2168 {
    2169     NOREF(pVGAState);
    2170 
    2171     VBVACONF32 parms;
    2172     parms.u32Index = pConf32->u32Index;
    2173     parms.u32Value = pConf32->u32Value;
    2174     ASMCompilerBarrier();
    2175 
    2176     LogFlowFunc(("VBVA_SET_CONF32: u32Index %d, u32Value 0x%x\n",
    2177                  parms.u32Index, parms.u32Value));
    2178 
    2179     int rc = VINF_SUCCESS;
    2180     if (parms.u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT)
    2181     {
    2182         /* do nothing. this is a const. */
    2183     }
    2184     else if (parms.u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE)
    2185     {
    2186         /* do nothing. this is a const. */
    2187     }
     2126        ASSERT_GUEST_MSG_FAILED_RETURN(("Invalid index %#x\n", idxQuery), VERR_INVALID_PARAMETER);
     2127
     2128    pConf32->u32Value = uValue;
     2129    return VINF_SUCCESS;
     2130}
     2131
     2132static int vbvaHandleSetConf32(VBVACONF32 RT_UNTRUSTED_VOLATILE_GUEST *pConf32)
     2133{
     2134    uint32_t const idxQuery = pConf32->u32Index;
     2135    uint32_t const uValue   = pConf32->u32Value;
     2136    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     2137    LogFlowFunc(("VBVA_SET_CONF32: u32Index %d, u32Value 0x%x\n", idxQuery, uValue));
     2138
     2139    if (idxQuery == VBOX_VBVA_CONF32_MONITOR_COUNT)
     2140    { /* do nothing. this is a const. */ }
     2141    else if (idxQuery == VBOX_VBVA_CONF32_HOST_HEAP_SIZE)
     2142    { /* do nothing. this is a const. */ }
    21882143    else
    2189     {
    2190         Log(("Unsupported VBVA_SET_CONF32 index %d!!!\n",
    2191              parms.u32Index));
    2192         rc = VERR_INVALID_PARAMETER;
    2193     }
    2194 
    2195     return rc;
     2144        ASSERT_GUEST_MSG_FAILED_RETURN(("Invalid index %#x (value=%u)\n", idxQuery, uValue), VERR_INVALID_PARAMETER);
     2145
     2146    return VINF_SUCCESS;
    21962147}
    21972148
    21982149static int vbvaHandleInfoHeap(PVGASTATE pVGAState, const VBVAINFOHEAP RT_UNTRUSTED_VOLATILE_GUEST *pInfoHeap)
    21992150{
    2200     VBVAINFOHEAP parms;
    2201     parms.u32HeapOffset = pInfoHeap->u32HeapOffset;
    2202     parms.u32HeapSize   = pInfoHeap->u32HeapSize;
    2203     ASMCompilerBarrier();
    2204     LogFlowFunc(("VBVA_INFO_HEAP: offset 0x%x, size 0x%x\n",
    2205                  parms.u32HeapOffset, parms.u32HeapSize));
    2206 
    2207     return HGSMIHostHeapSetup(pVGAState->pHGSMI, parms.u32HeapOffset, parms.u32HeapSize);
     2151    uint32_t const offHeap = pInfoHeap->u32HeapOffset;
     2152    uint32_t const cbHeap  = pInfoHeap->u32HeapSize;
     2153    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     2154    LogFlowFunc(("VBVA_INFO_HEAP: offset 0x%x, size 0x%x\n", offHeap, cbHeap));
     2155
     2156    return HGSMIHostHeapSetup(pVGAState->pHGSMI, offHeap, cbHeap);
    22082157}
    22092158
     
    22112160{
    22122161    VBVAINFOVIEW view;
    2213     view.u32ViewIndex     = pView->u32ViewIndex;
    2214     view.u32ViewOffset    = pView->u32ViewOffset;
    2215     view.u32ViewSize      = pView->u32ViewSize;
    2216     view.u32MaxScreenSize = pView->u32MaxScreenSize;
    2217     ASMCompilerBarrier();
     2162    RT_COPY_VOLATILE(view, *pView);
     2163    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    22182164
    22192165    LogFlowFunc(("VBVA_INFO_VIEW: u32ViewIndex %d, u32ViewOffset 0x%x, u32ViewSize 0x%x, u32MaxScreenSize 0x%x\n",
    22202166                 view.u32ViewIndex, view.u32ViewOffset, view.u32ViewSize, view.u32MaxScreenSize));
    22212167
    2222     PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
    2223     VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
    2224 
    2225     if (   view.u32ViewIndex < pCtx->cViews
    2226         && view.u32ViewOffset <= pVGAState->vram_size
    2227         && view.u32ViewSize <= pVGAState->vram_size
    2228         && view.u32ViewOffset <= pVGAState->vram_size - view.u32ViewSize
    2229         && view.u32MaxScreenSize <= view.u32ViewSize)
    2230     {
    2231         pCtx->aViews[view.u32ViewIndex].view = view;
    2232         return VINF_SUCCESS;
    2233     }
    2234 
    2235     LogRelFlow(("VBVA: InfoView: invalid data! index %d(%d), offset 0x%x, size 0x%x, max 0x%x, vram size 0x%x\n",
    2236                 view.u32ViewIndex, pCtx->cViews, view.u32ViewOffset, view.u32ViewSize,
    2237                 view.u32MaxScreenSize, pVGAState->vram_size));
    2238     return VERR_INVALID_PARAMETER;
     2168    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pVGAState->pHGSMI);
     2169    ASSERT_GUEST_LOGREL_MSG_RETURN(   view.u32ViewIndex     < pCtx->cViews
     2170                                   && view.u32ViewOffset    <= pVGAState->vram_size
     2171                                   && view.u32ViewSize      <= pVGAState->vram_size
     2172                                   && view.u32ViewOffset    <= pVGAState->vram_size - view.u32ViewSize
     2173                                   && view.u32MaxScreenSize <= view.u32ViewSize,
     2174                                   ("index %d(%d), offset 0x%x, size 0x%x, max 0x%x, vram size 0x%x\n",
     2175                                    view.u32ViewIndex, pCtx->cViews, view.u32ViewOffset, view.u32ViewSize,
     2176                                    view.u32MaxScreenSize, pVGAState->vram_size),
     2177                                   VERR_INVALID_PARAMETER);
     2178    RT_UNTRUSTED_VALIDATED_FENCE();
     2179
     2180    pCtx->aViews[view.u32ViewIndex].view = view;
     2181    return VINF_SUCCESS;
    22392182}
    22402183
    22412184int VBVAInfoScreen(PVGASTATE pVGAState, const VBVAINFOSCREEN RT_UNTRUSTED_VOLATILE_GUEST *pScreen)
    22422185{
     2186    /*
     2187     * Copy input into non-volatile buffer.
     2188     */
    22432189    VBVAINFOSCREEN screen;
    2244     memcpy(&screen, (void *)pScreen, sizeof(screen));
    2245     ASMCompilerBarrier();
     2190    RT_COPY_VOLATILE(screen, *pScreen);
     2191    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    22462192    LogRel(("VBVA: InfoScreen: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n",
    22472193            screen.u32ViewIndex, screen.i32OriginX, screen.i32OriginY,
     
    22492195            screen.u32LineSize, screen.u16BitsPerPixel, screen.u16Flags));
    22502196
    2251     PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
    2252     VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
    2253 
     2197    /*
     2198     * Validate input.
     2199     */
    22542200    /* Allow screen.u16BitsPerPixel == 0 because legacy guest code used it for screen blanking. */
    2255     if (   screen.u32ViewIndex < pCtx->cViews
    2256         && screen.u16BitsPerPixel <= 32
    2257         && screen.u32Width <= UINT16_MAX
    2258         && screen.u32Height <= UINT16_MAX
    2259         && screen.u32LineSize <= UINT16_MAX * 4)
    2260     {
    2261         const VBVAINFOVIEW *pView = &pCtx->aViews[screen.u32ViewIndex].view;
    2262         const uint32_t u32BytesPerPixel = (screen.u16BitsPerPixel + 7) / 8;
    2263         if (screen.u32Width <= screen.u32LineSize / (u32BytesPerPixel? u32BytesPerPixel: 1))
    2264         {
    2265             const uint64_t u64ScreenSize = (uint64_t)screen.u32LineSize * screen.u32Height;
    2266             if (   screen.u32StartOffset <= pView->u32ViewSize
    2267                 && u64ScreenSize         <= pView->u32MaxScreenSize
    2268                 && screen.u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize)
    2269             {
    2270                 vbvaResize(pVGAState, &pCtx->aViews[screen.u32ViewIndex], &screen, true);
    2271                 return VINF_SUCCESS;
    2272             }
    2273 
    2274             LogRelFlow(("VBVA: InfoScreen: invalid data! size %#RX64, max %#RX32\n",
    2275                         u64ScreenSize, pView->u32MaxScreenSize));
    2276         }
    2277     }
    2278     else
    2279         LogRelFlow(("VBVA: InfoScreen: invalid data! index %RU32(%RU32)\n", screen.u32ViewIndex, pCtx->cViews));
    2280 
    2281     return VERR_INVALID_PARAMETER;
     2201    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pVGAState->pHGSMI);
     2202    ASSERT_GUEST_LOGREL_MSG_RETURN(screen.u32ViewIndex <  pCtx->cViews,
     2203                                   ("Screen index %#x is out of bound (cViews=%#x)\n", screen.u32ViewIndex, pCtx->cViews),
     2204                                    VERR_INVALID_PARAMETER);
     2205    ASSERT_GUEST_LOGREL_MSG_RETURN(   screen.u16BitsPerPixel <= 32
     2206                                   && screen.u32Width        <= UINT16_MAX
     2207                                   && screen.u32Height       <= UINT16_MAX
     2208                                   && screen.u32LineSize     <= UINT16_MAX * UINT32_C(4),
     2209                                   ("One or more values out of range: u16BitsPerPixel=%#x u32Width=%#x u32Height=%#x u32LineSize=%#x\n",
     2210                                    screen.u16BitsPerPixel, screen.u32Width, screen.u32Height, screen.u32LineSize),
     2211                                   VERR_INVALID_PARAMETER);
     2212    RT_UNTRUSTED_VALIDATED_FENCE();
     2213
     2214    const VBVAINFOVIEW *pView = &pCtx->aViews[screen.u32ViewIndex].view;
     2215    const uint32_t      cbPerPixel = (screen.u16BitsPerPixel + 7) / 8;
     2216    ASSERT_GUEST_LOGREL_MSG_RETURN(screen.u32Width <= screen.u32LineSize / (cbPerPixel ? cbPerPixel : 1),
     2217                                   ("u32Width=%#x u32LineSize=%3x cbPerPixel=%#x\n",
     2218                                    screen.u32Width, screen.u32LineSize, cbPerPixel),
     2219                                   VERR_INVALID_PARAMETER);
     2220
     2221    const uint64_t u64ScreenSize = (uint64_t)screen.u32LineSize * screen.u32Height;
     2222
     2223    ASSERT_GUEST_LOGREL_MSG_RETURN(   screen.u32StartOffset <= pView->u32ViewSize
     2224                                   && u64ScreenSize         <= pView->u32MaxScreenSize
     2225                                   && screen.u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize,
     2226                                   ("u32StartOffset=%#x u32ViewSize=%#x u64ScreenSize=%#RX64 u32MaxScreenSize=%#x\n",
     2227                                    screen.u32StartOffset, pView->u32ViewSize, u64ScreenSize),
     2228                                   VERR_INVALID_PARAMETER);
     2229    RT_UNTRUSTED_VALIDATED_FENCE();
     2230
     2231    /*
     2232     * Do the job.
     2233     */
     2234    vbvaResize(pVGAState, &pCtx->aViews[screen.u32ViewIndex], &screen, true);
     2235    return VINF_SUCCESS;
    22822236}
    22832237
     
    22992253}
    23002254
    2301 static int vbvaHandleEnable(PVGASTATE pVGAState, VBVAENABLE const volatile *pVbvaEnable, uint32_t u32ScreenId)
    2302 {
     2255static int vbvaHandleEnable(PVGASTATE pVGAState, uint32_t fEnableFlags, uint32_t offEnable, uint32_t idScreen)
     2256{
     2257    LogFlowFunc(("VBVA_ENABLE[%u]: fEnableFlags=0x%x offEnable=%#x\n", idScreen, fEnableFlags, offEnable));
     2258    PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
     2259    VBVACONTEXT   *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
     2260
     2261    /*
     2262     * Validate input.
     2263     */
     2264    ASSERT_GUEST_LOGREL_MSG_RETURN(idScreen < pCtx->cViews, ("idScreen=%#x cViews=%#x\n", idScreen, pCtx->cViews), VERR_INVALID_PARAMETER);
     2265    ASSERT_GUEST_LOGREL_MSG_RETURN(   (fEnableFlags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_ENABLE
     2266                                    || (fEnableFlags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_DISABLE,
     2267                                   ("fEnableFlags=%#x\n", fEnableFlags),
     2268                                   VERR_INVALID_PARAMETER);
     2269    if (fEnableFlags & VBVA_F_ENABLE)
     2270    {
     2271        ASSERT_GUEST_LOGREL_MSG_RETURN(offEnable < pVGAState->vram_size,
     2272                                       ("offEnable=%#x vram_size=%#x\n", offEnable, pVGAState->vram_size),
     2273                                       VERR_INVALID_PARAMETER);
     2274        if (fEnableFlags & VBVA_F_ABSOFFSET)
     2275            /* Offset from VRAM start. */
     2276            ASSERT_GUEST_LOGREL_MSG_RETURN(   pVGAState->vram_size >= RT_UOFFSETOF(VBVABUFFER, au8Data)
     2277                                           && offEnable <= pVGAState->vram_size - RT_UOFFSETOF(VBVABUFFER, au8Data),
     2278                                           ("offEnable=%#x vram_size=%#x\n", offEnable, pVGAState->vram_size),
     2279                                           VERR_INVALID_PARAMETER);
     2280        else
     2281        {
     2282            /* Offset from the view start.  We'd be using idScreen here to fence required. */
     2283            RT_UNTRUSTED_VALIDATED_FENCE();
     2284            const VBVAINFOVIEW *pView = &pCtx->aViews[idScreen].view;
     2285            ASSERT_GUEST_LOGREL_MSG_RETURN(   pVGAState->vram_size - offEnable >= pView->u32ViewOffset
     2286                                           && pView->u32ViewSize >= RT_UOFFSETOF(VBVABUFFER, au8Data)
     2287                                           && offEnable <= pView->u32ViewSize - RT_UOFFSETOF(VBVABUFFER, au8Data),
     2288                                           ("offEnable=%#x vram_size=%#x view: %#x LB %#x\n",
     2289                                            offEnable, pVGAState->vram_size, pView->u32ViewOffset, pView->u32ViewSize),
     2290                                           VERR_INVALID_PARAMETER);
     2291            offEnable += pView->u32ViewOffset;
     2292        }
     2293        ASSERT_GUEST_LOGREL_MSG_RETURN(HGSMIIsOffsetValid(pIns, offEnable),
     2294                                       ("offEnable=%#x area %#x LB %#x\n",
     2295                                        offEnable, HGSMIGetAreaOffset(pIns), HGSMIGetAreaSize(pIns)),
     2296                                       VERR_INVALID_PARAMETER);
     2297    }
     2298    RT_UNTRUSTED_VALIDATED_FENCE();
     2299
     2300    /*
     2301     * Execute.
     2302     */
    23032303    int rc = VINF_SUCCESS;
    2304     PHGSMIINSTANCE pIns = pVGAState->pHGSMI;
    2305     VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns);
    2306 
    2307     if (u32ScreenId > pCtx->cViews)
    2308         return VERR_INVALID_PARAMETER;
    2309 
    2310     uint32_t fEnableFlags = pVbvaEnable->u32Flags;
    2311     uint32_t offEnable    = pVbvaEnable->u32Offset;
    2312     ASMCompilerBarrier();
    2313 
    2314     LogFlowFunc(("VBVA_ENABLE[%d]: u32Flags 0x%x u32Offset %#x\n", u32ScreenId, fEnableFlags, offEnable));
    2315 
    2316     if ((fEnableFlags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_ENABLE)
    2317     {
    2318         if (offEnable < pVGAState->vram_size)
    2319         {
    2320             /* Guest reported offset either absolute or relative to view. */
    2321             if (fEnableFlags & VBVA_F_ABSOFFSET)
    2322             {
    2323                 /* Offset from VRAM start. */
    2324                 if (   pVGAState->vram_size < RT_UOFFSETOF(VBVABUFFER, au8Data)
    2325                     || offEnable > pVGAState->vram_size - RT_UOFFSETOF(VBVABUFFER, au8Data))
    2326                 {
    2327                     rc = VERR_INVALID_PARAMETER;
    2328                 }
    2329             }
    2330             else
    2331             {
    2332                 /* Offset from the view start. */
    2333                 const VBVAINFOVIEW *pView = &pCtx->aViews[u32ScreenId].view;
    2334                 if (   pVGAState->vram_size - offEnable < pView->u32ViewOffset
    2335                     || pView->u32ViewSize < RT_UOFFSETOF(VBVABUFFER, au8Data)
    2336                     || offEnable > pView->u32ViewSize - RT_UOFFSETOF(VBVABUFFER, au8Data))
    2337                 {
    2338                     rc = VERR_INVALID_PARAMETER;
    2339                 }
    2340                 else
    2341                 {
    2342                     offEnable += pView->u32ViewOffset;
    2343                 }
    2344             }
    2345         }
    2346         else
    2347         {
    2348             rc = VERR_INVALID_PARAMETER;
    2349         }
    2350 
    2351         if (RT_SUCCESS(rc))
    2352         {
    2353             VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pIns, offEnable);
    2354             if (pVBVA)
    2355             {
    2356                 /* Process any pending orders and empty the VBVA ring buffer. */
    2357                 vbvaFlush(pVGAState, pCtx);
    2358 
    2359                 rc = vbvaEnable(u32ScreenId, pVGAState, pCtx, pVBVA, offEnable, false /* fRestored */);
    2360             }
    2361             else
    2362             {
    2363                 Log(("Invalid VBVABUFFER offset 0x%x!!!\n", offEnable));
    2364                 rc = VERR_INVALID_PARAMETER;
    2365             }
    2366         }
    2367 
     2304    if (fEnableFlags & VBVA_F_ENABLE)
     2305    {
     2306        VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA
     2307            = (VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *)HGSMIOffsetToPointerHost(pIns, offEnable);
     2308        ASSERT_GUEST_LOGREL_RETURN(pVBVA, VERR_INVALID_PARAMETER); /* already check above, but let's be careful. */
     2309
     2310        /* Process any pending orders and empty the VBVA ring buffer. */
     2311        vbvaFlush(pVGAState, pCtx);
     2312
     2313        rc = vbvaEnable(idScreen, pVGAState, pCtx, pVBVA, offEnable, false /* fRestored */);
    23682314        if (RT_FAILURE(rc))
    23692315            LogRelMax(8, ("VBVA: can not enable: %Rrc\n", rc));
    23702316    }
    2371     else if ((fEnableFlags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_DISABLE)
    2372     {
    2373         rc = vbvaDisable(u32ScreenId, pVGAState, pCtx);
    2374     }
    23752317    else
    2376     {
    2377         Log(("Invalid VBVA_ENABLE flags 0x%x!!!\n", fEnableFlags));
    2378         rc = VERR_INVALID_PARAMETER;
    2379     }
    2380 
     2318        rc = vbvaDisable(idScreen, pVGAState, pCtx);
    23812319    return rc;
    23822320}
     
    25122450        case VBVA_SET_CONF32:
    25132451            if (cbBuffer >= sizeof(VBVACONF32))
    2514                 rc = vbvaHandleSetConf32(pVGAState, (VBVACONF32 RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer);
     2452                rc = vbvaHandleSetConf32((VBVACONF32 RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer);
    25152453            else
    25162454                rc = VERR_INVALID_PARAMETER;
     
    25692507            {
    25702508                VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *pVbvaEnable = (VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer;
    2571                 const uint32_t u32Flags = pVbvaEnable->u32Flags;
     2509                uint32_t const fEnableFlags = pVbvaEnable->u32Flags;
     2510                uint32_t const offEnable    = pVbvaEnable->u32Offset;
    25722511                RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    25732512
    2574                 uint32_t u32ScreenId;
    2575                 if (u32Flags & VBVA_F_EXTENDED)
     2513                uint32_t idScreen;
     2514                if (fEnableFlags & VBVA_F_EXTENDED)
    25762515                {
    2577                     if (cbBuffer >= sizeof(VBVAENABLE_EX))
    2578                         u32ScreenId = ((VBVAENABLE_EX RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer)->u32ScreenId;
    2579                     else
    2580                     {
    2581                         rc = VERR_INVALID_PARAMETER;
    2582                         break;
    2583                     }
     2516                    ASSERT_GUEST_STMT_BREAK(cbBuffer >= sizeof(VBVAENABLE_EX), rc = VERR_INVALID_PARAMETER);
     2517                    idScreen = ((VBVAENABLE_EX RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer)->u32ScreenId;
     2518                    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    25842519                }
    25852520                else
    2586                     u32ScreenId = vbvaViewFromBufferPtr(pIns, pCtx, pvBuffer);
    2587 
    2588                 rc = vbvaHandleEnable(pVGAState, pVbvaEnable, u32ScreenId);
     2521                    idScreen = vbvaViewFromBufferPtr(pIns, pCtx, pvBuffer);
     2522
     2523                rc = vbvaHandleEnable(pVGAState, fEnableFlags, offEnable, idScreen);
    25892524                pVbvaEnable->i32Result = rc;
    25902525            }
     
    25942529            if (cbBuffer >= sizeof(VBVAMOUSEPOINTERSHAPE))
    25952530            {
    2596                 VBVAMOUSEPOINTERSHAPE RT_UNTRUSTED_VOLATILE_GUEST *pShape;
    2597                 pShape = (VBVAMOUSEPOINTERSHAPE RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer;
     2531                VBVAMOUSEPOINTERSHAPE RT_UNTRUSTED_VOLATILE_GUEST *pShape
     2532                    = (VBVAMOUSEPOINTERSHAPE RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer;
    25982533                rc = vbvaMousePointerShape(pVGAState, pCtx, pShape, cbBuffer);
    25992534                pShape->i32Result = rc;
  • trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp

    r71612 r71619  
    30873087    VBOXVDMA_CTL_TYPE enmCtl = pCmd->enmCtl;
    30883088    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     3089
     3090    int rc;
    30893091    if (enmCtl < VBOXVDMA_CTL_TYPE_END)
    30903092    {
     
    30943096        {
    30953097            case VBOXVDMA_CTL_TYPE_ENABLE:
    3096                 pCmd->i32Result = VINF_SUCCESS;
     3098                rc = VINF_SUCCESS;
    30973099                break;
    30983100            case VBOXVDMA_CTL_TYPE_DISABLE:
    3099                 pCmd->i32Result = VINF_SUCCESS;
     3101                rc = VINF_SUCCESS;
    31003102                break;
    31013103            case VBOXVDMA_CTL_TYPE_FLUSH:
    3102                 pCmd->i32Result = VINF_SUCCESS;
     3104                rc = VINF_SUCCESS;
    31033105                break;
     3106            case VBOXVDMA_CTL_TYPE_WATCHDOG:
    31043107#ifdef VBOX_VDMA_WITH_WATCHDOG
    3105             case VBOXVDMA_CTL_TYPE_WATCHDOG:
    3106                 pCmd->i32Result = vboxVDMAWatchDogCtl(pVdma, pCmd->u32Offset);
     3108                rc = vboxVDMAWatchDogCtl(pVdma, pCmd->u32Offset);
     3109#else
     3110                rc = VERR_NOT_SUPPORTED;
     3111#endif
    31073112                break;
    3108 #endif
    31093113            default:
    3110                 WARN(("cmd not supported"));
    3111                 pCmd->i32Result = VERR_NOT_SUPPORTED;
    3112                 break;
     3114                AssertFailedBreakStmt(rc = VERR_IPE_NOT_REACHED_DEFAULT_CASE);
    31133115        }
    31143116    }
     
    31163118    {
    31173119        RT_UNTRUSTED_VALIDATED_FENCE();
    3118         WARN(("cmd not supported"));
    3119         pCmd->i32Result = VERR_NOT_SUPPORTED;
    3120     }
    3121 
    3122     int rc = VBoxSHGSMICommandComplete(pIns, pCmd);
     3120        ASSERT_GUEST_FAILED();
     3121        rc = VERR_NOT_SUPPORTED;
     3122    }
     3123
     3124    pCmd->i32Result = rc;
     3125    rc = VBoxSHGSMICommandComplete(pIns, pCmd);
    31233126    AssertRC(rc);
    31243127}
  • trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp

    r71590 r71619  
    6666#include <iprt/string.h>
    6767
     68#include <VBox/AssertGuest.h>
    6869#include <VBox/err.h>
    6970#define LOG_GROUP LOG_GROUP_HGSMI
     
    491492 *
    492493 */
    493 static int hgsmiHostHeapLock (HGSMIINSTANCE *pIns)
    494 {
    495     int rc = RTCritSectEnter (&pIns->hostHeapCritSect);
     494static int hgsmiHostHeapLock(HGSMIINSTANCE *pIns)
     495{
     496    int rc = RTCritSectEnter(&pIns->hostHeapCritSect);
    496497    AssertRC (rc);
    497498    return rc;
    498499}
    499500
    500 static void hgsmiHostHeapUnlock (HGSMIINSTANCE *pIns)
    501 {
    502     int rc = RTCritSectLeave (&pIns->hostHeapCritSect);
     501static void hgsmiHostHeapUnlock(HGSMIINSTANCE *pIns)
     502{
     503    int rc = RTCritSectLeave(&pIns->hostHeapCritSect);
    503504    AssertRC (rc);
    504505}
     
    961962};
    962963
    963 int HGSMIHostHeapSetup(PHGSMIINSTANCE pIns,
    964                        HGSMIOFFSET    offHeap,
    965                        HGSMISIZE      cbHeap)
     964int HGSMIHostHeapSetup(PHGSMIINSTANCE pIns, HGSMIOFFSET RT_UNTRUSTED_GUEST offHeap, HGSMISIZE RT_UNTRUSTED_GUEST cbHeap)
    966965{
    967966    LogFlowFunc(("pIns %p, offHeap 0x%08X, cbHeap = 0x%08X\n", pIns, offHeap, cbHeap));
    968967
    969     int rc = VINF_SUCCESS;
    970 
     968    /*
     969     * Validate input.
     970     */
    971971    AssertPtrReturn(pIns, VERR_INVALID_PARAMETER);
    972972
    973     if (   offHeap >= pIns->area.cbArea
    974         || cbHeap > pIns->area.cbArea
    975         || offHeap > pIns->area.cbArea - cbHeap)
    976     {
    977         AssertLogRelMsgFailed(("offHeap 0x%08X, cbHeap = 0x%08X, pIns->area.cbArea 0x%08X\n",
    978                                offHeap, cbHeap, pIns->area.cbArea));
    979         rc = VERR_INVALID_PARAMETER;
    980     }
    981     else
    982     {
    983         rc = hgsmiHostHeapLock (pIns);
    984 
    985         if (RT_SUCCESS (rc))
    986         {
    987             if (pIns->hostHeap.cRefs)
    988             {
    989                 AssertLogRelMsgFailed(("HGSMI[%s]: host heap setup ignored. %d allocated.\n",
    990                                        pIns->pszName, pIns->hostHeap.cRefs));
    991                 /* It is possible to change the heap only if there is no pending allocations. */
    992                 rc = VERR_ACCESS_DENIED;
    993             }
    994             else
    995             {
    996                 rc = HGSMIAreaInitialize(&pIns->hostHeap.area, pIns->area.pu8Base + offHeap, cbHeap, offHeap);
    997                 if (RT_SUCCESS(rc))
    998                 {
    999                     rc = HGSMIMAInit(&pIns->hostHeap.u.ma, &pIns->hostHeap.area, NULL, 0, 0, &g_hgsmiEnv);
    1000                 }
    1001 
    1002                 if (RT_SUCCESS(rc))
    1003                 {
    1004                     pIns->hostHeap.u32HeapType = HGSMI_HEAP_TYPE_MA;
    1005                 }
    1006                 else
    1007                 {
    1008                     HGSMIAreaClear(&pIns->hostHeap.area);
    1009                 }
    1010             }
    1011 
    1012             hgsmiHostHeapUnlock (pIns);
    1013         }
    1014     }
     973    ASSERT_GUEST_LOGREL_MSG_RETURN(   offHeap <  pIns->area.cbArea
     974                                   && cbHeap  <= pIns->area.cbArea
     975                                   && offHeap <= pIns->area.cbArea - cbHeap,
     976                                   ("Heap: %#x LB %#x; Area: %#x LB %#x\n", offHeap, cbHeap, pIns->area.offBase, pIns->area.cbArea),
     977                                   VERR_INVALID_PARAMETER);
     978    RT_UNTRUSTED_VALIDATED_FENCE();
     979
     980
     981    /*
     982     * Lock the heap and do the job.
     983     */
     984    int rc = hgsmiHostHeapLock(pIns);
     985    AssertReturn(rc, rc);
     986
     987    /* It is possible to change the heap only if there is no pending allocations. */
     988    ASSERT_GUEST_LOGREL_MSG_STMT_RETURN(pIns->hostHeap.cRefs == 0,
     989                                        ("HGSMI[%s]: host heap setup ignored. %d allocated.\n", pIns->pszName, pIns->hostHeap.cRefs),
     990                                        hgsmiHostHeapUnlock(pIns),
     991                                        VERR_ACCESS_DENIED);
     992    rc = HGSMIAreaInitialize(&pIns->hostHeap.area, pIns->area.pu8Base + offHeap, cbHeap, offHeap);
     993    if (RT_SUCCESS(rc))
     994    {
     995        rc = HGSMIMAInit(&pIns->hostHeap.u.ma, &pIns->hostHeap.area, NULL, 0, 0, &g_hgsmiEnv);
     996        if (RT_SUCCESS(rc))
     997            pIns->hostHeap.u32HeapType = HGSMI_HEAP_TYPE_MA;
     998        else
     999            HGSMIAreaClear(&pIns->hostHeap.area);
     1000    }
     1001
     1002    hgsmiHostHeapUnlock(pIns);
    10151003
    10161004    LogFlowFunc(("rc = %Rrc\n", rc));
    1017 
    10181005    return rc;
    10191006}
     
    15211508
    15221509
     1510/**
     1511 * Checks if @a offBuffer is within the area of this instance.
     1512 *
     1513 * This is for use in input validations.
     1514 *
     1515 * @returns true / false.
     1516 * @param   pIns        The instance.
     1517 * @param   offBuffer   The buffer offset to check.
     1518 */
     1519bool HGSMIIsOffsetValid(PHGSMIINSTANCE pIns, HGSMIOFFSET offBuffer)
     1520{
     1521    return pIns
     1522        && offBuffer - pIns->area.offBase < pIns->area.cbArea;
     1523}
     1524
     1525
     1526/**
     1527 * Returns the area offset for use in logging and assertion messages.
     1528 */
     1529HGSMIOFFSET HGSMIGetAreaOffset(PHGSMIINSTANCE pIns)
     1530{
     1531    return pIns ? pIns->area.offBase : ~(HGSMIOFFSET)0;
     1532}
     1533
     1534
     1535/**
     1536 * Returns the area size for use in logging and assertion messages.
     1537 */
     1538HGSMIOFFSET HGSMIGetAreaSize(PHGSMIINSTANCE pIns)
     1539{
     1540    return pIns ? pIns->area.cbArea : 0;
     1541}
     1542
     1543
    15231544void *HGSMIContext (PHGSMIINSTANCE pIns)
    15241545{
  • trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.h

    r71590 r71619  
    5050void RT_UNTRUSTED_VOLATILE_GUEST *HGSMIOffsetToPointerHost(PHGSMIINSTANCE pIns, HGSMIOFFSET offBuffer);
    5151HGSMIOFFSET HGSMIPointerToOffsetHost(PHGSMIINSTANCE pIns, const void RT_UNTRUSTED_VOLATILE_GUEST *pv);
     52bool        HGSMIIsOffsetValid(PHGSMIINSTANCE pIns, HGSMIOFFSET offBuffer);
     53HGSMIOFFSET HGSMIGetAreaOffset(PHGSMIINSTANCE pIns);
     54HGSMIOFFSET HGSMIGetAreaSize(PHGSMIINSTANCE pIns);
     55
    5256
    5357int   HGSMIHostChannelRegister(PHGSMIINSTANCE pIns, uint8_t u8Channel,
     
    6165#endif
    6266
    63 int HGSMIHostHeapSetup(PHGSMIINSTANCE pIns, HGSMIOFFSET offHeap, HGSMISIZE cbHeap);
     67int HGSMIHostHeapSetup(PHGSMIINSTANCE pIns, HGSMIOFFSET RT_UNTRUSTED_GUEST offHeap, HGSMISIZE RT_UNTRUSTED_GUEST cbHeap);
    6468
    6569/*
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r71597 r71619  
    8787    bool fVBVAForceResize;
    8888    bool fRenderThreadMode;
    89     PVBVAHOSTFLAGS pVBVAHostFlags;
     89    VBVAHOSTFLAGS RT_UNTRUSTED_VOLATILE_GUEST *pVBVAHostFlags;
    9090#endif /* VBOX_WITH_HGSMI */
    9191
     
    363363#ifdef VBOX_WITH_HGSMI
    364364    static DECLCALLBACK(int)   i_displayVBVAEnable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId,
    365                                                    PVBVAHOSTFLAGS pHostFlags, bool fRenderThreadMode);
     365                                                   VBVAHOSTFLAGS RT_UNTRUSTED_VOLATILE_GUEST *pHostFlags, bool fRenderThreadMode);
    366366    static DECLCALLBACK(void)  i_displayVBVADisable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId);
    367367    static DECLCALLBACK(void)  i_displayVBVAUpdateBegin(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId);
    368368    static DECLCALLBACK(void)  i_displayVBVAUpdateProcess(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId,
    369                                                           PCVBVACMDHDR pCmd, size_t cbCmd);
     369                                                          struct VBVACMDHDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmd, size_t cbCmd);
    370370    static DECLCALLBACK(void)  i_displayVBVAUpdateEnd(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, int32_t x, int32_t y,
    371371                                                      uint32_t cx, uint32_t cy);
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r71597 r71619  
    40384038
    40394039#ifdef VBOX_WITH_HGSMI
    4040 DECLCALLBACK(int) Display::i_displayVBVAEnable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, PVBVAHOSTFLAGS pHostFlags,
     4040/**
     4041 * @interface_method_impl{PDMIDISPLAYCONNECTOR,pfnVBVAEnable}
     4042 */
     4043DECLCALLBACK(int) Display::i_displayVBVAEnable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId,
     4044                                               VBVAHOSTFLAGS RT_UNTRUSTED_VOLATILE_GUEST *pHostFlags,
    40414045                                               bool fRenderThreadMode)
    40424046{
     
    40654069}
    40664070
     4071/**
     4072 * @interface_method_impl{PDMIDISPLAYCONNECTOR,pfnVBVADisable}
     4073 */
    40674074DECLCALLBACK(void) Display::i_displayVBVADisable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId)
    40684075{
     
    41244131}
    41254132
     4133/**
     4134 * @interface_method_impl{PDMIDISPLAYCONNECTOR,pfnVBVAUpdateProcess}
     4135 */
    41264136DECLCALLBACK(void) Display::i_displayVBVAUpdateProcess(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId,
    4127                                                        PCVBVACMDHDR pCmd, size_t cbCmd)
     4137                                                       struct VBVACMDHDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmd, size_t cbCmd)
    41284138{
    41294139    LogFlowFunc(("uScreenId %d pCmd %p cbCmd %d, @%d,%d %dx%d\n", uScreenId, pCmd, cbCmd, pCmd->x, pCmd->y, pCmd->w, pCmd->h));
     4140    VBVACMDHDR hdrSaved;
     4141    RT_COPY_VOLATILE(hdrSaved, *pCmd);
     4142    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    41304143
    41314144    PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
     
    41394152            && !pFBInfo->fDisabled)
    41404153        {
    4141             pDrv->pUpPort->pfnUpdateDisplayRect(pDrv->pUpPort, pCmd->x, pCmd->y, pCmd->w, pCmd->h);
     4154            pDrv->pUpPort->pfnUpdateDisplayRect(pDrv->pUpPort, hdrSaved.x, hdrSaved.y, hdrSaved.w, hdrSaved.h);
    41424155        }
    41434156        else if (   !pFBInfo->pSourceBitmap.isNull()
     
    41604173            if (SUCCEEDED(hrc))
    41614174            {
    4162                 uint32_t width              = pCmd->w;
    4163                 uint32_t height             = pCmd->h;
     4175                uint32_t width              = hdrSaved.w;
     4176                uint32_t height             = hdrSaved.h;
    41644177
    41654178                const uint8_t *pu8Src       = pFBInfo->pu8FramebufferVRAM;
    4166                 int32_t xSrc                = pCmd->x - pFBInfo->xOrigin;
    4167                 int32_t ySrc                = pCmd->y - pFBInfo->yOrigin;
     4179                int32_t xSrc                = hdrSaved.x - pFBInfo->xOrigin;
     4180                int32_t ySrc                = hdrSaved.y - pFBInfo->yOrigin;
    41684181                uint32_t u32SrcWidth        = pFBInfo->w;
    41694182                uint32_t u32SrcHeight       = pFBInfo->h;
     
    41934206    }
    41944207
    4195     VBVACMDHDR hdrSaved = *pCmd;
    4196 
     4208    /*
     4209     * Here is your classic 'temporary' solution.
     4210     */
     4211    /** @todo New SendUpdate entry which can get a separate cmd header or coords. */
    41974212    VBVACMDHDR *pHdrUnconst = (VBVACMDHDR *)pCmd;
    41984213
     
    42004215    pHdrUnconst->y -= (int16_t)pFBInfo->yOrigin;
    42014216
    4202     /** @todo new SendUpdate entry which can get a separate cmd header or coords. */
    42034217    pThis->mParent->i_consoleVRDPServer()->SendUpdate(uScreenId, pHdrUnconst, (uint32_t)cbCmd);
    42044218
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