VirtualBox

Changeset 84317 in vbox


Ignore:
Timestamp:
May 15, 2020 9:40:53 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Asynchronous IOMMU command processing.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r84227 r84317  
    29812981/** Access denied for the address. */
    29822982#define VERR_IOMMU_ADDR_ACCESS_DENIED               (-7205)
     2983/** Internal error - Command not supported. */
     2984#define VERR_IOMMU_CMD_NOT_SUPPORTED                (-7206)
     2985/** Internal error - Command format (or reserved bits) invalid. */
     2986#define VERR_IOMMU_CMD_INVALID_FORMAT               (-7207)
     2987/** Internal error - Command hardware failure. */
     2988#define VERR_IOMMU_CMD_HW_ERROR                     (-7208)
    29832989/** @} */
    29842990
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r84315 r84317  
    21832183
    21842184/**
    2185  * ILLEGAL_COMMAND_ERROR Event Types.
    2186  * In accordance with the AMD spec.
    2187  */
    2188 typedef enum EVT_ILLEGAL_CMD_ERR_TYPE_T
    2189 {
    2190     kIllegalCmdErrType_RsvdNotZero = 0,
    2191     kIllegalCmdErrType_CmdNotSupported,
    2192     kIllegalCmdErrType_IotlbNotSupported
    2193 } EVT_ILLEGAL_CMD_ERR_TYPE_T;
    2194 /** Pointer to an illegal command error event type. */
    2195 typedef EVT_ILLEGAL_CMD_ERR_TYPE_T *PEVT_ILLEGAL_CMD_ERR_TYPE_T;
    2196 
    2197 /**
    21982185 * IOTLB_INV_TIMEOUT Event Types.
    21992186 * In accordance with the AMD spec.
     
    33463333    Assert(!(off & 7) || !(off & 3));
    33473334
    3348     PIOMMU     pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    3349     PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
     3335    PIOMMU      pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     3336    PCPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    33503337    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
    33513338
     
    37843771 * @param   pDevIns         The IOMMU device instance.
    37853772 * @param   pEvtIllegalCmd  The illegal command error event.
    3786  * @param   enmEvtType      The illegal command error event type.
    3787  */
    3788 static void iommuAmdRaiseIllegalCmdEvent(PPDMDEVINS pDevIns, PCEVT_ILLEGAL_CMD_ERR_T pEvtIllegalCmd,
    3789                                          EVT_ILLEGAL_CMD_ERR_TYPE_T enmEvtType)
     3773 */
     3774static void iommuAmdRaiseIllegalCmdEvent(PPDMDEVINS pDevIns, PCEVT_ILLEGAL_CMD_ERR_T pEvtIllegalCmd)
    37903775{
    37913776    AssertCompile(sizeof(EVT_GENERIC_T) == sizeof(EVT_ILLEGAL_DTE_T));
     
    38003785    IOMMU_UNLOCK(pDevIns);
    38013786
    3802     Log((IOMMU_LOG_PFX ": Raised ILLEGAL_COMMAND_ERROR. GCPhysCmd=%#RGp enmType=%u\n", pEvtIllegalCmd->n.u64Addr, enmEvtType));
    3803     NOREF(enmEvtType);
     3787    Log((IOMMU_LOG_PFX ": Raised ILLEGAL_COMMAND_ERROR. Addr=%#RGp\n", pEvtIllegalCmd->n.u64Addr));
    38043788}
    38053789
     
    46094593 * @returns VBox status code.
    46104594 * @param   pDevIns         The IOMMU device instance.
     4595 * @param   pCmd            The command to process.
    46114596 * @param   GCPhysCmd       The system physical address of the command.
    4612  * @param   pCmd            The command to process.
     4597 * @param   pEvtError       Where to store the error event in case of failures.
    46134598 *
    46144599 * @thread  Command thread.
    46154600 */
    4616 static int iommuAmdR3ProcessCmd(PPDMDEVINS pDevIns, RTGCPHYS GCPhysCmd, PCCMD_GENERIC_T pCmd)
     4601static int iommuAmdR3ProcessCmd(PPDMDEVINS pDevIns, PCCMD_GENERIC_T pCmd, RTGCPHYS GCPhysCmd, PEVT_GENERIC_T pEvtError)
    46174602{
    46184603    IOMMU_ASSERT_NOT_LOCKED(pDevIns);
    4619 
    4620     EVT_ILLEGAL_CMD_ERR_T EvtIllegalCmdErr;
    46214604
    46224605    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     
    46324615            if (!(pCmdComWait->au64[0] & ~IOMMU_CMD_COM_WAIT_QWORD_0_VALID_MASK))
    46334616            {
    4634                 /* If Completion Store is requested, write the Store Data to the specified Store Address.*/
     4617                /* If Completion Store is requested, write the StoreData to the specified address.*/
    46354618                if (pCmdComWait->n.u1Store)
    46364619                {
    46374620                    RTGCPHYS const GCPhysStore = RT_MAKE_U64(pCmdComWait->n.u29StoreAddrLo << 3, pCmdComWait->n.u20StoreAddrHi);
    46384621                    uint64_t const u64Data     = pCmdComWait->n.u64StoreData;
    4639 
    46404622                    int rc = PDMDevHlpPCIPhysWrite(pDevIns, GCPhysStore, &u64Data, sizeof(u64Data));
    46414623                    if (RT_FAILURE(rc))
    46424624                    {
    4643                         EVT_CMD_HW_ERR_T EvtCmdHwErr;
    4644                         iommuAmdInitCmdHwErrorEvent(GCPhysStore, &EvtCmdHwErr);
    4645                         iommuAmdRaiseCmdHwErrorEvent(pDevIns, &EvtCmdHwErr);
    4646                         Log((IOMMU_LOG_PFX ": Failed to write StoreData (%#RX64) to %#RGp. rc=%Rrc\n", u64Data, GCPhysStore, rc));
    4647                         return rc;
     4625                        Log((IOMMU_LOG_PFX ": Cmd(%#x): Failed to write StoreData (%#RX64) to %#RGp, rc=%Rrc\n", bCmd, u64Data,
     4626                             GCPhysStore, rc));
     4627                        iommuAmdInitCmdHwErrorEvent(GCPhysStore, (PEVT_CMD_HW_ERR_T)pEvtError);
     4628                        return VERR_IOMMU_CMD_HW_ERROR;
    46484629                    }
    46494630                }
    46504631
    4651                 /* If command completion interrupt is requested, honor it. */
     4632                /* If command completion interrupt is requested, raise an interrupt. */
    46524633                if (pCmdComWait->n.u1Interrupt)
    46534634                {
     
    46684649                return VINF_SUCCESS;
    46694650            }
    4670 
    4671             iommuAmdInitIllegalCmdEvent(GCPhysCmd, &EvtIllegalCmdErr);
    4672             iommuAmdRaiseIllegalCmdEvent(pDevIns, &EvtIllegalCmdErr, kIllegalCmdErrType_RsvdNotZero);
    4673             return VERR_INVALID_FUNCTION;
     4651            iommuAmdInitIllegalCmdEvent(GCPhysCmd, (PEVT_ILLEGAL_CMD_ERR_T)pEvtError);
     4652            return VERR_IOMMU_CMD_INVALID_FORMAT;
    46744653        }
    46754654
    46764655        case IOMMU_CMD_INV_DEV_TAB_ENTRY:
     4656        {
     4657            /** @todo IOMMU: Implement this once we implement IOTLB. Pretend success until
     4658             *        then. */
     4659            return VINF_SUCCESS;
     4660        }
     4661
    46774662        case IOMMU_CMD_INV_IOMMU_PAGES:
     4663        {
     4664            /** @todo IOMMU: Implement this once we implement IOTLB. Pretend success until
     4665             *        then. */
     4666            return VINF_SUCCESS;
     4667        }
     4668
    46784669        case IOMMU_CMD_INV_IOTLB_PAGES:
     4670        {
     4671            uint32_t const uCapHdr = PDMPciDevGetDWord(pDevIns->apPciDevs[0], IOMMU_PCI_OFF_CAP_HDR);
     4672            if (RT_BF_GET(uCapHdr, IOMMU_BF_CAPHDR_IOTLB_SUP))
     4673            {
     4674                /** @todo IOMMU: Implement remote IOTLB invalidation. */
     4675                return VERR_NOT_IMPLEMENTED;
     4676            }
     4677            iommuAmdInitIllegalCmdEvent(GCPhysCmd, (PEVT_ILLEGAL_CMD_ERR_T)pEvtError);
     4678            return VERR_IOMMU_CMD_NOT_SUPPORTED;
     4679        }
     4680
    46794681        case IOMMU_CMD_INV_INTR_TABLE:
    46804682        {
    4681             return VERR_NOT_IMPLEMENTED;
     4683            /** @todo IOMMU: Implement this once we implement IOTLB. Pretend success until
     4684             *        then. */
     4685            return VINF_SUCCESS;
    46824686        }
    46834687
     
    46864690            if (pThis->ExtFeat.n.u1PrefetchSup)
    46874691            {
    4688                 /** @todo IOMMU: Implement prefetch. */
     4692                /** @todo IOMMU: Implement prefetch. Pretend success until then. */
    46894693                return VINF_SUCCESS;
    46904694            }
    4691             iommuAmdInitIllegalCmdEvent(GCPhysCmd, &EvtIllegalCmdErr);
    4692             iommuAmdRaiseIllegalCmdEvent(pDevIns, &EvtIllegalCmdErr, kIllegalCmdErrType_CmdNotSupported);
    4693             return VERR_INVALID_FUNCTION;
     4695            iommuAmdInitIllegalCmdEvent(GCPhysCmd, (PEVT_ILLEGAL_CMD_ERR_T)pEvtError);
     4696            return VERR_IOMMU_CMD_NOT_SUPPORTED;
    46944697        }
    46954698
    46964699        case IOMMU_CMD_COMPLETE_PPR_REQ:
     4700        {
     4701            /* We don't support PPR requests yet. */
     4702            Assert(!pThis->ExtFeat.n.u1PprSup);
     4703            iommuAmdInitIllegalCmdEvent(GCPhysCmd, (PEVT_ILLEGAL_CMD_ERR_T)pEvtError);
     4704            return VERR_IOMMU_CMD_NOT_SUPPORTED;
     4705        }
     4706
    46974707        case IOMMU_CMD_INV_IOMMU_ALL:
    46984708        {
    4699             NOREF(pThis);
    4700             return VERR_NOT_IMPLEMENTED;
    4701         }
    4702 
    4703         default:
    4704             break;
    4705     }
    4706 
    4707     Log((IOMMU_LOG_PFX ": Unrecognized or unsupported command opcode %u (%#x)\n", bCmd, bCmd));
    4708     return VERR_NOT_SUPPORTED;
     4709            if (pThis->ExtFeat.n.u1InvAllSup)
     4710            {
     4711                /** @todo IOMMU: Invalidate all. Pretend success until then. */
     4712                return VINF_SUCCESS;
     4713            }
     4714            iommuAmdInitIllegalCmdEvent(GCPhysCmd, (PEVT_ILLEGAL_CMD_ERR_T)pEvtError);
     4715            return VERR_IOMMU_CMD_NOT_SUPPORTED;
     4716        }
     4717    }
     4718
     4719    Log((IOMMU_LOG_PFX ": Cmd(%#x): Unrecognized\n", bCmd));
     4720    iommuAmdInitIllegalCmdEvent(GCPhysCmd, (PEVT_ILLEGAL_CMD_ERR_T)pEvtError);
     4721    return VERR_IOMMU_CMD_NOT_SUPPORTED;
    47094722}
    47104723
     
    47764789
    47774790                    /* Process the fetched command. */
     4791                    EVT_GENERIC_T EvtError;
    47784792                    IOMMU_UNLOCK(pDevIns);
    4779                     rc = iommuAmdR3ProcessCmd(pDevIns, GCPhysCmd, &Cmd);
     4793                    rc = iommuAmdR3ProcessCmd(pDevIns, &Cmd, GCPhysCmd, &EvtError);
    47804794                    IOMMU_LOCK(pDevIns);
    47814795                    if (RT_FAILURE(rc))
     4796                    {
     4797                        if (   rc == VERR_IOMMU_CMD_NOT_SUPPORTED
     4798                            || rc == VERR_IOMMU_CMD_INVALID_FORMAT)
     4799                            iommuAmdRaiseIllegalCmdEvent(pDevIns, (PCEVT_ILLEGAL_CMD_ERR_T)&EvtError);
     4800                        else if (rc == VERR_IOMMU_CMD_HW_ERROR)
     4801                            iommuAmdRaiseCmdHwErrorEvent(pDevIns, (PCEVT_CMD_HW_ERR_T)&EvtError);
    47824802                        break;
     4803                    }
    47834804                }
    47844805                else
     
    49194940{
    49204941    PCIOMMU    pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    4921     PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
     4942    PCPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    49224943    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
    49234944
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