/**
 * 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);
}
예제 #2
0
/**
 * 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]);
}
예제 #3
0
/**
 * 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);
}
예제 #4
0
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);
}