VirtualBox

Changeset 55844 in vbox


Ignore:
Timestamp:
May 13, 2015 12:46:52 PM (10 years ago)
Author:
vboxsync
Message:

DevVGA: screen resize cleanup, logging

Location:
trunk/src/VBox/Devices/Graphics
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA.h

    r55795 r55844  
    661661void VBVARaiseIrqNoWait(PVGASTATE pVGAState, uint32_t fFlags);
    662662
    663 int VBVAInfoView(PVGASTATE pVGAState, VBVAINFOVIEW *pView);
    664 int VBVAInfoScreen(PVGASTATE pVGAState, VBVAINFOSCREEN *pScreen);
     663int VBVAInfoView(PVGASTATE pVGAState, const VBVAINFOVIEW *pView);
     664int VBVAInfoScreen(PVGASTATE pVGAState, const VBVAINFOSCREEN *pScreen);
    665665int VBVAGetInfoViewAndScreen(PVGASTATE pVGAState, uint32_t u32ViewIndex, VBVAINFOVIEW *pView, VBVAINFOSCREEN *pScreen);
    666666
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r55560 r55844  
    19911991}
    19921992
    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                      pView->u32ViewIndex, pView->u32ViewOffset, pView->u32ViewSize, pView->u32MaxScreenSize));
     1993int 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));
    19971997
    19981998    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
     2017int 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
    20162024    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
    20302029        && pScreen->u16BitsPerPixel <= 32
    20312030        && pScreen->u32Width <= UINT16_MAX
    20322031        && 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
    20482057    return VERR_INVALID_PARAMETER;
    20492058}
     
    22412250#endif
    22422251
    2243             if (cbBuffer < sizeof (VBVAINFOVIEW))
     2252            /* Expect at least one VBVAINFOVIEW structure. */
     2253            if (cbBuffer < sizeof(VBVAINFOVIEW))
    22442254            {
    22452255                rc = VERR_INVALID_PARAMETER;
     
    22482258
    22492259            /* Guest submits an array of VBVAINFOVIEW structures. */
    2250             VBVAINFOVIEW *pView = (VBVAINFOVIEW *)pvBuffer;
    2251 
     2260            const VBVAINFOVIEW *pView = (VBVAINFOVIEW *)pvBuffer;
    22522261            for (;
    2253                  cbBuffer >= sizeof (VBVAINFOVIEW);
    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);
    22582267                if (RT_FAILURE(rc))
    22592268                    break;
     
    22932302        case VBVA_INFO_SCREEN:
    22942303        {
    2295             if (cbBuffer < sizeof (VBVAINFOSCREEN))
    2296             {
    2297                 rc = VERR_INVALID_PARAMETER;
    2298                 break;
    2299             }
    2300 
    23012304#ifdef VBOX_WITH_CRHGSMI
    23022305            if (vboxCmdVBVAIsEnabled(pVGAState))
     
    23082311#endif
    23092312
    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;
    23122320            rc = VBVAInfoScreen(pVGAState, &Screen);
    23132321        } break;
  • trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp

    r55493 r55844  
    14371437}
    14381438
     1439static 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
    14391480static int vboxVDMACrGuestCtlResizeEntryProcess(struct VBOXVDMAHOST *pVdma, VBOXCMDVBVA_RESIZE_ENTRY *pEntry)
    14401481{
    14411482    PVGASTATE pVGAState = pVdma->pVGAState;
    14421483    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. */
    14431505    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 
    14751506    View.u32ViewOffset = 0;
    14761507    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);
    14871511
    14881512    for (int i = ASMBitFirstSet(aTargetMap, pVGAState->cMonitors);
     
    15201544        }
    15211545    }
    1522 
    1523     if (RT_FAILURE(rc))
    1524         return rc;
    1525 
    1526     Screen.u32ViewIndex = u32ViewIndex;
    15271546
    15281547    return rc;
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