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/VMMR0/PDMR0DevHlpTracing.cpp

    r86661 r87371  
    323323        Assert(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses));
    324324        PPDMPCIBUSR0 pBus = &pGVM->pdmr0.s.aPciBuses[idxBus];
    325 
    326         RTGCPHYS GCPhysOut;
    327325        uint16_t const uDeviceId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    328         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut);
    329         if (RT_SUCCESS(rc))
    330             GCPhys = GCPhysOut;
    331         else
     326        int rc = VINF_SUCCESS;
     327        while (cbRead > 0)
    332328        {
    333             Log(("pdmR0DevHlp_PCIPhysRead: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId,
    334                  GCPhys, cbRead, rc));
    335             return rc;
     329            RTGCPHYS GCPhysOut;
     330            size_t   cbContig;
     331            rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut, &cbContig);
     332            if (RT_SUCCESS(rc))
     333            {
     334                /** @todo Handle strict return codes from PGMPhysRead. */
     335                rc = pDevIns->pHlpR0->pfnPhysRead(pDevIns, GCPhysOut, pvBuf, cbRead, fFlags);
     336                if (RT_SUCCESS(rc))
     337                {
     338                    cbRead -= cbContig;
     339                    pvBuf   = (void *)((uintptr_t)pvBuf + cbContig);
     340                    GCPhys += cbContig;
     341                }
     342                else
     343                    break;
     344            }
     345            else
     346            {
     347                Log(("pdmR0DevHlp_PCIPhysRead: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId,
     348                     GCPhys, cbRead, rc));
     349                break;
     350            }
    336351        }
     352        return rc;
    337353    }
    338354#endif
     
    377393        Assert(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses));
    378394        PPDMPCIBUSR0 pBus = &pGVM->pdmr0.s.aPciBuses[idxBus];
    379 
    380         RTGCPHYS GCPhysOut;
    381395        uint16_t const uDeviceId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    382         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut);
    383         if (RT_SUCCESS(rc))
    384             GCPhys = GCPhysOut;
    385         else
     396        int rc = VINF_SUCCESS;
     397        while (cbWrite > 0)
    386398        {
    387             Log(("pdmR0DevHlp_PCIPhysWrite: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId,
    388                  GCPhys, cbWrite, rc));
    389             return rc;
     399            RTGCPHYS GCPhysOut;
     400            size_t   cbContig;
     401            rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig);
     402            if (RT_SUCCESS(rc))
     403            {
     404                /** @todo Handle strict return codes from PGMPhysWrite. */
     405                rc = pDevIns->pHlpR0->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbWrite, fFlags);
     406                if (RT_SUCCESS(rc))
     407                {
     408                    cbWrite -= cbContig;
     409                    pvBuf    = (const void *)((uintptr_t)pvBuf + cbContig);
     410                    GCPhys  += cbContig;
     411                }
     412                else
     413                    break;
     414            }
     415            else
     416            {
     417                Log(("pdmR0DevHlp_PCIPhysWrite: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId,
     418                     GCPhys, cbWrite, rc));
     419                break;
     420            }
    390421        }
     422        return rc;
    391423    }
    392424#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