Changeset 71603 in vbox
- Timestamp:
- Apr 1, 2018 4:48:45 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
r71598 r71603 2401 2401 static int vboxVDMACmdCheckCrCmd(struct VBOXVDMAHOST *pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmdDr, uint32_t cbCmdDr) 2402 2402 { 2403 uint32_t cbDmaCmd = 0; 2404 uint8_t *pbRam = pVdma->pVGAState->vram_ptrR3; 2405 int rc = VINF_NOT_SUPPORTED; 2406 2407 cbDmaCmd = pCmdDr->cbBuf; 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(); 2408 2409 2409 2410 VBOXVDMACMD RT_UNTRUSTED_VOLATILE_GUEST *pDmaCmd; 2410 if ( pCmdDr->fFlags& VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR)2411 if (fDmaCmd & VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR) 2411 2412 { 2412 2413 AssertReturn(cbCmdDr >= sizeof(*pCmdDr) + VBOXVDMACMD_HEADER_SIZE(), VERR_INVALID_PARAMETER); … … 2415 2416 pDmaCmd = VBOXVDMACBUF_DR_TAIL(pCmdDr, VBOXVDMACMD); 2416 2417 } 2417 else if ( pCmdDr->fFlags& VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET)2418 else if (fDmaCmd & VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET) 2418 2419 { 2419 2420 VBOXVIDEOOFFSET offBuf = pCmdDr->Location.offVramBuf; 2420 2421 AssertReturn( cbDmaCmd <= pVdma->pVGAState->vram_size 2421 2422 && offBuf <= pVdma->pVGAState->vram_size - cbDmaCmd, VERR_INVALID_PARAMETER); 2423 uint8_t *pbRam = pVdma->pVGAState->vram_ptrR3; 2422 2424 pDmaCmd = (VBOXVDMACMD RT_UNTRUSTED_VOLATILE_GUEST *)(pbRam + offBuf); 2423 2425 } 2424 2426 else 2425 pDmaCmd = NULL; 2426 if (pDmaCmd) 2427 { 2428 Assert(cbDmaCmd >= VBOXVDMACMD_HEADER_SIZE()); 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 */ 2429 2444 uint32_t cbBody = VBOXVDMACMD_BODY_SIZE(cbDmaCmd); 2430 2431 VBOXVDMACMD_TYPE const enmType = pDmaCmd->enmType; 2432 ASMCompilerBarrier(); 2433 switch (enmType) 2434 { 2435 case VBOXVDMACMD_TYPE_CHROMIUM_CMD: 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) 2436 2452 { 2437 VBOXVDMACMD_CHROMIUM_CMD RT_UNTRUSTED_VOLATILE_GUEST *pCrCmd = VBOXVDMACMD_BODY(pDmaCmd, VBOXVDMACMD_CHROMIUM_CMD); 2438 AssertReturn(cbBody >= sizeof(*pCrCmd), VERR_INVALID_PARAMETER); 2439 2440 PVGASTATE pVGAState = pVdma->pVGAState; 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); 2441 2477 rc = VINF_SUCCESS; 2442 if (pVGAState->pDrv->pfnCrHgsmiCommandProcess)2443 {2444 VBoxSHGSMICommandMarkAsynchCompletion(pCmdDr);2445 pVGAState->pDrv->pfnCrHgsmiCommandProcess(pVGAState->pDrv, pCrCmd, cbBody);2446 break;2447 }2448 2449 AssertFailed();2450 int tmpRc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmdDr);2451 AssertRC(tmpRc);2452 break;2453 2478 } 2454 2455 case VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER:2456 {2457 VBOXVDMACMD_DMA_BPB_TRANSFER RT_UNTRUSTED_VOLATILE_GUEST *pTransfer2458 = VBOXVDMACMD_BODY(pDmaCmd, VBOXVDMACMD_DMA_BPB_TRANSFER);2459 AssertReturn(cbBody >= sizeof(*pTransfer), VERR_INVALID_PARAMETER);2460 2461 rc = vboxVDMACmdExecBpbTransfer(pVdma, pTransfer, sizeof(*pTransfer));2462 AssertRC(rc);2463 if (RT_SUCCESS(rc))2464 {2465 pCmdDr->rc = VINF_SUCCESS;2466 rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmdDr);2467 AssertRC(rc);2468 rc = VINF_SUCCESS;2469 }2470 break;2471 }2472 2473 default:2474 break;2475 2479 } 2476 2480 } … … 2954 2958 * Get the command buffer (volatile). 2955 2959 */ 2956 uint16_t const cbCmdBuf = pCmd->cbBuf; 2957 uint32_t const fCmdFlags = pCmd->fFlags; 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 2958 2966 const uint8_t RT_UNTRUSTED_VOLATILE_GUEST *pbCmdBuf; 2959 2967 PGMPAGEMAPLOCK Lock; … … 2962 2970 { 2963 2971 pbCmdBuf = VBOXVDMACBUF_DR_TAIL(pCmd, const uint8_t); 2964 rc = VINF_SUCCESS;2965 2972 AssertBreakStmt((uintptr_t)&pbCmdBuf[cbCmdBuf] <= (uintptr_t)&((uint8_t *)pCmd)[cbCmd], 2966 2973 rc = VERR_INVALID_PARAMETER); 2974 RT_UNTRUSTED_VALIDATED_FENCE(); 2967 2975 } 2968 2976 else if (fCmdFlags & VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET) 2969 2977 { 2970 uint64_t const offVRam = pCmd->Location.offVramBuf; 2971 ASMCompilerBarrier(); 2972 AssertBreakStmt( offVRam <= pVdma->pVGAState->vram_size 2973 && offVRam + cbCmdBuf <= pVdma->pVGAState->vram_size, 2978 AssertBreakStmt( offVramBuf_or_GCPhysBuf <= pVdma->pVGAState->vram_size 2979 && offVramBuf_or_GCPhysBuf + cbCmdBuf <= pVdma->pVGAState->vram_size, 2974 2980 rc = VERR_INVALID_PARAMETER); 2975 pbCmdBuf = (uint8_t const RT_UNTRUSTED_VOLATILE_GUEST *)pVdma->pVGAState->vram_ptrR3 + offVRam;2976 rc = VINF_SUCCESS;2981 RT_UNTRUSTED_VALIDATED_FENCE(); 2982 pbCmdBuf = (uint8_t const RT_UNTRUSTED_VOLATILE_GUEST *)pVdma->pVGAState->vram_ptrR3 + offVramBuf_or_GCPhysBuf; 2977 2983 } 2978 2984 else 2979 2985 { 2980 2986 /* Make sure it doesn't cross a page. */ 2981 RTGCPHYS GCPhysBuf = pCmd->Location.phBuf; 2982 AssertBreakStmt((uint32_t)(GCPhysBuf & X86_PAGE_OFFSET_MASK) + cbCmdBuf <= (uint32_t)X86_PAGE_SIZE, 2987 AssertBreakStmt((uint32_t)(offVramBuf_or_GCPhysBuf & X86_PAGE_OFFSET_MASK) + cbCmdBuf <= (uint32_t)X86_PAGE_SIZE, 2983 2988 rc = VERR_INVALID_PARAMETER); 2984 2985 rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pVdma->pVGAState->pDevInsR3, GCPhysBuf, 0 /*fFlags*/, 2989 RT_UNTRUSTED_VALIDATED_FENCE(); 2990 2991 rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pVdma->pVGAState->pDevInsR3, offVramBuf_or_GCPhysBuf, 0 /*fFlags*/, 2986 2992 (const void **)&pbCmdBuf, &Lock); 2987 2993 AssertRCBreak(rc); /* if (rc == VERR_PGM_PHYS_PAGE_RESERVED) -> fall back on using PGMPhysRead ?? */ … … 3169 3175 3170 3176 VBOXVDMA_CTL_TYPE enmCtl = pCmd->enmCtl; 3171 ASMCompilerBarrier(); 3172 switch (enmCtl) 3173 { 3174 case VBOXVDMA_CTL_TYPE_ENABLE: 3175 pCmd->i32Result = VINF_SUCCESS; 3176 break; 3177 case VBOXVDMA_CTL_TYPE_DISABLE: 3178 pCmd->i32Result = VINF_SUCCESS; 3179 break; 3180 case VBOXVDMA_CTL_TYPE_FLUSH: 3181 pCmd->i32Result = VINF_SUCCESS; 3182 break; 3177 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); 3178 if (enmCtl < VBOXVDMA_CTL_TYPE_END) 3179 { 3180 RT_UNTRUSTED_VALIDATED_FENCE(); 3181 3182 switch (enmCtl) 3183 { 3184 case VBOXVDMA_CTL_TYPE_ENABLE: 3185 pCmd->i32Result = VINF_SUCCESS; 3186 break; 3187 case VBOXVDMA_CTL_TYPE_DISABLE: 3188 pCmd->i32Result = VINF_SUCCESS; 3189 break; 3190 case VBOXVDMA_CTL_TYPE_FLUSH: 3191 pCmd->i32Result = VINF_SUCCESS; 3192 break; 3183 3193 #ifdef VBOX_VDMA_WITH_WATCHDOG 3184 case VBOXVDMA_CTL_TYPE_WATCHDOG:3185 pCmd->i32Result = vboxVDMAWatchDogCtl(pVdma, pCmd->u32Offset);3186 break;3194 case VBOXVDMA_CTL_TYPE_WATCHDOG: 3195 pCmd->i32Result = vboxVDMAWatchDogCtl(pVdma, pCmd->u32Offset); 3196 break; 3187 3197 #endif 3188 default: 3189 WARN(("cmd not supported")); 3190 pCmd->i32Result = VERR_NOT_SUPPORTED; 3191 break; 3198 default: 3199 WARN(("cmd not supported")); 3200 pCmd->i32Result = VERR_NOT_SUPPORTED; 3201 break; 3202 } 3203 } 3204 else 3205 { 3206 RT_UNTRUSTED_VALIDATED_FENCE(); 3207 WARN(("cmd not supported")); 3208 pCmd->i32Result = VERR_NOT_SUPPORTED; 3192 3209 } 3193 3210 … … 3206 3223 { 3207 3224 #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 3208 3232 /* chromium commands are processed by crhomium hgcm thread independently from our internal cmd processing pipeline 3209 3233 * this is why we process them specially */ … … 3212 3236 return; 3213 3237 3214 if (RT_FAILURE(rc)) 3238 if (RT_SUCCESS(rc)) 3239 vboxVDMACommandProcess(pVdma, pCmd, cbCmd); 3240 else 3215 3241 { 3216 3242 pCmd->rc = rc; 3217 3243 rc = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmd); 3218 3244 AssertRC(rc); 3219 return; 3220 } 3221 3222 vboxVDMACommandProcess(pVdma, pCmd, cbCmd); 3223 3245 } 3224 3246 #else 3225 3247 RT_NOREF(cbCmd);
Note:
See TracChangeset
for help on using the changeset viewer.