Changeset 91347 in vbox
- Timestamp:
- Sep 23, 2021 10:19:05 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 147014
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Security/DrvTpmEmuTpms.cpp
r91327 r91347 49 49 *********************************************************************************************************************************/ 50 50 51 /** The TPMS saved state version. */52 #define TPMS_SAVED_STATE_VERSION 153 54 51 55 52 /********************************************************************************************************************************* … … 77 74 /** Currently set locality. */ 78 75 uint8_t bLoc; 79 /** Flag whether the TPM state was saved in save state operation (skips writing the state to the NVRAM file). */80 bool fSsmCalled;81 82 /** NVRAM file path. */83 char *pszNvramPath;84 85 void *pvNvPermall;86 size_t cbNvPermall;87 88 void *pvNvVolatile;89 size_t cbNvVolatile;90 91 76 } DRVTPMEMU; 92 77 /** Pointer to the TPM emulator instance data. */ … … 107 92 * Internal Functions * 108 93 *********************************************************************************************************************************/ 109 110 /**111 * Tries to load the NVRAM.112 *113 * @returns VBox status code.114 * @param pThis The emulator driver instance data.115 */116 static int drvTpmEmuTpmsNvramLoad(PDRVTPMEMU pThis)117 {118 RTVFSIOSTREAM hVfsIos;119 uint32_t offError = 0;120 RTERRINFOSTATIC ErrInfo;121 int rc = RTVfsChainOpenIoStream(pThis->pszNvramPath, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN,122 &hVfsIos, &offError, RTErrInfoInitStatic(&ErrInfo));123 if (RT_FAILURE(rc))124 {125 if (rc == VERR_FILE_NOT_FOUND) /* First run. */126 rc = VINF_SUCCESS;127 128 return rc;129 }130 131 RTVFSFSSTREAM hVfsFss = NIL_RTVFSFSSTREAM;132 rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, &hVfsFss);133 RTVfsIoStrmRelease(hVfsIos);134 if (RT_SUCCESS(rc))135 {136 /*137 * Process the stream.138 */139 for (;;)140 {141 /*142 * Retrieve the next object.143 */144 char *pszName;145 RTVFSOBJ hVfsObj;146 rc = RTVfsFsStrmNext(hVfsFss, &pszName, NULL, &hVfsObj);147 if (RT_FAILURE(rc))148 {149 if (rc == VERR_EOF)150 rc = VINF_SUCCESS;151 break;152 }153 154 RTFSOBJINFO UnixInfo;155 rc = RTVfsObjQueryInfo(hVfsObj, &UnixInfo, RTFSOBJATTRADD_UNIX);156 if (RT_SUCCESS(rc))157 {158 switch (UnixInfo.Attr.fMode & RTFS_TYPE_MASK)159 {160 case RTFS_TYPE_FILE:161 {162 void **ppvDataPtr = NULL;163 size_t *pcbData = NULL;164 if (!RTStrCmp(pszName, TPM_PERMANENT_ALL_NAME))165 {166 ppvDataPtr = &pThis->pvNvPermall;167 pcbData = &pThis->cbNvPermall;168 }169 else if (!RTStrCmp(pszName, TPM_VOLATILESTATE_NAME))170 {171 ppvDataPtr = &pThis->pvNvVolatile;172 pcbData = &pThis->cbNvVolatile;173 }174 else175 rc = VERR_NOT_FOUND;176 177 if (RT_SUCCESS(rc))178 {179 *ppvDataPtr = RTMemAllocZ(UnixInfo.cbObject);180 if (*ppvDataPtr)181 {182 RTVFSIOSTREAM hVfsIosData = RTVfsObjToIoStream(hVfsObj);183 184 rc = RTVfsIoStrmRead(hVfsIosData, *ppvDataPtr, UnixInfo.cbObject, true /*fBlocking*/, NULL);185 *pcbData = UnixInfo.cbObject;186 RTVfsIoStrmRelease(hVfsIosData);187 }188 else189 rc = VERR_NO_MEMORY;190 }191 break;192 }193 default:194 rc = VERR_NOT_SUPPORTED;195 break;196 }197 }198 199 /*200 * Release the current object and string.201 */202 RTVfsObjRelease(hVfsObj);203 RTStrFree(pszName);204 205 if (RT_FAILURE(rc))206 break;207 }208 }209 210 return rc;211 }212 213 214 static int drvTpmEmuTpmsNvramStoreEntity(RTVFSFSSTREAM hVfsFss, const char *pszName, const void *pvData, size_t cbData)215 {216 RTVFSIOSTREAM hVfsIosData;217 218 int rc = RTVfsIoStrmFromBuffer(RTFILE_O_READ, pvData, cbData, &hVfsIosData);219 if (RT_SUCCESS(rc))220 {221 RTVFSOBJ hVfsObj = RTVfsObjFromIoStream(hVfsIosData);222 rc = RTVfsFsStrmAdd(hVfsFss, pszName, hVfsObj, 0 /*fFlags*/);223 RTVfsObjRelease(hVfsObj);224 225 RTVfsIoStrmRelease(hVfsIosData);226 }227 228 return rc;229 }230 231 232 /**233 * Stores the NVRAM content.234 *235 * @returns VBox status code.236 * @param pThis The emulator driver instance data.237 */238 static int drvTpmEmuTpmsNvramStore(PDRVTPMEMU pThis)239 {240 uint32_t offError = 0;241 RTERRINFOSTATIC ErrInfo;242 RTVFSIOSTREAM hVfsIos;243 244 int rc = RTVfsChainOpenIoStream(pThis->pszNvramPath, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE,245 &hVfsIos, &offError, RTErrInfoInitStatic(&ErrInfo));246 if (RT_SUCCESS(rc))247 {248 RTVFSFSSTREAM hVfsFss;249 rc = RTZipTarFsStreamToIoStream(hVfsIos, RTZIPTARFORMAT_GNU, 0 /*fFlags*/, &hVfsFss);250 if (RT_SUCCESS(rc))251 {252 rc = drvTpmEmuTpmsNvramStoreEntity(hVfsFss, TPM_PERMANENT_ALL_NAME, pThis->pvNvPermall, pThis->cbNvPermall);253 if (RT_SUCCESS(rc) && pThis->pvNvVolatile)254 rc = drvTpmEmuTpmsNvramStoreEntity(hVfsFss, TPM_VOLATILESTATE_NAME, pThis->pvNvVolatile, pThis->cbNvVolatile);255 256 RTVfsFsStrmRelease(hVfsFss);257 }258 259 RTVfsIoStrmRelease(hVfsIos);260 }261 262 return rc;263 }264 265 266 /**267 * Tries to load the NVRAM from the VFS driver below.268 *269 * @returns VBox status code.270 * @param pThis The emulator driver instance data.271 */272 static int drvTpmEmuTpmsNvramLoadFromVfs(PDRVTPMEMU pThis)273 {274 uint64_t cbState = 0;275 int rc = pThis->pDrvVfs->pfnQuerySize(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, TPM_PERMANENT_ALL_NAME, &cbState);276 if (RT_SUCCESS(rc))277 {278 pThis->pvNvPermall = RTMemAllocZ(cbState);279 if (pThis->pvNvPermall)280 {281 pThis->cbNvPermall = (size_t)cbState;282 rc = pThis->pDrvVfs->pfnReadAll(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, TPM_PERMANENT_ALL_NAME,283 pThis->pvNvPermall, pThis->cbNvPermall);284 if (RT_SUCCESS(rc))285 {286 /* Load the volatile state if existing. */287 rc = pThis->pDrvVfs->pfnQuerySize(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, TPM_VOLATILESTATE_NAME, &cbState);288 if (RT_SUCCESS(rc))289 {290 pThis->pvNvVolatile = RTMemAllocZ(cbState);291 if (pThis->pvNvVolatile)292 {293 pThis->cbNvVolatile = (size_t)cbState;294 rc = pThis->pDrvVfs->pfnReadAll(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, TPM_VOLATILESTATE_NAME,295 pThis->pvNvVolatile, pThis->cbNvVolatile);296 }297 }298 else if (rc == VERR_NOT_FOUND)299 rc = VINF_SUCCESS; /* This is fine if there is no volatile state. */300 }301 }302 else303 rc = VERR_NO_MEMORY;304 }305 else if (rc == VERR_NOT_FOUND)306 rc = VINF_SUCCESS; /* This is fine for the first start of a new VM. */307 308 return rc;309 }310 311 312 /**313 * Stores the NVRAM content using the VFS driver below.314 *315 * @returns VBox status code.316 * @param pThis The emulator driver instance data.317 */318 static int drvTpmEmuTpmsNvramStoreToVfs(PDRVTPMEMU pThis)319 {320 AssertPtr(pThis->pvNvPermall);321 int rc = pThis->pDrvVfs->pfnWriteAll(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, TPM_PERMANENT_ALL_NAME,322 pThis->pvNvPermall, pThis->cbNvPermall);323 if ( RT_SUCCESS(rc)324 && pThis->pvNvVolatile)325 rc = pThis->pDrvVfs->pfnWriteAll(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, TPM_VOLATILESTATE_NAME,326 pThis->pvNvVolatile, pThis->cbNvVolatile);327 328 return rc;329 }330 331 94 332 95 /* -=-=-=-=- PDMITPMCONNECTOR interface callabcks. -=-=-=-=- */ … … 459 222 AssertReturn(idTpm == 0, TPM_FAIL); 460 223 461 void *pvDataPtr = NULL; 462 size_t cbData = 0; 463 if (!RTStrCmp(pszName, TPM_PERMANENT_ALL_NAME)) 224 uint64_t cbState = 0; 225 int rc = pThis->pDrvVfs->pfnQuerySize(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, pszName, &cbState); 226 if ( RT_SUCCESS(rc) 227 && cbState == (uint32_t)cbState) 464 228 { 465 pvDataPtr = pThis->pvNvPermall; 466 cbData = pThis->cbNvPermall; 229 void *pvData = malloc(cbState); 230 if (RT_LIKELY(pvData)) 231 { 232 rc = pThis->pDrvVfs->pfnReadAll(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, pszName, 233 pvData, cbState); 234 if (RT_SUCCESS(rc)) 235 { 236 *ppvData = (uint8_t *)pvData; 237 *pcbLength = (uint32_t)cbState; 238 return VINF_SUCCESS; 239 } 240 241 free(pvData); 242 } 467 243 } 468 else if (!RTStrCmp(pszName, TPM_VOLATILESTATE_NAME)) 469 { 470 pvDataPtr = pThis->pvNvVolatile; 471 cbData = pThis->cbNvVolatile; 472 } 473 else 474 return TPM_FAIL; 475 476 if (pvDataPtr) 477 { 478 *ppvData = (uint8_t *)malloc(cbData); 479 if (*ppvData) 480 { 481 memcpy(*ppvData, pvDataPtr, cbData); 482 *pcbLength = (uint32_t)cbData; 483 return TPM_SUCCESS; 484 } 485 486 return TPM_FAIL; 487 } 488 489 return TPM_RETRY; 244 else if (rc == VERR_NOT_FOUND) 245 return TPM_RETRY; /* This is fine for the first start of a new VM. */ 246 247 return TPM_FAIL; 490 248 } 491 249 … … 498 256 AssertReturn(idTpm == 0, TPM_FAIL); 499 257 500 void **ppvDataPtr = NULL; 501 size_t *pcbData = NULL; 502 if (!RTStrCmp(pszName, TPM_PERMANENT_ALL_NAME)) 503 { 504 ppvDataPtr = &pThis->pvNvPermall; 505 pcbData = &pThis->cbNvPermall; 506 } 507 else if (!RTStrCmp(pszName, TPM_VOLATILESTATE_NAME)) 508 { 509 ppvDataPtr = &pThis->pvNvVolatile; 510 pcbData = &pThis->cbNvVolatile; 511 } 512 else 513 return TPM_FAIL; 514 515 if ( *ppvDataPtr 516 && *pcbData == cbLength) 517 { 518 memcpy(*ppvDataPtr, pvData, cbLength); 258 int rc = pThis->pDrvVfs->pfnWriteAll(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, pszName, 259 pvData, cbLength); 260 if (RT_SUCCESS(rc)) 519 261 return TPM_SUCCESS; 520 }521 else522 {523 if (*ppvDataPtr)524 RTMemFree(*ppvDataPtr);525 526 *ppvDataPtr = RTMemDup(pvData, cbLength);527 if (*ppvDataPtr)528 {529 *pcbData = cbLength;530 return TPM_SUCCESS;531 }532 }533 262 534 263 return TPM_FAIL; … … 542 271 AssertReturn(idTpm == 0, TPM_FAIL); 543 272 544 void **ppvDataPtr = NULL; 545 size_t *pcbData = NULL; 546 if (!RTStrCmp(pszName, TPM_PERMANENT_ALL_NAME)) 547 { 548 ppvDataPtr = &pThis->pvNvPermall; 549 pcbData = &pThis->cbNvPermall; 550 } 551 else if (!RTStrCmp(pszName, TPM_VOLATILESTATE_NAME)) 552 { 553 ppvDataPtr = &pThis->pvNvVolatile; 554 pcbData = &pThis->cbNvVolatile; 555 } 556 else 273 int rc = pThis->pDrvVfs->pfnDelete(pThis->pDrvVfs, pThis->pDrvIns->pReg->szName, pszName); 274 if ( RT_SUCCESS(rc) 275 || ( rc == VERR_NOT_FOUND 276 && !fMustExist)) 557 277 return TPM_SUCCESS; 558 278 559 if (*ppvDataPtr) 560 { 561 RTMemFree(*ppvDataPtr); 562 *ppvDataPtr = NULL; 563 *pcbData = 0; 564 } 565 else if (fMustExist) 566 return TPM_FAIL; 567 568 return TPM_SUCCESS; 279 return TPM_FAIL; 569 280 } 570 281 … … 593 304 *pfPhysicalPresence = TRUE; 594 305 return TPM_SUCCESS; 595 }596 597 598 /* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */599 600 /**601 * @callback_method_impl{FNSSMDEVSAVEEXEC}602 */603 static DECLCALLBACK(int) drvTpmEmuTpmsSaveExec(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)604 {605 PDRVTPMEMU pThis = PDMINS_2_DATA(pDrvIns, PDRVTPMEMU);606 uint8_t *pbTpmStatePerm = NULL;607 uint32_t cbTpmStatePerm = 0;608 uint8_t *pbTpmStateVol = NULL;609 uint32_t cbTpmStateVol = 0;610 611 TPM_RESULT rcTpm = TPMLIB_GetState(TPMLIB_STATE_PERMANENT, &pbTpmStatePerm, &cbTpmStatePerm);612 if (rcTpm == TPM_SUCCESS)613 rcTpm = TPMLIB_GetState(TPMLIB_STATE_VOLATILE, &pbTpmStateVol, &cbTpmStateVol);614 if (rcTpm == TPM_SUCCESS)615 {616 SSMR3PutU32(pSSM, cbTpmStatePerm);617 int rc = SSMR3PutU32(pSSM, cbTpmStateVol);618 AssertRCReturn(rc, rc);619 620 SSMR3PutMem(pSSM, pbTpmStatePerm, cbTpmStatePerm);621 SSMR3PutMem(pSSM, pbTpmStateVol, cbTpmStateVol);622 623 free(pbTpmStatePerm);624 free(pbTpmStateVol);625 rc = SSMR3PutU32(pSSM, UINT32_MAX); /* sanity/terminator */626 if (RT_SUCCESS(rc))627 pThis->fSsmCalled = true;628 return rc;629 }630 631 if (pbTpmStatePerm)632 free(pbTpmStatePerm);633 634 return VERR_NO_MEMORY;635 }636 637 638 /**639 * @callback_method_impl{FNSSMDEVLOADEXEC}640 */641 static DECLCALLBACK(int) drvTpmEmuTpmsLoadExec(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)642 {643 PDRVTPMEMU pThis = PDMINS_2_DATA(pDrvIns, PDRVTPMEMU);644 645 Assert(uPass == SSM_PASS_FINAL); RT_NOREF(uPass);646 AssertMsgReturn(uVersion == TPMS_SAVED_STATE_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);647 648 uint8_t *pbTpmStatePerm = NULL;649 uint32_t cbTpmStatePerm = 0;650 uint8_t *pbTpmStateVol = NULL;651 uint32_t cbTpmStateVol = 0;652 653 int rc = SSMR3GetU32(pSSM, &cbTpmStatePerm);654 AssertRCReturn(rc, rc);655 656 rc = SSMR3GetU32(pSSM, &cbTpmStateVol);657 AssertRCReturn(rc, rc);658 659 pbTpmStatePerm = (uint8_t *)RTMemAllocZ(cbTpmStatePerm);660 if (pbTpmStatePerm)661 {662 pbTpmStateVol = (uint8_t *)RTMemAllocZ(cbTpmStateVol);663 if (pbTpmStateVol)664 {665 rc = SSMR3GetMem(pSSM, pbTpmStatePerm, cbTpmStatePerm);666 if (RT_SUCCESS(rc))667 rc = SSMR3GetMem(pSSM, pbTpmStateVol, cbTpmStateVol);668 669 if (RT_SUCCESS(rc))670 {671 TPM_RESULT rcTpm = TPMLIB_SetState(TPMLIB_STATE_PERMANENT, pbTpmStatePerm, cbTpmStatePerm);672 if (rcTpm == TPM_SUCCESS)673 {674 rcTpm = TPMLIB_SetState(TPMLIB_STATE_VOLATILE, pbTpmStateVol, cbTpmStateVol);675 if (rcTpm == TPM_SUCCESS)676 {677 uint32_t u32 = 0;678 679 /* The marker. */680 rc = SSMR3GetU32(pSSM, &u32);681 AssertRCReturn(rc, rc);682 AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);683 684 pThis->fSsmCalled = true;685 }686 else687 rc = VERR_INVALID_PARAMETER;688 }689 else690 rc = VERR_INVALID_PARAMETER;691 }692 693 RTMemFree(pbTpmStateVol);694 }695 696 RTMemFree(pbTpmStatePerm);697 }698 else699 rc = VERR_NO_MEMORY;700 701 return rc;702 }703 704 705 /**706 * @callback_method_impl{FNSSMDEVLOADDONE}707 */708 static DECLCALLBACK(int) drvTpmEmuTpmsLoadDone(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)709 {710 PDRVTPMEMU pThis = PDMINS_2_DATA(pDrvIns, PDRVTPMEMU);711 RT_NOREF(pSSM);712 713 if (!pThis->fSsmCalled)714 {715 /* Issue a warning as restoring a saved state without loading the TPM state will most likely cause issues in the guest. */716 }717 718 pThis->fSsmCalled = false;719 return VINF_SUCCESS;720 306 } 721 307 … … 747 333 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns); 748 334 749 PDRVTPMEMU pThis = PDMINS_2_DATA(pDrvIns, PDRVTPMEMU);750 751 335 TPMLIB_Terminate(); 752 753 int rc;754 if (pThis->pDrvVfs)755 rc = drvTpmEmuTpmsNvramStoreToVfs(pThis);756 else757 rc = drvTpmEmuTpmsNvramStore(pThis);758 AssertRC(rc);759 }760 761 762 /** @copydoc FNPDMDRVDESTRUCT */763 static DECLCALLBACK(void) drvTpmEmuTpmsDestruct(PPDMDRVINS pDrvIns)764 {765 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);766 767 PDRVTPMEMU pThis = PDMINS_2_DATA(pDrvIns, PDRVTPMEMU);768 LogFlow(("%s\n", __FUNCTION__));769 770 if (pThis->pvNvPermall)771 {772 RTMemFree(pThis->pvNvPermall);773 pThis->pvNvPermall = NULL;774 }775 776 if (pThis->pvNvVolatile)777 {778 RTMemFree(pThis->pvNvVolatile);779 pThis->pvNvVolatile = NULL;780 }781 782 #if 0783 if (pThis->pszNvramPath)784 {785 PDMDrvHlpMMHeapFree(pDrvIns, pThis->pszNvramPath);786 pThisCC->pszNvramPath = NULL;787 }788 #endif789 336 } 790 337 … … 803 350 pThis->enmVersion = TPMVERSION_UNKNOWN; 804 351 pThis->bLoc = TPM_NO_LOCALITY_SELECTED; 805 pThis->fSsmCalled = false;806 pThis->pvNvPermall = NULL;807 pThis->cbNvPermall = 0;808 pThis->pvNvVolatile = NULL;809 pThis->cbNvVolatile = 0;810 352 811 353 /* IBase */ … … 823 365 * Validate and read the configuration. 824 366 */ 825 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "TpmVersion|BufferSize |NvramPath", "");367 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "TpmVersion|BufferSize", ""); 826 368 827 369 TPMLIB_SetDebugFD(STDERR_FILENO); … … 833 375 PPDMIBASE pBase = NULL; 834 376 int rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBase); 835 if (RT_FAILURE(rc) && rc != VERR_PDM_NO_ATTACHED_DRIVER)377 if (RT_FAILURE(rc)) 836 378 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 837 379 N_("Failed to attach driver below us! %Rrc"), rc); 838 if (pBase) 839 { 840 pThis->pDrvVfs = PDMIBASE_QUERY_INTERFACE(pBase, PDMIVFSCONNECTOR); 841 if (!pThis->pDrvVfs) 842 return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW, 843 N_("No VFS interface below")); 844 845 rc = drvTpmEmuTpmsNvramLoadFromVfs(pThis); 846 if (RT_FAILURE(rc)) 847 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 848 N_("Failed to load TPM NVRAM data with %Rrc"), rc); 849 } 850 else 851 { 852 rc = CFGMR3QueryStringAlloc(pCfg, "NvramPath", &pThis->pszNvramPath); 853 if (RT_FAILURE(rc)) 854 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 855 N_("Configuration error: querying \"NvramPath\" resulted in %Rrc"), rc); 856 857 rc = drvTpmEmuTpmsNvramLoad(pThis); 858 if (RT_FAILURE(rc)) 859 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 860 N_("Failed to load TPM NVRAM data with %Rrc"), rc); 861 } 380 pThis->pDrvVfs = PDMIBASE_QUERY_INTERFACE(pBase, PDMIVFSCONNECTOR); 381 if (!pThis->pDrvVfs) 382 return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW, 383 N_("No VFS interface below")); 862 384 863 385 TPMLIB_TPMVersion enmVersion = TPMLIB_TPM_VERSION_2; … … 920 442 N_("Failed to register callbacks with the TPM emulation: %u"), 921 443 rcTpm); 922 923 rc = PDMDrvHlpSSMRegisterEx(pDrvIns, TPMS_SAVED_STATE_VERSION, 0 /*cbGuess*/,924 NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveVote*/,925 NULL /*pfnSavePrep*/, drvTpmEmuTpmsSaveExec, NULL /*pfnSaveDone*/,926 NULL /*pfnLoadPrep*/, drvTpmEmuTpmsLoadExec, drvTpmEmuTpmsLoadDone);927 if (RT_FAILURE(rc))928 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,929 N_("Failed to register saved state handlers"));930 444 931 445 /* We can only have one instance of the TPM emulation and require the global variable for the callbacks unfortunately. */ … … 961 475 drvTpmEmuTpmsConstruct, 962 476 /* pfnDestruct */ 963 drvTpmEmuTpmsDestruct,477 NULL, 964 478 /* pfnRelocate */ 965 479 NULL,
Note:
See TracChangeset
for help on using the changeset viewer.