VirtualBox

Ignore:
Timestamp:
May 2, 2020 6:26:46 PM (5 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Exclusion range.

File:
1 edited

Legend:

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

    r84131 r84132  
    580580#define IOMMU_DEV_TAB_ENTRY_QWORD_3_VALID_MASK      UINT64_C(0xffc0000000000000)
    581581/** Pointer to a device table entry. */
    582 typedef DEV_TAB_ENTRY_T *PDEVTAB_ENTRY_T;
     582typedef DEV_TAB_ENTRY_T *PDEV_TAB_ENTRY_T;
    583583/** Pointer to a const device table entry. */
    584584typedef DEV_TAB_ENTRY_T const *PCDEV_TAB_ENTRY_T;
     
    13101310    struct
    13111311    {
    1312         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;      /**< Bits 11:0  - Reserved. */
    1313         RT_GCC_EXTENSION uint64_t   u40ExclLimit : 40;  /**< Bits 51:12 - Exclusion Range Limit. */
     1312        RT_GCC_EXTENSION uint64_t   u52ExclLimit : 52;  /**< Bits 51:0 - Exclusion Range Limit (last 12 bits are treated as 1s). */
    13141313        RT_GCC_EXTENSION uint64_t   u12Rsvd1 : 12;      /**< Bits 63:52 - Reserved. */
    13151314    } n;
     
    13181317} IOMMU_EXCL_RANGE_LIMIT_T;
    13191318AssertCompileSize(IOMMU_EXCL_RANGE_LIMIT_T, 8);
    1320 #define IOMMU_EXCL_RANGE_LIMIT_VALID_MASK   UINT64_C(0x000ffffffffff000)
     1319#define IOMMU_EXCL_RANGE_LIMIT_VALID_MASK   UINT64_C(0x000fffffffffffff)
    13211320
    13221321/**
     
    25482547{
    25492548    RT_NOREF(pDevIns, iReg);
    2550     pThis->ExclRangeLimit.u64 = u64Value & IOMMU_EXCL_RANGE_LIMIT_VALID_MASK;
     2549    u64Value &= IOMMU_EXCL_RANGE_LIMIT_VALID_MASK;
     2550    u64Value |= UINT64_C(0xfff);
     2551    pThis->ExclRangeLimit.u64 = u64Value;
    25512552    return VINF_SUCCESS;
    25522553}
     
    34053406
    34063407
     3408
     3409/**
     3410 * Returns whether the device virtual address is allowed to be excluded from
     3411 * translation and permission checks.
     3412 *
     3413 * @returns @c true if the DVA is excluded, @c false otherwise.
     3414 * @param   pThis           The IOMMU device state.
     3415 * @param   pDevTabEntry    The device table entry.
     3416 * @param   uDva            The device virtual address.
     3417 */
     3418static bool iommuAmdIsDvaSubjectToExclRange(PCIOMMU pThis, PCDEV_TAB_ENTRY_T pDevTabEntry, uint64_t uDva)
     3419{
     3420    /* Check if the exclusion range is enabled. */
     3421    if (pThis->ExclRangeBaseAddr.n.u1ExclEnable)
     3422    {
     3423        /* Check if the device virtual address falls within the exclusion range. */
     3424        uint64_t const uDvaExclFirst = pThis->ExclRangeBaseAddr.n.u40ExclRangeBase << X86_PAGE_4K_SHIFT;
     3425        uint64_t const uDvaExclLast  = pThis->ExclRangeLimit.n.u52ExclLimit;
     3426        if (uDvaExclLast - uDva >= uDvaExclFirst)
     3427        {
     3428            /* Check if device access to addresses in the exclusion can be forwarded untranslated. */
     3429            if (    pThis->ExclRangeBaseAddr.n.u1AllowAll
     3430                ||  pDevTabEntry->n.u1AllowExclusion)
     3431                return true;
     3432        }
     3433    }
     3434    return false;
     3435}
     3436
     3437
    34073438/**
    34083439 * Reads a device table entry from guest memory given the device ID.
     
    34163447 * @thread  Any.
    34173448 */
    3418 static int iommuAmdReadDevTabEntry(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, DEV_TAB_ENTRY_T *pDevTabEntry)
     3449static int iommuAmdReadDevTabEntry(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, PDEV_TAB_ENTRY_T pDevTabEntry)
    34193450{
    34203451    PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     
    34903521                }
    34913522
    3492                 /** @todo IOMMU: Traverse the I/O page table and translate. */
    3493                 return VERR_NOT_IMPLEMENTED;
     3523                /* Check if the exclusion range is active. */
     3524                if (!iommuAmdIsDvaSubjectToExclRange(pThis, &DevTabEntry, uDva))
     3525                {
     3526                    /** @todo IOMMU: Traverse the I/O page table and translate. */
     3527                    return VERR_NOT_IMPLEMENTED;
     3528                }
    34943529            }
    34953530        }
     
    37743809        pHlp->pfnPrintf(pHlp, "  Exclusion Range Limit                   = %#RX64\n", ExclRangeLimit.u64);
    37753810        if (fVerbose)
    3776             pHlp->pfnPrintf(pHlp, "    Range limit                             = %#RX64\n", ExclRangeLimit.n.u40ExclLimit);
     3811            pHlp->pfnPrintf(pHlp, "    Range limit                             = %#RX64\n", ExclRangeLimit.n.u52ExclLimit);
    37773812    }
    37783813    /* Extended Feature Register. */
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