Changeset 93831 in vbox
- Timestamp:
- Feb 17, 2022 4:58:36 PM (3 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h
r93748 r93831 8593 8593 VMMRZCallRing3Enable(pVCpu); 8594 8594 #else 8595 /** @todo */ 8595 CPUMR3NemActivateGuestDebugState(pVCpu); 8596 Assert(CPUMIsGuestDebugStateActive(pVCpu)); 8597 Assert(!CPUMIsHyperDebugStateActive(pVCpu)); 8596 8598 #endif 8597 8599 … … 10700 10702 pDbgState->fCpe1Extra &= g_HmMsrs.u.vmx.ProcCtls.n.allowed1; 10701 10703 pDbgState->fCpe1Unwanted &= ~g_HmMsrs.u.vmx.ProcCtls.n.allowed0; 10702 #ifndef IN_NEM_DARWIN /** @todo */10704 #ifndef IN_NEM_DARWIN 10703 10705 if (pVCpu->hmr0.s.fDebugWantRdTscExit != RT_BOOL(pDbgState->fCpe1Extra & VMX_PROC_CTLS_RDTSC_EXIT)) 10704 10706 { 10705 10707 pVCpu->hmr0.s.fDebugWantRdTscExit ^= true; 10708 pVmxTransient->fUpdatedTscOffsettingAndPreemptTimer = false; 10709 } 10710 #else 10711 if (pVCpu->nem.s.fDebugWantRdTscExit != RT_BOOL(pDbgState->fCpe1Extra & VMX_PROC_CTLS_RDTSC_EXIT)) 10712 { 10713 pVCpu->nem.s.fDebugWantRdTscExit ^= true; 10706 10714 pVmxTransient->fUpdatedTscOffsettingAndPreemptTimer = false; 10707 10715 } -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp
r93826 r93831 1469 1469 1470 1470 /** 1471 * Exports the guest debug registers into the guest-state applying any hypervisor 1472 * debug related states (hardware breakpoints from the debugger, etc.). 1473 * 1474 * This also sets up whether \#DB and MOV DRx accesses cause VM-exits. 1475 * 1476 * @returns VBox status code. 1477 * @param pVCpu The cross context virtual CPU structure. 1478 * @param pVmxTransient The VMX-transient structure. 1479 */ 1480 static int nemR3DarwinExportDebugState(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransient) 1481 { 1482 PVMXVMCSINFO pVmcsInfo = pVmxTransient->pVmcsInfo; 1483 1484 #ifdef VBOX_STRICT 1485 /* Validate. Intel spec. 26.3.1.1 "Checks on Guest Controls Registers, Debug Registers, MSRs" */ 1486 if (pVmcsInfo->u32EntryCtls & VMX_ENTRY_CTLS_LOAD_DEBUG) 1487 { 1488 /* Validate. Intel spec. 17.2 "Debug Registers", recompiler paranoia checks. */ 1489 Assert((pVCpu->cpum.GstCtx.dr[7] & (X86_DR7_MBZ_MASK | X86_DR7_RAZ_MASK)) == 0); 1490 Assert((pVCpu->cpum.GstCtx.dr[7] & X86_DR7_RA1_MASK) == X86_DR7_RA1_MASK); 1491 } 1492 #endif 1493 1494 bool fSteppingDB = false; 1495 bool fInterceptMovDRx = false; 1496 uint32_t uProcCtls = pVmcsInfo->u32ProcCtls; 1497 if (pVCpu->nem.s.fSingleInstruction) 1498 { 1499 /* If the CPU supports the monitor trap flag, use it for single stepping in DBGF and avoid intercepting #DB. */ 1500 if (g_HmMsrs.u.vmx.ProcCtls.n.allowed1 & VMX_PROC_CTLS_MONITOR_TRAP_FLAG) 1501 { 1502 uProcCtls |= VMX_PROC_CTLS_MONITOR_TRAP_FLAG; 1503 Assert(fSteppingDB == false); 1504 } 1505 else 1506 { 1507 pVCpu->cpum.GstCtx.eflags.u32 |= X86_EFL_TF; 1508 pVCpu->nem.s.fCtxChanged |= HM_CHANGED_GUEST_RFLAGS; 1509 pVCpu->nem.s.fClearTrapFlag = true; 1510 fSteppingDB = true; 1511 } 1512 } 1513 1514 uint64_t u64GuestDr7; 1515 if ( fSteppingDB 1516 || (CPUMGetHyperDR7(pVCpu) & X86_DR7_ENABLED_MASK)) 1517 { 1518 /* 1519 * Use the combined guest and host DRx values found in the hypervisor register set 1520 * because the hypervisor debugger has breakpoints active or someone is single stepping 1521 * on the host side without a monitor trap flag. 1522 * 1523 * Note! DBGF expects a clean DR6 state before executing guest code. 1524 */ 1525 if (!CPUMIsHyperDebugStateActive(pVCpu)) 1526 { 1527 /* 1528 * Make sure the hypervisor values are up to date. 1529 */ 1530 CPUMRecalcHyperDRx(pVCpu, UINT8_MAX /* no loading, please */); 1531 1532 CPUMR3NemActivateHyperDebugState(pVCpu); 1533 1534 Assert(CPUMIsHyperDebugStateActive(pVCpu)); 1535 Assert(!CPUMIsGuestDebugStateActive(pVCpu)); 1536 } 1537 1538 /* Update DR7 with the hypervisor value (other DRx registers are handled by CPUM one way or another). */ 1539 u64GuestDr7 = CPUMGetHyperDR7(pVCpu); 1540 pVCpu->nem.s.fUsingHyperDR7 = true; 1541 fInterceptMovDRx = true; 1542 } 1543 else 1544 { 1545 /* 1546 * If the guest has enabled debug registers, we need to load them prior to 1547 * executing guest code so they'll trigger at the right time. 1548 */ 1549 HMVMX_CPUMCTX_ASSERT(pVCpu, CPUMCTX_EXTRN_DR7); 1550 if (pVCpu->cpum.GstCtx.dr[7] & (X86_DR7_ENABLED_MASK | X86_DR7_GD)) 1551 { 1552 if (!CPUMIsGuestDebugStateActive(pVCpu)) 1553 { 1554 CPUMR3NemActivateGuestDebugState(pVCpu); 1555 1556 Assert(CPUMIsGuestDebugStateActive(pVCpu)); 1557 Assert(!CPUMIsHyperDebugStateActive(pVCpu)); 1558 } 1559 Assert(!fInterceptMovDRx); 1560 } 1561 else if (!CPUMIsGuestDebugStateActive(pVCpu)) 1562 { 1563 /* 1564 * If no debugging enabled, we'll lazy load DR0-3. Unlike on AMD-V, we 1565 * must intercept #DB in order to maintain a correct DR6 guest value, and 1566 * because we need to intercept it to prevent nested #DBs from hanging the 1567 * CPU, we end up always having to intercept it. See hmR0VmxSetupVmcsXcptBitmap(). 1568 */ 1569 fInterceptMovDRx = true; 1570 } 1571 1572 /* Update DR7 with the actual guest value. */ 1573 u64GuestDr7 = pVCpu->cpum.GstCtx.dr[7]; 1574 pVCpu->nem.s.fUsingHyperDR7 = false; 1575 } 1576 1577 if (fInterceptMovDRx) 1578 uProcCtls |= VMX_PROC_CTLS_MOV_DR_EXIT; 1579 else 1580 uProcCtls &= ~VMX_PROC_CTLS_MOV_DR_EXIT; 1581 1582 /* 1583 * Update the processor-based VM-execution controls with the MOV-DRx intercepts and the 1584 * monitor-trap flag and update our cache. 1585 */ 1586 if (uProcCtls != pVmcsInfo->u32ProcCtls) 1587 { 1588 int rc = nemR3DarwinWriteVmcs32(pVCpu, VMX_VMCS32_CTRL_PROC_EXEC, uProcCtls); 1589 AssertRC(rc); 1590 pVmcsInfo->u32ProcCtls = uProcCtls; 1591 } 1592 1593 /* 1594 * If we have forced EFLAGS.TF to be set because we're single-stepping in the hypervisor debugger, 1595 * we need to clear interrupt inhibition if any as otherwise it causes a VM-entry failure. 1596 * 1597 * See Intel spec. 26.3.1.5 "Checks on Guest Non-Register State". 1598 */ 1599 if (fSteppingDB) 1600 { 1601 Assert(pVCpu->nem.s.fSingleInstruction); 1602 Assert(pVCpu->cpum.GstCtx.eflags.Bits.u1TF); 1603 1604 uint32_t fIntrState = 0; 1605 int rc = nemR3DarwinReadVmcs32(pVCpu, VMX_VMCS32_GUEST_INT_STATE, &fIntrState); 1606 AssertRC(rc); 1607 1608 if (fIntrState & (VMX_VMCS_GUEST_INT_STATE_BLOCK_STI | VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS)) 1609 { 1610 fIntrState &= ~(VMX_VMCS_GUEST_INT_STATE_BLOCK_STI | VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS); 1611 rc = nemR3DarwinWriteVmcs32(pVCpu, VMX_VMCS32_GUEST_INT_STATE, fIntrState); 1612 AssertRC(rc); 1613 } 1614 } 1615 1616 /* 1617 * Store status of the shared guest/host debug state at the time of VM-entry. 1618 */ 1619 pVmxTransient->fWasGuestDebugStateActive = CPUMIsGuestDebugStateActive(pVCpu); 1620 pVmxTransient->fWasHyperDebugStateActive = CPUMIsHyperDebugStateActive(pVCpu); 1621 1622 return VINF_SUCCESS; 1623 } 1624 1625 1626 /** 1471 1627 * Converts the given CPUM externalized bitmask to the appropriate HM changed bitmask. 1472 1628 * … … 1661 1817 } 1662 1818 1819 rc = nemR3DarwinExportDebugState(pVCpu, pVmxTransient); 1820 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc\n", rc), rc); 1821 1663 1822 vmxHCExportGuestXcptIntercepts(pVCpu, pVmxTransient); 1664 1823 vmxHCExportGuestRip(pVCpu); … … 1690 1849 if (fWhat & CPUMCTX_EXTRN_DR0_DR3) 1691 1850 { 1692 WRITE_GREG(HV_X86_DR0, pVCpu->cpum.GstCtx.dr[0]); //CPUMGetHyperDR0(pVCpu));1693 WRITE_GREG(HV_X86_DR1, pVCpu->cpum.GstCtx.dr[1]); //CPUMGetHyperDR1(pVCpu));1694 WRITE_GREG(HV_X86_DR2, pVCpu->cpum.GstCtx.dr[2]); //CPUMGetHyperDR2(pVCpu));1695 WRITE_GREG(HV_X86_DR3, pVCpu->cpum.GstCtx.dr[3]); //CPUMGetHyperDR3(pVCpu));1851 WRITE_GREG(HV_X86_DR0, CPUMGetHyperDR0(pVCpu)); 1852 WRITE_GREG(HV_X86_DR1, CPUMGetHyperDR1(pVCpu)); 1853 WRITE_GREG(HV_X86_DR2, CPUMGetHyperDR2(pVCpu)); 1854 WRITE_GREG(HV_X86_DR3, CPUMGetHyperDR3(pVCpu)); 1696 1855 ASMAtomicUoAndU64(&pVCpu->nem.s.fCtxChanged, ~HM_CHANGED_GUEST_DR0_DR3); 1697 1856 } 1698 1857 if (fWhat & CPUMCTX_EXTRN_DR6) 1699 1858 { 1700 WRITE_GREG(HV_X86_DR6, pVCpu->cpum.GstCtx.dr[6]); //CPUMGetHyperDR6(pVCpu));1859 WRITE_GREG(HV_X86_DR6, CPUMGetHyperDR6(pVCpu)); 1701 1860 ASMAtomicUoAndU64(&pVCpu->nem.s.fCtxChanged, ~HM_CHANGED_GUEST_DR6); 1702 1861 } 1703 1862 if (fWhat & CPUMCTX_EXTRN_DR7) 1704 1863 { 1705 WRITE_GREG(HV_X86_DR7, pVCpu->cpum.GstCtx.dr[7]); //CPUMGetHyperDR7(pVCpu));1864 WRITE_GREG(HV_X86_DR7, CPUMGetHyperDR7(pVCpu)); 1706 1865 ASMAtomicUoAndU64(&pVCpu->nem.s.fCtxChanged, ~HM_CHANGED_GUEST_DR7); 1707 1866 } … … 3205 3364 3206 3365 /** 3366 * Prepares the VM to run the guest. 3367 * 3368 * @returns Strict VBox status code. 3369 * @param pVM The cross context VM structure. 3370 * @param pVCpu The cross context virtual CPU structure. 3371 * @param pVmxTransient The VMX transient state. 3372 * @param fSingleStepping Flag whether we run in single stepping mode. 3373 */ 3374 static VBOXSTRICTRC nemR3DarwinPreRunGuest(PVM pVM, PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient, bool fSingleStepping) 3375 { 3376 /* 3377 * Check and process force flag actions, some of which might require us to go back to ring-3. 3378 */ 3379 VBOXSTRICTRC rcStrict = vmxHCCheckForceFlags(pVCpu, false /*fIsNestedGuest*/, fSingleStepping); 3380 if (rcStrict == VINF_SUCCESS) 3381 { /*likely */ } 3382 else 3383 return rcStrict; 3384 3385 /* 3386 * Do not execute in HV if the A20 isn't enabled. 3387 */ 3388 if (PGMPhysIsA20Enabled(pVCpu)) 3389 { /* likely */ } 3390 else 3391 { 3392 LogFlow(("NEM/%u: breaking: A20 disabled\n", pVCpu->idCpu)); 3393 return VINF_EM_RESCHEDULE_REM; 3394 } 3395 3396 /* 3397 * Evaluate events to be injected into the guest. 3398 * 3399 * Events in TRPM can be injected without inspecting the guest state. 3400 * If any new events (interrupts/NMI) are pending currently, we try to set up the 3401 * guest to cause a VM-exit the next time they are ready to receive the event. 3402 */ 3403 if (TRPMHasTrap(pVCpu)) 3404 vmxHCTrpmTrapToPendingEvent(pVCpu); 3405 3406 uint32_t fIntrState; 3407 rcStrict = vmxHCEvaluatePendingEvent(pVCpu, &pVCpu->nem.s.VmcsInfo, false /*fIsNestedGuest*/, &fIntrState); 3408 3409 /* 3410 * Event injection may take locks (currently the PGM lock for real-on-v86 case) and thus 3411 * needs to be done with longjmps or interrupts + preemption enabled. Event injection might 3412 * also result in triple-faulting the VM. 3413 * 3414 * With nested-guests, the above does not apply since unrestricted guest execution is a 3415 * requirement. Regardless, we do this here to avoid duplicating code elsewhere. 3416 */ 3417 rcStrict = vmxHCInjectPendingEvent(pVCpu, &pVCpu->nem.s.VmcsInfo, false /*fIsNestedGuest*/, fIntrState, fSingleStepping); 3418 if (RT_LIKELY(rcStrict == VINF_SUCCESS)) 3419 { /* likely */ } 3420 else 3421 return rcStrict; 3422 3423 int rc = nemR3DarwinExportGuestState(pVM, pVCpu, pVmxTransient); 3424 AssertRCReturn(rc, rc); 3425 3426 LogFlowFunc(("Running vCPU\n")); 3427 pVCpu->nem.s.Event.fPending = false; 3428 return VINF_SUCCESS; 3429 } 3430 3431 3432 /** 3207 3433 * The normal runloop (no debugging features enabled). 3208 3434 * … … 3230 3456 uint64_t offDeltaIgnored; 3231 3457 uint64_t const nsNextTimerEvt = TMTimerPollGIP(pVM, pVCpu, &offDeltaIgnored); NOREF(nsNextTimerEvt); 3232 3233 const bool fSingleStepping = DBGFIsStepping(pVCpu);3234 3458 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 3235 3459 for (unsigned iLoop = 0;; iLoop++) 3236 3460 { 3237 /* 3238 * Check and process force flag actions, some of which might require us to go back to ring-3. 3239 */ 3240 rcStrict = vmxHCCheckForceFlags(pVCpu, false /*fIsNestedGuest*/, fSingleStepping); 3241 if (rcStrict == VINF_SUCCESS) 3242 { /*likely */ } 3243 else 3244 { 3245 if (rcStrict == VINF_EM_RAW_TO_R3) 3246 rcStrict = VINF_SUCCESS; 3461 rcStrict = nemR3DarwinPreRunGuest(pVM, pVCpu, &VmxTransient, false /* fSingleStepping */); 3462 if (rcStrict != VINF_SUCCESS) 3247 3463 break; 3248 }3249 3250 /*3251 * Do not execute in HV if the A20 isn't enabled.3252 */3253 if (PGMPhysIsA20Enabled(pVCpu))3254 { /* likely */ }3255 else3256 {3257 rcStrict = VINF_EM_RESCHEDULE_REM;3258 LogFlow(("NEM/%u: breaking: A20 disabled\n", pVCpu->idCpu));3259 break;3260 }3261 3262 /*3263 * Evaluate events to be injected into the guest.3264 *3265 * Events in TRPM can be injected without inspecting the guest state.3266 * If any new events (interrupts/NMI) are pending currently, we try to set up the3267 * guest to cause a VM-exit the next time they are ready to receive the event.3268 */3269 if (TRPMHasTrap(pVCpu))3270 vmxHCTrpmTrapToPendingEvent(pVCpu);3271 3272 uint32_t fIntrState;3273 rcStrict = vmxHCEvaluatePendingEvent(pVCpu, &pVCpu->nem.s.VmcsInfo, false /*fIsNestedGuest*/, &fIntrState);3274 3275 /*3276 * Event injection may take locks (currently the PGM lock for real-on-v86 case) and thus3277 * needs to be done with longjmps or interrupts + preemption enabled. Event injection might3278 * also result in triple-faulting the VM.3279 *3280 * With nested-guests, the above does not apply since unrestricted guest execution is a3281 * requirement. Regardless, we do this here to avoid duplicating code elsewhere.3282 */3283 rcStrict = vmxHCInjectPendingEvent(pVCpu, &pVCpu->nem.s.VmcsInfo, false /*fIsNestedGuest*/, fIntrState, fSingleStepping);3284 if (RT_LIKELY(rcStrict == VINF_SUCCESS))3285 { /* likely */ }3286 else3287 {3288 AssertMsg(rcStrict == VINF_EM_RESET || (rcStrict == VINF_EM_DBG_STEPPED && fSingleStepping),3289 ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));3290 break;3291 }3292 3293 int rc = nemR3DarwinExportGuestState(pVM, pVCpu, &VmxTransient);3294 AssertRCReturn(rc, rc);3295 3296 LogFlowFunc(("Running vCPU\n"));3297 pVCpu->nem.s.Event.fPending = false;3298 3464 3299 3465 hv_return_t hrc = nemR3DarwinRunGuest(pVM, pVCpu, &VmxTransient); … … 3312 3478 break; 3313 3479 } 3314 //Assert(!pVCpu->cpum.GstCtx.fExtrn);3315 3480 } 3316 3481 else … … 3478 3643 VmxTransient.pVmcsInfo = &pVCpu->nem.s.VmcsInfo; 3479 3644 3645 bool const fSavedSingleInstruction = pVCpu->nem.s.fSingleInstruction; 3646 pVCpu->nem.s.fSingleInstruction = pVCpu->nem.s.fSingleInstruction || DBGFIsStepping(pVCpu); 3647 pVCpu->nem.s.fDebugWantRdTscExit = false; 3648 pVCpu->nem.s.fUsingDebugLoop = true; 3649 3480 3650 /* State we keep to help modify and later restore the VMCS fields we alter, and for detecting steps. */ 3481 3651 VMXRUNDBGSTATE DbgState; … … 3490 3660 uint64_t offDeltaIgnored; 3491 3661 uint64_t const nsNextTimerEvt = TMTimerPollGIP(pVM, pVCpu, &offDeltaIgnored); NOREF(nsNextTimerEvt); 3492 3493 const bool fSingleStepping = DBGFIsStepping(pVCpu);3494 3662 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 3495 3663 for (unsigned iLoop = 0;; iLoop++) 3496 3664 { 3665 bool fStepping = pVCpu->nem.s.fSingleInstruction; 3666 3497 3667 /* Set up VM-execution controls the next two can respond to. */ 3498 3668 vmxHCPreRunGuestDebugStateApply(pVCpu, &VmxTransient, &DbgState); 3499 3669 3500 /* 3501 * Check and process force flag actions, some of which might require us to go back to ring-3. 3502 */ 3503 rcStrict = vmxHCCheckForceFlags(pVCpu, false /*fIsNestedGuest*/, fSingleStepping); 3504 if (rcStrict == VINF_SUCCESS) 3505 { /*likely */ } 3506 else 3507 { 3508 if (rcStrict == VINF_EM_RAW_TO_R3) 3509 rcStrict = VINF_SUCCESS; 3670 rcStrict = nemR3DarwinPreRunGuest(pVM, pVCpu, &VmxTransient, fStepping); 3671 if (rcStrict != VINF_SUCCESS) 3510 3672 break; 3511 } 3512 3513 /* 3514 * Do not execute in HV if the A20 isn't enabled. 3515 */ 3516 if (PGMPhysIsA20Enabled(pVCpu)) 3517 { /* likely */ } 3518 else 3519 { 3520 rcStrict = VINF_EM_RESCHEDULE_REM; 3521 LogFlow(("NEM/%u: breaking: A20 disabled\n", pVCpu->idCpu)); 3522 break; 3523 } 3524 3525 /* 3526 * Evaluate events to be injected into the guest. 3527 * 3528 * Events in TRPM can be injected without inspecting the guest state. 3529 * If any new events (interrupts/NMI) are pending currently, we try to set up the 3530 * guest to cause a VM-exit the next time they are ready to receive the event. 3531 */ 3532 if (TRPMHasTrap(pVCpu)) 3533 vmxHCTrpmTrapToPendingEvent(pVCpu); 3534 3535 uint32_t fIntrState; 3536 rcStrict = vmxHCEvaluatePendingEvent(pVCpu, &pVCpu->nem.s.VmcsInfo, false /*fIsNestedGuest*/, &fIntrState); 3537 3538 /* 3539 * Event injection may take locks (currently the PGM lock for real-on-v86 case) and thus 3540 * needs to be done with longjmps or interrupts + preemption enabled. Event injection might 3541 * also result in triple-faulting the VM. 3542 * 3543 * With nested-guests, the above does not apply since unrestricted guest execution is a 3544 * requirement. Regardless, we do this here to avoid duplicating code elsewhere. 3545 */ 3546 rcStrict = vmxHCInjectPendingEvent(pVCpu, &pVCpu->nem.s.VmcsInfo, false /*fIsNestedGuest*/, fIntrState, fSingleStepping); 3547 if (RT_LIKELY(rcStrict == VINF_SUCCESS)) 3548 { /* likely */ } 3549 else 3550 { 3551 AssertMsg(rcStrict == VINF_EM_RESET || (rcStrict == VINF_EM_DBG_STEPPED && fSingleStepping), 3552 ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 3553 break; 3554 } 3555 3556 int rc = nemR3DarwinExportGuestState(pVM, pVCpu, &VmxTransient); 3557 AssertRCReturn(rc, rc); 3558 3559 LogFlowFunc(("Running vCPU\n")); 3560 pVCpu->nem.s.Event.fPending = false; 3561 3562 /* Override any obnoxious code in the above two calls. */ 3673 3674 /* Override any obnoxious code in the above call. */ 3563 3675 vmxHCPreRunGuestDebugStateApply(pVCpu, &VmxTransient, &DbgState); 3564 3676 … … 3578 3690 break; 3579 3691 } 3580 //Assert(!pVCpu->cpum.GstCtx.fExtrn); 3692 3693 /* 3694 * Stepping: Did the RIP change, if so, consider it a single step. 3695 * Otherwise, make sure one of the TFs gets set. 3696 */ 3697 if (fStepping) 3698 { 3699 int rc = vmxHCImportGuestState(pVCpu, VmxTransient.pVmcsInfo, CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_RIP); 3700 AssertRC(rc); 3701 if ( pVCpu->cpum.GstCtx.rip != DbgState.uRipStart 3702 || pVCpu->cpum.GstCtx.cs.Sel != DbgState.uCsStart) 3703 { 3704 rcStrict = VINF_EM_DBG_STEPPED; 3705 break; 3706 } 3707 ASMAtomicUoOrU64(&pVCpu->nem.s.fCtxChanged, HM_CHANGED_GUEST_DR7); 3708 } 3581 3709 } 3582 3710 else … … 3587 3715 } 3588 3716 } /* the run loop */ 3717 3718 /* 3719 * Clear the X86_EFL_TF if necessary. 3720 */ 3721 if (pVCpu->nem.s.fClearTrapFlag) 3722 { 3723 int rc = vmxHCImportGuestState(pVCpu, VmxTransient.pVmcsInfo, CPUMCTX_EXTRN_RFLAGS); 3724 AssertRC(rc); 3725 pVCpu->nem.s.fClearTrapFlag = false; 3726 pVCpu->cpum.GstCtx.eflags.Bits.u1TF = 0; 3727 } 3728 3729 pVCpu->nem.s.fUsingDebugLoop = false; 3730 pVCpu->nem.s.fDebugWantRdTscExit = false; 3731 pVCpu->nem.s.fSingleInstruction = fSavedSingleInstruction; 3589 3732 3590 3733 /* Restore all controls applied by vmxHCPreRunGuestDebugStateApply above. */ … … 3623 3766 else 3624 3767 rcStrict = nemR3DarwinRunGuestDebug(pVM, pVCpu); 3768 3769 if (rcStrict == VINF_EM_RAW_TO_R3) 3770 rcStrict = VINF_SUCCESS; 3625 3771 3626 3772 /* -
trunk/src/VBox/VMM/include/NEMInternal.h
r93787 r93831 335 335 /** Whether we're executing a single instruction. */ 336 336 bool fSingleInstruction : 1; 337 /** Set if we using the debug loop and wish to intercept RDTSC. */ 338 bool fDebugWantRdTscExit : 1; 339 /** Whether we are currently executing in the debug loop. 340 * Mainly for assertions. */ 341 bool fUsingDebugLoop : 1; 342 /** Set if we need to clear the trap flag because of single stepping. */ 343 bool fClearTrapFlag : 1; 344 /** Whether we're using the hyper DR7 or guest DR7. */ 345 bool fUsingHyperDR7 : 1; 337 346 338 347 #if defined(RT_OS_LINUX)
Note:
See TracChangeset
for help on using the changeset viewer.