/**
 * Hyper-V state-save operation.
 *
 * @returns VBox status code.
 * @param   pVM     Pointer to the VM.
 * @param   pSSM    Pointer to the SSM handle.
 */
VMMR3_INT_DECL(int) gimR3HvSave(PVM pVM, PSSMHANDLE pSSM)
{
    PCGIMHV pcHv = &pVM->gim.s.u.Hv;

    /*
     * Save the Hyper-V SSM version.
     */
    SSMR3PutU32(pSSM, GIM_HV_SAVED_STATE_VERSION);

    /*
     * Save per-VM MSRs.
     */
    SSMR3PutU64(pSSM, pcHv->u64GuestOsIdMsr);
    SSMR3PutU64(pSSM, pcHv->u64HypercallMsr);
    SSMR3PutU64(pSSM, pcHv->u64TscPageMsr);

    /*
     * Save Hyper-V features / capabilities.
     */
    SSMR3PutU32(pSSM, pcHv->uBaseFeat);
    SSMR3PutU32(pSSM, pcHv->uPartFlags);
    SSMR3PutU32(pSSM, pcHv->uPowMgmtFeat);
    SSMR3PutU32(pSSM, pcHv->uMiscFeat);
    SSMR3PutU32(pSSM, pcHv->uHyperHints);
    SSMR3PutU32(pSSM, pcHv->uHyperCaps);

    /*
     * Save the Hypercall region.
     */
    PCGIMMMIO2REGION pcRegion = &pcHv->aMmio2Regions[GIM_HV_HYPERCALL_PAGE_REGION_IDX];
    SSMR3PutU8(pSSM,     pcRegion->iRegion);
    SSMR3PutBool(pSSM,   pcRegion->fRCMapping);
    SSMR3PutU32(pSSM,    pcRegion->cbRegion);
    SSMR3PutGCPhys(pSSM, pcRegion->GCPhysPage);
    SSMR3PutStrZ(pSSM,   pcRegion->szDescription);

    /*
     * Save the reference TSC region.
     */
    pcRegion = &pcHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX];
    SSMR3PutU8(pSSM,     pcRegion->iRegion);
    SSMR3PutBool(pSSM,   pcRegion->fRCMapping);
    SSMR3PutU32(pSSM,    pcRegion->cbRegion);
    SSMR3PutGCPhys(pSSM, pcRegion->GCPhysPage);
    SSMR3PutStrZ(pSSM,   pcRegion->szDescription);
    /* Save the TSC sequence so we can bump it on restore (as the CPU frequency/offset may change). */
    uint32_t uTscSequence = 0;
    if (   pcRegion->fMapped
        && MSR_GIM_HV_REF_TSC_IS_ENABLED(pcHv->u64TscPageMsr))
    {
        PCGIMHVREFTSC pcRefTsc = (PCGIMHVREFTSC)pcRegion->pvPageR3;
        uTscSequence = pcRefTsc->u32TscSequence;
    }

    return SSMR3PutU32(pSSM, uTscSequence);
}
Esempio n. 2
0
/* @todo add hashtable walker with result info and intermediate abort */
static void crVBoxServerSaveCreateInfoCB(unsigned long key, void *data1, void *data2)
{
    CRCreateInfo_t *pCreateInfo = (CRCreateInfo_t *) data1;
    PSSMHANDLE pSSM = (PSSMHANDLE) data2;
    int32_t rc;

    CRASSERT(pCreateInfo && pSSM);

    rc = SSMR3PutMem(pSSM, &key, sizeof(key));
    CRASSERT(rc == VINF_SUCCESS);

    rc = SSMR3PutMem(pSSM, pCreateInfo, sizeof(*pCreateInfo));
    CRASSERT(rc == VINF_SUCCESS);

    if (pCreateInfo->pszDpyName)
    {
        rc = SSMR3PutStrZ(pSSM, pCreateInfo->pszDpyName);
        CRASSERT(rc == VINF_SUCCESS);
    }
}