VirtualBox

Changeset 23716 in vbox


Ignore:
Timestamp:
Oct 13, 2009 9:38:42 AM (15 years ago)
Author:
vboxsync
Message:

PDM: Save the device list in pass 0 (as well as in the final pass) so the config can be verified up front.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDM.cpp

    r23584 r23716  
    287287*   Internal Functions                                                         *
    288288*******************************************************************************/
    289 static DECLCALLBACK(int) pdmR3Save(PVM pVM, PSSMHANDLE pSSM);
    290 static DECLCALLBACK(int) pdmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
     289static DECLCALLBACK(int) pdmR3LiveExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass);
     290static DECLCALLBACK(int) pdmR3SaveExec(PVM pVM, PSSMHANDLE pSSM);
     291static DECLCALLBACK(int) pdmR3LoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
    291292static DECLCALLBACK(int) pdmR3LoadPrep(PVM pVM, PSSMHANDLE pSSM);
    292293
     
    357358         */
    358359        rc = SSMR3RegisterInternal(pVM, "pdm", 1, PDM_SAVED_STATE_VERSION, 128,
    359                                    NULL, NULL, NULL,
    360                                    NULL, pdmR3Save, NULL,
    361                                    pdmR3LoadPrep, pdmR3Load, NULL);
     360                                   NULL, pdmR3LiveExec, NULL,
     361                                   NULL, pdmR3SaveExec, NULL,
     362                                   pdmR3LoadPrep, pdmR3LoadExec, NULL);
    362363        if (RT_SUCCESS(rc))
    363364        {
     
    620621
    621622
    622 
     623/**
     624 * Bits that are saved in pass 0 and in the final pass.
     625 *
     626 * @param   pVM             The VM handle.
     627 * @param   pSSM            The saved state handle.
     628 */
     629static void pdmR3SaveBoth(PVM pVM, PSSMHANDLE pSSM)
     630{
     631    /*
     632     * Save the list of device instances so we can check that they're all still
     633     * there when we load the state and that nothing new has been added.
     634     */
     635    uint32_t i = 0;
     636    for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3, i++)
     637    {
     638        SSMR3PutU32(pSSM, i);
     639        SSMR3PutStrZ(pSSM, pDevIns->pDevReg->szDeviceName);
     640        SSMR3PutU32(pSSM, pDevIns->iInstance);
     641    }
     642    SSMR3PutU32(pSSM, UINT32_MAX); /* terminator */
     643}
     644
     645
     646/**
     647 * Live save.
     648 *
     649 * @returns VBox status code.
     650 * @param   pVM             The VM handle.
     651 * @param   pSSM            The saved state handle.
     652 * @param   uPass           The pass.
     653 */
     654static DECLCALLBACK(int) pdmR3LiveExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass)
     655{
     656    LogFlow(("pdmR3LiveExec:\n"));
     657    AssertReturn(uPass == 0, VERR_INTERNAL_ERROR_4);
     658    pdmR3SaveBoth(pVM, pSSM);
     659    return VINF_SSM_DONT_CALL_AGAIN;
     660}
    623661
    624662
     
    627665 *
    628666 * @returns VBox status code.
    629  * @param   pVM             VM Handle.
    630  * @param   pSSM            SSM operation handle.
    631  */
    632 static DECLCALLBACK(int) pdmR3Save(PVM pVM, PSSMHANDLE pSSM)
    633 {
    634     LogFlow(("pdmR3Save:\n"));
     667 * @param   pVM             The VM handle.
     668 * @param   pSSM            The saved state handle.
     669 */
     670static DECLCALLBACK(int) pdmR3SaveExec(PVM pVM, PSSMHANDLE pSSM)
     671{
     672    LogFlow(("pdmR3SaveExec:\n"));
    635673
    636674    /*
     
    647685    SSMR3PutUInt(pSSM, VM_FF_ISSET(pVM, VM_FF_PDM_DMA));
    648686
    649     /*
    650      * Save the list of device instances so we can check that
    651      * they're all still there when we load the state and that
    652      * nothing new have been added.
    653      */
    654     /** @todo We might have to filter out some device classes, like USB attached devices. */
    655     uint32_t i = 0;
    656     for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3, i++)
    657     {
    658         SSMR3PutU32(pSSM, i);
    659         SSMR3PutStrZ(pSSM, pDevIns->pDevReg->szDeviceName);
    660         SSMR3PutU32(pSSM, pDevIns->iInstance);
    661     }
    662     return SSMR3PutU32(pSSM, UINT32_MAX); /* terminator */
     687    pdmR3SaveBoth(pVM, pSSM);
     688    return VINF_SUCCESS;
    663689}
    664690
     
    719745 * @param   uPass           The data pass.
    720746 */
    721 static DECLCALLBACK(int) pdmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     747static DECLCALLBACK(int) pdmR3LoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    722748{
    723749    int rc;
    724750
    725     LogFlow(("pdmR3Load:\n"));
    726     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
     751    LogFlow(("pdmR3LoadExec: uPass=%#x\n", uPass));
    727752
    728753    /*
     
    732757        &&  uVersion != PDM_SAVED_STATE_VERSION_PRE_NMI_FF)
    733758    {
    734         AssertMsgFailed(("pdmR3Load: Invalid version uVersion=%d!\n", uVersion));
     759        AssertMsgFailed(("Invalid version uVersion=%d!\n", uVersion));
    735760        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    736761    }
    737762
    738     /*
    739      * Load the interrupt and DMA states.
    740      */
    741     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    742     {
    743         PVMCPU pVCpu = &pVM->aCpus[idCpu];
    744 
    745         /* APIC interrupt */
    746         RTUINT fInterruptPending = 0;
    747         rc = SSMR3GetUInt(pSSM, &fInterruptPending);
    748         if (RT_FAILURE(rc))
    749             return rc;
    750         if (fInterruptPending & ~1)
    751         {
    752             AssertMsgFailed(("fInterruptPending=%#x (APIC)\n", fInterruptPending));
    753             return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    754         }
    755         AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC));
    756         if (fInterruptPending)
    757             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    758 
    759         /* PIC interrupt */
    760         fInterruptPending = 0;
    761         rc = SSMR3GetUInt(pSSM, &fInterruptPending);
    762         if (RT_FAILURE(rc))
    763             return rc;
    764         if (fInterruptPending & ~1)
    765         {
    766             AssertMsgFailed(("fInterruptPending=%#x (PIC)\n", fInterruptPending));
    767             return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    768         }
    769         AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC));
    770         if (fInterruptPending)
    771             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    772 
    773         if (uVersion > PDM_SAVED_STATE_VERSION_PRE_NMI_FF)
    774         {
    775             /* NMI interrupt */
     763    if (uPass == SSM_PASS_FINAL)
     764    {
     765        /*
     766         * Load the interrupt and DMA states.
     767         */
     768        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     769        {
     770            PVMCPU pVCpu = &pVM->aCpus[idCpu];
     771
     772            /* APIC interrupt */
    776773            RTUINT fInterruptPending = 0;
    777774            rc = SSMR3GetUInt(pSSM, &fInterruptPending);
     
    780777            if (fInterruptPending & ~1)
    781778            {
    782                 AssertMsgFailed(("fInterruptPending=%#x (NMI)\n", fInterruptPending));
     779                AssertMsgFailed(("fInterruptPending=%#x (APIC)\n", fInterruptPending));
    783780                return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    784781            }
    785             AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_NMI));
     782            AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC));
    786783            if (fInterruptPending)
    787                 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
    788 
    789             /* SMI interrupt */
     784                VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     785
     786            /* PIC interrupt */
    790787            fInterruptPending = 0;
    791788            rc = SSMR3GetUInt(pSSM, &fInterruptPending);
     
    794791            if (fInterruptPending & ~1)
    795792            {
    796                 AssertMsgFailed(("fInterruptPending=%#x (SMI)\n", fInterruptPending));
     793                AssertMsgFailed(("fInterruptPending=%#x (PIC)\n", fInterruptPending));
    797794                return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    798795            }
    799             AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_SMI));
     796            AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC));
    800797            if (fInterruptPending)
    801                 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
    802         }
    803     }
    804 
    805     /* DMA pending */
    806     RTUINT fDMAPending = 0;
    807     rc = SSMR3GetUInt(pSSM, &fDMAPending);
    808     if (RT_FAILURE(rc))
    809         return rc;
    810     if (fDMAPending & ~1)
    811     {
    812         AssertMsgFailed(("fDMAPending=%#x\n", fDMAPending));
    813         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    814     }
    815     if (fDMAPending)
    816         VM_FF_SET(pVM, VM_FF_PDM_DMA);
    817     Log(("pdmR3Load: VM_FF_PDM_DMA=%RTbool\n", VM_FF_ISSET(pVM, VM_FF_PDM_DMA)));
     798                VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     799
     800            if (uVersion > PDM_SAVED_STATE_VERSION_PRE_NMI_FF)
     801            {
     802                /* NMI interrupt */
     803                RTUINT fInterruptPending = 0;
     804                rc = SSMR3GetUInt(pSSM, &fInterruptPending);
     805                if (RT_FAILURE(rc))
     806                    return rc;
     807                if (fInterruptPending & ~1)
     808                {
     809                    AssertMsgFailed(("fInterruptPending=%#x (NMI)\n", fInterruptPending));
     810                    return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     811                }
     812                AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_NMI));
     813                if (fInterruptPending)
     814                    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
     815
     816                /* SMI interrupt */
     817                fInterruptPending = 0;
     818                rc = SSMR3GetUInt(pSSM, &fInterruptPending);
     819                if (RT_FAILURE(rc))
     820                    return rc;
     821                if (fInterruptPending & ~1)
     822                {
     823                    AssertMsgFailed(("fInterruptPending=%#x (SMI)\n", fInterruptPending));
     824                    return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     825                }
     826                AssertRelease(!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_SMI));
     827                if (fInterruptPending)
     828                    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
     829            }
     830        }
     831
     832        /* DMA pending */
     833        RTUINT fDMAPending = 0;
     834        rc = SSMR3GetUInt(pSSM, &fDMAPending);
     835        if (RT_FAILURE(rc))
     836            return rc;
     837        if (fDMAPending & ~1)
     838        {
     839            AssertMsgFailed(("fDMAPending=%#x\n", fDMAPending));
     840            return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     841        }
     842        if (fDMAPending)
     843            VM_FF_SET(pVM, VM_FF_PDM_DMA);
     844        Log(("pdmR3LoadExec: VM_FF_PDM_DMA=%RTbool\n", VM_FF_ISSET(pVM, VM_FF_PDM_DMA)));
     845    }
    818846
    819847    /*
     
    821849     */
    822850    for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)
    823         pDevIns->Internal.s.fIntFlags &= PDMDEVINSINT_FLAGS_FOUND;
     851        pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_FOUND;
    824852
    825853    for (uint32_t i = 0; ; i++)
     
    851879                && pDevIns->iInstance == iInstance)
    852880            {
    853                 AssertLogRelReturn(!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_FOUND), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     881                AssertLogRelMsgReturn(!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_FOUND),
     882                                      ("%s/#%u\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance),
     883                                      VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    854884                pDevIns->Internal.s.fIntFlags |= PDMDEVINSINT_FLAGS_FOUND;
    855885                break;
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