VirtualBox

Changeset 108439 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Mar 4, 2025 1:38:06 PM (2 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167813
Message:

VMM/GIC: bugref:10404 Saved-state bits.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/GICR3.cpp

    r108427 r108439  
    5151*********************************************************************************************************************************/
    5252/** GIC saved state version. */
    53 #define GIC_SAVED_STATE_VERSION                     1
     53#define GIC_SAVED_STATE_VERSION                     2
    5454
    5555# define GIC_SYSREGRANGE(a_uFirst, a_uLast, a_szName) \
     
    352352    return rc;
    353353#else
    354     RT_NOREF2(pDevIns, pSSM);
    355     return VERR_NOT_IMPLEMENTED;
     354
     355    PCVM          pVM     = PDMDevHlpGetVM(pDevIns);
     356    PCPDMDEVHLPR3 pHlp    = pDevIns->pHlpR3;
     357    PCGICDEV      pGicDev = PDMDEVINS_2_DATA(pDevIns, PCGICDEV);
     358    AssertPtrReturn(pVM, VERR_INVALID_VM_HANDLE);
     359    LogFlowFunc(("\n"));
     360
     361#define GIC_SSM_PUT_ARRAY(a_pfnSSM, a_Array) \
     362    do \
     363    { \
     364        pHlp->pfnSSMPutU32(pSSM, RT_ELEMENTS(a_Array)); \
     365        for (uint32_t i = 0; i < RT_ELEMENTS(a_Array); i++) \
     366            (a_pfnSSM)(pSSM, (a_Array)[i]); \
     367    } while (0)
     368
     369    /*
     370     * Save per-VM data.
     371     */
     372    pHlp->pfnSSMPutU32(pSSM,  pVM->cCpus);
     373    pHlp->pfnSSMPutU8(pSSM,   pGicDev->uArchRev);
     374    pHlp->pfnSSMPutBool(pSSM, pGicDev->fNmi);
     375    /** @todo I am not sure we really benefit offering this amount of customization
     376     *        right now. It makes the code way more complicated (lots of extra bounds
     377     *        checking in lots of places we cannot really test) and it only reduces
     378     *        functionality rather than increase it in the end. */
     379#if 0
     380    pHlp->pfnSSMPutU16(pSSM,  pGicDev->uMaxSpi);
     381    pHlp->pfnSSMPutU16(pSSM,  pGicDev->uMaxExtSpi);
     382    pHlp->pfnSSMPutU8(pSSM,   pGicDev->fPpiNum);
     383    pHlp->pfnSSMPutBool(pSSM, pGicDev->fExtSpi);
     384    pHlp->pfnSSMPutBool(pSSM, pGicDev->fRangeSelSupport);
     385#endif
     386    pHlp->pfnSSMPutBool(pSSM, pGicDev->fIrqGrp0Enabled);
     387    pHlp->pfnSSMPutBool(pSSM, pGicDev->fIrqGrp1Enabled);
     388    pHlp->pfnSSMPutBool(pSSM, pGicDev->fAffRoutingEnabled);
     389    GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicDev->bmIntrGroup);
     390    GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicDev->bmIntrConfig);
     391    GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicDev->bmIntrEnabled);
     392    GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicDev->bmIntrPending);
     393    GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicDev->bmIntrActive);
     394    GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU8,  pGicDev->abIntrPriority);
     395    GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicDev->au32IntrRouting);
     396    GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicDev->bmIntrRoutingMode);
     397
     398    /*
     399     * Save per-VCPU data.
     400     */
     401    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     402    {
     403        PCGICCPU pGicCpu = VMCPU_TO_GICCPU(pVM->apCpusR3[idCpu]);
     404        Assert(pGicCpu);
     405
     406        GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicCpu->bmIntrGroup);
     407        GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicCpu->bmIntrConfig);
     408        GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicCpu->bmIntrEnabled);
     409        GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicCpu->bmIntrPending);
     410        GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU32, pGicCpu->bmIntrActive);
     411        GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU8,  pGicCpu->abIntrPriority);
     412
     413        pHlp->pfnSSMPutU64(pSSM,             pGicCpu->uIccCtlr);
     414        GIC_SSM_PUT_ARRAY(pHlp->pfnSSMPutU8, pGicCpu->abRunningPriorities);
     415        pHlp->pfnSSMPutU8(pSSM,              pGicCpu->idxRunningPriority);
     416        pHlp->pfnSSMPutU8(pSSM,              pGicCpu->bInterruptPriority);
     417        pHlp->pfnSSMPutU8(pSSM,              pGicCpu->bBinaryPointGrp0);
     418        pHlp->pfnSSMPutU8(pSSM,              pGicCpu->bBinaryPointGrp1);
     419        pHlp->pfnSSMPutBool(pSSM,            pGicCpu->fIrqGrp0Enabled);
     420        pHlp->pfnSSMPutBool(pSSM,            pGicCpu->fIrqGrp1Enabled);
     421    }
     422
     423    return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX);
     424#undef GIC_SSM_PUT_ARRAY
    356425#endif
    357426}
     
    416485    return rc;
    417486#else
    418     RT_NOREF4(pDevIns, pSSM, uVersion, uPass);
    419     return VERR_NOT_IMPLEMENTED;
     487    PVM           pVM  = PDMDevHlpGetVM(pDevIns);
     488    PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
     489
     490    AssertPtrReturn(pVM, VERR_INVALID_VM_HANDLE);
     491    AssertReturn(uPass == SSM_PASS_FINAL, VERR_WRONG_ORDER);
     492    LogFlowFunc(("uVersion=%u uPass=%#x\n", uVersion, uPass));
     493
     494    /*
     495     * Validate supported saved-state versions.
     496     */
     497    if (uVersion != GIC_SAVED_STATE_VERSION)
     498        return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Invalid saved-state version %u (%#x)"), uVersion, uVersion);
     499
     500#define GIC_SSM_GET_ARRAY(a_pfnSSM, a_Array) \
     501    do \
     502    { \
     503        uint32_t       cItems    = 0; \
     504        uint32_t const cExpected = RT_ELEMENTS(a_Array); \
     505        int const      rcSsm     = pHlp->pfnSSMGetU32(pSSM, &cItems); \
     506        AssertRCReturn(rcSsm, rcSsm); \
     507        if (cItems != cExpected) \
     508            return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, \
     509                                           N_("Config mismatch: number of elements in " RT_STR(a_Array) ": got=%u expected=%u"), \
     510                                           cItems, cExpected); \
     511        for (uint32_t i = 0; i < cExpected; i++) \
     512            (a_pfnSSM)(pSSM, &(a_Array)[i]); \
     513    } while (0)
     514
     515    /*
     516     * Load per-VM data.
     517     */
     518    uint32_t cCpus;
     519    pHlp->pfnSSMGetU32(pSSM,  &cCpus);
     520    if (cCpus != pVM->cCpus)
     521        return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch: cCpus: got=%u expected=%u"), cCpus, pVM->cCpus);
     522
     523    PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV);
     524    pHlp->pfnSSMGetU8(pSSM,   &pGicDev->uArchRev);
     525    pHlp->pfnSSMGetBool(pSSM, &pGicDev->fNmi);
     526#if 0
     527    pHlp->pfnSSMGetU16(pSSM,  &pGicDev->uMaxSpi);
     528    pHlp->pfnSSMGetU16(pSSM,  &pGicDev->uMaxExtSpi);
     529    pHlp->pfnSSMGetU8(pSSM,   &pGicDev->fPpiNum);
     530    pHlp->pfnSSMGetBool(pSSM, &pGicDev->fExtSpi);
     531    pHlp->pfnSSMGetBool(pSSM, &pGicDev->fRangeSelSupport);
     532#endif
     533    pHlp->pfnSSMGetBool(pSSM, &pGicDev->fIrqGrp0Enabled);
     534    pHlp->pfnSSMGetBool(pSSM, &pGicDev->fIrqGrp1Enabled);
     535    pHlp->pfnSSMGetBool(pSSM, &pGicDev->fAffRoutingEnabled);
     536    GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicDev->bmIntrGroup);
     537    GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicDev->bmIntrConfig);
     538    GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicDev->bmIntrEnabled);
     539    GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicDev->bmIntrPending);
     540    GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicDev->bmIntrActive);
     541    GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU8,  pGicDev->abIntrPriority);
     542    GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicDev->au32IntrRouting);
     543    GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicDev->bmIntrRoutingMode);
     544
     545    /*
     546     * Load per-VCPU data.
     547     */
     548    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     549    {
     550        PGICCPU pGicCpu = VMCPU_TO_GICCPU(pVM->apCpusR3[idCpu]);
     551        Assert(pGicCpu);
     552
     553        GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicCpu->bmIntrGroup);
     554        GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicCpu->bmIntrConfig);
     555        GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicCpu->bmIntrEnabled);
     556        GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicCpu->bmIntrPending);
     557        GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU32, pGicCpu->bmIntrActive);
     558        GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU8,  pGicCpu->abIntrPriority);
     559
     560        pHlp->pfnSSMGetU64(pSSM,             &pGicCpu->uIccCtlr);
     561        GIC_SSM_GET_ARRAY(pHlp->pfnSSMGetU8, pGicCpu->abRunningPriorities);
     562        pHlp->pfnSSMGetU8(pSSM,              &pGicCpu->idxRunningPriority);
     563        pHlp->pfnSSMGetU8(pSSM,              &pGicCpu->bInterruptPriority);
     564        pHlp->pfnSSMGetU8(pSSM,              &pGicCpu->bBinaryPointGrp0);
     565        pHlp->pfnSSMGetU8(pSSM,              &pGicCpu->bBinaryPointGrp1);
     566        pHlp->pfnSSMGetBool(pSSM,            &pGicCpu->fIrqGrp0Enabled);
     567        pHlp->pfnSSMGetBool(pSSM,            &pGicCpu->fIrqGrp1Enabled);
     568    }
     569
     570    /*
     571     * Check that we're still good wrt restored data.
     572     */
     573    int rc = pHlp->pfnSSMHandleGetStatus(pSSM);
     574    AssertRCReturn(rc, rc);
     575
     576    uint32_t uMarker = 0;
     577    rc = pHlp->pfnSSMGetU32(pSSM, &uMarker);
     578    AssertRCReturn(rc, rc);
     579    if (uMarker == UINT32_MAX)
     580    { /* likely */ }
     581    else
     582        return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch: Marker: got=%u expected=%u"), uMarker, UINT32_MAX);
     583    return rc;
     584#undef GIC_SSM_GET_ARRAY
    420585#endif
    421586}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette