VirtualBox

Changeset 87867 in vbox


Ignore:
Timestamp:
Feb 25, 2021 7:55:17 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 SSM bits.

File:
1 edited

Legend:

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

    r87866 r87867  
    41934193 * Gets the I/O permission and IOMMU operation type for the given access flags.
    41944194 *
     4195 * @param   pThis       The shared IOMMU device state.
    41954196 * @param   fFlags      The PDM IOMMU flags, PDMIOMMU_MEM_F_XXX.
    41964197 * @param   penmOp      Where to store the IOMMU operation.
     
    41984199 * @param   fBulk       Whether this is a bulk read or write.
    41994200 */
    4200 DECLINLINE(void) iommuAmdMemAccessGetPermAndOp(uint32_t fFlags, PIOMMUOP penmOp, uint8_t *pfPerm, bool fBulk)
     4201DECLINLINE(void) iommuAmdMemAccessGetPermAndOp(PIOMMU pThis, uint32_t fFlags, PIOMMUOP penmOp, uint8_t *pfPerm, bool fBulk)
    42014202{
    42024203    if (fFlags & PDMIOMMU_MEM_F_WRITE)
     
    42064207#ifdef VBOX_WITH_STATISTICS
    42074208        if (!fBulk)
    4208             STAM_COUNTER_INC(pThis->CTX_SUFF_Z(StatMemRead));
     4209            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemRead));
    42094210        else
    4210             STAM_COUNTER_INC(pThis->CTX_SUFF_Z(StatMemBulkRead));
     4211            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemBulkRead));
    42114212#else
    4212         RT_NOREF(fBulk);
     4213        RT_NOREF2(pThis, fBulk);
    42134214#endif
    42144215    }
     
    42204221#ifdef VBOX_WITH_STATISTICS
    42214222        if (!fBulk)
    4222             STAM_COUNTER_INC(pThis->CTX_SUFF_Z(StatMemWrite));
     4223            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemWrite));
    42234224        else
    4224             STAM_COUNTER_INC(pThis->CTX_SUFF_Z(StatMemBulkWrite));
     4225            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemBulkWrite));
    42254226#else
    4226         RT_NOREF(fBulk);
     4227        RT_NOREF2(pThis, fBulk);
    42274228#endif
    42284229    }
     
    42604261        IOMMUOP enmOp;
    42614262        uint8_t fPerm;
    4262         iommuAmdMemAccessGetPermAndOp(fFlags, &enmOp, &fPerm, false /* fBulk */);
     4263        iommuAmdMemAccessGetPermAndOp(pThis, fFlags, &enmOp, &fPerm, false /* fBulk */);
    42634264        LogFlowFunc(("%s: uDevId=%#x uIova=%#RX64 cb=%zu\n", iommuAmdMemAccessGetPermName(fPerm), uDevId, uIova, cbAccess));
    4264         NOREF(pThis);
    42654265
    42664266        int rc;
     
    43484348        IOMMUOP enmOp;
    43494349        uint8_t fPerm;
    4350         iommuAmdMemAccessGetPermAndOp(fFlags, &enmOp, &fPerm, true /* fBulk */);
     4350        iommuAmdMemAccessGetPermAndOp(pThis, fFlags, &enmOp, &fPerm, true /* fBulk */);
    43514351        LogFlowFunc(("%s: uDevId=%#x cIovas=%zu\n", iommuAmdMemAccessGetPermName(fPerm), uDevId, cIovas));
    43524352
     
    51575157
    51585158/**
     5159 * Writes the upper 32-bits of the IOMMU base address register.
     5160 *
     5161 * @param   pThis           The shared IOMMU device state.
     5162 * @param   uIommuBarHi     The upper 32-bits of the IOMMU BAR.
     5163 */
     5164static void iommuAmdR3IommuBarHiWrite(PIOMMU pThis, uint32_t uIommuBarHi)
     5165{
     5166    AssertCompile((IOMMU_BAR_VALID_MASK >> 32) == 0xffffffff);
     5167    pThis->IommuBar.au32[1] = uIommuBarHi;
     5168}
     5169
     5170
     5171/**
     5172 * Writes the lower 32-bits of the IOMMU base address register.
     5173 *
     5174 * @param   pDevIns         The IOMMU instance data.
     5175 * @param   pThis           The shared IOMMU device state.
     5176 * @param   uIommuBarLo     The lower 32-bits of the IOMMU BAR.
     5177 */
     5178static VBOXSTRICTRC iommuAmdR3IommuBarLoWrite(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t uIommuBarLo)
     5179{
     5180    pThis->IommuBar.au32[0] = uIommuBarLo & IOMMU_BAR_VALID_MASK;
     5181    if (pThis->IommuBar.n.u1Enable)
     5182    {
     5183        Assert(pThis->hMmio != NIL_IOMMMIOHANDLE);  /* Paranoia. Ensure we have a valid IOM MMIO handle. */
     5184        Assert(!pThis->ExtFeat.n.u1PerfCounterSup); /* Base is 16K aligned when performance counters aren't supported. */
     5185        RTGCPHYS const GCPhysMmioBase     = RT_MAKE_U64(pThis->IommuBar.au32[0] & 0xffffc000, pThis->IommuBar.au32[1]);
     5186        RTGCPHYS const GCPhysMmioBasePrev = PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmio);
     5187
     5188        /* If the MMIO region is already mapped at the specified address, we're done. */
     5189        Assert(GCPhysMmioBase != NIL_RTGCPHYS);
     5190        if (GCPhysMmioBasePrev == GCPhysMmioBase)
     5191            return VINF_SUCCESS;
     5192
     5193        /* Unmap the previous MMIO region (which is at a different address). */
     5194        if (GCPhysMmioBasePrev != NIL_RTGCPHYS)
     5195        {
     5196            LogFlowFunc(("Unmapping previous MMIO region at %#RGp\n", GCPhysMmioBasePrev));
     5197            VBOXSTRICTRC rcStrict = PDMDevHlpMmioUnmap(pDevIns, pThis->hMmio);
     5198            if (RT_FAILURE(rcStrict))
     5199            {
     5200                LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     5201                return rcStrict;
     5202            }
     5203        }
     5204
     5205        /* Map the newly specified MMIO region. */
     5206        LogFlowFunc(("Mapping MMIO region at %#RGp\n", GCPhysMmioBase));
     5207        VBOXSTRICTRC rcStrict = PDMDevHlpMmioMap(pDevIns, pThis->hMmio, GCPhysMmioBase);
     5208        if (RT_FAILURE(rcStrict))
     5209        {
     5210            LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     5211            return rcStrict;
     5212        }
     5213    }
     5214
     5215    return VINF_SUCCESS;
     5216}
     5217
     5218
     5219/**
    51595220 * @callback_method_impl{FNPCICONFIGWRITE}
    51605221 */
     
    51845245    IOMMU_LOCK(pDevIns, pThisR3);
    51855246
    5186     VBOXSTRICTRC rcStrict = VERR_IOMMU_IPE_3;
     5247    VBOXSTRICTRC rcStrict;
    51875248    switch (uAddress)
    51885249    {
    51895250        case IOMMU_PCI_OFF_BASE_ADDR_REG_LO:
    51905251        {
    5191             if (pThis->IommuBar.n.u1Enable)
    5192             {
    5193                 rcStrict = VINF_SUCCESS;
    5194                 LogFunc(("Writing Base Address (Lo) when it's already enabled -> Ignored\n"));
    5195                 break;
    5196             }
    5197 
    5198             pThis->IommuBar.au32[0] = u32Value & IOMMU_BAR_VALID_MASK;
    5199             if (pThis->IommuBar.n.u1Enable)
    5200             {
    5201                 Assert(pThis->hMmio != NIL_IOMMMIOHANDLE);  /* Paranoia. Ensure we have a valid IOM MMIO handle. */
    5202                 Assert(!pThis->ExtFeat.n.u1PerfCounterSup); /* Base is 16K aligned when performance counters aren't supported. */
    5203                 RTGCPHYS const GCPhysMmioBase     = RT_MAKE_U64(pThis->IommuBar.au32[0] & 0xffffc000, pThis->IommuBar.au32[1]);
    5204                 RTGCPHYS const GCPhysMmioBasePrev = PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmio);
    5205 
    5206                 /* If the MMIO region is already mapped at the specified address, we're done. */
    5207                 Assert(GCPhysMmioBase != NIL_RTGCPHYS);
    5208                 if (GCPhysMmioBasePrev == GCPhysMmioBase)
    5209                 {
    5210                     rcStrict = VINF_SUCCESS;
    5211                     break;
    5212                 }
    5213 
    5214                 /* Unmap the previous MMIO region (which is at a different address). */
    5215                 if (GCPhysMmioBasePrev != NIL_RTGCPHYS)
    5216                 {
    5217                     LogFlowFunc(("Unmapping previous MMIO region at %#RGp\n", GCPhysMmioBasePrev));
    5218                     rcStrict = PDMDevHlpMmioUnmap(pDevIns, pThis->hMmio);
    5219                     if (RT_FAILURE(rcStrict))
    5220                     {
    5221                         LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    5222                         break;
    5223                     }
    5224                 }
    5225 
    5226                 /* Map the newly specified MMIO region. */
    5227                 LogFlowFunc(("Mapping MMIO region at %#RGp\n", GCPhysMmioBase));
    5228                 rcStrict = PDMDevHlpMmioMap(pDevIns, pThis->hMmio, GCPhysMmioBase);
    5229                 if (RT_FAILURE(rcStrict))
    5230                 {
    5231                     LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    5232                     break;
    5233                 }
    5234             }
    5235             else
    5236                 rcStrict = VINF_SUCCESS;
    5237             break;
    5238         }
    5239 
    5240         case IOMMU_PCI_OFF_BASE_ADDR_REG_HI:
    5241         {
    52425252            if (!pThis->IommuBar.n.u1Enable)
    5243                 pThis->IommuBar.au32[1] = u32Value;
     5253                rcStrict = iommuAmdR3IommuBarLoWrite(pDevIns, pThis, u32Value);
    52445254            else
    52455255            {
     5256                LogFunc(("Writing Base Address (Lo) when it's already enabled -> Ignored\n"));
    52465257                rcStrict = VINF_SUCCESS;
     5258            }
     5259            break;
     5260        }
     5261
     5262        case IOMMU_PCI_OFF_BASE_ADDR_REG_HI:
     5263        {
     5264            if (!pThis->IommuBar.n.u1Enable)
     5265                iommuAmdR3IommuBarHiWrite(pThis, u32Value);
     5266            else
    52475267                LogFunc(("Writing Base Address (Hi) when it's already enabled -> Ignored\n"));
    5248             }
     5268            rcStrict = VINF_SUCCESS;
    52495269            break;
    52505270        }
     
    61416161
    61426162/**
    6143  * @callback_method_impl{FNSSMDEVLIVEEXEC}
    6144  */
    6145 static DECLCALLBACK(int) iommuAmdR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
     6163 * @callback_method_impl{FNSSMDEVSAVEEXEC}
     6164 */
     6165static DECLCALLBACK(int) iommuAmdR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    61466166{
    61476167    PCIOMMU       pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    61486168    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
    6149     RT_NOREF(uPass);
    61506169    LogFlowFunc(("\n"));
    61516170
    6152     /* Save registers that cannot be modified by the guest. */
     6171    /* First, save ExtFeat and other registers that cannot be modified by the guest. */
    61536172    pHlp->pfnSSMPutU64(pSSM, pThis->ExtFeat.u64);
    61546173    pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificFeat.u64);
     
    61586177    pHlp->pfnSSMPutU64(pSSM, pThis->RsvdReg);
    61596178
    6160     return VINF_SSM_DONT_CALL_AGAIN;
    6161 }
    6162 
    6163 
    6164 /**
    6165  * @callback_method_impl{FNSSMDEVSAVEEXEC}
    6166  */
    6167 static DECLCALLBACK(int) iommuAmdR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    6168 {
    6169     PCIOMMU       pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    6170     PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
    6171     LogFlowFunc(("\n"));
    6172 
     6179    /* Next, save all registers that can be modified by the guest. */
    61736180    pHlp->pfnSSMPutU64(pSSM, pThis->IommuBar.u64);
    61746181
     
    61776184    for (uint8_t i = 0; i < cDevTabBaseAddrs; i++)
    61786185        pHlp->pfnSSMPutU64(pSSM, pThis->aDevTabBaseAddrs[i].u64);
     6186
     6187    AssertReturn(pThis->CmdBufBaseAddr.n.u4Len >= 8, VERR_IOMMU_IPE_4);
    61796188    pHlp->pfnSSMPutU64(pSSM, pThis->CmdBufBaseAddr.u64);
    61806189    pHlp->pfnSSMPutU64(pSSM, pThis->EvtLogBaseAddr.u64);
     
    61836192    pHlp->pfnSSMPutU64(pSSM, pThis->ExclRangeLimit.u64);
    61846193#if 0
    6185     pHlp->pfnSSMPutU64(pSSM, pThis->ExtFeat.u64);  /* read-only, done in liveExec */
     6194    pHlp->pfnSSMPutU64(pSSM, pThis->ExtFeat.u64);  /* read-only, done already (above). */
    61866195#endif
    61876196
     
    61986207
    61996208#if 0
    6200     pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificFeat.u64);       /* read-only, done in liveExec */
    6201     pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificCtrl.u64);       /* read-only, done in liveExec */
    6202     pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificStatus.u64);     /* read-only, done in liveExec */
    6203 
    6204     pHlp->pfnSSMPutU64(pSSM, pThis->MiscInfo.u64);              /* read-only, done in liveExec */
     6209    pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificFeat.u64);       /* read-only, done already (above). */
     6210    pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificCtrl.u64);       /* read-only, done already (above). */
     6211    pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificStatus.u64);     /* read-only, done already (above). */
     6212
     6213    pHlp->pfnSSMPutU64(pSSM, pThis->MiscInfo.u64);              /* read-only, done already (above). */
    62056214#endif
    62066215    pHlp->pfnSSMPutU32(pSSM, pThis->PerfOptCtrl.u32);
     
    62206229
    62216230#if 0
    6222     pHlp->pfnSSMPutU64(pSSM, pThis->RsvdReg);       /* read-only, done in liveExec */
     6231    pHlp->pfnSSMPutU64(pSSM, pThis->RsvdReg);       /* read-only, done already (above). */
    62236232#endif
    62246233
     
    62576266    PIOMMU        pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    62586267    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
     6268    int const     rcErr = VERR_SSM_UNEXPECTED_DATA;
    62596269    LogFlowFunc(("\n"));
    62606270
    62616271    /* Validate. */
    6262     if (uPass != SSM_PASS_FINAL)
    6263         return VINF_SUCCESS;
     6272    AssertReturn(uPass == SSM_PASS_FINAL, VERR_WRONG_ORDER);
    62646273    if (uVersion != IOMMU_SAVED_STATE_VERSION)
     6274    {
     6275        LogRel(("%s: Invalid saved-state version %#x\n", IOMMU_LOG_PFX, uVersion));
    62656276        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    6266     int const rcDataError = VERR_SSM_UNEXPECTED_DATA;
    6267 
     6277    }
     6278
     6279    /* Load ExtFeat and other read-only registers first. */
    62686280    int rc = pHlp->pfnSSMGetU64(pSSM, &pThis->ExtFeat.u64);
    62696281    AssertRCReturn(rc, rc);
    62706282    AssertLogRelMsgReturn(pThis->ExtFeat.n.u2HostAddrTranslateSize < 0x3,
    6271                           ("ExtFeat invalid %#RX64\n", pThis->ExtFeat.u64), rcDataError);
    6272 
     6283                          ("ExtFeat.HATS register invalid %#RX64\n", pThis->ExtFeat.u64), rcErr);
    62736284    pHlp->pfnSSMGetU64(pSSM, &pThis->DevSpecificFeat.u64);
    62746285    pHlp->pfnSSMGetU64(pSSM, &pThis->DevSpecificCtrl.u64);
     
    62776288    pHlp->pfnSSMGetU64(pSSM, &pThis->RsvdReg);
    62786289
     6290    /* IOMMU base address register. */
     6291    rc = pHlp->pfnSSMGetU64(pSSM, &pThis->IommuBar.u64);
     6292    AssertRCReturn(rc, rc);
     6293    pThis->IommuBar.u64 &= IOMMU_BAR_VALID_MASK;
     6294
    62796295    /* Device table base address registers. */
    62806296    uint8_t cDevTabBaseAddrs;
    62816297    rc = pHlp->pfnSSMGetU8(pSSM, &cDevTabBaseAddrs);
    62826298    AssertRCReturn(rc, rc);
    6283     AssertLogRelMsgReturn(cDevTabBaseAddrs <= RT_ELEMENTS(pThis->aDevTabBaseAddrs),
    6284                           ("Device table segment count invalid %#x\n", cDevTabBaseAddrs), rcDataError);
     6299    AssertLogRelMsgReturn(cDevTabBaseAddrs > 0 && cDevTabBaseAddrs <= RT_ELEMENTS(pThis->aDevTabBaseAddrs),
     6300                          ("Device table segment count invalid %#x\n", cDevTabBaseAddrs), rcErr);
    62856301    for (uint8_t i = 0; i < cDevTabBaseAddrs; i++)
    62866302    {
     
    62896305        pThis->aDevTabBaseAddrs[i].u64 &= IOMMU_DEV_TAB_BAR_VALID_MASK;
    62906306        AssertLogRelMsgReturn(pThis->aDevTabBaseAddrs[i].n.u9Size <= g_auDevTabSegMaxSizes[0],
    6291                               ("Device table segment size invalid %#x\n", pThis->aDevTabBaseAddrs[i].n.u9Size), rcDataError);
     6307                              ("Device table segment size invalid %#x\n", pThis->aDevTabBaseAddrs[i].n.u9Size), rcErr);
    62926308    }
    62936309
     
    62976313    pThis->CmdBufBaseAddr.u64 &= IOMMU_CMD_BUF_BAR_VALID_MASK;
    62986314    AssertLogRelMsgReturn(pThis->CmdBufBaseAddr.n.u4Len >= 8,
    6299                           ("Command buffer base address invalid %#RX64\n", pThis->CmdBufBaseAddr.u64), rcDataError);
     6315                          ("Command buffer base address invalid %#RX64\n", pThis->CmdBufBaseAddr.u64), rcErr);
    63006316
    63016317    /* Event log base address register. */
    6302     pHlp->pfnSSMPutU64(pSSM, pThis->EvtLogBaseAddr.u64);
    63036318    rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogBaseAddr.u64);
    63046319    AssertRCReturn(rc, rc);
    63056320    pThis->EvtLogBaseAddr.u64 &= IOMMU_EVT_LOG_BAR_VALID_MASK;
    63066321    AssertLogRelMsgReturn(pThis->EvtLogBaseAddr.n.u4Len >= 8,
    6307                           ("Event log base address invalid %#RX64\n", pThis->EvtLogBaseAddr.u64), rcDataError);
     6322                          ("Event log base address invalid %#RX64\n", pThis->EvtLogBaseAddr.u64), rcErr);
    63086323
    63096324    /* Control register. */
    6310     rc = pHlp->pfnSSMPutU64(pSSM, pThis->Ctrl.u64);
     6325    rc = pHlp->pfnSSMGetU64(pSSM, &pThis->Ctrl.u64);
    63116326    AssertRCReturn(rc, rc);
    63126327    pThis->Ctrl.u64 &= IOMMU_CTRL_VALID_MASK;
    63136328    AssertLogRelMsgReturn(pThis->Ctrl.n.u3DevTabSegEn <= pThis->ExtFeat.n.u2DevTabSegSup,
    6314                           ("Control register invalid %#RX64\n", pThis->Ctrl.u64), rcDataError);
     6329                          ("Control register invalid %#RX64\n", pThis->Ctrl.u64), rcErr);
    63156330
    63166331    /* Exclusion range base address register. */
     
    64026417        rc = pHlp->pfnSSMGetU8(pSSM, &cMarcApers);
    64036418        AssertRCReturn(rc, rc);
    6404         AssertLogRelMsgReturn(cMarcApers <= RT_ELEMENTS(pThis->aMarcApers),
    6405                               ("MARC register count invalid %#x\n", cMarcApers), rcDataError);
     6419        AssertLogRelMsgReturn(cMarcApers > 0 && cMarcApers <= RT_ELEMENTS(pThis->aMarcApers),
     6420                              ("MARC register count invalid %#x\n", cMarcApers), rcErr);
    64066421        for (uint8_t i = 0; i < cMarcApers; i++)
    64076422        {
     
    64236438
    64246439    /* Command buffer head pointer register. */
    6425     {
    6426         rc = pHlp->pfnSSMGetU64(pSSM, &pThis->CmdBufHeadPtr.u64);
    6427         AssertRCReturn(rc, rc);
    6428 
     6440    rc = pHlp->pfnSSMGetU64(pSSM, &pThis->CmdBufHeadPtr.u64);
     6441    AssertRCReturn(rc, rc);
     6442    {
    64296443        /*
    64306444         * IOMMU behavior is undefined when software writes a value outside the buffer length.
     
    64366450        Assert(cbBuf <= _512K);
    64376451        AssertLogRelMsgReturn(offBuf < cbBuf,
    6438                               ("Command buffer head pointer invalid %#x\n", pThis->CmdBufHeadPtr.u64), rcDataError);
     6452                              ("Command buffer head pointer invalid %#x\n", pThis->CmdBufHeadPtr.u64), rcErr);
    64396453    }
    64406454
    64416455    /* Command buffer tail pointer register. */
    6442     {
    6443         rc = pHlp->pfnSSMGetU64(pSSM, &pThis->CmdBufTailPtr.u64);
    6444         AssertRCReturn(rc, rc);
    6445 
     6456    rc = pHlp->pfnSSMGetU64(pSSM, &pThis->CmdBufTailPtr.u64);
     6457    AssertRCReturn(rc, rc);
     6458    {
    64466459        uint32_t const offBuf = pThis->CmdBufTailPtr.u64 & IOMMU_CMD_BUF_TAIL_PTR_VALID_MASK;
    64476460        uint32_t const cbBuf  = iommuAmdGetTotalBufLength(pThis->CmdBufBaseAddr.n.u4Len);
    64486461        Assert(cbBuf <= _512K);
    64496462        AssertLogRelMsgReturn(offBuf < cbBuf,
    6450                               ("Command buffer tail pointer invalid %#x\n", pThis->CmdBufTailPtr.u64), rcDataError);
     6463                              ("Command buffer tail pointer invalid %#x\n", pThis->CmdBufTailPtr.u64), rcErr);
    64516464    }
    64526465
    64536466    /* Event log head pointer register. */
    6454     {
    6455         rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogHeadPtr.u64);
    6456         AssertRCReturn(rc, rc);
    6457 
     6467    rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogHeadPtr.u64);
     6468    AssertRCReturn(rc, rc);
     6469    {
    64586470        uint32_t const offBuf = pThis->EvtLogHeadPtr.u64 & IOMMU_EVT_LOG_HEAD_PTR_VALID_MASK;
    64596471        uint32_t const cbBuf  = iommuAmdGetTotalBufLength(pThis->EvtLogBaseAddr.n.u4Len);
    64606472        Assert(cbBuf <= _512K);
    64616473        AssertLogRelMsgReturn(offBuf < cbBuf,
    6462                               ("Event log head pointer invalid %#x\n", pThis->EvtLogHeadPtr.u64), rcDataError);
     6474                              ("Event log head pointer invalid %#x\n", pThis->EvtLogHeadPtr.u64), rcErr);
    64636475    }
    64646476
    64656477    /* Event log tail pointer register. */
    6466     {
    6467         rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogTailPtr.u64);
    6468         AssertRCReturn(rc, rc);
    6469 
     6478    rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogTailPtr.u64);
     6479    AssertRCReturn(rc, rc);
     6480    {
    64706481        uint32_t const offBuf = pThis->EvtLogTailPtr.u64 & IOMMU_EVT_LOG_TAIL_PTR_VALID_MASK;
    64716482        uint32_t const cbBuf  = iommuAmdGetTotalBufLength(pThis->EvtLogBaseAddr.n.u4Len);
    64726483        Assert(cbBuf <= _512K);
    64736484        AssertLogRelMsgReturn(offBuf < cbBuf,
    6474                               ("Event log tail pointer invalid %#x\n", pThis->EvtLogTailPtr.u64), rcDataError);
     6485                              ("Event log tail pointer invalid %#x\n", pThis->EvtLogTailPtr.u64), rcErr);
    64756486    }
    64766487
     
    65416552        AssertLogRelMsgRCReturn(rc, ("Failed to read end marker. rc=%Rrc\n", rc), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    65426553        AssertLogRelMsgReturn(uEndMarker == UINT32_MAX, ("End marker invalid (%#x expected %#x)\n", uEndMarker, UINT32_MAX),
    6543                               rcDataError);
    6544     }
    6545 
     6554                              rcErr);
     6555    }
     6556
     6557    return rc;
     6558}
     6559
     6560
     6561/**
     6562 * @callback_method_impl{FNSSMDEVLOADDONE}
     6563 */
     6564static DECLCALLBACK(int) iommuAmdR3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     6565{
     6566    PIOMMU   pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     6567    PIOMMUR3 pThisR3 = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUR3);
     6568    RT_NOREF(pSSM);
     6569    LogFlowFunc(("\n"));
     6570
     6571    /* Sanity. */
     6572    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     6573    AssertPtrReturn(pThisR3, VERR_INVALID_POINTER);
     6574
     6575    IOMMU_LOCK(pDevIns, pThisR3);
     6576
     6577    /* Write the IOMMU base registers and map MMIO regions as needed. */
     6578    iommuAmdR3IommuBarHiWrite(pThis, pThis->IommuBar.au32[1]);
     6579    iommuAmdR3IommuBarLoWrite(pDevIns, pThis, pThis->IommuBar.au32[0]);
     6580
     6581    /* Wake up the command thread if commands need processing. */
    65466582    iommuAmdCmdThreadWakeUpIfNeeded(pDevIns);
     6583
     6584    IOMMU_UNLOCK(pDevIns, pThisR3);
    65476585    return VINF_SUCCESS;
    65486586}
     
    68486886     * Register saved state.
    68496887     */
    6850     rc = PDMDevHlpSSMRegister3(pDevIns, IOMMU_SAVED_STATE_VERSION, sizeof(IOMMU), iommuAmdR3LiveExec, iommuAmdR3SaveExec,
    6851                                iommuAmdR3LoadExec);
     6888    rc = PDMDevHlpSSMRegisterEx(pDevIns, IOMMU_SAVED_STATE_VERSION, sizeof(IOMMU), NULL /* pszBefore */,
     6889                                NULL /* pfnLivePrep */,  NULL /* pfnLiveExec */,  NULL /* pfnLiveVote */,
     6890                                NULL /* pfnSavePrep */,  iommuAmdR3SaveExec, NULL /* pfnSaveDone */,
     6891                                NULL /* pfnLoadPrep */,  iommuAmdR3LoadExec, iommuAmdR3LoadDone);
    68526892    AssertLogRelRCReturn(rc, rc);
    68536893
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