/** * 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); }
/** * Save a queue state. * * @param pSSM SSM handle to write the state to. * @param pQ Pointer to the queue. */ static void ps2kSaveQueue(PSSMHANDLE pSSM, GeneriQ *pQ) { uint32_t cItems = pQ->cUsed; int i; /* Only save the number of items. Note that the read/write * positions aren't saved as they will be rebuilt on load. */ SSMR3PutU32(pSSM, cItems); LogFlow(("Storing %d items from queue %p\n", cItems, pQ)); /* Save queue data - only the bytes actually used (typically zero). */ for (i = pQ->rpos; cItems-- > 0; i = (i + 1) % pQ->cSize) SSMR3PutU8(pSSM, pQ->abQueue[i]); }
/** * KVM state-save operation. * * @returns VBox status code. * @param pVM Pointer to the VM. * @param pSSM Pointer to the SSM handle. */ VMMR3_INT_DECL(int) gimR3KvmSave(PVM pVM, PSSMHANDLE pSSM) { PCGIMKVM pcKvm = &pVM->gim.s.u.Kvm; /* * Save the KVM SSM version. */ SSMR3PutU32(pSSM, GIM_KVM_SAVED_STATE_VERSION); /* * Save per-VCPU data. */ for (uint32_t i = 0; i < pVM->cCpus; i++) { PCGIMKVMCPU pcKvmCpu = &pVM->aCpus[i].gim.s.u.KvmCpu; /* Guest may alter flags (namely GIM_KVM_SYSTEM_TIME_FLAGS_GUEST_PAUSED bit). So re-read them from guest-memory. */ GIMKVMSYSTEMTIME SystemTime; RT_ZERO(SystemTime); if (MSR_GIM_KVM_SYSTEM_TIME_IS_ENABLED(pcKvmCpu->u64SystemTimeMsr)) { int rc = PGMPhysSimpleReadGCPhys(pVM, &SystemTime, pcKvmCpu->GCPhysSystemTime, sizeof(GIMKVMSYSTEMTIME)); AssertRCReturn(rc, rc); } SSMR3PutU64(pSSM, pcKvmCpu->u64SystemTimeMsr); SSMR3PutU64(pSSM, pcKvmCpu->uTsc); SSMR3PutU64(pSSM, pcKvmCpu->uVirtNanoTS); SSMR3PutGCPhys(pSSM, pcKvmCpu->GCPhysSystemTime); SSMR3PutU32(pSSM, pcKvmCpu->u32SystemTimeVersion); SSMR3PutU8(pSSM, SystemTime.fFlags); } /* * Save per-VM data. */ SSMR3PutU64(pSSM, pcKvm->u64WallClockMsr); return SSMR3PutU32(pSSM, pcKvm->uBaseFeat); }
void PS2MSaveState(PPS2M pThis, PSSMHANDLE pSSM) { LogFlowFunc(("Saving PS2M state\n")); /* Save the core auxiliary device state. */ SSMR3PutU8(pSSM, pThis->u8State); SSMR3PutU8(pSSM, pThis->u8SampleRate); SSMR3PutU8(pSSM, pThis->u8Resolution); SSMR3PutU8(pSSM, pThis->u8CurrCmd); SSMR3PutU8(pSSM, pThis->enmMode); SSMR3PutU8(pSSM, pThis->enmProtocol); SSMR3PutU8(pSSM, pThis->enmKnockState); /* Save the command and event queues. */ ps2kSaveQueue(pSSM, (GeneriQ *)&pThis->cmdQ); ps2kSaveQueue(pSSM, (GeneriQ *)&pThis->evtQ); /* Save the command delay timer. Note that the rate throttling * timer is *not* saved. */ TMR3TimerSave(pThis->CTX_SUFF(pDelayTimer), pSSM); }