VirtualBox

Changeset 89572 in vbox for trunk/src/VBox/Devices/Bus


Ignore:
Timestamp:
Jun 9, 2021 7:30:38 AM (3 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 Implemented saved state support.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp

    r89553 r89572  
    9999#define DMAR_FRCD_REG_COUNT                         UINT32_C(1)
    100100
     101/** Number of register groups (used in saved states). */
     102#define DMAR_MMIO_GROUP_COUNT                       2
    101103/** Offset of first register in group 0. */
    102104#define DMAR_MMIO_GROUP_0_OFF_FIRST                 VTD_MMIO_OFF_VER_REG
     
    319321    /** IOMMU device index. */
    320322    uint32_t                    idxIommu;
    321     /** DMAR magic. */
    322     uint32_t                    u32Magic;
     323    /** Padding. */
     324    uint32_t                    u32Padding0;
    323325
    324326    /** Registers (group 0). */
     
    23992401static int dmarDrLegacyModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARMEMREQREMAP pMemReqRemap)
    24002402{
    2401     PCDMARMEMREQIN  pMemReqIn  = &pMemReqRemap->In;
    2402     PDMARMEMREQAUX  pMemReqAux = &pMemReqRemap->Aux;
    2403     PDMARMEMREQOUT  pMemReqOut = &pMemReqRemap->Out;
     2403    PCDMARMEMREQIN pMemReqIn  = &pMemReqRemap->In;
     2404    PDMARMEMREQAUX pMemReqAux = &pMemReqRemap->Aux;
     2405    PDMARMEMREQOUT pMemReqOut = &pMemReqRemap->Out;
    24042406    Assert(pMemReqAux->fTtm == VTD_TTM_LEGACY_MODE);    /* Paranoia. */
    24052407
     
    36793681{
    36803682    PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR);
     3683    LogFlowFunc(("\n"));
    36813684
    36823685    /*
     
    38223825
    38233826/**
     3827 * @callback_method_impl{FNSSMDEVSAVEEXEC}
     3828 */
     3829static DECLCALLBACK(int) dmarR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     3830{
     3831    PCDMAR        pThis = PDMDEVINS_2_DATA(pDevIns, PCDMAR);
     3832    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
     3833    LogFlowFunc(("\n"));
     3834
     3835    /* First, save software-immutable registers that we validate on state load. */
     3836    pHlp->pfnSSMPutU32(pSSM, pThis->uVerReg);
     3837    pHlp->pfnSSMPutU64(pSSM, pThis->fCapReg);
     3838    pHlp->pfnSSMPutU64(pSSM, pThis->fExtCapReg);
     3839
     3840    /* Save MMIO registers. */
     3841    pHlp->pfnSSMPutU32(pSSM, DMAR_MMIO_GROUP_COUNT);
     3842    pHlp->pfnSSMPutU32(pSSM, sizeof(pThis->abRegs0));
     3843    pHlp->pfnSSMPutMem(pSSM, &pThis->abRegs0[0], sizeof(pThis->abRegs0));
     3844    pHlp->pfnSSMPutU32(pSSM, sizeof(pThis->abRegs1));
     3845    pHlp->pfnSSMPutMem(pSSM, &pThis->abRegs1[0], sizeof(pThis->abRegs1));
     3846
     3847    /* Save lazily activated registers. */
     3848    pHlp->pfnSSMPutU64(pSSM, pThis->uIrtaReg);
     3849    pHlp->pfnSSMPutU64(pSSM, pThis->uRtaddrReg);
     3850
     3851    /* Save terminator marker and return status. */
     3852    return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX);
     3853}
     3854
     3855
     3856/**
     3857 * @callback_method_impl{FNSSMDEVLOADEXEC}
     3858 */
     3859static DECLCALLBACK(int) dmarR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     3860{
     3861    PDMAR         pThis     = PDMDEVINS_2_DATA(pDevIns, PDMAR);
     3862    PCPDMDEVHLPR3 pHlp      = pDevIns->pHlpR3;
     3863    int const     rcDataErr = VERR_SSM_UNEXPECTED_DATA;
     3864    int const     rcFmtErr  = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     3865    LogFlowFunc(("\n"));
     3866
     3867    /*
     3868     * Validate saved-state version.
     3869     */
     3870    AssertReturn(uPass == SSM_PASS_FINAL, VERR_WRONG_ORDER);
     3871    if (uVersion != DMAR_SAVED_STATE_VERSION)
     3872    {
     3873        LogRel(("%s: Invalid saved-state version %#x\n", DMAR_LOG_PFX, uVersion));
     3874        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     3875    }
     3876
     3877    /*
     3878     * Load and validate software-immutable registers.
     3879     */
     3880    {
     3881        /* VER_REG */
     3882        uint32_t uVerReg;
     3883        int rc = pHlp->pfnSSMGetU32(pSSM, &uVerReg);
     3884        AssertRCReturn(rc, rc);
     3885        AssertLogRelMsgReturn(uVerReg == pThis->uVerReg,
     3886                              ("%s: VER_REG mismatch (expected %#RX32 got %#RX32)\n", DMAR_LOG_PFX, pThis->uVerReg, uVerReg),
     3887                              rcDataErr);
     3888
     3889        /* CAP_REG */
     3890        uint64_t fCapReg;
     3891        pHlp->pfnSSMGetU64(pSSM, &fCapReg);
     3892        AssertLogRelMsgReturn(fCapReg == pThis->fCapReg,
     3893                              ("%s: CAP_REG mismatch (expected %#RX64 got %#RX64)\n", DMAR_LOG_PFX, pThis->fCapReg, fCapReg),
     3894                              rcDataErr);
     3895
     3896        /* ECAP_REG */
     3897        uint64_t fExtCapReg;
     3898        pHlp->pfnSSMGetU64(pSSM, &fExtCapReg);
     3899        AssertLogRelMsgReturn(fExtCapReg == pThis->fExtCapReg,
     3900                              ("%s: ECAP_REG mismatch (expected %#RX64 got %#RX64)\n", DMAR_LOG_PFX, pThis->fExtCapReg,
     3901                               fExtCapReg), rcDataErr);
     3902    }
     3903
     3904    /*
     3905     * Load MMIO registers.
     3906     */
     3907    {
     3908        /* Group count. */
     3909        uint32_t cRegGroups;
     3910        pHlp->pfnSSMGetU32(pSSM, &cRegGroups);
     3911        AssertLogRelMsgReturn(cRegGroups == DMAR_MMIO_GROUP_COUNT,
     3912                              ("%s: MMIO group count mismatch (expected %u got %u)\n", DMAR_LOG_PFX, DMAR_MMIO_GROUP_COUNT,
     3913                               cRegGroups), rcDataErr);
     3914
     3915        /* Group 0. */
     3916        uint32_t cbRegs0;
     3917        pHlp->pfnSSMGetU32(pSSM, &cbRegs0);
     3918        AssertLogRelMsgReturn(cbRegs0 == sizeof(pThis->abRegs0),
     3919                              ("%s: MMIO group 0 size mismatch (expected %u got %u)\n", DMAR_LOG_PFX, sizeof(pThis->abRegs0),
     3920                               cbRegs0), rcDataErr);
     3921        pHlp->pfnSSMGetMem(pSSM, &pThis->abRegs0[0], cbRegs0);
     3922
     3923        /* Group 1. */
     3924        uint32_t cbRegs1;
     3925        pHlp->pfnSSMGetU32(pSSM, &cbRegs1);
     3926        AssertLogRelMsgReturn(cbRegs1 == sizeof(pThis->abRegs1),
     3927                              ("%s: MMIO group 1 size mismatch (expected %u got %u)\n", DMAR_LOG_PFX, sizeof(pThis->abRegs1),
     3928                               cbRegs1), rcDataErr);
     3929        pHlp->pfnSSMGetMem(pSSM, &pThis->abRegs1[0], cbRegs1);
     3930    }
     3931
     3932    /*
     3933     * Load lazily activated registers.
     3934     */
     3935    {
     3936        /* Active IRTA_REG. */
     3937        pHlp->pfnSSMGetU64(pSSM, &pThis->uIrtaReg);
     3938        AssertLogRelMsgReturn(!(pThis->uIrtaReg & ~VTD_IRTA_REG_RW_MASK),
     3939                              ("%s: IRTA_REG reserved bits set %#RX64\n", DMAR_LOG_PFX, pThis->uIrtaReg), rcDataErr);
     3940
     3941        /* Active RTADDR_REG. */
     3942        pHlp->pfnSSMGetU64(pSSM, &pThis->uRtaddrReg);
     3943        AssertLogRelMsgReturn(!(pThis->uRtaddrReg & ~VTD_RTADDR_REG_RW_MASK),
     3944                              ("%s: RTADDR_REG reserved bits set %#RX64\n", DMAR_LOG_PFX, pThis->uRtaddrReg), rcDataErr);
     3945    }
     3946
     3947    /*
     3948     * Load and verify terminator marker.
     3949     */
     3950    {
     3951        uint32_t uEndMarker;
     3952        int const rc = pHlp->pfnSSMGetU32(pSSM, &uEndMarker);
     3953        AssertRCReturn(rc, rc);
     3954        AssertLogRelMsgReturn(uEndMarker == UINT32_MAX,
     3955                              ("%s: End marker mismatch (expected %#RX32 got %#RX32)\n", DMAR_LOG_PFX, UINT32_MAX, uEndMarker),
     3956                              rcFmtErr);
     3957    }
     3958    return VINF_SUCCESS;
     3959}
     3960
     3961
     3962/**
     3963 * @callback_method_impl{FNSSMDEVLOADDONE}
     3964 */
     3965static DECLCALLBACK(int) dmarR3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     3966{
     3967    PDMARR3 pThisR3 = PDMDEVINS_2_DATA_CC(pDevIns, PDMARR3);
     3968    LogFlowFunc(("\n"));
     3969    RT_NOREF(pSSM);
     3970    AssertPtrReturn(pThisR3, VERR_INVALID_POINTER);
     3971
     3972    DMAR_LOCK(pDevIns, pThisR3);
     3973    dmarInvQueueThreadWakeUpIfNeeded(pDevIns);
     3974    DMAR_UNLOCK(pDevIns, pThisR3);
     3975    return VINF_SUCCESS;
     3976}
     3977
     3978
     3979/**
    38243980 * @interface_method_impl{PDMDEVREG,pfnReset}
    38253981 */
     
    39224078    PDMPciDevSetStatus(pPciDev,            0);
    39234079    PDMPciDevSetCapabilityList(pPciDev,    0);
    3924 
    39254080    /** @todo VTBAR at 0x180? */
    39264081
     
    39304085    rc = PDMDevHlpPCIRegister(pDevIns, pPciDev);
    39314086    AssertLogRelRCReturn(rc, rc);
    3932 
    3933     /** @todo Register MSI but what's the MSI capability offset? */
    3934 #if 0
    3935     /*
    3936      * Register MSI support for the PCI device.
    3937      * This must be done -after- registering it as a PCI device!
    3938      */
    3939 #endif
    39404087
    39414088    /*
     
    39464093                                   IOMMMIO_FLAGS_READ_DWORD_QWORD | IOMMMIO_FLAGS_WRITE_DWORD_QWORD_ZEROED, "Intel-IOMMU",
    39474094                                   &pThis->hMmio);
     4095    AssertLogRelRCReturn(rc, rc);
     4096
     4097    /*
     4098     * Register saved state handlers.
     4099     */
     4100    rc = PDMDevHlpSSMRegisterEx(pDevIns, DMAR_SAVED_STATE_VERSION, sizeof(DMAR), NULL /* pszBefore */,
     4101                                NULL /* pfnLivePrep */,  NULL /* pfnLiveExec */,  NULL /* pfnLiveVote */,
     4102                                NULL /* pfnSavePrep */,  dmarR3SaveExec, NULL /* pfnSaveDone */,
     4103                                NULL /* pfnLoadPrep */,  dmarR3LoadExec, dmarR3LoadDone);
    39484104    AssertLogRelRCReturn(rc, rc);
    39494105
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