VirtualBox

Changeset 88346 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Apr 1, 2021 1:16:25 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143577
Message:

Forward ported r143574 from 6.1: VMM: Must do vmR3SetHaltMethodCallback on all EMTs or only one of them will be doing halting in ring-0. oem2ticketref:40

Location:
trunk/src/VBox/VMM/VMMR3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/VMEmt.cpp

    r86118 r88346  
    12531253static DECLCALLBACK(VBOXSTRICTRC) vmR3SetHaltMethodCallback(PVM pVM, PVMCPU pVCpu, void *pvUser)
    12541254{
    1255     PUVM        pUVM = pVM->pUVM;
    1256     uintptr_t   i    = (uintptr_t)pvUser;
     1255    PUVM      pUVM = pVM->pUVM;
     1256    int       rc   = VINF_SUCCESS;
     1257    uintptr_t i    = (uintptr_t)pvUser;
    12571258    Assert(i < RT_ELEMENTS(g_aHaltMethods));
    1258     NOREF(pVCpu);
    1259 
    1260     /*
    1261      * Terminate the old one.
    1262      */
    1263     if (    pUVM->vm.s.enmHaltMethod != VMHALTMETHOD_INVALID
    1264         &&  g_aHaltMethods[pUVM->vm.s.iHaltMethod].pfnTerm)
    1265     {
    1266         g_aHaltMethods[pUVM->vm.s.iHaltMethod].pfnTerm(pUVM);
    1267         pUVM->vm.s.enmHaltMethod = VMHALTMETHOD_INVALID;
    1268     }
    1269 
    1270     /* Assert that the failure fallback is where we expect. */
    1271     Assert(g_aHaltMethods[0].enmHaltMethod == VMHALTMETHOD_BOOTSTRAP);
    1272     Assert(!g_aHaltMethods[0].pfnTerm && !g_aHaltMethods[0].pfnInit);
    1273 
    1274     /*
    1275      * Init the new one.
    1276      */
    1277     int rc = VINF_SUCCESS;
    1278     memset(&pUVM->vm.s.Halt, 0, sizeof(pUVM->vm.s.Halt));
    1279     if (g_aHaltMethods[i].pfnInit)
    1280     {
    1281         rc = g_aHaltMethods[i].pfnInit(pUVM);
    1282         if (RT_FAILURE(rc))
    1283         {
    1284             /* Fall back on the bootstrap method. This requires no
    1285                init/term (see assertion above), and will always work. */
    1286             AssertLogRelRC(rc);
    1287             i = 0;
    1288         }
    1289     }
    1290 
    1291     /*
    1292      * Commit it.
    1293      */
    1294     pUVM->vm.s.enmHaltMethod = g_aHaltMethods[i].enmHaltMethod;
    1295     ASMAtomicWriteU32(&pUVM->vm.s.iHaltMethod, i);
    1296 
     1259
     1260    /*
     1261     * Main job is done once on EMT0 (it goes thru here first).
     1262     */
     1263    if (pVCpu->idCpu == 0)
     1264    {
     1265        /*
     1266         * Terminate the old one.
     1267         */
     1268        if (    pUVM->vm.s.enmHaltMethod != VMHALTMETHOD_INVALID
     1269            &&  g_aHaltMethods[pUVM->vm.s.iHaltMethod].pfnTerm)
     1270        {
     1271            g_aHaltMethods[pUVM->vm.s.iHaltMethod].pfnTerm(pUVM);
     1272            pUVM->vm.s.enmHaltMethod = VMHALTMETHOD_INVALID;
     1273        }
     1274
     1275        /* Assert that the failure fallback is where we expect. */
     1276        Assert(g_aHaltMethods[0].enmHaltMethod == VMHALTMETHOD_BOOTSTRAP);
     1277        Assert(!g_aHaltMethods[0].pfnTerm && !g_aHaltMethods[0].pfnInit);
     1278
     1279        /*
     1280         * Init the new one.
     1281         */
     1282        memset(&pUVM->vm.s.Halt, 0, sizeof(pUVM->vm.s.Halt));
     1283        if (g_aHaltMethods[i].pfnInit)
     1284        {
     1285            rc = g_aHaltMethods[i].pfnInit(pUVM);
     1286            if (RT_FAILURE(rc))
     1287            {
     1288                /* Fall back on the bootstrap method. This requires no
     1289                   init/term (see assertion above), and will always work. */
     1290                AssertLogRelRC(rc);
     1291                i = 0;
     1292            }
     1293        }
     1294
     1295        /*
     1296         * Commit it.
     1297         */
     1298        pUVM->vm.s.enmHaltMethod = g_aHaltMethods[i].enmHaltMethod;
     1299        ASMAtomicWriteU32(&pUVM->vm.s.iHaltMethod, i);
     1300    }
     1301    else
     1302        i = pUVM->vm.s.iHaltMethod;
     1303
     1304    /*
     1305     * All EMTs must update their ring-0 halt configuration.
     1306     */
    12971307    VMMR3SetMayHaltInRing0(pVCpu, g_aHaltMethods[i].fMayHaltInRing0,
    12981308                           g_aHaltMethods[i].enmHaltMethod == VMHALTMETHOD_GLOBAL_1
     
    13511361     * This needs to be done while the other EMTs are not sleeping or otherwise messing around.
    13521362     */
    1353     return VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, vmR3SetHaltMethodCallback, (void *)(uintptr_t)i);
     1363    return VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ASCENDING, vmR3SetHaltMethodCallback, (void *)(uintptr_t)i);
    13541364}
    13551365
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r88344 r88346  
    21342134VMMR3_INT_DECL(void) VMMR3SetMayHaltInRing0(PVMCPU pVCpu, bool fMayHaltInRing0, uint32_t cNsSpinBlockThreshold)
    21352135{
     2136    LogFlow(("VMMR3SetMayHaltInRing0(#%u, %d, %u)\n", pVCpu->idCpu, fMayHaltInRing0, cNsSpinBlockThreshold));
    21362137    pVCpu->vmm.s.fMayHaltInRing0       = fMayHaltInRing0;
    21372138    pVCpu->vmm.s.cNsSpinBlockThreshold = cNsSpinBlockThreshold;
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