VirtualBox

Changeset 84237 in vbox


Ignore:
Timestamp:
May 10, 2020 7:07:40 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137845
Message:

AMD IOMMU: bugref:9654 Multi-page I/O page walk bits.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r84236 r84237  
    42664266        iommuAmdInitIotlbe(NIL_RTGCPHYS, 0 /* cShift */, IOMMU_IO_PERM_NONE, &Iotlbe);
    42674267
    4268         uint64_t cbChecked = 0;
    4269         uint64_t uBaseIova = uIova & X86_PAGE_4K_BASE_MASK;
     4268        uint64_t uBaseIova   = uIova & X86_PAGE_4K_BASE_MASK;
     4269        uint64_t offIova     = uIova & X86_PAGE_4K_OFFSET_MASK;
     4270        uint64_t cbRemaining = cbAccess;
    42704271        for (;;)
    42714272        {
    4272             /* Walk the I/O page tables to translate and get permission bits for the IOVA access. */
     4273            /* Walk the I/O page tables to translate the IOVA and check permission for the access. */
    42734274            rc = iommuAmdWalkIoPageTables(pDevIns, uDevId, uBaseIova, fAccess, &Dte, enmOp, &Iotlbe);
    42744275            if (RT_SUCCESS(rc))
    42754276            {
    4276                 /* Record the translated base address (before continuing to check permission bits of any subsequent pages). */
    4277                 if (cbChecked == 0)
     4277                /* Store the translated base address before continuing to check permissions for any more pages. */
     4278                if (cbRemaining == cbAccess)
    42784279                {
    42794280                    RTGCPHYS const offSpa = ~(UINT64_C(0xffffffffffffffff) << Iotlbe.cShift);
     
    42844285
    42854286                uint64_t const cbPhysPage = UINT64_C(1) << Iotlbe.cShift;
    4286                 cbChecked += cbPhysPage;        /** @todo IOMMU: We need to consider the offset here. */
    4287                 if (cbChecked >= cbAccess)
     4287                if (cbRemaining > cbPhysPage - offIova)
     4288                {
     4289                    cbRemaining -= (cbPhysPage - offIova);
     4290                    uBaseIova   += cbPhysPage;
     4291                    offIova      = 0;
     4292                }
     4293                else
    42884294                    break;
    4289                 uBaseIova += cbPhysPage;
    42904295            }
    42914296            else
    42924297            {
    4293                 Log((IOMMU_LOG_PFX ": I/O page table walk failed. uIova=%#RX64 uBaseIova=%#RX64 fAccess=%u rc=%Rrc\n",
    4294                      uIova, uBaseIova, fAccess, rc));
     4298                Log((IOMMU_LOG_PFX ": I/O page table walk failed. uIova=%#RX64 uBaseIova=%#RX64 fAccess=%u rc=%Rrc\n", uIova,
     4299                     uBaseIova, fAccess, rc));
    42954300                *pGCPhysSpa = NIL_RTGCPHYS;
    42964301                return rc;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette