diff options
| author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
|---|---|---|
| committer | <> | 2014-05-08 15:03:54 +0000 |
| commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
| tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/VMMR3/SSM.cpp | |
| parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
| download | VirtualBox-master.tar.gz | |
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/VMM/VMMR3/SSM.cpp')
| -rw-r--r-- | src/VBox/VMM/VMMR3/SSM.cpp | 416 |
1 files changed, 280 insertions, 136 deletions
diff --git a/src/VBox/VMM/VMMR3/SSM.cpp b/src/VBox/VMM/VMMR3/SSM.cpp index e303d0a6..5d77327a 100644 --- a/src/VBox/VMM/VMMR3/SSM.cpp +++ b/src/VBox/VMM/VMMR3/SSM.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -146,9 +146,12 @@ #define LOG_GROUP LOG_GROUP_SSM #include <VBox/vmm/ssm.h> #include <VBox/vmm/dbgf.h> +#include <VBox/vmm/pdmapi.h> +#include <VBox/vmm/pdmcritsect.h> #include <VBox/vmm/mm.h> #include "SSMInternal.h" #include <VBox/vmm/vm.h> +#include <VBox/vmm/uvm.h> #include <VBox/err.h> #include <VBox/log.h> #include <VBox/version.h> @@ -1091,7 +1094,7 @@ static DECLCALLBACK(int) ssmR3LiveControlLoadExec(PVM pVM, PSSMHANDLE pSSM, uint AssertMsg(uPct < 100, ("uPct=%d uPartsPerTenThousand=%d uPercentPrepare=%d uPercentDone=%d\n", uPct, uPartsPerTenThousand, pSSM->uPercentPrepare, pSSM->uPercentDone)); pSSM->uPercent = uPct; if (pSSM->pfnProgress) - pSSM->pfnProgress(pVM, RT_MIN(uPct, 100 - pSSM->uPercentDone), pSSM->pvUser); + pSSM->pfnProgress(pVM->pUVM, RT_MIN(uPct, 100 - pSSM->uPercentDone), pSSM->pvUser); } } return rc; @@ -1231,10 +1234,12 @@ static int ssmR3Register(PVM pVM, const char *pszName, uint32_t uInstance, * @param pfnLoadExec Execute load callback, optional. * @param pfnLoadDone Done load callback, optional. */ -VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, const char *pszBefore, - PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote, - PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, - PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone) +VMMR3_INT_DECL(int) +SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, + uint32_t uInstance, uint32_t uVersion, size_t cbGuess, const char *pszBefore, + PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote, + PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, + PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone) { PSSMUNIT pUnit; int rc = ssmR3Register(pVM, pszName, uInstance, uVersion, cbGuess, pszBefore, &pUnit); @@ -1251,6 +1256,7 @@ VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszN pUnit->u.Dev.pfnLoadExec = pfnLoadExec; pUnit->u.Dev.pfnLoadDone = pfnLoadDone; pUnit->u.Dev.pDevIns = pDevIns; + pUnit->pCritSect = PDMR3DevGetCritSect(pVM, pDevIns); } return rc; } @@ -1282,10 +1288,11 @@ VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszN * @param pfnLoadExec Execute load callback, optional. * @param pfnLoadDone Done load callback, optional. */ -VMMR3DECL(int) SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, - PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote, - PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone, - PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone) +VMMR3_INT_DECL(int) +SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, + PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote, + PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone, + PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone) { PSSMUNIT pUnit; int rc = ssmR3Register(pVM, pszName, uInstance, uVersion, cbGuess, NULL, &pUnit); @@ -1361,7 +1368,7 @@ VMMR3DECL(int) SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uIns * * @returns VBox status. * - * @param pVM Pointer to the VM. + * @param pUVM The user mode VM handle. * @param pszName Data unit name. * @param uInstance The instance identifier of the data unit. * This must together with the name be unique. @@ -1382,11 +1389,15 @@ VMMR3DECL(int) SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uIns * @param pfnLoadDone Done load callback, optional. * @param pvUser User argument. */ -VMMR3DECL(int) SSMR3RegisterExternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, +VMMR3DECL(int) SSMR3RegisterExternal(PUVM pUVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote, PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone, PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser) { + UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); + PVM pVM = pUVM->pVM; + VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); + PSSMUNIT pUnit; int rc = ssmR3Register(pVM, pszName, uInstance, uVersion, cbGuess, NULL, &pUnit); if (RT_SUCCESS(rc)) @@ -1408,6 +1419,37 @@ VMMR3DECL(int) SSMR3RegisterExternal(PVM pVM, const char *pszName, uint32_t uIns /** + * @callback_method_impl{FNSSMINTLOADEXEC, + * Stub that skips the whole unit (see SSMR3RegisterStub).} + */ +static DECLCALLBACK(int) ssmR3LoadExecStub(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) +{ + NOREF(pVM); NOREF(uVersion); NOREF(uPass); + return SSMR3SkipToEndOfUnit(pSSM); +} + + +/** + * Registers a stub state loader for working around legacy. + * + * This is used to deal with irelevant PATM and CSAM saved state units in HM + * mode and when built without raw-mode. + * + * @returns VBox status code. + * @param pVM The VM handle. + * @param pszName Data unit name. + * @param uInstance Instance number. + */ +VMMR3DECL(int) SSMR3RegisterStub(PVM pVM, const char *pszName, uint32_t uInstance) +{ + return SSMR3RegisterInternal(pVM, pszName, uInstance, UINT32_MAX, 0, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, ssmR3LoadExecStub, NULL); +} + + +/** * Deregister one or more PDM Device data units. * * @returns VBox status. @@ -1637,8 +1679,12 @@ VMMR3DECL(int) SSMR3DeregisterInternal(PVM pVM, const char *pszName) * @param pszName Data unit name. * @remark Only for dynamic data units. */ -VMMR3DECL(int) SSMR3DeregisterExternal(PVM pVM, const char *pszName) +VMMR3DECL(int) SSMR3DeregisterExternal(PUVM pUVM, const char *pszName) { + UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); + PVM pVM = pUVM->pVM; + VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); + return ssmR3DeregisterByNameAndType(pVM, pszName, SSMUNITTYPE_EXTERNAL); } @@ -2978,7 +3024,7 @@ static void ssmR3ProgressByByte(PSSMHANDLE pSSM, uint64_t cbAdvance) && pSSM->uPercent <= 100 - pSSM->uPercentDone) { if (pSSM->pfnProgress) - pSSM->pfnProgress(pSSM->pVM, pSSM->uPercent, pSSM->pvUser); + pSSM->pfnProgress(pSSM->pVM->pUVM, pSSM->uPercent, pSSM->pvUser); pSSM->uPercent++; pSSM->offEstProgress = (pSSM->uPercent - pSSM->uPercentPrepare - pSSM->uPercentLive) * pSSM->cbEstTotal / (100 - pSSM->uPercentDone - pSSM->uPercentPrepare - pSSM->uPercentLive); @@ -3421,24 +3467,25 @@ VMMR3DECL(int) SSMR3PutStruct(PSSMHANDLE pSSM, const void *pvStruct, PCSSMFIELD break; case SSMFIELDTRANS_GCPTR: - AssertMsgReturn(pCur->cb == sizeof(RTGCPTR), ("%#x (%s)\n", pCur->cb, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTGCPTR), ("%#x (%s)\n", pCur->cb, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3PutGCPtr(pSSM, *(PRTGCPTR)pbField); break; case SSMFIELDTRANS_GCPHYS: - AssertMsgReturn(pCur->cb == sizeof(RTGCPHYS), ("%#x (%s)\n", pCur->cb, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTGCPHYS), ("%#x (%s)\n", pCur->cb, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3PutGCPhys(pSSM, *(PRTGCPHYS)pbField); break; case SSMFIELDTRANS_RCPTR: - AssertMsgReturn(pCur->cb == sizeof(RTRCPTR), ("%#x (%s)\n", pCur->cb, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTRCPTR), ("%#x (%s)\n", pCur->cb, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3PutRCPtr(pSSM, *(PRTRCPTR)pbField); break; case SSMFIELDTRANS_RCPTR_ARRAY: { uint32_t const cEntries = pCur->cb / sizeof(RTRCPTR); - AssertMsgReturn(pCur->cb == cEntries * sizeof(RTRCPTR) && cEntries, ("%#x (%s)\n", pCur->cb, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == cEntries * sizeof(RTRCPTR) && cEntries, ("%#x (%s)\n", pCur->cb, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = VINF_SUCCESS; for (uint32_t i = 0; i < cEntries && RT_SUCCESS(rc); i++) rc = SSMR3PutRCPtr(pSSM, ((PRTRCPTR)pbField)[i]); @@ -3446,10 +3493,14 @@ VMMR3DECL(int) SSMR3PutStruct(PSSMHANDLE pSSM, const void *pvStruct, PCSSMFIELD } default: - AssertMsgFailedReturn(("%#x\n", pCur->pfnGetPutOrTransformer), VERR_SSM_FIELD_COMPLEX); + AssertMsgFailedBreakStmt(("%#x\n", pCur->pfnGetPutOrTransformer), rc = VERR_SSM_FIELD_COMPLEX); } if (RT_FAILURE(rc)) + { + if (RT_SUCCESS(pSSM->rc)) + pSSM->rc = rc; return rc; + } } /* end marker */ @@ -3521,7 +3572,7 @@ VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cb */ SSM_ASSERT_WRITEABLE_RET(pSSM); SSM_CHECK_CANCELLED_RET(pSSM); - AssertMsgReturn(!(fFlags & ~SSMSTRUCT_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); + AssertMsgReturn(!(fFlags & ~SSMSTRUCT_FLAGS_VALID_MASK), ("%#x\n", fFlags), pSSM->rc = VERR_INVALID_PARAMETER); AssertPtr(pvStruct); AssertPtr(paFields); @@ -3539,6 +3590,7 @@ VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cb /* * Put the fields */ + rc = VINF_SUCCESS; uint32_t off = 0; for (PCSSMFIELD pCur = paFields; pCur->cb != UINT32_MAX && pCur->off != UINT32_MAX; @@ -3553,15 +3605,15 @@ VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cb : SSMFIELDTRANS_IS_PADDING(pCur->pfnGetPutOrTransformer) ? RT_HIWORD(pCur->cb) : pCur->cb; - AssertMsgReturn( cbField <= cbStruct - && offField + cbField <= cbStruct - && offField + cbField >= offField, - ("off=%#x cb=%#x cbStruct=%#x (%s)\n", cbField, offField, cbStruct, pCur->pszName), - VERR_SSM_FIELD_OUT_OF_BOUNDS); - AssertMsgReturn( !(fFlags & SSMSTRUCT_FLAGS_FULL_STRUCT) - || off == offField, - ("off=%#x offField=%#x (%s)\n", off, offField, pCur->pszName), - VERR_SSM_FIELD_NOT_CONSECUTIVE); + AssertMsgBreakStmt( cbField <= cbStruct + && offField + cbField <= cbStruct + && offField + cbField >= offField, + ("off=%#x cb=%#x cbStruct=%#x (%s)\n", cbField, offField, cbStruct, pCur->pszName), + rc = VERR_SSM_FIELD_OUT_OF_BOUNDS); + AssertMsgBreakStmt( !(fFlags & SSMSTRUCT_FLAGS_FULL_STRUCT) + || off == offField, + ("off=%#x offField=%#x (%s)\n", off, offField, pCur->pszName), + rc = VERR_SSM_FIELD_NOT_CONSECUTIVE); rc = VINF_SUCCESS; uint8_t const *pbField = (uint8_t const *)pvStruct + offField; @@ -3572,53 +3624,60 @@ VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cb break; case SSMFIELDTRANS_GCPHYS: - AssertMsgReturn(cbField == sizeof(RTGCPHYS), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTGCPHYS), ("%#x (%s)\n", cbField, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3PutGCPhys(pSSM, *(PRTGCPHYS)pbField); break; case SSMFIELDTRANS_GCPTR: - AssertMsgReturn(cbField == sizeof(RTGCPTR), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTGCPTR), ("%#x (%s)\n", cbField, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3PutGCPtr(pSSM, *(PRTGCPTR)pbField); break; case SSMFIELDTRANS_RCPTR: - AssertMsgReturn(cbField == sizeof(RTRCPTR), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTRCPTR), ("%#x (%s)\n", cbField, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3PutRCPtr(pSSM, *(PRTRCPTR)pbField); break; case SSMFIELDTRANS_RCPTR_ARRAY: { uint32_t const cEntries = cbField / sizeof(RTRCPTR); - AssertMsgReturn(cbField == cEntries * sizeof(RTRCPTR) && cEntries, ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == cEntries * sizeof(RTRCPTR) && cEntries, ("%#x (%s)\n", cbField, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); for (uint32_t i = 0; i < cEntries && RT_SUCCESS(rc); i++) rc = SSMR3PutRCPtr(pSSM, ((PRTRCPTR)pbField)[i]); break; } case SSMFIELDTRANS_HCPTR_NI: - AssertMsgReturn(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = ssmR3PutHCPtrNI(pSSM, *(void * const *)pbField, fFlags); break; case SSMFIELDTRANS_HCPTR_NI_ARRAY: { uint32_t const cEntries = cbField / sizeof(void *); - AssertMsgReturn(cbField == cEntries * sizeof(void *) && cEntries, ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == cEntries * sizeof(void *) && cEntries, ("%#x (%s)\n", cbField, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); for (uint32_t i = 0; i < cEntries && RT_SUCCESS(rc); i++) rc = ssmR3PutHCPtrNI(pSSM, ((void * const *)pbField)[i], fFlags); break; } case SSMFIELDTRANS_HCPTR_HACK_U32: - AssertMsgReturn(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); - AssertMsgReturn(*(uintptr_t *)pbField <= UINT32_MAX, ("%p (%s)\n", *(uintptr_t *)pbField, pCur->pszName), VERR_SSM_FIELD_INVALID_VALUE); + AssertMsgBreakStmt(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(*(uintptr_t *)pbField <= UINT32_MAX, ("%p (%s)\n", *(uintptr_t *)pbField, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_VALUE); rc = ssmR3DataWrite(pSSM, pbField, sizeof(uint32_t)); - if ((fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) && sizeof(void *) != sizeof(uint32_t)) + if ((fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) && sizeof(void *) != sizeof(uint32_t) && RT_SUCCESS(rc)) rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(uint32_t)); break; case SSMFIELDTRANS_U32_ZX_U64: - AssertFailedReturn(VERR_SSM_FIELD_LOAD_ONLY_TRANSFORMATION); + AssertFailedBreakStmt(rc = VERR_SSM_FIELD_LOAD_ONLY_TRANSFORMATION); break; case SSMFIELDTRANS_IGNORE: @@ -3627,62 +3686,68 @@ VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cb break; case SSMFIELDTRANS_IGN_GCPHYS: - AssertMsgReturn(cbField == sizeof(RTGCPHYS), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTGCPHYS), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(RTGCPHYS)); break; case SSMFIELDTRANS_IGN_GCPTR: - AssertMsgReturn(cbField == sizeof(RTGCPTR), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTGCPTR), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(RTGCPTR)); break; case SSMFIELDTRANS_IGN_RCPTR: - AssertMsgReturn(cbField == sizeof(RTRCPTR), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTRCPTR), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(RTRCPTR)); break; case SSMFIELDTRANS_IGN_HCPTR: - AssertMsgReturn(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(void *)); break; case SSMFIELDTRANS_OLD: - AssertMsgReturn(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = ssmR3PutZeros(pSSM, pCur->cb); break; case SSMFIELDTRANS_OLD_GCPHYS: - AssertMsgReturn(pCur->cb == sizeof(RTGCPHYS) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTGCPHYS) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(RTGCPHYS)); break; case SSMFIELDTRANS_OLD_GCPTR: - AssertMsgReturn(pCur->cb == sizeof(RTGCPTR) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTGCPTR) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(RTGCPTR)); break; case SSMFIELDTRANS_OLD_RCPTR: - AssertMsgReturn(pCur->cb == sizeof(RTRCPTR) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTRCPTR) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(RTRCPTR)); break; case SSMFIELDTRANS_OLD_HCPTR: - AssertMsgReturn(pCur->cb == sizeof(void *) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(void *) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = ssmR3DataWrite(pSSM, g_abZero, sizeof(void *)); break; case SSMFIELDTRANS_OLD_PAD_HC: - AssertMsgReturn(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); rc = ssmR3PutZeros(pSSM, HC_ARCH_BITS == 64 ? RT_HIWORD(pCur->cb) : RT_LOWORD(pCur->cb)); break; case SSMFIELDTRANS_OLD_PAD_MSC32: - AssertMsgReturn(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_SIZE); if (SSM_HOST_IS_MSC_32) rc = ssmR3PutZeros(pSSM, pCur->cb); break; @@ -3704,37 +3769,46 @@ VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cb || ( (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_MSC32_AUTO && !ssmR3IsHostMsc32(pSSM)) ? cb64 : cb32; - AssertMsgReturn( cbField == cbCtx - && ( ( pCur->off == UINT32_MAX / 2 - && ( cbField == 0 - || (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_HC_AUTO - || (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_MSC32_AUTO - ) + AssertMsgBreakStmt( cbField == cbCtx + && ( ( pCur->off == UINT32_MAX / 2 + && ( cbField == 0 + || (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_HC_AUTO + || (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_MSC32_AUTO + ) + ) + || (pCur->off != UINT32_MAX / 2 && cbField != 0) ) - || (pCur->off != UINT32_MAX / 2 && cbField != 0) - ) - , ("cbField=%#x cb32=%#x cb64=%#x HC_ARCH_BITS=%u cbCtx=%#x cbSaved=%#x off=%#x\n", - cbField, cb32, cb64, HC_ARCH_BITS, cbCtx, cbSaved, pCur->off), - VERR_SSM_FIELD_INVALID_PADDING_SIZE); + , ("cbField=%#x cb32=%#x cb64=%#x HC_ARCH_BITS=%u cbCtx=%#x cbSaved=%#x off=%#x\n", + cbField, cb32, cb64, HC_ARCH_BITS, cbCtx, cbSaved, pCur->off), + rc = VERR_SSM_FIELD_INVALID_PADDING_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = ssmR3PutZeros(pSSM, cbSaved); break; } default: - AssertPtrReturn(pCur->pfnGetPutOrTransformer, VERR_SSM_FIELD_INVALID_CALLBACK); + AssertPtrBreakStmt(pCur->pfnGetPutOrTransformer, rc = VERR_SSM_FIELD_INVALID_CALLBACK); rc = pCur->pfnGetPutOrTransformer(pSSM, pCur, (void *)pvStruct, fFlags, false /*fGetOrPut*/, pvUser); break; } if (RT_FAILURE(rc)) - return rc; + break; /* Deal with failures in one place (see below). */ off = offField + cbField; } - AssertMsgReturn( !(fFlags & SSMSTRUCT_FLAGS_FULL_STRUCT) - || off == cbStruct, - ("off=%#x cbStruct=%#x\n", off, cbStruct), - VERR_SSM_FIELD_NOT_CONSECUTIVE); + + if (RT_SUCCESS(rc)) + AssertMsgStmt( !(fFlags & SSMSTRUCT_FLAGS_FULL_STRUCT) + || off == cbStruct, + ("off=%#x cbStruct=%#x\n", off, cbStruct), + rc = VERR_SSM_FIELD_NOT_CONSECUTIVE); + + if (RT_FAILURE(rc)) + { + if (RT_SUCCESS(pSSM->rc)) + pSSM->rc = rc; + return rc; + } /* * End marker @@ -4229,6 +4303,39 @@ static int ssmR3LiveControlEmit(PSSMHANDLE pSSM, long double lrdPct, uint32_t uP } + +/** + * Enters the critical session (optionally) associated with the unit. + * + * @param pUnit The unit. + */ +DECLINLINE(void) ssmR3UnitCritSectEnter(PSSMUNIT pUnit) +{ + PPDMCRITSECT pCritSect = pUnit->pCritSect; + if (pCritSect) + { + int rc = PDMCritSectEnter(pCritSect, VERR_IGNORED); + AssertRC(rc); + } +} + + +/** + * Leaves the critical session (optionally) associated with the unit. + * + * @param pUnit The unit. + */ +DECLINLINE(void) ssmR3UnitCritSectLeave(PSSMUNIT pUnit) +{ + PPDMCRITSECT pCritSect = pUnit->pCritSect; + if (pCritSect) + { + int rc = PDMCritSectLeave(pCritSect); + AssertRC(rc); + } +} + + /** * Do the pfnSaveDone run. * @@ -4252,6 +4359,7 @@ static int ssmR3SaveDoDoneRun(PVM pVM, PSSMHANDLE pSSM) { int rcOld = pSSM->rc; int rc; + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -4270,6 +4378,7 @@ static int ssmR3SaveDoDoneRun(PVM pVM, PSSMHANDLE pSSM) rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); if (RT_SUCCESS(rc) && pSSM->rc != rcOld) rc = pSSM->rc; if (RT_FAILURE(rc)) @@ -4308,7 +4417,7 @@ static int ssmR3SaveDoClose(PVM pVM, PSSMHANDLE pSSM) { Assert(pSSM->enmOp == SSMSTATE_SAVE_DONE); if (pSSM->pfnProgress) - pSSM->pfnProgress(pVM, 100, pSSM->pvUser); + pSSM->pfnProgress(pVM->pUVM, 100, pSSM->pvUser); LogRel(("SSM: Successfully saved the VM state to '%s'\n", pSSM->pszFilename ? pSSM->pszFilename : "<remote-machine>")); } @@ -4524,7 +4633,7 @@ static void ssmR3ProgressByUnit(PSSMHANDLE pSSM, uint32_t iUnit) { ssmR3LiveControlEmit(pSSM, lrdPct, SSM_PASS_FINAL); pSSM->uPercent = uPct; - pSSM->pfnProgress(pSSM->pVM, uPct, pSSM->pvUser); + pSSM->pfnProgress(pSSM->pVM->pUVM, uPct, pSSM->pvUser); } } } @@ -4599,6 +4708,7 @@ static int ssmR3SaveDoExecRun(PVM pVM, PSSMHANDLE pSSM) * Call the execute handler. */ ssmR3DataWriteBegin(pSSM); + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -4618,6 +4728,7 @@ static int ssmR3SaveDoExecRun(PVM pVM, PSSMHANDLE pSSM) rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); pUnit->fCalled = true; if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc)) pSSM->rc = rc; @@ -4687,6 +4798,7 @@ static int ssmR3SaveDoPrepRun(PVM pVM, PSSMHANDLE pSSM) if (pUnit->u.Common.pfnSavePrep) { int rc; + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -4705,6 +4817,7 @@ static int ssmR3SaveDoPrepRun(PVM pVM, PSSMHANDLE pSSM) rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); pUnit->fCalled = true; if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc)) pSSM->rc = rc; @@ -4724,7 +4837,7 @@ static int ssmR3SaveDoPrepRun(PVM pVM, PSSMHANDLE pSSM) * Work the progress indicator if we got one. */ if (pSSM->pfnProgress) - pSSM->pfnProgress(pVM, pSSM->uPercentPrepare + pSSM->uPercentLive - 1, pSSM->pvUser); + pSSM->pfnProgress(pVM->pUVM, pSSM->uPercentPrepare + pSSM->uPercentLive - 1, pSSM->pvUser); pSSM->uPercent = pSSM->uPercentPrepare + pSSM->uPercentLive; return VINF_SUCCESS; @@ -5028,6 +5141,7 @@ static int ssmR3LiveDoVoteRun(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) && !pUnit->fDoneLive) { int rc; + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -5046,6 +5160,7 @@ static int ssmR3LiveDoVoteRun(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); pUnit->fCalled = true; Assert(pSSM->rc == VINF_SUCCESS); if (rc != VINF_SUCCESS) @@ -5096,7 +5211,7 @@ static int ssmR3LiveDoVoteRun(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) { ssmR3LiveControlEmit(pSSM, lrdPct, uPass); pSSM->uPercent = uPct; - pSSM->pfnProgress(pVM, uPct, pSSM->pvUser); + pSSM->pfnProgress(pVM->pUVM, uPct, pSSM->pvUser); } } } @@ -5166,6 +5281,7 @@ static int ssmR3LiveDoExecRun(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) * Call the execute handler. */ ssmR3DataWriteBegin(pSSM); + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -5184,6 +5300,7 @@ static int ssmR3LiveDoExecRun(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); pUnit->fCalled = true; if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc)) pSSM->rc = rc; @@ -5323,6 +5440,7 @@ static int ssmR3DoLivePrepRun(PVM pVM, PSSMHANDLE pSSM) if (pUnit->u.Common.pfnLivePrep) { int rc; + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -5341,6 +5459,7 @@ static int ssmR3DoLivePrepRun(PVM pVM, PSSMHANDLE pSSM) rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); pUnit->fCalled = true; if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc)) pSSM->rc = rc; @@ -5360,7 +5479,7 @@ static int ssmR3DoLivePrepRun(PVM pVM, PSSMHANDLE pSSM) * Work the progress indicator if we got one. */ if (pSSM->pfnProgress) - pSSM->pfnProgress(pVM, 2, pSSM->pvUser); + pSSM->pfnProgress(pVM->pUVM, 2, pSSM->pvUser); pSSM->uPercent = 2; return VINF_SUCCESS; @@ -5720,7 +5839,7 @@ DECLINLINE(int) ssmR3DataReadV2RawLzfHdr(PSSMHANDLE pSSM, uint32_t *pcbDecompr) AssertLogRelMsgReturn( pSSM->u.Read.cbRecLeft > 1 && pSSM->u.Read.cbRecLeft <= RT_SIZEOFMEMB(SSMHANDLE, u.Read.abComprBuffer) + 2, ("%#x\n", pSSM->u.Read.cbRecLeft), - VERR_SSM_INTEGRITY_DECOMPRESSION); + pSSM->rc = VERR_SSM_INTEGRITY_DECOMPRESSION); uint8_t cKB; int rc = ssmR3DataReadV2Raw(pSSM, &cKB, 1); @@ -5732,7 +5851,7 @@ DECLINLINE(int) ssmR3DataReadV2RawLzfHdr(PSSMHANDLE pSSM, uint32_t *pcbDecompr) AssertLogRelMsgReturn( cbDecompr >= pSSM->u.Read.cbRecLeft && cbDecompr <= RT_SIZEOFMEMB(SSMHANDLE, u.Read.abDataBuffer), ("%#x\n", cbDecompr), - VERR_SSM_INTEGRITY_DECOMPRESSION); + pSSM->rc = VERR_SSM_INTEGRITY_DECOMPRESSION); *pcbDecompr = cbDecompr; return VINF_SUCCESS; @@ -5780,7 +5899,7 @@ static int ssmR3DataReadV2RawLzf(PSSMHANDLE pSSM, void *pvDst, size_t cbDecompr) pvDst, cbDecompr, &cbDstActual); if (RT_SUCCESS(rc)) { - AssertLogRelMsgReturn(cbDstActual == cbDecompr, ("%#x %#x\n", cbDstActual, cbDecompr), VERR_SSM_INTEGRITY_DECOMPRESSION); + AssertLogRelMsgReturn(cbDstActual == cbDecompr, ("%#x %#x\n", cbDstActual, cbDecompr), pSSM->rc = VERR_SSM_INTEGRITY_DECOMPRESSION); return VINF_SUCCESS; } @@ -5799,7 +5918,7 @@ static int ssmR3DataReadV2RawLzf(PSSMHANDLE pSSM, void *pvDst, size_t cbDecompr) DECLINLINE(int) ssmR3DataReadV2RawZeroHdr(PSSMHANDLE pSSM, uint32_t *pcbZero) { *pcbZero = 0; /* shuts up gcc. */ - AssertLogRelMsgReturn(pSSM->u.Read.cbRecLeft == 1, ("%#x\n", pSSM->u.Read.cbRecLeft), VERR_SSM_INTEGRITY_DECOMPRESSION); + AssertLogRelMsgReturn(pSSM->u.Read.cbRecLeft == 1, ("%#x\n", pSSM->u.Read.cbRecLeft), pSSM->rc = VERR_SSM_INTEGRITY_DECOMPRESSION); uint8_t cKB; int rc = ssmR3DataReadV2Raw(pSSM, &cKB, 1); @@ -5809,7 +5928,7 @@ DECLINLINE(int) ssmR3DataReadV2RawZeroHdr(PSSMHANDLE pSSM, uint32_t *pcbZero) uint32_t cbZero = (uint32_t)cKB * _1K; AssertLogRelMsgReturn(cbZero <= RT_SIZEOFMEMB(SSMHANDLE, u.Read.abDataBuffer), - ("%#x\n", cbZero), VERR_SSM_INTEGRITY_DECOMPRESSION); + ("%#x\n", cbZero), pSSM->rc = VERR_SSM_INTEGRITY_DECOMPRESSION); *pcbZero = cbZero; return VINF_SUCCESS; @@ -5988,6 +6107,7 @@ static int ssmR3DataReadRecHdrV2(PSSMHANDLE pSSM) /** * Buffer miss, do an unbuffered read. * + * @returns VBox status code. Sets pSSM->rc on error. * @param pSSM The saved state handle. * @param pvBuf Where to store the read data. * @param cbBuf Number of bytes to read. @@ -6089,7 +6209,7 @@ static int ssmR3DataReadUnbufferedV2(PSSMHANDLE pSSM, void *pvBuf, size_t cbBuf) } default: - AssertMsgFailedReturn(("%x\n", pSSM->u.Read.u8TypeAndFlags), VERR_SSM_BAD_REC_TYPE); + AssertMsgFailedReturn(("%x\n", pSSM->u.Read.u8TypeAndFlags), pSSM->rc = VERR_SSM_BAD_REC_TYPE); } pSSM->offUnitUser += cbToRead; @@ -6192,7 +6312,7 @@ static int ssmR3DataReadBufferedV2(PSSMHANDLE pSSM, void *pvBuf, size_t cbBuf) } default: - AssertMsgFailedReturn(("%x\n", pSSM->u.Read.u8TypeAndFlags), VERR_SSM_BAD_REC_TYPE); + AssertMsgFailedReturn(("%x\n", pSSM->u.Read.u8TypeAndFlags), pSSM->rc = VERR_SSM_BAD_REC_TYPE); } /*pSSM->u.Read.offDataBuffer = 0;*/ @@ -6277,7 +6397,7 @@ VMMR3DECL(int) SSMR3GetStruct(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFiel int rc = SSMR3GetU32(pSSM, &u32Magic); if (RT_FAILURE(rc)) return rc; - AssertMsgReturn(u32Magic == SSMR3STRUCT_BEGIN, ("u32Magic=%#RX32\n", u32Magic), VERR_SSM_STRUCTURE_MAGIC); + AssertMsgReturn(u32Magic == SSMR3STRUCT_BEGIN, ("u32Magic=%#RX32\n", u32Magic), pSSM->rc = VERR_SSM_STRUCTURE_MAGIC); /* get the fields */ for (PCSSMFIELD pCur = paFields; @@ -6292,24 +6412,24 @@ VMMR3DECL(int) SSMR3GetStruct(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFiel break; case SSMFIELDTRANS_GCPTR: - AssertMsgReturn(pCur->cb == sizeof(RTGCPTR), ("%#x (%s)\n", pCur->cb, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTGCPTR), ("%#x (%s)\n", pCur->cb, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3GetGCPtr(pSSM, (PRTGCPTR)pbField); break; case SSMFIELDTRANS_GCPHYS: - AssertMsgReturn(pCur->cb == sizeof(RTGCPHYS), ("%#x (%s)\n", pCur->cb, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTGCPHYS), ("%#x (%s)\n", pCur->cb, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3GetGCPhys(pSSM, (PRTGCPHYS)pbField); break; case SSMFIELDTRANS_RCPTR: - AssertMsgReturn(pCur->cb == sizeof(RTRCPTR), ("%#x (%s)\n", pCur->cb, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTRCPTR), ("%#x (%s)\n", pCur->cb, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3GetRCPtr(pSSM, (PRTRCPTR)pbField); break; case SSMFIELDTRANS_RCPTR_ARRAY: { uint32_t const cEntries = pCur->cb / sizeof(RTRCPTR); - AssertMsgReturn(pCur->cb == cEntries * sizeof(RTRCPTR) && cEntries, ("%#x (%s)\n", pCur->cb, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == cEntries * sizeof(RTRCPTR) && cEntries, ("%#x (%s)\n", pCur->cb, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = VINF_SUCCESS; for (uint32_t i = 0; i < cEntries && RT_SUCCESS(rc); i++) rc = SSMR3GetRCPtr(pSSM, &((PRTRCPTR)pbField)[i]); @@ -6317,17 +6437,21 @@ VMMR3DECL(int) SSMR3GetStruct(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFiel } default: - AssertMsgFailedReturn(("%#x\n", pCur->pfnGetPutOrTransformer), VERR_SSM_FIELD_COMPLEX); + AssertMsgFailedBreakStmt(("%#x\n", pCur->pfnGetPutOrTransformer), rc = VERR_SSM_FIELD_COMPLEX); } if (RT_FAILURE(rc)) + { + if (RT_SUCCESS(pSSM->rc)) + pSSM->rc = rc; return rc; + } } /* end marker */ rc = SSMR3GetU32(pSSM, &u32Magic); if (RT_FAILURE(rc)) return rc; - AssertMsgReturn(u32Magic == SSMR3STRUCT_END, ("u32Magic=%#RX32\n", u32Magic), VERR_SSM_STRUCTURE_MAGIC); + AssertMsgReturn(u32Magic == SSMR3STRUCT_END, ("u32Magic=%#RX32\n", u32Magic), pSSM->rc = VERR_SSM_STRUCTURE_MAGIC); return rc; } @@ -6400,7 +6524,7 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct */ SSM_ASSERT_READABLE_RET(pSSM); SSM_CHECK_CANCELLED_RET(pSSM); - AssertMsgReturn(!(fFlags & ~SSMSTRUCT_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); + AssertMsgReturn(!(fFlags & ~SSMSTRUCT_FLAGS_VALID_MASK), ("%#x\n", fFlags), pSSM->rc = VERR_INVALID_PARAMETER); AssertPtr(pvStruct); AssertPtr(paFields); @@ -6412,12 +6536,13 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct rc = SSMR3GetU32(pSSM, &u32Magic); if (RT_FAILURE(rc)) return rc; - AssertMsgReturn(u32Magic == SSMR3STRUCT_BEGIN, ("u32Magic=%#RX32\n", u32Magic), VERR_SSM_STRUCTURE_MAGIC); + AssertMsgReturn(u32Magic == SSMR3STRUCT_BEGIN, ("u32Magic=%#RX32\n", u32Magic), pSSM->rc = VERR_SSM_STRUCTURE_MAGIC); } /* * Put the fields */ + rc = VINF_SUCCESS; uint32_t off = 0; for (PCSSMFIELD pCur = paFields; pCur->cb != UINT32_MAX && pCur->off != UINT32_MAX; @@ -6436,11 +6561,11 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct && offField + cbField <= cbStruct && offField + cbField >= offField, ("off=%#x cb=%#x cbStruct=%#x (%s)\n", cbField, offField, cbStruct, pCur->pszName), - VERR_SSM_FIELD_OUT_OF_BOUNDS); + pSSM->rc = VERR_SSM_FIELD_OUT_OF_BOUNDS); AssertMsgReturn( !(fFlags & SSMSTRUCT_FLAGS_FULL_STRUCT) || off == offField, ("off=%#x offField=%#x (%s)\n", off, offField, pCur->pszName), - VERR_SSM_FIELD_NOT_CONSECUTIVE); + pSSM->rc = VERR_SSM_FIELD_NOT_CONSECUTIVE); rc = VINF_SUCCESS; uint8_t *pbField = (uint8_t *)pvStruct + offField; @@ -6451,24 +6576,24 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct break; case SSMFIELDTRANS_GCPHYS: - AssertMsgReturn(cbField == sizeof(RTGCPHYS), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTGCPHYS), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3GetGCPhys(pSSM, (PRTGCPHYS)pbField); break; case SSMFIELDTRANS_GCPTR: - AssertMsgReturn(cbField == sizeof(RTGCPTR), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTGCPTR), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3GetGCPtr(pSSM, (PRTGCPTR)pbField); break; case SSMFIELDTRANS_RCPTR: - AssertMsgReturn(cbField == sizeof(RTRCPTR), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTRCPTR), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3GetRCPtr(pSSM, (PRTRCPTR)pbField); break; case SSMFIELDTRANS_RCPTR_ARRAY: { uint32_t const cEntries = cbField / sizeof(RTRCPTR); - AssertMsgReturn(cbField == cEntries * sizeof(RTRCPTR) && cEntries, ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == cEntries * sizeof(RTRCPTR) && cEntries, ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = VINF_SUCCESS; for (uint32_t i = 0; i < cEntries && RT_SUCCESS(rc); i++) rc = SSMR3GetRCPtr(pSSM, &((PRTRCPTR)pbField)[i]); @@ -6476,14 +6601,14 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct } case SSMFIELDTRANS_HCPTR_NI: - AssertMsgReturn(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = ssmR3GetHCPtrNI(pSSM, (void **)pbField, fFlags); break; case SSMFIELDTRANS_HCPTR_NI_ARRAY: { uint32_t const cEntries = cbField / sizeof(void *); - AssertMsgReturn(cbField == cEntries * sizeof(void *) && cEntries, ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == cEntries * sizeof(void *) && cEntries, ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = VINF_SUCCESS; for (uint32_t i = 0; i < cEntries && RT_SUCCESS(rc); i++) rc = ssmR3GetHCPtrNI(pSSM, &((void **)pbField)[i], fFlags); @@ -6491,21 +6616,21 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct } case SSMFIELDTRANS_HCPTR_HACK_U32: - AssertMsgReturn(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); *(uintptr_t *)pbField = 0; rc = ssmR3DataRead(pSSM, pbField, sizeof(uint32_t)); if ((fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) && ssmR3GetHostBits(pSSM) == 64) { uint32_t u32; rc = ssmR3DataRead(pSSM, &u32, sizeof(uint32_t)); - AssertMsgReturn(RT_FAILURE(rc) || u32 == 0 || (fFlags & SSMSTRUCT_FLAGS_SAVED_AS_MEM), - ("high=%#x low=%#x (%s)\n", u32, *(uint32_t *)pbField, pCur->pszName), - VERR_SSM_FIELD_INVALID_VALUE); + AssertMsgBreakStmt(RT_FAILURE(rc) || u32 == 0 || (fFlags & SSMSTRUCT_FLAGS_SAVED_AS_MEM), + ("high=%#x low=%#x (%s)\n", u32, *(uint32_t *)pbField, pCur->pszName), + rc = VERR_SSM_FIELD_INVALID_VALUE); } break; case SSMFIELDTRANS_U32_ZX_U64: - AssertMsgReturn(cbField == sizeof(uint64_t), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(uint64_t), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); ((uint32_t *)pbField)[1] = 0; rc = SSMR3GetU32(pSSM, (uint32_t *)pbField); break; @@ -6517,62 +6642,62 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct break; case SSMFIELDTRANS_IGN_GCPHYS: - AssertMsgReturn(cbField == sizeof(RTGCPHYS), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTGCPHYS), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = SSMR3Skip(pSSM, pSSM->u.Read.cbGCPhys); break; case SSMFIELDTRANS_IGN_GCPTR: - AssertMsgReturn(cbField == sizeof(RTGCPTR), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTGCPTR), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = SSMR3Skip(pSSM, pSSM->u.Read.cbGCPtr); break; case SSMFIELDTRANS_IGN_RCPTR: - AssertMsgReturn(cbField == sizeof(RTRCPTR), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(RTRCPTR), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = SSMR3Skip(pSSM, sizeof(RTRCPTR)); break; case SSMFIELDTRANS_IGN_HCPTR: - AssertMsgReturn(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(cbField == sizeof(void *), ("%#x (%s)\n", cbField, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = SSMR3Skip(pSSM, ssmR3GetHostBits(pSSM) / 8); break; case SSMFIELDTRANS_OLD: - AssertMsgReturn(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3Skip(pSSM, pCur->cb); break; case SSMFIELDTRANS_OLD_GCPHYS: - AssertMsgReturn(pCur->cb == sizeof(RTGCPHYS) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTGCPHYS) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3Skip(pSSM, pSSM->u.Read.cbGCPhys); break; case SSMFIELDTRANS_OLD_GCPTR: - AssertMsgReturn(pCur->cb == sizeof(RTGCPTR) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTGCPTR) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3Skip(pSSM, pSSM->u.Read.cbGCPtr); break; case SSMFIELDTRANS_OLD_RCPTR: - AssertMsgReturn(pCur->cb == sizeof(RTRCPTR) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(RTRCPTR) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3Skip(pSSM, sizeof(RTRCPTR)); break; case SSMFIELDTRANS_OLD_HCPTR: - AssertMsgReturn(pCur->cb == sizeof(void *) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->cb == sizeof(void *) && pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3Skip(pSSM, ssmR3GetHostBits(pSSM) / 8); break; case SSMFIELDTRANS_OLD_PAD_HC: - AssertMsgReturn(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); rc = SSMR3Skip(pSSM, ssmR3GetHostBits(pSSM) == 64 ? RT_HIWORD(pCur->cb) : RT_LOWORD(pCur->cb)); break; case SSMFIELDTRANS_OLD_PAD_MSC32: - AssertMsgReturn(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), VERR_SSM_FIELD_INVALID_SIZE); + AssertMsgBreakStmt(pCur->off == UINT32_MAX / 2, ("%#x %#x (%s)\n", pCur->cb, pCur->off, pCur->pszName), rc = VERR_SSM_FIELD_INVALID_SIZE); if (ssmR3IsHostMsc32(pSSM)) rc = SSMR3Skip(pSSM, pCur->cb); break; @@ -6594,37 +6719,46 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct || ( (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_MSC32_AUTO && !ssmR3IsHostMsc32(pSSM)) ? cb64 : cb32; - AssertMsgReturn( cbField == cbCtx - && ( ( pCur->off == UINT32_MAX / 2 - && ( cbField == 0 - || (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_HC_AUTO - || (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_MSC32_AUTO - ) + AssertMsgBreakStmt( cbField == cbCtx + && ( ( pCur->off == UINT32_MAX / 2 + && ( cbField == 0 + || (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_HC_AUTO + || (uintptr_t)pCur->pfnGetPutOrTransformer == SSMFIELDTRANS_PAD_MSC32_AUTO + ) + ) + || (pCur->off != UINT32_MAX / 2 && cbField != 0) ) - || (pCur->off != UINT32_MAX / 2 && cbField != 0) - ) - , ("cbField=%#x cb32=%#x cb64=%#x HC_ARCH_BITS=%u cbCtx=%#x cbSaved=%#x off=%#x\n", - cbField, cb32, cb64, HC_ARCH_BITS, cbCtx, cbSaved, pCur->off), - VERR_SSM_FIELD_INVALID_PADDING_SIZE); + , ("cbField=%#x cb32=%#x cb64=%#x HC_ARCH_BITS=%u cbCtx=%#x cbSaved=%#x off=%#x\n", + cbField, cb32, cb64, HC_ARCH_BITS, cbCtx, cbSaved, pCur->off), + rc = VERR_SSM_FIELD_INVALID_PADDING_SIZE); if (fFlags & SSMSTRUCT_FLAGS_DONT_IGNORE) rc = SSMR3Skip(pSSM, cbSaved); break; } default: - AssertPtrReturn(pCur->pfnGetPutOrTransformer, VERR_SSM_FIELD_INVALID_CALLBACK); + AssertBreakStmt(pCur->pfnGetPutOrTransformer, rc = VERR_SSM_FIELD_INVALID_CALLBACK); rc = pCur->pfnGetPutOrTransformer(pSSM, pCur, pvStruct, fFlags, true /*fGetOrPut*/, pvUser); break; } if (RT_FAILURE(rc)) - return rc; + break; off = offField + cbField; } - AssertMsgReturn( !(fFlags & SSMSTRUCT_FLAGS_FULL_STRUCT) - || off == cbStruct, - ("off=%#x cbStruct=%#x\n", off, cbStruct), - VERR_SSM_FIELD_NOT_CONSECUTIVE); + + if (RT_SUCCESS(rc)) + AssertMsgStmt( !(fFlags & SSMSTRUCT_FLAGS_FULL_STRUCT) + || off == cbStruct, + ("off=%#x cbStruct=%#x\n", off, cbStruct), + rc = VERR_SSM_FIELD_NOT_CONSECUTIVE); + + if (RT_FAILURE(rc)) + { + if (RT_SUCCESS(pSSM->rc)) + pSSM->rc = rc; + return rc; + } /* * End marker @@ -6634,7 +6768,7 @@ VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct rc = SSMR3GetU32(pSSM, &u32Magic); if (RT_FAILURE(rc)) return rc; - AssertMsgReturn(u32Magic == SSMR3STRUCT_END, ("u32Magic=%#RX32\n", u32Magic), VERR_SSM_STRUCTURE_MAGIC); + AssertMsgReturn(u32Magic == SSMR3STRUCT_END, ("u32Magic=%#RX32\n", u32Magic), pSSM->rc = VERR_SSM_STRUCTURE_MAGIC); } return VINF_SUCCESS; @@ -7908,6 +8042,7 @@ static int ssmR3LoadExecV1(PVM pVM, PSSMHANDLE pSSM) pSSM->rc = rc = VERR_SSM_NO_LOAD_EXEC; break; } + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -7926,6 +8061,7 @@ static int ssmR3LoadExecV1(PVM pVM, PSSMHANDLE pSSM) rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); pUnit->fCalled = true; if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc)) pSSM->rc = rc; @@ -8171,6 +8307,7 @@ static int ssmR3LoadExecV2(PVM pVM, PSSMHANDLE pSSM) pSSM->u.Read.uCurUnitPass = UnitHdr.u32Pass; pSSM->u.Read.pCurUnit = pUnit; ssmR3DataReadBeginV2(pSSM); + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -8189,6 +8326,7 @@ static int ssmR3LoadExecV2(PVM pVM, PSSMHANDLE pSSM) rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); pUnit->fCalled = true; if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc)) pSSM->rc = rc; @@ -8321,7 +8459,7 @@ VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamO Handle.u.Read.cHostBits, Handle.u.Read.cbGCPhys, Handle.u.Read.cbGCPtr)); if (pfnProgress) - pfnProgress(pVM, Handle.uPercent, pvProgressUser); + pfnProgress(pVM->pUVM, Handle.uPercent, pvProgressUser); /* * Clear the per unit flags. @@ -8341,6 +8479,7 @@ VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamO { Handle.u.Read.pCurUnit = pUnit; pUnit->fCalled = true; + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -8359,6 +8498,7 @@ VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamO rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); Handle.u.Read.pCurUnit = NULL; if (RT_FAILURE(rc) && RT_SUCCESS_NP(Handle.rc)) Handle.rc = rc; @@ -8374,7 +8514,7 @@ VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamO /* end of prepare % */ if (pfnProgress) - pfnProgress(pVM, Handle.uPercentPrepare - 1, pvProgressUser); + pfnProgress(pVM->pUVM, Handle.uPercentPrepare - 1, pvProgressUser); Handle.uPercent = Handle.uPercentPrepare; Handle.cbEstTotal = Handle.u.Read.cbLoadFile; Handle.offEstUnitEnd = Handle.u.Read.cbLoadFile; @@ -8412,6 +8552,7 @@ VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamO Handle.u.Read.pCurUnit = pUnit; int const rcOld = Handle.rc; rc = VINF_SUCCESS; + ssmR3UnitCritSectEnter(pUnit); switch (pUnit->enmType) { case SSMUNITTYPE_DEV: @@ -8430,6 +8571,7 @@ VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamO rc = VERR_SSM_IPE_1; break; } + ssmR3UnitCritSectLeave(pUnit); Handle.u.Read.pCurUnit = NULL; if (RT_SUCCESS(rc) && Handle.rc != rcOld) rc = Handle.rc; @@ -8448,7 +8590,7 @@ VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamO /* progress */ if (pfnProgress) - pfnProgress(pVM, 99, pvProgressUser); + pfnProgress(pVM->pUVM, 99, pvProgressUser); ssmR3SetCancellable(pVM, &Handle, false); ssmR3StrmClose(&Handle.Strm, Handle.rc == VERR_SSM_CANCELLED); @@ -8462,7 +8604,7 @@ VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamO { /* progress */ if (pfnProgress) - pfnProgress(pVM, 100, pvProgressUser); + pfnProgress(pVM->pUVM, 100, pvProgressUser); Log(("SSM: Load of '%s' completed!\n", pszFilename)); } return rc; @@ -9131,12 +9273,14 @@ VMMR3DECL(const char *) SSMR3HandleHostOSAndArch(PSSMHANDLE pSSM) * @retval VERR_SSM_ALREADY_CANCELLED if the operation as already been * cancelled. * - * @param pVM Pointer to the VM. + * @param pUVM The VM handle. * * @thread Any. */ -VMMR3DECL(int) SSMR3Cancel(PVM pVM) +VMMR3DECL(int) SSMR3Cancel(PUVM pUVM) { + UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); + PVM pVM = pUVM->pVM; VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); int rc = RTCritSectEnter(&pVM->ssm.s.CancelCritSect); |
