VirtualBox

Changeset 81484 in vbox for trunk/src/VBox/Devices/EFI


Ignore:
Timestamp:
Oct 23, 2019 10:27:53 AM (5 years ago)
Author:
vboxsync
Message:

DevEFI.cpp: Implement new style saved states with proper NVRAM support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/DevEFI.cpp

    r81473 r81484  
    272272*********************************************************************************************************************************/
    273273/** The saved state version. */
    274 #define EFI_SSM_VERSION 2
     274#define EFI_SSM_VERSION                  3
     275/** The saved state version before working NVRAM support was implemented. */
     276#define EFI_SSM_VERSION_PRE_PROPER_NVRAM 2
    275277/** The saved state version from VBox 4.2. */
    276 #define EFI_SSM_VERSION_4_2 1
     278#define EFI_SSM_VERSION_4_2              1
    277279
    278280/** Non-volatile EFI variable. */
     
    16531655    LogFlow(("efiSaveExec:\n"));
    16541656
    1655     /*
    1656      * Set variables only used when saving state.
    1657      */
    1658     uint32_t idUniqueSavedState = 0;
    1659     PEFIVAR pEfiVar;
    1660     RTListForEach(&pThis->NVRAM.VarList, pEfiVar, EFIVAR, ListNode)
    1661     {
    1662         pEfiVar->idUniqueSavedState = idUniqueSavedState++;
    1663     }
    1664     Assert(idUniqueSavedState == pThis->NVRAM.cVariables);
    1665 
    1666     pThis->NVRAM.idUniqueCurVar = pThis->NVRAM.pCurVar
    1667                                 ? pThis->NVRAM.pCurVar->idUniqueSavedState
    1668                                 : UINT32_MAX;
    1669 
    1670     /*
    1671      * Save the NVRAM state.
    1672      */
    1673     SSMR3PutStructEx(pSSM, &pThis->NVRAM,          sizeof(NVRAMDESC), 0, g_aEfiNvramDescField,     NULL);
    1674     SSMR3PutStructEx(pSSM, &pThis->NVRAM.VarOpBuf, sizeof(EFIVAR),    0, g_aEfiVariableDescFields, NULL);
    1675 
    1676     /*
    1677      * Save the list variables (we saved the length above).
    1678      */
    1679     RTListForEach(&pThis->NVRAM.VarList, pEfiVar, EFIVAR, ListNode)
    1680     {
    1681         SSMR3PutStructEx(pSSM, pEfiVar, sizeof(EFIVAR), 0, g_aEfiVariableDescFields, NULL);
    1682     }
    1683 
    1684     return VINF_SUCCESS; /* SSM knows */
     1657    return flashR3SsmSaveExec(&pThis->Flash, pSSM);
    16851658}
    16861659
     
    16961669        return VERR_SSM_UNEXPECTED_PASS;
    16971670    if (   uVersion != EFI_SSM_VERSION
     1671        && uVersion != EFI_SSM_VERSION_PRE_PROPER_NVRAM
    16981672        && uVersion != EFI_SSM_VERSION_4_2
    16991673        )
    17001674        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    17011675
    1702     /*
    1703      * Kill the current variables before loading anything.
    1704      */
    1705     nvramFlushDeviceVariableList(pThis);
    1706 
    1707     /*
    1708      * Load the NVRAM state.
    1709      */
    1710     int rc = SSMR3GetStructEx(pSSM, &pThis->NVRAM, sizeof(NVRAMDESC), 0, g_aEfiNvramDescField, NULL);
    1711     AssertRCReturn(rc, rc);
    1712     pThis->NVRAM.pCurVar = NULL;
    1713 
    1714     rc = SSMR3GetStructEx(pSSM, &pThis->NVRAM.VarOpBuf, sizeof(EFIVAR), 0, g_aEfiVariableDescFields, NULL);
    1715     AssertRCReturn(rc, rc);
    1716 
    1717     /*
    1718      * Load variables.
    1719      */
    1720     pThis->NVRAM.pCurVar = NULL;
    1721     Assert(RTListIsEmpty(&pThis->NVRAM.VarList));
    1722     RTListInit(&pThis->NVRAM.VarList);
    1723     for (uint32_t i = 0; i < pThis->NVRAM.cVariables; i++)
    1724     {
    1725         PEFIVAR pEfiVar = (PEFIVAR)RTMemAllocZ(sizeof(EFIVAR));
    1726         AssertReturn(pEfiVar, VERR_NO_MEMORY);
    1727 
    1728         rc = SSMR3GetStructEx(pSSM, pEfiVar, sizeof(EFIVAR), 0, g_aEfiVariableDescFields, NULL);
    1729         if (RT_SUCCESS(rc))
     1676    int rc;
     1677    if (uVersion > EFI_SSM_VERSION_PRE_PROPER_NVRAM)
     1678        rc = flashR3SsmLoadExec(&pThis->Flash, pSSM);
     1679    else
     1680    {
     1681        /*
     1682         * Kill the current variables before loading anything.
     1683         */
     1684        nvramFlushDeviceVariableList(pThis);
     1685
     1686        /*
     1687         * Load the NVRAM state.
     1688         */
     1689        rc = SSMR3GetStructEx(pSSM, &pThis->NVRAM, sizeof(NVRAMDESC), 0, g_aEfiNvramDescField, NULL);
     1690        AssertRCReturn(rc, rc);
     1691        pThis->NVRAM.pCurVar = NULL;
     1692
     1693        rc = SSMR3GetStructEx(pSSM, &pThis->NVRAM.VarOpBuf, sizeof(EFIVAR), 0, g_aEfiVariableDescFields, NULL);
     1694        AssertRCReturn(rc, rc);
     1695
     1696        /*
     1697         * Load variables.
     1698         */
     1699        pThis->NVRAM.pCurVar = NULL;
     1700        Assert(RTListIsEmpty(&pThis->NVRAM.VarList));
     1701        RTListInit(&pThis->NVRAM.VarList);
     1702        for (uint32_t i = 0; i < pThis->NVRAM.cVariables; i++)
    17301703        {
    1731             if (   pEfiVar->cbValue > sizeof(pEfiVar->abValue)
    1732                 || pEfiVar->cbValue == 0)
     1704            PEFIVAR pEfiVar = (PEFIVAR)RTMemAllocZ(sizeof(EFIVAR));
     1705            AssertReturn(pEfiVar, VERR_NO_MEMORY);
     1706
     1707            rc = SSMR3GetStructEx(pSSM, pEfiVar, sizeof(EFIVAR), 0, g_aEfiVariableDescFields, NULL);
     1708            if (RT_SUCCESS(rc))
    17331709            {
    1734                 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    1735                 LogRel(("EFI: Loaded invalid variable value length %#x\n", pEfiVar->cbValue));
     1710                if (   pEfiVar->cbValue > sizeof(pEfiVar->abValue)
     1711                    || pEfiVar->cbValue == 0)
     1712                {
     1713                    rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     1714                    LogRel(("EFI: Loaded invalid variable value length %#x\n", pEfiVar->cbValue));
     1715                }
     1716                uint32_t cchVarName = (uint32_t)RTStrNLen(pEfiVar->szName, sizeof(pEfiVar->szName));
     1717                if (cchVarName >= sizeof(pEfiVar->szName))
     1718                {
     1719                    rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     1720                    LogRel(("EFI: Loaded variable name is unterminated.\n"));
     1721                }
     1722                if (pEfiVar->cchName > cchVarName) /* No check for 0 here, busted load code in 4.2, so now storing 0 here. */
     1723                {
     1724                    rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     1725                    LogRel(("EFI: Loaded invalid variable name length %#x (cchVarName=%#x)\n", pEfiVar->cchName, cchVarName));
     1726                }
     1727                if (RT_SUCCESS(rc))
     1728                    pEfiVar->cchName = cchVarName;
    17361729            }
    1737             uint32_t cchVarName = (uint32_t)RTStrNLen(pEfiVar->szName, sizeof(pEfiVar->szName));
    1738             if (cchVarName >= sizeof(pEfiVar->szName))
    1739             {
    1740                 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    1741                 LogRel(("EFI: Loaded variable name is unterminated.\n"));
    1742             }
    1743             if (pEfiVar->cchName > cchVarName) /* No check for 0 here, busted load code in 4.2, so now storing 0 here. */
    1744             {
    1745                 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    1746                 LogRel(("EFI: Loaded invalid variable name length %#x (cchVarName=%#x)\n", pEfiVar->cchName, cchVarName));
    1747             }
    1748             if (RT_SUCCESS(rc))
    1749                 pEfiVar->cchName = cchVarName;
     1730            AssertRCReturnStmt(rc, RTMemFree(pEfiVar), rc);
     1731
     1732            /* Add it (not using nvramInsertVariable to preserve saved order),
     1733               updating the current variable pointer while we're here. */
     1734#if 1
     1735            RTListAppend(&pThis->NVRAM.VarList, &pEfiVar->ListNode);
     1736#else
     1737            nvramInsertVariable(pThis, pEfiVar);
     1738#endif
     1739            if (pThis->NVRAM.idUniqueCurVar == pEfiVar->idUniqueSavedState)
     1740                pThis->NVRAM.pCurVar = pEfiVar;
    17501741        }
    1751         AssertRCReturnStmt(rc, RTMemFree(pEfiVar), rc);
    1752 
    1753         /* Add it (not using nvramInsertVariable to preserve saved order),
    1754            updating the current variable pointer while we're here. */
    1755 #if 1
    1756         RTListAppend(&pThis->NVRAM.VarList, &pEfiVar->ListNode);
    1757 #else
    1758         nvramInsertVariable(pThis, pEfiVar);
    1759 #endif
    1760         if (pThis->NVRAM.idUniqueCurVar == pEfiVar->idUniqueSavedState)
    1761             pThis->NVRAM.pCurVar = pEfiVar;
    1762     }
    1763 
    1764     return VINF_SUCCESS;
     1742    }
     1743
     1744    return rc;
    17651745}
    17661746
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