VirtualBox

Changeset 71604 in vbox


Ignore:
Timestamp:
Apr 1, 2018 6:11:34 PM (6 years ago)
Author:
vboxsync
Message:

DevVGA,VBoxVideo: Code cleanup in progress: Backed vboxVDMACmdCheckCrCmd into vboxVDMACmdExec. bugref:9094

File:
1 edited

Legend:

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

    r71603 r71604  
    23932393
    23942394/**
    2395  * Check if this is an external command to be passed to the chromium backend.
    2396  *
    2397  * @retval VINF_NOT_SUPPORTED if not chromium command.
    2398  *
    2399  * @note    cbCmdDr is at least sizeof(VBOXVDMACBUF_DR).
    2400  */
    2401 static int vboxVDMACmdCheckCrCmd(struct VBOXVDMAHOST *pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmdDr, uint32_t cbCmdDr)
    2402 {
    2403     /*
    2404      * A chromium command has a VBOXVDMACMD part, so get that first.
    2405      */
    2406     uint32_t cbDmaCmd = pCmdDr->cbBuf;
    2407     uint16_t fDmaCmd  = pCmdDr->fFlags;
    2408     RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    2409 
    2410     VBOXVDMACMD RT_UNTRUSTED_VOLATILE_GUEST *pDmaCmd;
    2411     if (fDmaCmd & VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR)
    2412     {
    2413         AssertReturn(cbCmdDr  >=           sizeof(*pCmdDr) + VBOXVDMACMD_HEADER_SIZE(), VERR_INVALID_PARAMETER);
    2414         AssertReturn(cbDmaCmd >= cbCmdDr - sizeof(*pCmdDr) - VBOXVDMACMD_HEADER_SIZE(), VERR_INVALID_PARAMETER);
    2415 
    2416         pDmaCmd = VBOXVDMACBUF_DR_TAIL(pCmdDr, VBOXVDMACMD);
    2417     }
    2418     else if (fDmaCmd & VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET)
    2419     {
    2420         VBOXVIDEOOFFSET offBuf = pCmdDr->Location.offVramBuf;
    2421         AssertReturn(   cbDmaCmd <= pVdma->pVGAState->vram_size
    2422                      && offBuf <= pVdma->pVGAState->vram_size - cbDmaCmd, VERR_INVALID_PARAMETER);
    2423         uint8_t *pbRam = pVdma->pVGAState->vram_ptrR3;
    2424         pDmaCmd = (VBOXVDMACMD RT_UNTRUSTED_VOLATILE_GUEST *)(pbRam + offBuf);
    2425     }
    2426     else
    2427         return VINF_NOT_SUPPORTED;
    2428     Assert(cbDmaCmd >= VBOXVDMACMD_HEADER_SIZE()); /* checked by vbvaChannelHandler already */
    2429 
    2430     /*
    2431      * Check if command type is a chromium one.
    2432      */
    2433     int rc = VINF_NOT_SUPPORTED;
    2434     VBOXVDMACMD_TYPE const enmType = pDmaCmd->enmType;
    2435     RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    2436     if (   enmType == VBOXVDMACMD_TYPE_CHROMIUM_CMD
    2437         || enmType == VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER)
    2438     {
    2439         RT_UNTRUSTED_VALIDATED_FENCE();
    2440 
    2441         /*
    2442          * Process the Cr command.
    2443          */
    2444         uint32_t cbBody = VBOXVDMACMD_BODY_SIZE(cbDmaCmd);
    2445         if (enmType == VBOXVDMACMD_TYPE_CHROMIUM_CMD)
    2446         {
    2447             VBOXVDMACMD_CHROMIUM_CMD RT_UNTRUSTED_VOLATILE_GUEST *pCrCmd = VBOXVDMACMD_BODY(pDmaCmd, VBOXVDMACMD_CHROMIUM_CMD);
    2448             AssertReturn(cbBody >= sizeof(*pCrCmd), VERR_INVALID_PARAMETER);
    2449 
    2450             PVGASTATE pVGAState = pVdma->pVGAState;
    2451             if (pVGAState->pDrv->pfnCrHgsmiCommandProcess)
    2452             {
    2453                 VBoxSHGSMICommandMarkAsynchCompletion(pCmdDr);
    2454                 pVGAState->pDrv->pfnCrHgsmiCommandProcess(pVGAState->pDrv, pCrCmd, cbBody);
    2455             }
    2456             else
    2457             {
    2458                 AssertFailed();
    2459                 rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmdDr);
    2460                 AssertRC(rc);
    2461             }
    2462             rc = VINF_SUCCESS;
    2463         }
    2464         else
    2465         {
    2466             VBOXVDMACMD_DMA_BPB_TRANSFER RT_UNTRUSTED_VOLATILE_GUEST *pTransfer
    2467                 = VBOXVDMACMD_BODY(pDmaCmd, VBOXVDMACMD_DMA_BPB_TRANSFER);
    2468             AssertReturn(cbBody >= sizeof(*pTransfer), VERR_INVALID_PARAMETER);
    2469 
    2470             rc = vboxVDMACmdExecBpbTransfer(pVdma, pTransfer, sizeof(*pTransfer));
    2471             AssertRC(rc);
    2472             if (RT_SUCCESS(rc))
    2473             {
    2474                 pCmdDr->rc = VINF_SUCCESS;
    2475                 rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmdDr);
    2476                 AssertRC(rc);
    2477                 rc = VINF_SUCCESS;
    2478             }
    2479         }
    2480     }
    2481     return rc;
    2482 }
    2483 
    2484 /**
    24852395 * @interface_method_impl{PDMIDISPLAYVBVACALLBACKS,pfnCrHgsmiControlCompleteAsync,
    24862396 *      Some indirect completion magic, you gotta love this code! }
     
    25382448            && (uintptr_t)(pbDstSurf + offBoth) - (uintptr_t)pbRam <= cbVRamSize - cbToCopy
    25392449            && (uintptr_t)(pbSrcSurf + offBoth) - (uintptr_t)pbRam <= cbVRamSize - cbToCopy)
     2450        {
     2451            RT_UNTRUSTED_VALIDATED_FENCE();
    25402452            memcpy(pbDstSurf + offBoth, pbSrcSurf + offBoth, cbToCopy);
     2453        }
    25412454        else
    25422455            return VERR_INVALID_PARAMETER;
     
    25692482                && (uintptr_t)pbDstStart - (uintptr_t)pbRam <= cbVRamSize - cbDstLine
    25702483                && (uintptr_t)pbSrcStart - (uintptr_t)pbRam <= cbVRamSize - cbDstLine)
     2484            {
     2485                RT_UNTRUSTED_VALIDATED_FENCE(); /** @todo this could potentially be buzzkiller. */
    25712486                memcpy(pbDstStart, pbSrcStart, cbDstLine);
     2487            }
    25722488            else
    25732489                return VERR_INVALID_PARAMETER;
     
    26312547    VBOXVDMACMD_DMA_PRESENT_BLT BltSafe;
    26322548    memcpy(&BltSafe, (void const *)pBlt, RT_UOFFSETOF(VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects));
    2633     ASMCompilerBarrier();
     2549    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    26342550
    26352551    AssertReturn(BltSafe.cDstSubRects < _8M, VERR_INVALID_PARAMETER);
    26362552    uint32_t const cbBlt = RT_UOFFSETOF(VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[BltSafe.cDstSubRects]);
    26372553    AssertReturn(cbBuffer >= cbBlt, VERR_INVALID_PARAMETER);
    2638 
    26392554
    26402555    /*
     
    26462561    Assert(BltSafe.cDstSubRects);
    26472562
     2563    RT_UNTRUSTED_VALIDATED_FENCE();
     2564
     2565    /*
     2566     * Do the work.
     2567     */
    26482568    //VBOXVDMA_RECTL updateRectl = {0, 0, 0, 0}; - pointless
    2649 
    26502569    if (BltSafe.cDstSubRects)
    26512570    {
     
    26572576            dstSubRectl.width  = pBlt->aDstSubRects[i].width;
    26582577            dstSubRectl.height = pBlt->aDstSubRects[i].height;
    2659             ASMCompilerBarrier();
     2578            RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    26602579
    26612580            VBOXVDMA_RECTL srcSubRectl = dstSubRectl;
     
    27082627    VBOXVDMACMD_DMA_BPB_TRANSFER TransferSafeCopy;
    27092628    memcpy(&TransferSafeCopy, (void const *)pTransfer, sizeof(TransferSafeCopy));
    2710     ASMCompilerBarrier();
     2629    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    27112630
    27122631    PVGASTATE   pVGAState    = pVdma->pVGAState;
     
    27272646                     && TransferSafeCopy.Dst.offVramBuf <= pVGAState->vram_size - cbTransfer,
    27282647                     VERR_INVALID_PARAMETER);
     2648    RT_UNTRUSTED_VALIDATED_FENCE();
    27292649
    27302650    /*
     
    27992719 * @param   pbBuffer    Command buffer, considered volatile.
    28002720 * @param   cbBuffer    The number of bytes at @a pbBuffer.
    2801  */
    2802 static int vboxVDMACmdExec(PVBOXVDMAHOST pVdma, const uint8_t *pbBuffer, uint32_t cbBuffer)
     2721 * @param   pCmdDr      The command.  For setting the async flag on chromium
     2722 *                      requests.
     2723 * @param   pfAsyncCmd  Flag to set if async command completion on chromium
     2724 *                      requests.  Input stat is false, so it only ever need to
     2725 *                      be set to true.
     2726 */
     2727static int vboxVDMACmdExec(PVBOXVDMAHOST pVdma, const uint8_t *pbBuffer, uint32_t cbBuffer,
     2728                           VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmdDr, bool *pfAsyncCmd)
    28032729{
    28042730    AssertReturn(pbBuffer, VERR_INVALID_POINTER);
     
    28152741            case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
    28162742            {
    2817 # ifdef VBOXWDDM_TEST_UHGSMI
    2818                 static int count = 0;
    2819                 static uint64_t start, end;
    2820                 if (count==0)
    2821                 {
    2822                     start = RTTimeNanoTS();
    2823                 }
    2824                 ++count;
    2825                 if (count==100000)
    2826                 {
    2827                     end = RTTimeNanoTS();
    2828                     float ems = (end-start)/1000000.f;
    2829                     LogRel(("100000 calls took %i ms, %i cps\n", (int)ems, (int)(100000.f*1000.f/ems) ));
    2830                 }
    2831 # endif
    2832                 /** @todo post the buffer to chromium */
     2743                VBOXVDMACMD_CHROMIUM_CMD RT_UNTRUSTED_VOLATILE_GUEST *pCrCmd = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_CHROMIUM_CMD);
     2744                uint32_t const cbBody = VBOXVDMACMD_BODY_SIZE(cbBuffer);
     2745                AssertReturn(cbBody >= sizeof(*pCrCmd), VERR_INVALID_PARAMETER);
     2746
     2747                PVGASTATE pVGAState = pVdma->pVGAState;
     2748                AssertReturn(pVGAState->pDrv->pfnCrHgsmiCommandProcess, VERR_NOT_SUPPORTED);
     2749
     2750                VBoxSHGSMICommandMarkAsynchCompletion(pCmdDr);
     2751                pVGAState->pDrv->pfnCrHgsmiCommandProcess(pVGAState->pDrv, pCrCmd, cbBody);
     2752                *pfAsyncCmd = true;
    28332753                return VINF_SUCCESS;
    28342754            }
     
    28762796        }
    28772797        else
     2798        {
     2799            RT_UNTRUSTED_VALIDATED_FENCE();
    28782800            return cbProcessed; /* error status */
    2879 
     2801        }
    28802802    }
    28812803}
     
    29432865 * Worker for vboxVDMACommand.
    29442866 *
     2867 * @returns VBox status code of the operation.
     2868 * @param   pVdma       VDMA instance data.
    29452869 * @param   pCmd        The command to process.  Consider content volatile.
    29462870 * @param   cbCmd       Number of valid bytes at @a pCmd.  This is at least
    29472871 *                      sizeof(VBOXVDMACBUF_DR).
     2872 * @param   pfAsyncCmd  Flag to set if async command completion on chromium
     2873 *                      requests.  Input stat is false, so it only ever need to
     2874 *                      be set to true.
    29482875 * @thread  VDMA
    29492876 */
    2950 static void vboxVDMACommandProcess(PVBOXVDMAHOST pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
    2951 {
    2952     PHGSMIINSTANCE pHgsmi = pVdma->pHgsmi;
    2953     int rc;
    2954 
    2955     do /* break loop */
    2956     {
    2957         /*
    2958          * Get the command buffer (volatile).
    2959          */
    2960         uint16_t const cbCmdBuf                = pCmd->cbBuf;
    2961         uint16_t const fCmdFlags               = pCmd->fFlags;
    2962         uint64_t const offVramBuf_or_GCPhysBuf = pCmd->Location.offVramBuf;
    2963         AssertCompile(sizeof(pCmd->Location.offVramBuf) == sizeof(pCmd->Location.phBuf));
    2964         RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
    2965 
    2966         const uint8_t RT_UNTRUSTED_VOLATILE_GUEST  *pbCmdBuf;
    2967         PGMPAGEMAPLOCK                              Lock;
    2968         bool                                        fReleaseLocked = false;
    2969         if (fCmdFlags & VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR)
    2970         {
    2971             pbCmdBuf = VBOXVDMACBUF_DR_TAIL(pCmd, const uint8_t);
    2972             AssertBreakStmt((uintptr_t)&pbCmdBuf[cbCmdBuf] <= (uintptr_t)&((uint8_t *)pCmd)[cbCmd],
    2973                             rc = VERR_INVALID_PARAMETER);
    2974             RT_UNTRUSTED_VALIDATED_FENCE();
    2975         }
    2976         else if (fCmdFlags & VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET)
    2977         {
    2978             AssertBreakStmt(   offVramBuf_or_GCPhysBuf <= pVdma->pVGAState->vram_size
    2979                             && offVramBuf_or_GCPhysBuf + cbCmdBuf <= pVdma->pVGAState->vram_size,
    2980                             rc = VERR_INVALID_PARAMETER);
    2981             RT_UNTRUSTED_VALIDATED_FENCE();
    2982             pbCmdBuf = (uint8_t const RT_UNTRUSTED_VOLATILE_GUEST *)pVdma->pVGAState->vram_ptrR3 + offVramBuf_or_GCPhysBuf;
    2983         }
    2984         else
    2985         {
    2986             /* Make sure it doesn't cross a page. */
    2987             AssertBreakStmt((uint32_t)(offVramBuf_or_GCPhysBuf & X86_PAGE_OFFSET_MASK) + cbCmdBuf <= (uint32_t)X86_PAGE_SIZE,
    2988                             rc = VERR_INVALID_PARAMETER);
    2989             RT_UNTRUSTED_VALIDATED_FENCE();
    2990 
    2991             rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pVdma->pVGAState->pDevInsR3, offVramBuf_or_GCPhysBuf, 0 /*fFlags*/,
     2877static int vboxVDMACommandProcess(PVBOXVDMAHOST pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd,
     2878                                  uint32_t cbCmd, bool *pfAsyncCmd)
     2879{
     2880    /*
     2881     * Get the command buffer (volatile).
     2882     */
     2883    uint16_t const cbCmdBuf                = pCmd->cbBuf;
     2884    uint16_t const fCmdFlags               = pCmd->fFlags;
     2885    uint64_t const offVramBuf_or_GCPhysBuf = pCmd->Location.offVramBuf;
     2886    AssertCompile(sizeof(pCmd->Location.offVramBuf) == sizeof(pCmd->Location.phBuf));
     2887    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     2888
     2889    const uint8_t RT_UNTRUSTED_VOLATILE_GUEST  *pbCmdBuf;
     2890    PGMPAGEMAPLOCK                              Lock;
     2891    bool                                        fReleaseLocked = false;
     2892    if (fCmdFlags & VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR)
     2893    {
     2894        pbCmdBuf = VBOXVDMACBUF_DR_TAIL(pCmd, const uint8_t);
     2895        AssertReturn((uintptr_t)&pbCmdBuf[cbCmdBuf] <= (uintptr_t)&((uint8_t *)pCmd)[cbCmd],
     2896                     VERR_INVALID_PARAMETER);
     2897        RT_UNTRUSTED_VALIDATED_FENCE();
     2898    }
     2899    else if (fCmdFlags & VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET)
     2900    {
     2901        AssertReturn(   offVramBuf_or_GCPhysBuf <= pVdma->pVGAState->vram_size
     2902                     && offVramBuf_or_GCPhysBuf + cbCmdBuf <= pVdma->pVGAState->vram_size,
     2903                     VERR_INVALID_PARAMETER);
     2904        RT_UNTRUSTED_VALIDATED_FENCE();
     2905
     2906        pbCmdBuf = (uint8_t const RT_UNTRUSTED_VOLATILE_GUEST *)pVdma->pVGAState->vram_ptrR3 + offVramBuf_or_GCPhysBuf;
     2907    }
     2908    else
     2909    {
     2910        /* Make sure it doesn't cross a page. */
     2911        AssertReturn((uint32_t)(offVramBuf_or_GCPhysBuf & X86_PAGE_OFFSET_MASK) + cbCmdBuf <= (uint32_t)X86_PAGE_SIZE,
     2912                     VERR_INVALID_PARAMETER);
     2913        RT_UNTRUSTED_VALIDATED_FENCE();
     2914
     2915        int rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pVdma->pVGAState->pDevInsR3, offVramBuf_or_GCPhysBuf, 0 /*fFlags*/,
    29922916                                                   (const void **)&pbCmdBuf, &Lock);
    2993             AssertRCBreak(rc); /* if (rc == VERR_PGM_PHYS_PAGE_RESERVED) -> fall back on using PGMPhysRead ?? */
    2994             fReleaseLocked = true;
    2995         }
    2996 
    2997         /*
    2998          * Process the command.
    2999          */
    3000         rc = vboxVDMACmdExec(pVdma, (uint8_t const *)pbCmdBuf, cbCmdBuf); /** @todo fixme later */
    3001         AssertRC(rc);
    3002 
    3003         /* Clean up comand buffer. */
    3004         if (fReleaseLocked)
    3005             PDMDevHlpPhysReleasePageMappingLock(pVdma->pVGAState->pDevInsR3, &Lock);
    3006 
    3007     } while (0);
     2917        AssertRCReturn(rc, rc); /* if (rc == VERR_PGM_PHYS_PAGE_RESERVED) -> fall back on using PGMPhysRead ?? */
     2918        fReleaseLocked = true;
     2919    }
    30082920
    30092921    /*
    3010      * Complete the command.
     2922     * Process the command.
    30112923     */
    3012     pCmd->rc = rc;
    3013     rc = VBoxSHGSMICommandComplete(pHgsmi, pCmd);
     2924    int rc = vboxVDMACmdExec(pVdma, (uint8_t const *)pbCmdBuf, cbCmdBuf, pCmd, pfAsyncCmd); /** @todo fixme later */
    30142925    AssertRC(rc);
     2926
     2927    /* Clean up comand buffer. */
     2928    if (fReleaseLocked)
     2929        PDMDevHlpPhysReleasePageMappingLock(pVdma->pVGAState->pDevInsR3, &Lock);
     2930    return rc;
    30152931}
    30162932
     
    32223138void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
    32233139{
     3140    /*
     3141     * Process the command.
     3142     */
     3143    bool fAsyncCmd = false;
    32243144#ifdef VBOX_WITH_CRHGSMI
    3225     /** @todo r=bird: This detour to vboxVDMACmdCheckCrCmd is inefficient and
    3226      * utterly confusing. It  should instead have been added to vboxVDMACmdExec or
    3227      * maybe vboxVDMACommandProcess.  Try reverse engineer wtf vboxVDMACmdExec
    3228      * does handle VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER.  Is it because of the case
    3229      * where neither VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET or
    3230      * VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER is set?  This code is certifiable!! */
    3231 
    3232     /* chromium commands are processed by crhomium hgcm thread independently from our internal cmd processing pipeline
    3233      * this is why we process them specially */
    3234     int rc = vboxVDMACmdCheckCrCmd(pVdma, pCmd, cbCmd);
    3235     if (rc == VINF_SUCCESS)
    3236         return;
    3237 
    3238     if (RT_SUCCESS(rc))
    3239         vboxVDMACommandProcess(pVdma, pCmd, cbCmd);
    3240     else
    3241     {
    3242         pCmd->rc = rc;
    3243         rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmd);
    3244         AssertRC(rc);
    3245     }
     3145    int rc = vboxVDMACommandProcess(pVdma, pCmd, cbCmd, &fAsyncCmd);
    32463146#else
    32473147    RT_NOREF(cbCmd);
    3248     pCmd->rc = VERR_NOT_IMPLEMENTED;
    3249     int rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmd);
    3250     AssertRC(rc);
     3148    int rc = VERR_NOT_IMPLEMENTED;
    32513149#endif
     3150
     3151    /*
     3152     * Complete the command unless it's asynchronous (e.g. chromium).
     3153     */
     3154    if (!fAsyncCmd)
     3155    {
     3156        pCmd->rc = rc;
     3157        int rc2 = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmd);
     3158        AssertRC(rc2);
     3159    }
    32523160}
    32533161
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