Changeset 84301 in vbox for trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
- Timestamp:
- May 14, 2020 4:36:56 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r84292 r84301 1129 1129 uint32_t u28Rsvd0 : 28; /**< Bits 47:32 - Reserved. */ 1130 1130 uint32_t u4EvtCode : 4; /**< Bits 63:60 - Event code. */ 1131 uint32_t u4Rsvd0 : 4; /**< Bits 67:64 - Reserved. */ 1132 uint32_t u28AddrLo : 28; /**< Bits 95:68 - Address: SPA of the invalid command (Lo). */ 1133 uint32_t u32AddrHi; /**< Bits 127:96 - Address: SPA of the invalid command (Hi). */ 1131 uint64_t u64Addr; /**< Bits 127:64 - Address: SPA of the invalid command. */ 1134 1132 } n; 1135 1133 /** The 32-bit unsigned integer view. */ … … 1139 1137 } EVT_ILLEGAL_CMD_ERR_T; 1140 1138 AssertCompileSize(EVT_ILLEGAL_CMD_ERR_T, 16); 1139 /** Pointer to an illegal command error event. */ 1140 typedef EVT_ILLEGAL_CMD_ERR_T *PEVT_ILLEGAL_CMD_ERR_T; 1141 /** Pointer to a const illegal command error event. */ 1142 typedef EVT_ILLEGAL_CMD_ERR_T const *PCEVT_ILLEGAL_CMD_ERR_T; 1141 1143 1142 1144 /** … … 2185 2187 kIllegalCmdErrType_IotlbNotSupported 2186 2188 } EVT_ILLEGAL_CMD_ERR_TYPE_T; 2189 /** Pointer to an illegal command error event type. */ 2190 typedef EVT_ILLEGAL_CMD_ERR_TYPE_T *PEVT_ILLEGAL_CMD_ERR_TYPE_T; 2187 2191 2188 2192 /** … … 2539 2543 * @param uEncodedLen The length (power-of-2 encoded). 2540 2544 */ 2541 DECLINLINE(uint32_t) iommuAmdGet BufLength(uint8_t uEncodedLen)2545 DECLINLINE(uint32_t) iommuAmdGetTotalBufLength(uint8_t uEncodedLen) 2542 2546 { 2543 2547 Assert(uEncodedLen > 7); … … 3014 3018 */ 3015 3019 uint32_t const offBuf = u64Value & IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK; 3016 uint32_t const cbBuf = iommuAmdGet BufLength(pThis->CmdBufBaseAddr.n.u4Len);3020 uint32_t const cbBuf = iommuAmdGetTotalBufLength(pThis->CmdBufBaseAddr.n.u4Len); 3017 3021 Assert(cbBuf <= _512K); 3018 3022 if (offBuf >= cbBuf) … … 3046 3050 */ 3047 3051 uint32_t const offBuf = u64Value & IOMMU_CMD_BUF_TAIL_PTR_VALID_MASK; 3048 uint32_t const cbBuf = iommuAmdGet BufLength(pThis->CmdBufBaseAddr.n.u4Len);3052 uint32_t const cbBuf = iommuAmdGetTotalBufLength(pThis->CmdBufBaseAddr.n.u4Len); 3049 3053 Assert(cbBuf <= _512K); 3050 3054 if (offBuf >= cbBuf) … … 3088 3092 */ 3089 3093 uint32_t const offBuf = u64Value & IOMMU_EVT_LOG_HEAD_PTR_VALID_MASK; 3090 uint32_t const cbBuf = iommuAmdGet BufLength(pThis->EvtLogBaseAddr.n.u4Len);3094 uint32_t const cbBuf = iommuAmdGetTotalBufLength(pThis->EvtLogBaseAddr.n.u4Len); 3091 3095 Assert(cbBuf <= _512K); 3092 3096 if (offBuf >= cbBuf) … … 3130 3134 */ 3131 3135 uint32_t const offBuf = u64Value & IOMMU_EVT_LOG_TAIL_PTR_VALID_MASK; 3132 uint32_t const cbBuf = iommuAmdGet BufLength(pThis->EvtLogBaseAddr.n.u4Len);3136 uint32_t const cbBuf = iommuAmdGetTotalBufLength(pThis->EvtLogBaseAddr.n.u4Len); 3133 3137 Assert(cbBuf <= _512K); 3134 3138 if (offBuf >= cbBuf) … … 3569 3573 3570 3574 /* Increment the event log tail pointer. */ 3571 uint32_t const cbEvtLog = iommuAmdGet BufLength(pThis->EvtLogBaseAddr.n.u4Len);3575 uint32_t const cbEvtLog = iommuAmdGetTotalBufLength(pThis->EvtLogBaseAddr.n.u4Len); 3572 3576 pThis->EvtLogTailPtr.n.off = (offEvt + cbEvt) % cbEvtLog; 3573 3577 … … 3770 3774 Log((IOMMU_LOG_PFX ": Raised DEV_TAB_HARDWARE_ERROR. uDevId=%#x GCPhysDte=%#RGp enmOp=%u enmType=%u\n", 3771 3775 pEvtDevTabHwErr->n.u16DevId, pEvtDevTabHwErr->n.u64Addr, enmOp, enmEvtType)); 3776 NOREF(enmEvtType); 3777 } 3778 3779 3780 /** 3781 * Initializes an ILLEGAL_COMMAND_ERROR event. 3782 * 3783 * @param GCPhysCmd The system physical address of the failed command 3784 * access. 3785 * @param pEvtIllegalCmd Where to store the initialized event. 3786 */ 3787 static void iommuAmdInitIllegalCmdEvent(RTGCPHYS GCPhysCmd, PEVT_ILLEGAL_CMD_ERR_T pEvtIllegalCmd) 3788 { 3789 Assert(!(GCPhysCmd & UINT64_C(0xf))); 3790 memset(pEvtIllegalCmd, 0, sizeof(*pEvtIllegalCmd)); 3791 pEvtIllegalCmd->n.u4EvtCode = IOMMU_EVT_ILLEGAL_CMD_ERROR; 3792 pEvtIllegalCmd->n.u64Addr = GCPhysCmd; 3793 } 3794 3795 3796 /** 3797 * Raises an ILLEGAL_COMMAND_ERROR event. 3798 * 3799 * @param pDevIns The IOMMU device instance. 3800 * @param pEvtIllegalCmd The illegal command error event. 3801 * @param enmEvtType The illegal command error event type. 3802 */ 3803 static void iommuAmdRaiseIllegalCmdEvent(PPDMDEVINS pDevIns, PCEVT_ILLEGAL_CMD_ERR_T pEvtIllegalCmd, 3804 EVT_ILLEGAL_CMD_ERR_TYPE_T enmEvtType) 3805 { 3806 AssertCompile(sizeof(EVT_GENERIC_T) == sizeof(EVT_ILLEGAL_DTE_T)); 3807 PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtIllegalCmd; 3808 3809 IOMMU_LOCK_NORET(pDevIns); 3810 3811 iommuAmdWriteEvtLogEntry(pDevIns, pEvent); 3812 iommuAmdHaltCmdProcessing(pDevIns); 3813 3814 IOMMU_UNLOCK(pDevIns); 3815 3816 Log((IOMMU_LOG_PFX ": Raised ILLEGAL_COMMAND_ERROR. GCPhysCmd=%#RGp enmType=%u\n", pEvtIllegalCmd->n.u64Addr, enmEvtType)); 3772 3817 NOREF(enmEvtType); 3773 3818 } … … 3808 3853 * @param enmOp The IOMMU operation being performed. 3809 3854 * @param pEvtIllegalDte The illegal device table entry event. 3810 * @param enmEvtType The illegal DTEevent type.3855 * @param enmEvtType The illegal device table entry event type. 3811 3856 * 3812 3857 * @thread Any. … … 4577 4622 * 4578 4623 * @returns VBox status code. 4579 * @param pDevIns The IOMMU device instance. 4580 * @param pCmd The command to process. 4581 */ 4582 static int iommuAmdR3ProcessCmd(PPDMDEVINS pDevIns, PCCMD_GENERIC_T pCmd) 4624 * @param pDevIns The IOMMU device instance. 4625 * @param pCmd The command to process. 4626 * @param penmEvtType Where to store the illegal command error event type in 4627 * case of failures. 4628 */ 4629 static int iommuAmdR3ProcessCmd(PPDMDEVINS pDevIns, PCCMD_GENERIC_T pCmd, PEVT_ILLEGAL_CMD_ERR_TYPE_T penmEvtType) 4583 4630 { 4584 4631 IOMMU_ASSERT_NOT_LOCKED(pDevIns); … … 4606 4653 4607 4654 Log((IOMMU_LOG_PFX ": Invalid/Unrecognized command opcode %u (%#x)\n", bCmd, bCmd)); 4655 *penmEvtType = kIllegalCmdErrType_CmdNotSupported; 4608 4656 return VERR_INVALID_FUNCTION; 4609 4657 } … … 4658 4706 IOMMU_LOCK(pDevIns); 4659 4707 4660 uint32_t const cbCmdBuf = iommuAmdGetBufLength(pThis->CmdBufBaseAddr.n.u4Len); 4708 /* Get the offset we need to read the command from memory (circular buffer offset). */ 4709 uint32_t const cbCmdBuf = iommuAmdGetTotalBufLength(pThis->CmdBufBaseAddr.n.u4Len); 4661 4710 uint32_t offHead = pThis->CmdBufHeadPtr.n.off; 4662 4711 Assert(!(offHead & ~IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK)); 4712 Assert(offHead < cbCmdBuf); 4663 4713 while (offHead != pThis->CmdBufTailPtr.n.off) 4664 4714 { 4665 /* Fetch the command from guestmemory. */4715 /* Read the command from memory. */ 4666 4716 CMD_GENERIC_T Cmd; 4667 4717 RTGCPHYS const GCPhysCmd = (pThis->CmdBufBaseAddr.n.u40Base << X86_PAGE_4K_SHIFT) + offHead; … … 4674 4724 4675 4725 /* Process the fetched command. */ 4726 EVT_ILLEGAL_CMD_ERR_TYPE_T enmEvtType; 4676 4727 IOMMU_UNLOCK(pDevIns); 4677 rc = iommuAmdR3ProcessCmd(pDevIns, &Cmd );4728 rc = iommuAmdR3ProcessCmd(pDevIns, &Cmd, &enmEvtType); 4678 4729 IOMMU_LOCK(pDevIns); 4679 4730 if (RT_SUCCESS(rc)) … … 4681 4732 else 4682 4733 { 4683 /** @todo IOMMU: Raise illegal command error. */4684 /* Stop command processing. */4685 ASMAtomicAndU64(&pThis->Status.u64, ~IOMMU_STATUS_CMD_BUF_RUNNING);4734 EVT_ILLEGAL_CMD_ERR_T EvtIllegalCmdErr; 4735 iommuAmdInitIllegalCmdEvent(GCPhysCmd, &EvtIllegalCmdErr); 4736 iommuAmdRaiseIllegalCmdEvent(pDevIns, &EvtIllegalCmdErr, enmEvtType); 4686 4737 break; 4687 4738 } … … 4846 4897 uint8_t const uEncodedLen = CmdBufBar.n.u4Len; 4847 4898 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 4848 uint32_t const cbBuffer = iommuAmdGet BufLength(uEncodedLen);4899 uint32_t const cbBuffer = iommuAmdGetTotalBufLength(uEncodedLen); 4849 4900 pHlp->pfnPrintf(pHlp, " Command buffer BAR = %#RX64\n", CmdBufBar.u64); 4850 4901 if (fVerbose) … … 4860 4911 uint8_t const uEncodedLen = EvtLogBar.n.u4Len; 4861 4912 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 4862 uint32_t const cbBuffer = iommuAmdGet BufLength(uEncodedLen);4913 uint32_t const cbBuffer = iommuAmdGetTotalBufLength(uEncodedLen); 4863 4914 pHlp->pfnPrintf(pHlp, " Event log BAR = %#RX64\n", EvtLogBar.u64); 4864 4915 if (fVerbose) … … 4982 5033 uint8_t const uEncodedLen = PprLogBar.n.u4Len; 4983 5034 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 4984 uint32_t const cbBuffer = iommuAmdGet BufLength(uEncodedLen);5035 uint32_t const cbBuffer = iommuAmdGetTotalBufLength(uEncodedLen); 4985 5036 pHlp->pfnPrintf(pHlp, " PPR Log BAR = %#RX64\n", PprLogBar.u64); 4986 5037 if (fVerbose) … … 5018 5069 uint8_t const uEncodedLen = GALogBar.n.u4Len; 5019 5070 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 5020 uint32_t const cbBuffer = iommuAmdGet BufLength(uEncodedLen);5071 uint32_t const cbBuffer = iommuAmdGetTotalBufLength(uEncodedLen); 5021 5072 pHlp->pfnPrintf(pHlp, " Guest Log BAR = %#RX64\n", GALogBar.u64); 5022 5073 if (fVerbose) … … 5039 5090 uint8_t const uEncodedLen = PprLogBBar.n.u4Len; 5040 5091 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 5041 uint32_t const cbBuffer = iommuAmdGet BufLength(uEncodedLen);5092 uint32_t const cbBuffer = iommuAmdGetTotalBufLength(uEncodedLen); 5042 5093 pHlp->pfnPrintf(pHlp, " PPR Log B BAR = %#RX64\n", PprLogBBar.u64); 5043 5094 if (fVerbose) … … 5053 5104 uint8_t const uEncodedLen = EvtLogBBar.n.u4Len; 5054 5105 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 5055 uint32_t const cbBuffer = iommuAmdGet BufLength(uEncodedLen);5106 uint32_t const cbBuffer = iommuAmdGetTotalBufLength(uEncodedLen); 5056 5107 pHlp->pfnPrintf(pHlp, " Event Log B BAR = %#RX64\n", EvtLogBBar.u64); 5057 5108 if (fVerbose)
Note:
See TracChangeset
for help on using the changeset viewer.