Changeset 84291 in vbox for trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
- Timestamp:
- May 13, 2020 3:49:35 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r84285 r84291 497 497 else \ 498 498 return rcLock; \ 499 } while (0) 500 501 /** 502 * Acquires the IOMMU PDM lock (no return, only asserts on failure). 503 * This will make a long jump to ring-3 to acquire the lock if necessary. 504 */ 505 #define IOMMU_LOCK_NORET(a_pDevIns, a_pThis) \ 506 do { \ 507 NOREF(pThis); \ 508 int rcLock = PDMDevHlpCritSectEnter((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS); \ 509 AssertRC(rcLock); \ 499 510 } while (0) 500 511 … … 995 1006 /** The 32-bit unsigned integer view. */ 996 1007 uint32_t au32[4]; 1008 /** The 64-bit unsigned integer view. */ 1009 uint64_t au64[2]; 997 1010 } EVT_ILLEGAL_DTE_T; 998 1011 AssertCompileSize(EVT_ILLEGAL_DTE_T, 16); … … 1028 1041 /** The 32-bit unsigned integer view. */ 1029 1042 uint32_t au32[4]; 1043 /** The 64-bit unsigned integer view. */ 1044 uint64_t au64[2]; 1030 1045 } EVT_IO_PAGE_FAULT_T; 1031 1046 AssertCompileSize(EVT_IO_PAGE_FAULT_T, 16); … … 1059 1074 /** The 32-bit unsigned integer view. */ 1060 1075 uint32_t au32[4]; 1076 /** The 64-bit unsigned integer view. */ 1077 uint64_t au64[2]; 1061 1078 } EVT_DEV_TAB_HW_ERROR_T; 1062 1079 AssertCompileSize(EVT_DEV_TAB_HW_ERROR_T, 16); … … 1094 1111 /** The 32-bit unsigned integer view. */ 1095 1112 uint32_t au32[4]; 1113 /** The 64-bit unsigned integer view. */ 1114 uint64_t au64[2]; 1096 1115 } EVT_PAGE_TAB_HW_ERR_T; 1097 1116 AssertCompileSize(EVT_PAGE_TAB_HW_ERR_T, 16); … … 1100 1119 /** Pointer to a const page table hardware error event. */ 1101 1120 typedef EVT_PAGE_TAB_HW_ERR_T const *PCEVT_PAGE_TAB_HW_ERR_T; 1102 1103 1121 1104 1122 /** … … 1119 1137 /** The 32-bit unsigned integer view. */ 1120 1138 uint32_t au32[4]; 1139 /** The 64-bit unsigned integer view. */ 1140 uint64_t au64[2]; 1121 1141 } EVT_ILLEGAL_CMD_ERR_T; 1122 1142 AssertCompileSize(EVT_ILLEGAL_CMD_ERR_T, 16); … … 1130 1150 struct 1131 1151 { 1132 uint32_t u32Rsvd0; /**< Bits 31:0 - Reserved. */ 1133 uint32_t u4Rsvd0 : 4; /**< Bits 35:32 - Reserved. */ 1134 uint32_t u28AddrLo : 28; /**< Bits 63:36 - Address: SPA of the attempted access (Lo). */ 1135 uint32_t u32AddrHi; /**< Bits 95:64 - Address: SPA of the attempted access (Hi). */ 1152 uint32_t u32Rsvd0; /**< Bits 31:0 - Reserved. */ 1153 uint32_t u25Rsvd1 : 25; /**< Bits 56:32 - Reserved. */ 1154 uint32_t u2Type : 2; /**< Bits 58:57 - Type: The type of hardware error. */ 1155 uint32_t u1Rsvd1 : 1; /**< Bit 59 - Reserved. */ 1156 uint32_t u4EvtCode : 4; /**< Bits 63:60 - Event code. */ 1157 uint64_t u64Addr; /**< Bits 128:64 - Address: SPA of the attempted access. */ 1136 1158 } n; 1137 1159 /** The 32-bit unsigned integer view. */ 1138 uint32_t au32[3]; 1139 } EVT_CMD_HW_ERROR_T; 1140 AssertCompileSize(EVT_CMD_HW_ERROR_T, 12); 1160 uint32_t au32[4]; 1161 /** The 64-bit unsigned integer view. */ 1162 uint64_t au64[2]; 1163 } EVT_CMD_HW_ERR_T; 1164 AssertCompileSize(EVT_CMD_HW_ERR_T, 16); 1165 /** Pointer to a command hardware error event. */ 1166 typedef EVT_CMD_HW_ERR_T *PEVT_CMD_HW_ERR_T; 1167 /** Pointer to a const command hardware error event. */ 1168 typedef EVT_CMD_HW_ERR_T const *PCEVT_CMD_HW_ERR_T; 1141 1169 1142 1170 /** … … 2602 2630 2603 2631 /** 2632 * Halts command processing. 2633 * 2634 * @param pDevIns The IOMMU device instance. 2635 */ 2636 static void iommuAmdHaltCmdProcessing(PPDMDEVINS pDevIns) 2637 { 2638 IOMMU_ASSERT_LOCKED(pDevIns); 2639 2640 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 2641 ASMAtomicAndU64(&pThis->Status.u64, ~IOMMU_STATUS_CMD_BUF_RUNNING); 2642 } 2643 2644 2645 /** 2604 2646 * Wakes up the command thread if there are commands to be processed or if 2605 2647 * processing is requested to be stopped by software. … … 3566 3608 static void iommuAmdSetHwError(PPDMDEVINS pDevIns, PCEVT_GENERIC_T pEvent) 3567 3609 { 3568 /** @todo IOMMU: We should probably lock the device here */3569 3610 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 3611 IOMMU_LOCK_NORET(pDevIns, pThis); 3570 3612 if (pThis->ExtFeat.n.u1HwErrorSup) 3571 3613 { … … 3577 3619 Assert(pThis->HwEvtHi.n.u4EvtCode == IOMMU_EVT_DEV_TAB_HW_ERROR); 3578 3620 } 3621 IOMMU_UNLOCK(pDevIns, pThis); 3579 3622 } 3580 3623 … … 3600 3643 pEvtPageTabHwErr->n.u1ReadWrite = RT_BOOL(enmOp == IOMMUOP_MEM_WRITE); 3601 3644 pEvtPageTabHwErr->n.u1Translation = RT_BOOL(enmOp == IOMMUOP_TRANSLATE_REQ); 3602 pEvtPageTabHwErr->n.u2Type = enmOp == IOMMUOP_CMD ? HWEVTTYPE_DATA_ERROR : HWEVTTYPE_TARGET_ABORT; ;3645 pEvtPageTabHwErr->n.u2Type = enmOp == IOMMUOP_CMD ? HWEVTTYPE_DATA_ERROR : HWEVTTYPE_TARGET_ABORT; 3603 3646 pEvtPageTabHwErr->n.u4EvtCode = IOMMU_EVT_PAGE_TAB_HW_ERROR; 3604 3647 pEvtPageTabHwErr->n.u64Addr = GCPhysPtEntity; … … 3627 3670 Log((IOMMU_LOG_PFX ": Raised PAGE_TAB_HARDWARE_ERROR. uDevId=%#x uDomainId=%#x GCPhysPtEntity=%#RGp enmOp=%u enmType=%u\n", 3628 3671 pEvtPageTabHwErr->n.u16DevId, pEvtPageTabHwErr->n.u16DomainOrPasidLo, pEvtPageTabHwErr->n.u64Addr, enmOp, enmEvtType)); 3672 NOREF(enmEvtType); 3673 } 3674 3675 3676 /** 3677 * Initializes a COMMAND_HARDWARE_ERROR event. 3678 * 3679 * @param GCPhysCmd The system physical address of the command that caused 3680 * the error. 3681 * @param pEvtCmdHwErr Where to store the initialized event. 3682 */ 3683 static void iommuAmdInitCmdHwErrorEvent(RTGCPHYS GCPhysCmd, HWEVTTYPE enmHwErrType, PEVT_CMD_HW_ERR_T pEvtCmdHwErr) 3684 { 3685 memset(pEvtCmdHwErr, 0, sizeof(*pEvtCmdHwErr)); 3686 pEvtCmdHwErr->n.u2Type = enmHwErrType; 3687 pEvtCmdHwErr->n.u4EvtCode = IOMMU_EVT_COMMAND_HW_ERROR; 3688 pEvtCmdHwErr->n.u64Addr = GCPhysCmd; 3689 } 3690 3691 3692 /** 3693 * Raises a COMMAND_HARDWARE_ERROR event. 3694 * 3695 * @param pDevIns The IOMMU device instance. 3696 * @param pEvtCmdHwErr The command hardware error event. 3697 * @param enmEvtType The hardware error event type. 3698 */ 3699 static void iommuAmdRaiseCmdHwErrorEvent(PPDMDEVINS pDevIns, PCEVT_CMD_HW_ERR_T pEvtCmdHwErr, EVT_HW_ERR_TYPE_T enmEvtType) 3700 { 3701 AssertCompile(sizeof(EVT_GENERIC_T) == sizeof(EVT_CMD_HW_ERR_T)); 3702 PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtCmdHwErr; 3703 3704 iommuAmdSetHwError(pDevIns, (PCEVT_GENERIC_T)pEvent); 3705 iommuAmdWriteEvtLogEntry(pDevIns, (PCEVT_GENERIC_T)pEvent); 3706 iommuAmdHaltCmdProcessing(pDevIns); 3707 3708 Log((IOMMU_LOG_PFX ": Raised COMMAND_HARDWARE_ERROR. GCPhysCmd=%#RGp enmType=%u\n", pEvtCmdHwErr->n.u64Addr, enmEvtType)); 3629 3709 NOREF(enmEvtType); 3630 3710 } … … 4548 4628 * mappings and accessing them directly. */ 4549 4629 IOMMU_STATUS_T Status = iommuAmdGetStatus(pThis); 4550 if (Status. n.u1CmdBufRunning)4630 if (Status.u64 & IOMMU_STATUS_CMD_BUF_RUNNING) 4551 4631 { 4552 4632 IOMMU_LOCK(pDevIns, pThis); … … 4583 4663 else 4584 4664 { 4585 /** @todo IOMMU: Raise command hardware error. */ 4586 /* Stop command processing. */ 4587 ASMAtomicAndU64(&pThis->Status.u64, ~IOMMU_STATUS_CMD_BUF_RUNNING); 4665 /* Reporting this as a "data error". Maybe target abort is more appropriate? */ 4666 EVT_CMD_HW_ERR_T EvtCmdHwErr; 4667 iommuAmdInitCmdHwErrorEvent(GCPhysCmd, HWEVTTYPE_DATA_ERROR, & EvtCmdHwErr); 4668 iommuAmdRaiseCmdHwErrorEvent(pDevIns, &EvtCmdHwErr, kHwErrType_PoisonedData); 4588 4669 break; 4589 4670 }
Note:
See TracChangeset
for help on using the changeset viewer.