VirtualBox

Ignore:
Timestamp:
Jan 22, 2021 2:42:17 PM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Handle the case where an access might result in non-contiguous physical addresses after address translation via the IOMMU.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlpTracing.cpp

    r86661 r87371  
    429429        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    430430        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    431 
    432         RTGCPHYS GCPhysOut;
    433431        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    434         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut);
    435         if (RT_SUCCESS(rc))
    436             GCPhys = GCPhysOut;
    437         else
     432        int rc = VINF_SUCCESS;
     433        while (cbRead > 0)
    438434        {
    439             Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
    440                  cbRead, rc));
    441             return rc;
     435            RTGCPHYS GCPhysOut;
     436            size_t   cbContig;
     437            rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut, &cbContig);
     438            if (RT_SUCCESS(rc))
     439            {
     440                /** @todo Handle strict return codes from PGMPhysRead. */
     441                rc = pDevIns->pHlpR3->pfnPhysRead(pDevIns, GCPhysOut, pvBuf, cbRead, fFlags);
     442                if (RT_SUCCESS(rc))
     443                {
     444                    cbRead -= cbContig;
     445                    pvBuf   = (void *)((uintptr_t)pvBuf + cbContig);
     446                    GCPhys += cbContig;
     447                }
     448                else
     449                    break;
     450            }
     451            else
     452            {
     453                Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
     454                     cbRead, rc));
     455                break;
     456            }
    442457        }
    443 
    444         GCPhys = GCPhysOut;
     458        return rc;
    445459    }
    446460#endif
     
    485499        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    486500        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    487 
    488         RTGCPHYS GCPhysOut;
    489501        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    490         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, & GCPhysOut);
    491         if (RT_SUCCESS(rc))
    492             GCPhys = GCPhysOut;
    493         else
     502        int rc = VINF_SUCCESS;
     503        while (cbWrite > 0)
    494504        {
    495             Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
    496                  cbWrite, rc));
    497             return rc;
     505            RTGCPHYS GCPhysOut;
     506            size_t   cbContig;
     507            rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig);
     508            if (RT_SUCCESS(rc))
     509            {
     510                /** @todo Handle strict return codes from PGMPhysWrite. */
     511                rc = pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbContig, fFlags);
     512                if (RT_SUCCESS(rc))
     513                {
     514                    cbWrite -= cbContig;
     515                    pvBuf    = (const void *)((uintptr_t)pvBuf + cbContig);
     516                    GCPhys  += cbContig;
     517                }
     518                else
     519                    break;
     520            }
     521            else
     522            {
     523                Log(("pdmR3DevHlp_PCIPhysWrite: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
     524                     cbWrite, rc));
     525                break;
     526            }
    498527        }
    499 
    500         GCPhys = GCPhysOut;
     528        return rc;
    501529    }
    502530#endif
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