VirtualBox

Changeset 108757 in vbox


Ignore:
Timestamp:
Mar 26, 2025 2:26:34 PM (3 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168184
Message:

VMM/NEMR3Native-win-armv8.cpp: Need to save/restore the WHvRegisterInternalActivity register or SMP guests get stuck after a saved state is loaded because all but the first vCPU are suspended, bugref:10392

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win-armv8.cpp

    r108748 r108757  
    7676# define WHvMapGpaRangeFlagTrackDirtyPages      ((WHV_MAP_GPA_RANGE_FLAGS)0x00000008)
    7777#endif
     78
     79/** Our saved state version for Hyper-V specific things. */
     80#define NEM_HV_SAVED_STATE_VERSION 1
    7881
    7982
     
    10871090
    10881091
     1092/**
     1093 * Execute state save operation.
     1094 *
     1095 * @returns VBox status code.
     1096 * @param   pVM             The cross context VM structure.
     1097 * @param   pSSM            SSM operation handle.
     1098 */
     1099static DECLCALLBACK(int) nemR3Save(PVM pVM, PSSMHANDLE pSSM)
     1100{
     1101    /*
     1102     * Save the Hyper-V activity state for all CPUs.
     1103     */
     1104    for (VMCPUID i = 0; i < pVM->cCpus; i++)
     1105    {
     1106        PVMCPUCC pVCpu = pVM->apCpusR3[i];
     1107
     1108        static const WHV_REGISTER_NAME s_Name = WHvRegisterInternalActivityState;
     1109        WHV_REGISTER_VALUE Reg;
     1110
     1111        HRESULT hrc = WHvGetVirtualProcessorRegisters(pVM->nem.s.hPartition, pVCpu->idCpu, &s_Name, 1, &Reg);
     1112        AssertLogRelMsgReturn(SUCCEEDED(hrc),
     1113                              ("WHvSetVirtualProcessorRegisters(%p, 0,{WHvRegisterInternalActivityState}, 1,) -> %Rhrc (Last=%#x/%u)\n",
     1114                               pVM->nem.s.hPartition, pVCpu->idCpu, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())
     1115                              , VERR_NEM_IPE_9);
     1116
     1117        SSMR3PutU64(pSSM, Reg.Reg64);
     1118    }
     1119
     1120    return SSMR3PutU32(pSSM, UINT32_MAX); /* terminator */
     1121}
     1122
     1123
     1124/**
     1125 * Execute state load operation.
     1126 *
     1127 * @returns VBox status code.
     1128 * @param   pVM             The cross context VM structure.
     1129 * @param   pSSM            SSM operation handle.
     1130 * @param   uVersion        Data layout version.
     1131 * @param   uPass           The data pass.
     1132 */
     1133static DECLCALLBACK(int) nemR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     1134{
     1135    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
     1136
     1137    /*
     1138     * Validate version.
     1139     */
     1140    if (uVersion != 1)
     1141    {
     1142        AssertMsgFailed(("nemR3Load: Invalid version uVersion=%u!\n", uVersion));
     1143        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     1144    }
     1145
     1146    /*
     1147     * Restore the Hyper-V activity states for all vCPUs.
     1148     */
     1149    VMCPU_SET_STATE(pVM->apCpusR3[0], VMCPUSTATE_STARTED);
     1150    for (VMCPUID i = 0; i < pVM->cCpus; i++)
     1151    {
     1152        PVMCPUCC pVCpu = pVM->apCpusR3[i];
     1153
     1154        static const WHV_REGISTER_NAME s_Name = WHvRegisterInternalActivityState;
     1155        WHV_REGISTER_VALUE Reg;
     1156        int rc = SSMR3GetU64(pSSM, &Reg.Reg64);
     1157        if (RT_FAILURE(rc))
     1158            return rc;
     1159
     1160        HRESULT hrc = WHvSetVirtualProcessorRegisters(pVM->nem.s.hPartition, pVCpu->idCpu, &s_Name, 1, &Reg);
     1161        AssertLogRelMsgReturn(SUCCEEDED(hrc),
     1162                              ("WHvSetVirtualProcessorRegisters(%p, 0,{WHvRegisterInternalActivityState}, 1,) -> %Rhrc (Last=%#x/%u)\n",
     1163                               pVM->nem.s.hPartition, pVCpu->idCpu, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())
     1164                              , VERR_NEM_IPE_9);
     1165    }
     1166
     1167    /* terminator */
     1168    uint32_t u32;
     1169    int rc = SSMR3GetU32(pSSM, &u32);
     1170    if (RT_FAILURE(rc))
     1171        return rc;
     1172    if (u32 != UINT32_MAX)
     1173    {
     1174        AssertMsgFailed(("u32=%#x\n", u32));
     1175        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
     1176    }
     1177    return VINF_SUCCESS;
     1178}
     1179
     1180
    10891181int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
    10901182{
    10911183    //BOOL fRet = SetThreadPriority(GetCurrentThread(), 0);
    10921184    //AssertLogRel(fRet);
     1185
     1186    if (enmWhat == VMINITCOMPLETED_RING3)
     1187    {
     1188        /*
     1189         * Register the saved state data unit.
     1190         */
     1191        int rc = SSMR3RegisterInternal(pVM, "nem-win", 1, NEM_HV_SAVED_STATE_VERSION,
     1192                                       sizeof(uint64_t),
     1193                                       NULL, NULL, NULL,
     1194                                       NULL, nemR3Save, NULL,
     1195                                       NULL, nemR3Load, NULL);
     1196        if (RT_FAILURE(rc))
     1197            return rc;
     1198    }
    10931199
    10941200    NOREF(pVM); NOREF(enmWhat);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette