Changeset 55844 in vbox
- Timestamp:
- May 13, 2015 12:46:52 PM (10 years ago)
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA.h
r55795 r55844 661 661 void VBVARaiseIrqNoWait(PVGASTATE pVGAState, uint32_t fFlags); 662 662 663 int VBVAInfoView(PVGASTATE pVGAState, VBVAINFOVIEW *pView);664 int VBVAInfoScreen(PVGASTATE pVGAState, VBVAINFOSCREEN *pScreen);663 int VBVAInfoView(PVGASTATE pVGAState, const VBVAINFOVIEW *pView); 664 int VBVAInfoScreen(PVGASTATE pVGAState, const VBVAINFOSCREEN *pScreen); 665 665 int VBVAGetInfoViewAndScreen(PVGASTATE pVGAState, uint32_t u32ViewIndex, VBVAINFOVIEW *pView, VBVAINFOSCREEN *pScreen); 666 666 -
trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
r55560 r55844 1991 1991 } 1992 1992 1993 int VBVAInfoView(PVGASTATE pVGAState, VBVAINFOVIEW *pView)1994 { 1995 LogFlowFunc(("VBVA_INFO_VIEW: index %d, offset 0x%x, size 0x%x, max screen size 0x%x\n",1996 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 1997 1998 1998 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 1999 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext (pIns); 2000 2001 /* @todo verify view data. */ 2002 if (pView->u32ViewIndex >= pCtx->cViews) 2003 { 2004 Log(("View index too large %d!!!\n", 2005 pView->u32ViewIndex)); 2006 return VERR_INVALID_PARAMETER; 2007 } 2008 2009 pCtx->aViews[pView->u32ViewIndex].view = *pView; 2010 2011 return VINF_SUCCESS; 2012 } 2013 2014 int VBVAInfoScreen(PVGASTATE pVGAState, VBVAINFOSCREEN *pScreen) 2015 { 1999 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns); 2000 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)); 2023 2016 2024 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 2017 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext (pIns); 2018 VBVAINFOVIEW *pView = &pCtx->aViews[pScreen->u32ViewIndex].view; 2019 /* Calculate the offset of the end of the screen so we can make 2020 * sure it is inside the view. I assume that screen rollover is not 2021 * implemented. */ 2022 int64_t offEnd = (int64_t)pScreen->u32Height * pScreen->u32LineSize 2023 + pScreen->u32Width + pScreen->u32StartOffset; 2024 LogRel(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n", 2025 pScreen->u32ViewIndex, pScreen->i32OriginX, pScreen->i32OriginY, 2026 pScreen->u32Width, pScreen->u32Height, 2027 pScreen->u32LineSize, pScreen->u16BitsPerPixel, pScreen->u16Flags)); 2028 2029 if ( pScreen->u32ViewIndex < RT_ELEMENTS (pCtx->aViews) 2025 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns); 2026 2027 /* Allow pScreen->u16BitsPerPixel == 0 because legacy guest code used it for screen blanking. */ 2028 if ( pScreen->u32ViewIndex < pCtx->cViews 2030 2029 && pScreen->u16BitsPerPixel <= 32 2031 2030 && pScreen->u32Width <= UINT16_MAX 2032 2031 && pScreen->u32Height <= UINT16_MAX 2033 && pScreen->u32LineSize <= UINT16_MAX * 4 2034 && offEnd < pView->u32MaxScreenSize) 2035 { 2036 vbvaResize (pVGAState, &pCtx->aViews[pScreen->u32ViewIndex], pScreen); 2037 return VINF_SUCCESS; 2038 } 2039 2040 LogRelFlow(("VBVA_INFO_SCREEN [%lu]: bad data: %lux%lu, line 0x%lx, BPP %u, start offset %lu, max screen size %lu\n", 2041 (unsigned long)pScreen->u32ViewIndex, 2042 (unsigned long)pScreen->u32Width, 2043 (unsigned long)pScreen->u32Height, 2044 (unsigned long)pScreen->u32LineSize, 2045 (unsigned long)pScreen->u16BitsPerPixel, 2046 (unsigned long)pScreen->u32StartOffset, 2047 (unsigned long)pView->u32MaxScreenSize)); 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 2040 && u64ScreenSize <= pView->u32MaxScreenSize 2041 && pScreen->u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize) 2042 { 2043 vbvaResize(pVGAState, &pCtx->aViews[pScreen->u32ViewIndex], pScreen); 2044 return VINF_SUCCESS; 2045 } 2046 2047 LogRelFlow(("VBVA_INFO_SCREEN: invalid data: size 0x%RX64, max 0x%RX32\n", 2048 u64ScreenSize, pView->u32MaxScreenSize)); 2049 } 2050 } 2051 else 2052 { 2053 LogRelFlow(("VBVA_INFO_SCREEN: invalid data: index %RU32(%RU32)\n", 2054 pScreen->u32ViewIndex, pCtx->cViews)); 2055 } 2056 2048 2057 return VERR_INVALID_PARAMETER; 2049 2058 } … … 2241 2250 #endif 2242 2251 2243 if (cbBuffer < sizeof (VBVAINFOVIEW)) 2252 /* Expect at least one VBVAINFOVIEW structure. */ 2253 if (cbBuffer < sizeof(VBVAINFOVIEW)) 2244 2254 { 2245 2255 rc = VERR_INVALID_PARAMETER; … … 2248 2258 2249 2259 /* Guest submits an array of VBVAINFOVIEW structures. */ 2250 VBVAINFOVIEW *pView = (VBVAINFOVIEW *)pvBuffer; 2251 2260 const VBVAINFOVIEW *pView = (VBVAINFOVIEW *)pvBuffer; 2252 2261 for (; 2253 cbBuffer >= sizeof 2254 pView++, cbBuffer -= sizeof(VBVAINFOVIEW))2255 { 2256 VBVAINFOVIEW View = *pView;2257 rc = VBVAInfoView(pVGAState, & View);2262 cbBuffer >= sizeof(VBVAINFOVIEW); 2263 ++pView, cbBuffer -= sizeof(VBVAINFOVIEW)) 2264 { 2265 VBVAINFOVIEW view = *pView; 2266 rc = VBVAInfoView(pVGAState, &view); 2258 2267 if (RT_FAILURE(rc)) 2259 2268 break; … … 2293 2302 case VBVA_INFO_SCREEN: 2294 2303 { 2295 if (cbBuffer < sizeof (VBVAINFOSCREEN))2296 {2297 rc = VERR_INVALID_PARAMETER;2298 break;2299 }2300 2301 2304 #ifdef VBOX_WITH_CRHGSMI 2302 2305 if (vboxCmdVBVAIsEnabled(pVGAState)) … … 2308 2311 #endif 2309 2312 2310 VBVAINFOSCREEN *pScreen = (VBVAINFOSCREEN *)pvBuffer; 2311 VBVAINFOSCREEN Screen = *pScreen; 2313 if (cbBuffer < sizeof(VBVAINFOSCREEN)) 2314 { 2315 rc = VERR_INVALID_PARAMETER; 2316 break; 2317 } 2318 2319 VBVAINFOSCREEN Screen = *(VBVAINFOSCREEN *)pvBuffer; 2312 2320 rc = VBVAInfoScreen(pVGAState, &Screen); 2313 2321 } break; -
trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
r55493 r55844 1437 1437 } 1438 1438 1439 static int vboxVDMASetupScreenInfo(PVGASTATE pVGAState, VBVAINFOSCREEN *pScreen) 1440 { 1441 const uint32_t u32ViewIndex = pScreen->u32ViewIndex; 1442 const bool fDisabled = RT_BOOL(pScreen->u16Flags & VBVA_SCREEN_F_DISABLED); 1443 1444 if (fDisabled) 1445 { 1446 if ( u32ViewIndex < pVGAState->cMonitors 1447 || u32ViewIndex == UINT32_C(0xFFFFFFFF)) 1448 { 1449 RT_ZERO(*pScreen); 1450 pScreen->u32ViewIndex = u32ViewIndex; 1451 pScreen->u16Flags = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED; 1452 return VINF_SUCCESS; 1453 } 1454 } 1455 else 1456 { 1457 if ( u32ViewIndex < pVGAState->cMonitors 1458 && pScreen->u16BitsPerPixel <= 32 1459 && pScreen->u32Width <= UINT16_MAX 1460 && pScreen->u32Height <= UINT16_MAX 1461 && pScreen->u32LineSize <= UINT16_MAX * 4) 1462 { 1463 const uint32_t u32BytesPerPixel = (pScreen->u16BitsPerPixel + 7) / 8; 1464 if (pScreen->u32Width <= pScreen->u32LineSize / (u32BytesPerPixel? u32BytesPerPixel: 1)) 1465 { 1466 const uint64_t u64ScreenSize = (uint64_t)pScreen->u32LineSize * pScreen->u32Height; 1467 if ( pScreen->u32StartOffset <= pVGAState->vram_size 1468 && u64ScreenSize <= pVGAState->vram_size 1469 && pScreen->u32StartOffset <= pVGAState->vram_size - (uint32_t)u64ScreenSize) 1470 { 1471 return VINF_SUCCESS; 1472 } 1473 } 1474 } 1475 } 1476 1477 return VERR_INVALID_PARAMETER; 1478 } 1479 1439 1480 static int vboxVDMACrGuestCtlResizeEntryProcess(struct VBOXVDMAHOST *pVdma, VBOXCMDVBVA_RESIZE_ENTRY *pEntry) 1440 1481 { 1441 1482 PVGASTATE pVGAState = pVdma->pVGAState; 1442 1483 VBVAINFOSCREEN Screen = pEntry->Screen; 1484 1485 /* Verify and cleanup local copy of the input data. */ 1486 int rc = vboxVDMASetupScreenInfo(pVGAState, &Screen); 1487 if (RT_FAILURE(rc)) 1488 { 1489 WARN(("invalid screen data\n")); 1490 return rc; 1491 } 1492 1493 VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aTargetMap); 1494 memcpy(aTargetMap, pEntry->aTargetMap, sizeof(aTargetMap)); 1495 ASMBitClearRange(aTargetMap, pVGAState->cMonitors, VBOX_VIDEO_MAX_SCREENS); 1496 1497 rc = pVdma->CrSrvInfo.pfnResize(pVdma->CrSrvInfo.hSvr, &Screen, aTargetMap); 1498 if (RT_FAILURE(rc)) 1499 { 1500 WARN(("pfnResize failed %d\n", rc)); 1501 return rc; 1502 } 1503 1504 /* A fake view which contains the current screen for the 2D VBVAInfoView. */ 1443 1505 VBVAINFOVIEW View; 1444 VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aTargetMap);1445 uint32_t u32ViewIndex = Screen.u32ViewIndex;1446 uint16_t u16Flags = Screen.u16Flags;1447 bool fDisable = false;1448 1449 memcpy(aTargetMap, pEntry->aTargetMap, sizeof (aTargetMap));1450 1451 ASMBitClearRange(aTargetMap, pVGAState->cMonitors, VBOX_VIDEO_MAX_SCREENS);1452 1453 if (u16Flags & VBVA_SCREEN_F_DISABLED)1454 {1455 fDisable = true;1456 memset(&Screen, 0, sizeof (Screen));1457 Screen.u32ViewIndex = u32ViewIndex;1458 Screen.u16Flags = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED;1459 }1460 1461 if (u32ViewIndex > pVGAState->cMonitors)1462 {1463 if (u32ViewIndex != 0xffffffff)1464 {1465 WARN(("invalid view index\n"));1466 return VERR_INVALID_PARAMETER;1467 }1468 else if (!fDisable)1469 {1470 WARN(("0xffffffff view index only valid for disable requests\n"));1471 return VERR_INVALID_PARAMETER;1472 }1473 }1474 1475 1506 View.u32ViewOffset = 0; 1476 1507 View.u32ViewSize = Screen.u32LineSize * Screen.u32Height + Screen.u32StartOffset; 1477 View.u32MaxScreenSize = View.u32ViewSize + Screen.u32Width + 1; /* <- make VBVAInfoScreen logic (offEnd < pView->u32MaxScreenSize) happy */ 1478 1479 int rc = VINF_SUCCESS; 1480 1481 rc = pVdma->CrSrvInfo.pfnResize(pVdma->CrSrvInfo.hSvr, &Screen, aTargetMap); 1482 if (RT_FAILURE(rc)) 1483 { 1484 WARN(("pfnResize failed %d\n", rc)); 1485 return rc; 1486 } 1508 View.u32MaxScreenSize = Screen.u32LineSize * Screen.u32Height; 1509 1510 const bool fDisable = RT_BOOL(Screen.u16Flags & VBVA_SCREEN_F_DISABLED); 1487 1511 1488 1512 for (int i = ASMBitFirstSet(aTargetMap, pVGAState->cMonitors); … … 1520 1544 } 1521 1545 } 1522 1523 if (RT_FAILURE(rc))1524 return rc;1525 1526 Screen.u32ViewIndex = u32ViewIndex;1527 1546 1528 1547 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.