VirtualBox

Changeset 87506 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Feb 1, 2021 3:18:35 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142530
Message:

AMD IOMMU: bugref:9654 IOTLB cache bits.

File:
1 edited

Legend:

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

    r87499 r87506  
    29122912
    29132913/**
     2914 * Checks whether two I/O walk results are physically contiguous.
     2915 *
     2916 * @returns @c true if they are physically contiguous, @c false otherwise.
     2917 * @param   pWalkResultPrev     The I/O walk result of the previous page.
     2918 * @param   pWalkResult         The I/O walk result of the current page.
     2919 */
     2920DECL_FORCE_INLINE(bool) iommuAmdDteLookupIsAddrPhysContig(PCIOWALKRESULT pWalkResultPrev, PCIOWALKRESULT pWalkResult)
     2921{
     2922    size_t const   cbPrev      = RT_BIT_64(pWalkResultPrev->cShift);
     2923    RTGCPHYS const GCPhysPrev  = pWalkResultPrev->GCPhysSpa;
     2924    RTGCPHYS const GCPhys      = pWalkResult->GCPhysSpa;
     2925    uint64_t const offMaskPrev = ~(UINT64_C(0xffffffffffffffff) << pWalkResultPrev->cShift);
     2926    uint64_t const offMask     = ~(UINT64_C(0xffffffffffffffff) << pWalkResult->cShift);
     2927
     2928    /* Paranoia: Ensure offset bits are 0. */
     2929    Assert(!(GCPhysPrev & offMaskPrev));
     2930    Assert(!(GCPhys     & offMask));
     2931
     2932    if ((GCPhysPrev & ~offMaskPrev) + cbPrev == (GCPhys & ~offMask))
     2933        return true;
     2934    return false;
     2935}
     2936
     2937
     2938/**
     2939 * Checks whether two I/O walk results form a "contiguous" access.
     2940 *
     2941 * When IOTLB caching is used, in addition to the translated system-physical
     2942 * addresses being physically contiguous, this function also verifies that the two
     2943 * pages are identical in terms of their page size and permissions.
     2944 *
     2945 * This is required to simplify IOTLB lookups for for large accesses (e.g. ATA
     2946 * device doing 65k transfers on Ubuntu 18.04 guests).
     2947 *
     2948 * @returns @c true if they are contiguous, @c false otherwise.
     2949 * @param   pWalkResultPrev     The I/O walk result of the previous page.
     2950 * @param   pWalkResult         The I/O walk result of the current page.
     2951 */
     2952DECL_FORCE_INLINE(bool) iommuAmdDteLookupIsAccessContig(PCIOWALKRESULT pWalkResultPrev, PCIOWALKRESULT pWalkResult)
     2953{
     2954#ifdef IOMMU_WITH_IOTLBE_CACHE
     2955    if (   pWalkResultPrev->cShift  == pWalkResult->cShift
     2956        && pWalkResultPrev->fIoPerm == pWalkResult->fIoPerm
     2957        && iommuAmdDteLookupIsAddrPhysContig(pWalkResultPrev, pWalkResult))
     2958        return true;
     2959    return false;
     2960#else
     2961    return iommuAmdDteLookupIsAddrPhysContig(pWalkResultPrev, pWalkResult);
     2962#endif
     2963}
     2964
     2965
     2966/**
    29142967 * Looks up an I/O virtual address from the device table.
    29152968 *
     
    29653018                        uint64_t offIova     = uIova & X86_PAGE_4K_OFFSET_MASK;
    29663019                        uint64_t cbPages     = 0;
    2967 #ifdef IOMMU_WITH_IOTLBE_CACHE
    29683020                        IOWALKRESULT WalkResultPrev;
    29693021                        RT_ZERO(WalkResultPrev);
    2970 #endif
    29713022                        for (;;)
    29723023                        {
     
    29803031                                    uint64_t const offMask = ~(UINT64_C(0xffffffffffffffff) << WalkResult.cShift);
    29813032                                    uint64_t const offSpa  = uIova & offMask;
     3033                                    Assert(!(WalkResult.GCPhysSpa & offMask));
    29823034                                    GCPhysSpa = WalkResult.GCPhysSpa | offSpa;
    2983 #ifdef IOMMU_WITH_IOTLBE_CACHE
     3035
    29843036                                    /* Store the walk result from the first page. */
    29853037                                    WalkResultPrev = WalkResult;
    2986 #endif
    29873038                                }
    2988 #ifdef IOMMU_WITH_IOTLBE_CACHE
    2989                                 /* Check if addresses translated so far result in a physically contiguous region
    2990                                    and that permissions and page sizes are identical for all pages in the access. */
    2991                                 else if (   (GCPhysSpa & X86_PAGE_4K_BASE_MASK) + cbPages == WalkResult.GCPhysSpa
    2992                                          && WalkResultPrev.cShift  == WalkResult.cShift
    2993                                          && WalkResultPrev.fIoPerm == WalkResult.fIoPerm)
    2994                                 {
    2995                                     /* Paranoia. */
    2996                                     Assert((WalkResultPrev.GCPhysSpa & X86_PAGE_4K_BASE_MASK)
    2997                                            + RT_BIT_64(WalkResultPrev.cShift) == WalkResult.GCPhysSpa);
    2998                                     /* Store the walk result before moving on to the next page. */
     3039                                /* Check if addresses translated so far result in a physically contiguous region. */
     3040                                else if (iommuAmdDteLookupIsAccessContig(&WalkResultPrev, &WalkResult))
    29993041                                    WalkResultPrev = WalkResult;
    3000                                 }
    3001 #else
    3002                                 /* Check if addresses translated so far result in a physically contiguous region. */
    3003                                 else if (   (GCPhysSpa & X86_PAGE_4K_BASE_MASK) + cbPages == WalkResult.GCPhysSpa)
    3004                                 { /* likely */ }
    3005 #endif
    30063042                                else
    30073043                                {
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