Changeset 84134 in vbox
- Timestamp:
- May 4, 2020 7:05:33 AM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 137724
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r84133 r84134 419 419 /** @} */ 420 420 421 /** @name IOMMU_PERM_XXX: IOMMU I/O access permissions bits. 422 * In accordance with the AMD spec. 423 * 424 * These values match the shifted values of the IR and IW field of the DTE and the 425 * PTE, PDE of the I/O page tables. 426 * 427 * @{ */ 428 #define IOMMU_IO_PERM_READ RT_BIT_64(0) 429 #define IOMMU_IO_PERM_WRITE RT_BIT_64(1) 430 #define IOMMU_IO_PERM_SHIFT 61 431 #define IOMMU_IO_PERM_MASK 0x3 432 /** @} */ 433 421 434 /** 422 435 * @name IOMMU Control Register Bits. … … 522 535 struct 523 536 { 524 uint32_t u1Valid : 1; /**< Bit 0 - V: Valid. */ 525 uint32_t u1TranslationValid : 1; /**< Bit 1 - TV: Translation information Valid. */ 526 uint32_t u5Rsvd0 : 5; /**< Bits 6:2 - Reserved. */ 527 uint32_t u2Had : 2; /**< Bits 8:7 - HAD: Host Access Dirty. */ 528 uint32_t u3Mode : 3; /**< Bits 11:9 - Mode: Paging mode. */ 529 uint32_t u20PageTableRootPtrLo : 20; /**< Bits 31:12 - Page Table Root Pointer (Lo). */ 530 uint32_t u20PageTableRootPtrHi : 20; /**< Bits 51:32 - Page Table Root Pointer (Hi). */ 531 uint32_t u1Ppr : 1; /**< Bit 52 - PPR: Peripheral Page Request. */ 532 uint32_t u1GstPprRespPasid : 1; /**< Bit 53 - GRPR: Guest PPR Response with PASID. */ 533 uint32_t u1GstIoValid : 1; /**< Bit 54 - GIoV: Guest I/O Protection Valid. */ 534 uint32_t u1GstTranslateValid : 1; /**< Bit 55 - GV: Guest translation Valid. */ 535 uint32_t u2GstCr3RootTblTranslated : 2; /**< Bits 57:56 - GLX: Guest Levels Translated. */ 536 uint32_t u3GstCr3TableRootPtrLo : 2; /**< Bits 60:58 - GCR3 TRP: Guest CR3 Table Root Pointer (Lo). */ 537 uint32_t u1IoRead : 1; /**< Bit 61 - IR: I/O Read permission. */ 538 uint32_t u1IoWrite : 1; /**< Bit 62 - IW: I/O Write permission. */ 539 uint32_t u1Rsvd0 : 1; /**< Bit 63 - Reserved. */ 540 uint32_t u16DomainId : 1; /**< Bits 79:64 - Domain ID. */ 541 uint32_t u16GstCr3TableRootPtrMed : 16; /**< Bits 95:80 - GCR3 TRP: Guest CR3 Table Root Pointer (Mid). */ 542 uint32_t u1IoTlbEnable : 1; /**< Bit 96 - I: IOTLB Enable. */ 543 uint32_t u1SuppressPfEvents : 1; /**< Bit 97 - SE: Supress Page-fault events. */ 544 uint32_t u1SuppressAllPfEvents : 1; /**< Bit 98 - SA: Supress All Page-fault events. */ 545 uint32_t u2IoCtl : 1; /**< Bits 100:99 - IoCtl: Port I/O Control. */ 546 uint32_t u1Cache : 1; /**< Bit 101 - Cache: IOTLB Cache Hint. */ 547 uint32_t u1SnoopDisable : 1; /**< Bit 102 - SD: Snoop Disable. */ 548 uint32_t u1AllowExclusion : 1; /**< Bit 103 - EX: Allow Exclusion. */ 549 uint32_t u2SysMgt : 2; /**< Bits 105:104 - SysMgt: System Management message enable. */ 550 uint32_t u1Rsvd1 : 1; /**< Bit 106 - Reserved. */ 551 uint32_t u21GstCr3TableRootPtrHi : 21; /**< Bits 127:107 - GCR3 TRP: Guest CR3 Table Root Pointer (Hi). */ 552 uint32_t u1IntrMapValid : 1; /**< Bit 128 - IV: Interrupt map Valid. */ 553 uint32_t u4IntrTableLength : 4; /**< Bits 132:129 - IntTabLen: Interrupt Table Length. */ 554 uint32_t u1IgnoreUnmappedIntrs : 1; /**< Bits 133 - IG: Ignore unmapped interrupts. */ 555 uint32_t u26IntrTableRootPtr : 26; /**< Bits 159:134 - Interrupt Root Table Pointer (Lo). */ 556 uint32_t u20IntrTableRootPtr : 20; /**< Bits 179:160 - Interrupt Root Table Pointer (Hi). */ 557 uint32_t u4Rsvd0 : 4; /**< Bits 183:180 - Reserved. */ 558 uint32_t u1InitPassthru : 1; /**< Bits 184 - INIT Pass-through. */ 559 uint32_t u1ExtIntPassthru : 1; /**< Bits 185 - External Interrupt Pass-through. */ 560 uint32_t u1NmiPassthru : 1; /**< Bits 186 - NMI Pass-through. */ 561 uint32_t u1Rsvd2 : 1; /**< Bits 187 - Reserved. */ 562 uint32_t u2IntrCtrl : 2; /**< Bits 189:188 - IntCtl: Interrupt Control. */ 563 uint32_t u1Lint0Passthru : 1; /**< Bit 190 - Lint0Pass: LINT0 (Legacy PIC NMI) Pass-thru. */ 564 uint32_t u1Lint1Passthru : 1; /**< Bit 191 - Lint1Pass: LINT1 (Legacy PIC NMI) Pass-thru. */ 565 uint32_t u32Rsvd0; /**< Bits 223:192 - Reserved. */ 566 uint32_t u22Rsvd0 : 22; /**< Bits 245:224 - Reserved. */ 567 uint32_t u1AttrOverride : 1; /**< Bit 246 - AttrV: Attribute Override. */ 568 uint32_t u1Mode0FC: 1; /**< Bit 247 - Mode0FC. */ 569 uint32_t u8SnoopAttr: 1; /**< Bits 255:248 - Snoop Attribute. */ 537 RT_GCC_EXTENSION uint64_t u1Valid : 1; /**< Bit 0 - V: Valid. */ 538 RT_GCC_EXTENSION uint64_t u1TranslationValid : 1; /**< Bit 1 - TV: Translation information Valid. */ 539 RT_GCC_EXTENSION uint64_t u5Rsvd0 : 5; /**< Bits 6:2 - Reserved. */ 540 RT_GCC_EXTENSION uint64_t u2Had : 2; /**< Bits 8:7 - HAD: Host Access Dirty. */ 541 RT_GCC_EXTENSION uint64_t u3Mode : 3; /**< Bits 11:9 - Mode: Paging mode. */ 542 RT_GCC_EXTENSION uint64_t u40PageTableRootPtrLo : 40; /**< Bits 51:12 - Page Table Root Pointer. */ 543 RT_GCC_EXTENSION uint64_t u1Ppr : 1; /**< Bit 52 - PPR: Peripheral Page Request. */ 544 RT_GCC_EXTENSION uint64_t u1GstPprRespPasid : 1; /**< Bit 53 - GRPR: Guest PPR Response with PASID. */ 545 RT_GCC_EXTENSION uint64_t u1GstIoValid : 1; /**< Bit 54 - GIoV: Guest I/O Protection Valid. */ 546 RT_GCC_EXTENSION uint64_t u1GstTranslateValid : 1; /**< Bit 55 - GV: Guest translation Valid. */ 547 RT_GCC_EXTENSION uint64_t u2GstCr3RootTblTranslated : 2; /**< Bits 57:56 - GLX: Guest Levels Translated. */ 548 RT_GCC_EXTENSION uint64_t u3GstCr3TableRootPtrLo : 2; /**< Bits 60:58 - GCR3 TRP: Guest CR3 Table Root Ptr (Lo). */ 549 RT_GCC_EXTENSION uint64_t u1IoRead : 1; /**< Bit 61 - IR: I/O Read permission. */ 550 RT_GCC_EXTENSION uint64_t u1IoWrite : 1; /**< Bit 62 - IW: I/O Write permission. */ 551 RT_GCC_EXTENSION uint64_t u1Rsvd0 : 1; /**< Bit 63 - Reserved. */ 552 RT_GCC_EXTENSION uint64_t u16DomainId : 1; /**< Bits 79:64 - Domain ID. */ 553 RT_GCC_EXTENSION uint64_t u16GstCr3TableRootPtrMed : 16; /**< Bits 95:80 - GCR3 TRP: Guest CR3 Table Root Ptr (Mid). */ 554 RT_GCC_EXTENSION uint64_t u1IoTlbEnable : 1; /**< Bit 96 - I: IOTLB Enable. */ 555 RT_GCC_EXTENSION uint64_t u1SuppressPfEvents : 1; /**< Bit 97 - SE: Supress Page-fault events. */ 556 RT_GCC_EXTENSION uint64_t u1SuppressAllPfEvents : 1; /**< Bit 98 - SA: Supress All Page-fault events. */ 557 RT_GCC_EXTENSION uint64_t u2IoCtl : 1; /**< Bits 100:99 - IoCtl: Port I/O Control. */ 558 RT_GCC_EXTENSION uint64_t u1Cache : 1; /**< Bit 101 - Cache: IOTLB Cache Hint. */ 559 RT_GCC_EXTENSION uint64_t u1SnoopDisable : 1; /**< Bit 102 - SD: Snoop Disable. */ 560 RT_GCC_EXTENSION uint64_t u1AllowExclusion : 1; /**< Bit 103 - EX: Allow Exclusion. */ 561 RT_GCC_EXTENSION uint64_t u2SysMgt : 2; /**< Bits 105:104 - SysMgt: System Management message enable. */ 562 RT_GCC_EXTENSION uint64_t u1Rsvd1 : 1; /**< Bit 106 - Reserved. */ 563 RT_GCC_EXTENSION uint64_t u21GstCr3TableRootPtrHi : 21; /**< Bits 127:107 - GCR3 TRP: Guest CR3 Table Root Ptr (Hi). */ 564 RT_GCC_EXTENSION uint64_t u1IntrMapValid : 1; /**< Bit 128 - IV: Interrupt map Valid. */ 565 RT_GCC_EXTENSION uint64_t u4IntrTableLength : 4; /**< Bits 132:129 - IntTabLen: Interrupt Table Length. */ 566 RT_GCC_EXTENSION uint64_t u1IgnoreUnmappedIntrs : 1; /**< Bits 133 - IG: Ignore unmapped interrupts. */ 567 RT_GCC_EXTENSION uint64_t u26IntrTableRootPtr : 26; /**< Bits 159:134 - Interrupt Root Table Pointer (Lo). */ 568 RT_GCC_EXTENSION uint64_t u20IntrTableRootPtr : 20; /**< Bits 179:160 - Interrupt Root Table Pointer (Hi). */ 569 RT_GCC_EXTENSION uint64_t u4Rsvd0 : 4; /**< Bits 183:180 - Reserved. */ 570 RT_GCC_EXTENSION uint64_t u1InitPassthru : 1; /**< Bits 184 - INIT Pass-through. */ 571 RT_GCC_EXTENSION uint64_t u1ExtIntPassthru : 1; /**< Bits 185 - External Interrupt Pass-through. */ 572 RT_GCC_EXTENSION uint64_t u1NmiPassthru : 1; /**< Bits 186 - NMI Pass-through. */ 573 RT_GCC_EXTENSION uint64_t u1Rsvd2 : 1; /**< Bits 187 - Reserved. */ 574 RT_GCC_EXTENSION uint64_t u2IntrCtrl : 2; /**< Bits 189:188 - IntCtl: Interrupt Control. */ 575 RT_GCC_EXTENSION uint64_t u1Lint0Passthru : 1; /**< Bit 190 - Lint0Pass: LINT0 Pass-through. */ 576 RT_GCC_EXTENSION uint64_t u1Lint1Passthru : 1; /**< Bit 191 - Lint1Pass: LINT1 Pass-through. */ 577 RT_GCC_EXTENSION uint64_t u32Rsvd0 : 32; /**< Bits 223:192 - Reserved. */ 578 RT_GCC_EXTENSION uint64_t u22Rsvd0 : 22; /**< Bits 245:224 - Reserved. */ 579 RT_GCC_EXTENSION uint64_t u1AttrOverride : 1; /**< Bit 246 - AttrV: Attribute Override. */ 580 RT_GCC_EXTENSION uint64_t u1Mode0FC: 1; /**< Bit 247 - Mode0FC. */ 581 RT_GCC_EXTENSION uint64_t u8SnoopAttr: 1; /**< Bits 255:248 - Snoop Attribute. */ 570 582 } n; 571 583 /** The 32-bit unsigned integer view. */ … … 573 585 /** The 64-bit unsigned integer view. */ 574 586 uint64_t au64[4]; 575 } D EV_TAB_ENTRY_T;576 AssertCompileSize(D EV_TAB_ENTRY_T, 32);577 #define IOMMU_D EV_TAB_ENTRY_QWORD_0_VALID_MASK UINT64_C(0x7fffffffffffff83)578 #define IOMMU_D EV_TAB_ENTRY_QWORD_1_VALID_MASK UINT64_C(0xfffffbffffffffff)579 #define IOMMU_D EV_TAB_ENTRY_QWORD_2_VALID_MASK UINT64_C(0xf70fffffffffffff)580 #define IOMMU_D EV_TAB_ENTRY_QWORD_3_VALID_MASK UINT64_C(0xffc0000000000000)587 } DTE_T; 588 AssertCompileSize(DTE_T, 32); 589 #define IOMMU_DTE_QWORD_0_VALID_MASK UINT64_C(0x7fffffffffffff83) 590 #define IOMMU_DTE_QWORD_1_VALID_MASK UINT64_C(0xfffffbffffffffff) 591 #define IOMMU_DTE_QWORD_2_VALID_MASK UINT64_C(0xf70fffffffffffff) 592 #define IOMMU_DTE_QWORD_3_VALID_MASK UINT64_C(0xffc0000000000000) 581 593 /** Pointer to a device table entry. */ 582 typedef D EV_TAB_ENTRY_T *PDEV_TAB_ENTRY_T;594 typedef DTE_T *PDTE_T; 583 595 /** Pointer to a const device table entry. */ 584 typedef D EV_TAB_ENTRY_T const *PCDEV_TAB_ENTRY_T;596 typedef DTE_T const *PCDTE_T; 585 597 586 598 /** … … 717 729 /** The 64-bit unsigned integer view. */ 718 730 uint64_t au64[2]; 719 } CMD_INV_D EV_TAB_ENTRY_T;720 AssertCompileSize(CMD_INV_D EV_TAB_ENTRY_T, 16);731 } CMD_INV_DTE_T; 732 AssertCompileSize(CMD_INV_DTE_T, 16); 721 733 722 734 /** … … 899 911 /** The 32-bit unsigned integer view. */ 900 912 uint32_t au32[4]; 901 } EVT_ILLEGAL_D EV_TAB_ENTRY_T;902 AssertCompileSize(EVT_ILLEGAL_D EV_TAB_ENTRY_T, 16);913 } EVT_ILLEGAL_DTE_T; 914 AssertCompileSize(EVT_ILLEGAL_DTE_T, 16); 903 915 /** Pointer to an illegal device table entry event. */ 904 typedef EVT_ILLEGAL_D EV_TAB_ENTRY_T *PEVT_ILLEGAL_DEV_TAB_ENTRY_T;916 typedef EVT_ILLEGAL_DTE_T *PEVT_ILLEGAL_DTE_T; 905 917 906 918 /** … … 2007 2019 AssertCompileSize(IOMMUOP, 4); 2008 2020 2009 2010 2021 /** 2011 2022 * The shared IOMMU device state. … … 3213 3224 } 3214 3225 3226 3215 3227 /** 3216 3228 * Clears the MSI interrupt for the IOMMU device. … … 3313 3325 * Constructs a DEV_TAB_HARDWARE_ERROR event. 3314 3326 * 3315 * @param uDevId 3316 * @param GCPhysD evTabEntry The system physical address of the failed device3317 * tableaccess.3318 * @param enmOp 3319 * @param pEvent 3327 * @param uDevId The device ID. 3328 * @param GCPhysDte The system physical address of the failed device table 3329 * access. 3330 * @param enmOp The operation being performed. 3331 * @param pEvent Where to store the constructed event. 3320 3332 * 3321 3333 * @thread Any. 3322 3334 */ 3323 static void iommuAmdMakeDevTabHwErrorEvent(uint16_t uDevId, RTGCPHYS GCPhysD evTabEntry, IOMMUOP enmOp, PEVT_GENERIC_T pEvent)3335 static void iommuAmdMakeDevTabHwErrorEvent(uint16_t uDevId, RTGCPHYS GCPhysDte, IOMMUOP enmOp, PEVT_GENERIC_T pEvent) 3324 3336 { 3325 3337 memset(pEvent, 0, sizeof(*pEvent)); … … 3332 3344 pDevTabHwErr->n.u2Type = enmOp == IOMMUOP_CMD ? HWEVTTYPE_DATA_ERROR : HWEVTTYPE_TARGET_ABORT; 3333 3345 pDevTabHwErr->n.u4EvtCode = IOMMU_EVT_DEV_TAB_HW_ERROR; 3334 pDevTabHwErr->n.u64Addr = GCPhysD evTabEntry;3346 pDevTabHwErr->n.u64Addr = GCPhysDte; 3335 3347 } 3336 3348 … … 3339 3351 * Raises a DEV_TAB_HARDWARE_ERROR event. 3340 3352 * 3341 * @param pDevIns 3342 * @param uDevId 3343 * @param GCPhysD evTabEntry The system physical address of the failed device3344 * tableaccess.3345 * @param enmOp 3346 */ 3347 static void iommuAmdRaiseDevTabHwErrorEvent(PPDMDEVINS pDevIns, uint16_t uDevId, RTGCPHYS GCPhysD evTabEntry, IOMMUOP enmOp)3353 * @param pDevIns The IOMMU device instance. 3354 * @param uDevId The device ID. 3355 * @param GCPhysDte The system physical address of the failed device table 3356 * access. 3357 * @param enmOp The operation being performed by the IOMMU. 3358 */ 3359 static void iommuAmdRaiseDevTabHwErrorEvent(PPDMDEVINS pDevIns, uint16_t uDevId, RTGCPHYS GCPhysDte, IOMMUOP enmOp) 3348 3360 { 3349 3361 EVT_GENERIC_T Event; 3350 iommuAmdMakeDevTabHwErrorEvent(uDevId, GCPhysD evTabEntry, enmOp, &Event);3362 iommuAmdMakeDevTabHwErrorEvent(uDevId, GCPhysDte, enmOp, &Event); 3351 3363 iommuAmdSetHwError(pDevIns, &Event); 3352 3364 iommuAmdWriteEvtLogEntry(pDevIns, &Event); … … 3366 3378 * @param pEvent Where to store the constructed event. 3367 3379 */ 3368 static void iommuAmdMakeIllegalDevTabEntryEvent(uint16_t uDevId, uint64_t uDva, bool fRsvdNotZero, IOMMUOP enmOp, 3369 PEVT_GENERIC_T pEvent) 3380 static void iommuAmdMakeIllegalDteEvent(uint16_t uDevId, uint64_t uDva, bool fRsvdNotZero, IOMMUOP enmOp, PEVT_GENERIC_T pEvent) 3370 3381 { 3371 3382 memset(pEvent, 0, sizeof(*pEvent)); 3372 AssertCompile(sizeof(EVT_ILLEGAL_D EV_TAB_ENTRY_T) == sizeof(EVT_GENERIC_T));3373 PEVT_ILLEGAL_D EV_TAB_ENTRY_T pIllegalDteErr = (PEVT_ILLEGAL_DEV_TAB_ENTRY_T)pEvent;3383 AssertCompile(sizeof(EVT_ILLEGAL_DTE_T) == sizeof(EVT_GENERIC_T)); 3384 PEVT_ILLEGAL_DTE_T pIllegalDteErr = (PEVT_ILLEGAL_DTE_T)pEvent; 3374 3385 pIllegalDteErr->n.u16DevId = uDevId; 3375 3386 pIllegalDteErr->n.u1Interrupt = RT_BOOL(enmOp == IOMMUOP_INTR_REQ); … … 3395 3406 * @param enmOp The operation being performed. 3396 3407 */ 3397 static void iommuAmdRaiseIllegalDevTabEntryEvent(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uDva, bool fRsvdNotZero, 3398 IOMMUOP enmOp) 3408 static void iommuAmdRaiseIllegalDteEvent(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uDva, bool fRsvdNotZero, IOMMUOP enmOp) 3399 3409 { 3400 3410 EVT_GENERIC_T Event; 3401 iommuAmdMakeIllegalD evTabEntryEvent(uDevId, uDva, fRsvdNotZero, enmOp, &Event);3411 iommuAmdMakeIllegalDteEvent(uDevId, uDva, fRsvdNotZero, enmOp, &Event); 3402 3412 iommuAmdWriteEvtLogEntry(pDevIns, &Event); 3403 3413 if (enmOp != IOMMUOP_CMD) 3404 3414 iommuAmdSetPciTargetAbort(pDevIns); 3405 3415 } 3406 3407 3416 3408 3417 … … 3412 3421 * 3413 3422 * @returns @c true if the DVA is excluded, @c false otherwise. 3414 * @param pThis 3415 * @param pD evTabEntryThe device table entry.3416 * @param uDva 3417 */ 3418 static bool iommuAmdIsDvaSubjectToExclRange(PCIOMMU pThis, PCD EV_TAB_ENTRY_T pDevTabEntry, uint64_t uDva)3423 * @param pThis The IOMMU device state. 3424 * @param pDte The device table entry. 3425 * @param uDva The device virtual address. 3426 */ 3427 static bool iommuAmdIsDvaSubjectToExclRange(PCIOMMU pThis, PCDTE_T pDte, uint64_t uDva) 3419 3428 { 3420 3429 /* Check if the exclusion range is enabled. */ … … 3428 3437 /* Check if device access to addresses in the exclusion range can be forwarded untranslated. */ 3429 3438 if ( pThis->ExclRangeBaseAddr.n.u1AllowAll 3430 || pD evTabEntry->n.u1AllowExclusion)3439 || pDte->n.u1AllowExclusion) 3431 3440 return true; 3432 3441 } … … 3440 3449 * 3441 3450 * @returns VBox status code. 3442 * @param pDevIns 3443 * @param uDevId 3444 * @param enmOp 3445 * @param pD evTabEntryWhere to store the device table entry.3451 * @param pDevIns The IOMMU device instance. 3452 * @param uDevId The device ID. 3453 * @param enmOp The operation being performed by the IOMMU. 3454 * @param pDte Where to store the device table entry. 3446 3455 * 3447 3456 * @thread Any. 3448 3457 */ 3449 static int iommuAmdReadD evTabEntry(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, PDEV_TAB_ENTRY_T pDevTabEntry)3458 static int iommuAmdReadDte(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, PDTE_T pDte) 3450 3459 { 3451 3460 PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); … … 3458 3467 Assert(idxSeg < RT_ELEMENTS(pThis->aDevTabBaseAddrs)); 3459 3468 3460 RTGCPHYS const GCPhysDevTab 3461 uint16_t const offD evTabEntry= uDevId & ~g_auDevTabSegMasks[idxSegsEn];3462 RTGCPHYS const GCPhysD evTabEntry = GCPhysDevTab + offDevTabEntry;3469 RTGCPHYS const GCPhysDevTab = pThis->aDevTabBaseAddrs[idxSeg].n.u40Base << X86_PAGE_4K_SHIFT; 3470 uint16_t const offDte = uDevId & ~g_auDevTabSegMasks[idxSegsEn]; 3471 RTGCPHYS const GCPhysDte = GCPhysDevTab + offDte; 3463 3472 3464 3473 Assert(!(GCPhysDevTab & X86_PAGE_4K_OFFSET_MASK)); 3465 int rc = PDMDevHlpPCIPhysRead(pDevIns, GCPhysD evTabEntry, pDevTabEntry, sizeof(*pDevTabEntry));3474 int rc = PDMDevHlpPCIPhysRead(pDevIns, GCPhysDte, pDte, sizeof(*pDte)); 3466 3475 if (RT_FAILURE(rc)) 3467 3476 { 3468 Log((IOMMU_LOG_PFX ": Failed to read device table entry at %#RGp. rc=%Rrc\n", GCPhysD evTabEntry, rc));3469 iommuAmdRaiseDevTabHwErrorEvent(pDevIns, uDevId, GCPhysD evTabEntry, enmOp);3477 Log((IOMMU_LOG_PFX ": Failed to read device table entry at %#RGp. rc=%Rrc\n", GCPhysDte, rc)); 3478 iommuAmdRaiseDevTabHwErrorEvent(pDevIns, uDevId, GCPhysDte, enmOp); 3470 3479 } 3471 3480 … … 3474 3483 3475 3484 3476 /** 3477 * Memory read transaction from a device. 3485 #if 0 3486 /** 3487 * Walks the I/O page tables to translate the given device virtual address and 3488 * associated data. 3489 * 3490 * @returns VBox status code. 3491 * @param pDevIns The IOMMU device instance. 3492 * @param uDva The device virtual address. 3493 * @param cbRead The size of the access. 3494 * @param fPerms The access permissions (IOMMU_PERM_XXX). 3495 * @param pGCPhys Where to store the translated address. 3496 */ 3497 static int iommuAmdWalkIoPageTable(PPDMDEVINS pDevIns, uint64_t uDva, size_t cbRead, uint32_t fAccess, PRTGCPHYS pGCPhys) 3498 { 3499 3500 } 3501 #endif 3502 3503 3504 /** 3505 * Memory read translation request from a device. 3478 3506 * 3479 3507 * @returns VBox status code. … … 3503 3531 3504 3532 /* Read the device table entry. */ 3505 D EV_TAB_ENTRY_T DevTabEntry;3506 int rc = iommuAmdReadD evTabEntry(pDevIns, uDevId, enmOp, &DevTabEntry);3533 DTE_T Dte; 3534 int rc = iommuAmdReadDte(pDevIns, uDevId, enmOp, &Dte); 3507 3535 if (RT_SUCCESS(rc)) 3508 3536 { 3509 3537 /* Addresses are forwarded without translation when DTE.V is 0. */ 3510 if (D evTabEntry.n.u1Valid)3538 if (Dte.n.u1Valid) 3511 3539 { 3512 3540 /* Validate bits 127:0 of the device table entry when DTE.V is 1. */ 3513 uint64_t const fRsvdQword0 = D evTabEntry.au64[0] & ~IOMMU_DEV_TAB_ENTRY_QWORD_0_VALID_MASK;3514 uint64_t const fRsvdQword1 = D evTabEntry.au64[1] & ~IOMMU_DEV_TAB_ENTRY_QWORD_1_VALID_MASK;3541 uint64_t const fRsvdQword0 = Dte.au64[0] & ~IOMMU_DTE_QWORD_0_VALID_MASK; 3542 uint64_t const fRsvdQword1 = Dte.au64[1] & ~IOMMU_DTE_QWORD_1_VALID_MASK; 3515 3543 if ( fRsvdQword0 3516 3544 || fRsvdQword1) 3517 3545 { 3518 3546 Log((IOMMU_LOG_PFX ":DTE invalid reserved bits ([0]=%#RX64 [1]=%#RX64)\n", fRsvdQword0, fRsvdQword1)); 3519 iommuAmdRaiseIllegalD evTabEntryEvent(pDevIns, uDevId, uDva, true /* fRsvdNotZero */, enmOp);3547 iommuAmdRaiseIllegalDteEvent(pDevIns, uDevId, uDva, true /* fRsvdNotZero */, enmOp); 3520 3548 return VERR_GENERAL_FAILURE; /** @todo IOMMU: Change this. */ 3521 3549 } 3522 3550 3523 /* Check if the exclusion range is active. */3524 if (!iommuAmdIsDvaSubjectToExclRange(pThis, &D evTabEntry, uDva))3551 /* Check if the device virtual address is subject to address exclusion. */ 3552 if (!iommuAmdIsDvaSubjectToExclRange(pThis, &Dte, uDva)) 3525 3553 { 3526 3554 /** @todo IOMMU: Traverse the I/O page table and translate. */ 3555 3527 3556 return VERR_NOT_IMPLEMENTED; 3528 3557 } … … 3542 3571 3543 3572 /** 3544 * Memory write trans actionfrom a device.3573 * Memory write translation request from a device. 3545 3574 * 3546 3575 * @returns VBox status code.
Note:
See TracChangeset
for help on using the changeset viewer.