Changeset 84132 in vbox for trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
- Timestamp:
- May 2, 2020 6:26:46 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r84131 r84132 580 580 #define IOMMU_DEV_TAB_ENTRY_QWORD_3_VALID_MASK UINT64_C(0xffc0000000000000) 581 581 /** Pointer to a device table entry. */ 582 typedef DEV_TAB_ENTRY_T *PDEV TAB_ENTRY_T;582 typedef DEV_TAB_ENTRY_T *PDEV_TAB_ENTRY_T; 583 583 /** Pointer to a const device table entry. */ 584 584 typedef DEV_TAB_ENTRY_T const *PCDEV_TAB_ENTRY_T; … … 1310 1310 struct 1311 1311 { 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). */ 1314 1313 RT_GCC_EXTENSION uint64_t u12Rsvd1 : 12; /**< Bits 63:52 - Reserved. */ 1315 1314 } n; … … 1318 1317 } IOMMU_EXCL_RANGE_LIMIT_T; 1319 1318 AssertCompileSize(IOMMU_EXCL_RANGE_LIMIT_T, 8); 1320 #define IOMMU_EXCL_RANGE_LIMIT_VALID_MASK UINT64_C(0x000ffffffffff 000)1319 #define IOMMU_EXCL_RANGE_LIMIT_VALID_MASK UINT64_C(0x000fffffffffffff) 1321 1320 1322 1321 /** … … 2548 2547 { 2549 2548 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; 2551 2552 return VINF_SUCCESS; 2552 2553 } … … 3405 3406 3406 3407 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 */ 3418 static 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 3407 3438 /** 3408 3439 * Reads a device table entry from guest memory given the device ID. … … 3416 3447 * @thread Any. 3417 3448 */ 3418 static int iommuAmdReadDevTabEntry(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, DEV_TAB_ENTRY_T *pDevTabEntry)3449 static int iommuAmdReadDevTabEntry(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, PDEV_TAB_ENTRY_T pDevTabEntry) 3419 3450 { 3420 3451 PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); … … 3490 3521 } 3491 3522 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 } 3494 3529 } 3495 3530 } … … 3774 3809 pHlp->pfnPrintf(pHlp, " Exclusion Range Limit = %#RX64\n", ExclRangeLimit.u64); 3775 3810 if (fVerbose) 3776 pHlp->pfnPrintf(pHlp, " Range limit = %#RX64\n", ExclRangeLimit.n.u 40ExclLimit);3811 pHlp->pfnPrintf(pHlp, " Range limit = %#RX64\n", ExclRangeLimit.n.u52ExclLimit); 3777 3812 } 3778 3813 /* Extended Feature Register. */
Note:
See TracChangeset
for help on using the changeset viewer.