- Timestamp:
- Sep 18, 2008 2:58:57 PM (16 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/CPUM.cpp
r12542 r12578 709 709 710 710 pCtx->dr6 = X86_DR6_INIT_VAL; 711 pCtx->dr7 = 0x400;711 pCtx->dr7 = X86_DR7_INIT_VAL; 712 712 713 713 pCtx->fpu.FTW = 0xff; /* All tags are set, i.e. the regs are empty. */ -
trunk/src/VBox/VMM/HWACCM.cpp
r12554 r12578 163 163 STAM_REG(pVM, &pVM->hwaccm.s.StatTSCIntercept, STAMTYPE_COUNTER, "/HWACCM/TSC/Intercept", STAMUNIT_OCCURENCES, "Nr of occurances"); 164 164 165 STAM_REG(pVM, &pVM->hwaccm.s.StatDR0Armed, STAMTYPE_COUNTER, "/HWACCM/Debug/Armed/DR0", STAMUNIT_OCCURENCES, "Nr of occurances"); 166 STAM_REG(pVM, &pVM->hwaccm.s.StatDR1Armed, STAMTYPE_COUNTER, "/HWACCM/Debug/Armed/DR1", STAMUNIT_OCCURENCES, "Nr of occurances"); 167 STAM_REG(pVM, &pVM->hwaccm.s.StatDR2Armed, STAMTYPE_COUNTER, "/HWACCM/Debug/Armed/DR2", STAMUNIT_OCCURENCES, "Nr of occurances"); 168 STAM_REG(pVM, &pVM->hwaccm.s.StatDR3Armed, STAMTYPE_COUNTER, "/HWACCM/Debug/Armed/DR3", STAMUNIT_OCCURENCES, "Nr of occurances"); 165 STAM_REG(pVM, &pVM->hwaccm.s.StatDRxArmed, STAMTYPE_COUNTER, "/HWACCM/Debug/Armed", STAMUNIT_OCCURENCES, "Nr of occurances"); 169 166 STAM_REG(pVM, &pVM->hwaccm.s.StatDRxContextSwitch, STAMTYPE_COUNTER, "/HWACCM/Debug/ContextSwitch", STAMUNIT_OCCURENCES, "Nr of occurances"); 170 167 -
trunk/src/VBox/VMM/HWACCMInternal.h
r12566 r12578 112 112 */ 113 113 #ifdef VBOX_STRICT 114 #define HWACCM_VMX_TRAP_MASK RT_BIT(X86_XCPT_DE) | RT_BIT(X86_XCPT_ DB) | RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF) | RT_BIT(X86_XCPT_UD) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_MF)114 #define HWACCM_VMX_TRAP_MASK RT_BIT(X86_XCPT_DE) | RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF) | RT_BIT(X86_XCPT_UD) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_MF) 115 115 #define HWACCM_SVM_TRAP_MASK HWACCM_VMX_TRAP_MASK 116 116 #else 117 #define HWACCM_VMX_TRAP_MASK RT_BIT(X86_XCPT_ DB) | RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF)117 #define HWACCM_VMX_TRAP_MASK RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF) 118 118 #define HWACCM_SVM_TRAP_MASK RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF) 119 119 #endif … … 285 285 uint32_t ulLastInstrError; 286 286 287 /** Current trap mask. */ 288 uint32_t u32TrapMask; 289 287 290 struct 288 291 { … … 377 380 /** Currenty shadow paging mode. */ 378 381 PGMMODE enmShadowMode; 379 380 381 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT382 struct383 {384 /* Saved host debug registers. */385 uint64_t dr0, dr1, dr2, dr3, dr6, dr7;386 bool fHostDR7Saved;387 bool fHostDebugRegsSaved;388 } savedhoststate;389 #endif390 382 391 383 #ifdef VBOX_STRICT … … 450 442 451 443 STAMCOUNTER StatExitReasonNPF; 452 STAMCOUNTER StatDR0Armed; 453 STAMCOUNTER StatDR1Armed; 454 STAMCOUNTER StatDR2Armed; 455 STAMCOUNTER StatDR3Armed; 444 STAMCOUNTER StatDRxArmed; 456 445 STAMCOUNTER StatDRxContextSwitch; 457 446 … … 484 473 /* Dummy callback handlers. */ 485 474 HWACCMR0DECL(int) HWACCMR0DummyEnter(PVM pVM, PHWACCM_CPUINFO pCpu); 486 HWACCMR0DECL(int) HWACCMR0DummyLeave(PVM pVM );475 HWACCMR0DECL(int) HWACCMR0DummyLeave(PVM pVM, CPUMCTX *pCtx); 487 476 HWACCMR0DECL(int) HWACCMR0DummyEnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys); 488 477 HWACCMR0DECL(int) HWACCMR0DummyDisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys); -
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r11704 r12578 1806 1806 1807 1807 1808 1809 /** 1810 * Checks if the guest debug state is active 1811 * 1812 * @returns boolean 1813 * @param pVM VM handle. 1814 */ 1815 CPUMDECL(bool) CPUMIsGuestDebugStateActive(PVM pVM) 1816 { 1817 return (pVM->cpum.s.fUseFlags & CPUM_USE_DEBUG_REGS) != 0; 1818 } 1819 1820 /** 1821 * Mark the guest's debug state as inactive 1822 * 1823 * @returns boolean 1824 * @param pVM VM handle. 1825 */ 1826 CPUMDECL(void) CPUMDeactivateGuestDebugtate(PVM pVM) 1827 { 1828 pVM->cpum.s.fUseFlags &= ~CPUM_USE_DEBUG_REGS; 1829 } 1830 1831 1808 1832 /** 1809 1833 * Checks if the hidden selector registers are valid -
trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp
r12227 r12578 167 167 #ifndef CPUM_CAN_HANDLE_NM_TRAPS_IN_KERNEL_MODE 168 168 uint64_t oldMsrEFERHost; 169 169 uint32_t oldCR0 = ASMGetCR0(); 170 170 171 171 /* Clear MSR_K6_EFER_FFXSR or else we'll be unable to save/restore the XMM state with fxsave/fxrstor. */ … … 194 194 ASMSetCR0(oldCR0); 195 195 #else 196 /* Save the FPU control word and MXCSR, so we can restore the properly afterwards.196 /* Save the FPU control word and MXCSR, so we can restore the state properly afterwards. 197 197 * We don't want the guest to be able to trigger floating point/SSE exceptions on the host. 198 198 */ … … 272 272 return VINF_SUCCESS; 273 273 } 274 275 276 /** 277 * Save guest debug state 278 * 279 * @returns VBox status code. 280 * @param pVM VM handle. 281 * @param pCtx CPU context 282 * @param fDR6 Include DR6 or not 283 */ 284 CPUMR0DECL(int) CPUMR0SaveGuestDebugState(PVM pVM, PCPUMCTX pCtx, bool fDR6) 285 { 286 Assert(pVM->cpum.s.fUseFlags & CPUM_USE_DEBUG_REGS); 287 288 /* Save the guest's debug state. The caller is responsible for DR7. */ 289 pCtx->dr0 = ASMGetDR0(); 290 pCtx->dr1 = ASMGetDR1(); 291 pCtx->dr2 = ASMGetDR2(); 292 pCtx->dr3 = ASMGetDR3(); 293 if (fDR6) 294 pCtx->dr6 = ASMGetDR6(); 295 296 /* Restore the host's debug state. DR0-3, DR6 and only then DR7! */ 297 ASMSetDR0(pVM->cpum.s.Host.dr0); 298 ASMSetDR1(pVM->cpum.s.Host.dr1); 299 ASMSetDR2(pVM->cpum.s.Host.dr2); 300 ASMSetDR3(pVM->cpum.s.Host.dr3); 301 ASMSetDR6(pVM->cpum.s.Host.dr6); 302 ASMSetDR7(pVM->cpum.s.Host.dr7); 303 304 pVM->cpum.s.fUseFlags &= ~CPUM_USE_DEBUG_REGS; 305 return VINF_SUCCESS; 306 } 307 308 309 /** 310 * Lazily sync in the debug state 311 * 312 * @returns VBox status code. 313 * @param pVM VM handle. 314 * @param pCtx CPU context 315 * @param fDR6 Include DR6 or not 316 */ 317 CPUMR0DECL(int) CPUMR0LoadGuestDebugState(PVM pVM, PCPUMCTX pCtx, bool fDR6) 318 { 319 /* Save the host state. */ 320 pVM->cpum.s.Host.dr0 = ASMGetDR0(); 321 pVM->cpum.s.Host.dr1 = ASMGetDR1(); 322 pVM->cpum.s.Host.dr2 = ASMGetDR2(); 323 pVM->cpum.s.Host.dr3 = ASMGetDR3(); 324 pVM->cpum.s.Host.dr6 = ASMGetDR6(); 325 pVM->cpum.s.Host.dr7 = ASMGetDR7(); 326 /* Make sure DR7 is harmless or else we could trigger breakpoints when restoring dr0-3 (!) */ 327 ASMSetDR7(X86_DR7_INIT_VAL); 328 329 /* Activate the guest state DR0-3; DR7 is left to the caller. */ 330 ASMSetDR0(pCtx->dr0); 331 ASMSetDR1(pCtx->dr1); 332 ASMSetDR2(pCtx->dr2); 333 ASMSetDR3(pCtx->dr3); 334 if (fDR6) 335 ASMSetDR6(pCtx->dr6); 336 337 pVM->cpum.s.fUseFlags |= CPUM_USE_DEBUG_REGS; 338 return VINF_SUCCESS; 339 } -
trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
r12554 r12578 64 64 /** Ring 0 handlers for VT-x and AMD-V. */ 65 65 DECLR0CALLBACKMEMBER(int, pfnEnterSession,(PVM pVM, PHWACCM_CPUINFO pCpu)); 66 DECLR0CALLBACKMEMBER(int, pfnLeaveSession,(PVM pVM ));66 DECLR0CALLBACKMEMBER(int, pfnLeaveSession,(PVM pVM, CPUMCTX *pCtx)); 67 67 DECLR0CALLBACKMEMBER(int, pfnSaveHostState,(PVM pVM)); 68 68 DECLR0CALLBACKMEMBER(int, pfnLoadGuestState,(PVM pVM, CPUMCTX *pCtx)); … … 747 747 CPUMDeactivateGuestFPUState(pVM); 748 748 749 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 750 /* 751 * Check if host debug registers are armed. All context switches set DR7 back to 0x400. 752 */ 753 uint64_t u64DR7 = ASMGetDR7(); 754 if (u64DR7 & (X86_DR7_ENABLED_MASK | X86_DR7_GD)) 755 { 756 pVM->hwaccm.s.savedhoststate.dr7 = u64DR7; 757 pVM->hwaccm.s.savedhoststate.fHostDR7Saved = true; 758 } 759 else 760 pVM->hwaccm.s.savedhoststate.fHostDR7Saved = false; 761 #endif 749 /* Always load the guest's debug state on-demand. */ 750 CPUMDeactivateGuestDebugtate(pVM); 762 751 763 752 /* Always reload the host context and the guest's CR0 register. (!!!!) */ … … 818 807 } 819 808 820 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 821 /* Restore the host debug registers. First dr0-3, then dr6 and only then dr7! */ 822 if (pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved) 823 { 824 ASMSetDR0(pVM->hwaccm.s.savedhoststate.dr0); 825 ASMSetDR1(pVM->hwaccm.s.savedhoststate.dr1); 826 ASMSetDR2(pVM->hwaccm.s.savedhoststate.dr2); 827 ASMSetDR3(pVM->hwaccm.s.savedhoststate.dr3); 828 ASMSetDR6(pVM->hwaccm.s.savedhoststate.dr6); 829 pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved = false; 830 831 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxContextSwitch); 832 } 833 if (pVM->hwaccm.s.savedhoststate.fHostDR7Saved) 834 { 835 ASMSetDR7(pVM->hwaccm.s.savedhoststate.dr7); 836 pVM->hwaccm.s.savedhoststate.fHostDR7Saved = false; 837 } 838 #endif 839 840 /* Resync the debug register on the next entry. */ 841 pVM->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_DEBUG; 842 rc = HWACCMR0Globals.pfnLeaveSession(pVM); 809 rc = HWACCMR0Globals.pfnLeaveSession(pVM, pCtx); 843 810 844 811 #ifdef VBOX_STRICT … … 1165 1132 } 1166 1133 1167 HWACCMR0DECL(int) HWACCMR0DummyLeave(PVM pVM )1134 HWACCMR0DECL(int) HWACCMR0DummyLeave(PVM pVM, PCPUMCTX pCtx) 1168 1135 { 1169 1136 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r12554 r12578 276 276 pVMCB->ctrl.u16InterceptWrCRx = RT_BIT(0) | RT_BIT(4) | RT_BIT(8); 277 277 278 /* Intercept all DRx reads and writes . (@todo not necessary to intercept all)*/278 /* Intercept all DRx reads and writes by default. Changed later on. */ 279 279 pVMCB->ctrl.u16InterceptRdDRx = 0xFFFF; 280 280 pVMCB->ctrl.u16InterceptWrDRx = 0xFFFF; … … 686 686 if (pVM->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_DEBUG) 687 687 { 688 pCtx->dr7 &= 0xffffffff; /* upper 32 bits reserved */ 689 pCtx->dr7 &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */ 690 pCtx->dr7 |= 0x400; /* must be one */ 691 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 688 pCtx->dr6 |= X86_DR6_INIT_VAL; /* set all reserved bits to 1. */ 689 pCtx->dr6 &= ~RT_BIT(12); /* must be zero. */ 690 691 pCtx->dr7 &= 0xffffffff; /* upper 32 bits reserved */ 692 pCtx->dr7 &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */ 693 pCtx->dr7 |= 0x400; /* must be one */ 694 692 695 pVMCB->guest.u64DR7 = pCtx->dr7; 693 #else694 pVMCB->guest.u64DR7 = 0x400;695 #endif696 696 pVMCB->guest.u64DR6 = pCtx->dr6; 697 697 698 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 699 /* Any guest breakpoints enabled? */ 700 if ( (pCtx->dr7 & X86_DR7_ENABLED_MASK) 701 && !pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved) 702 { 703 /* Save the host debug register; a bit paranoid if the host has no active breakpoints set in dr7, but we 704 * do not want anything from the guest to leak into the host! 705 */ 706 pVM->hwaccm.s.savedhoststate.dr0 = ASMGetDR0(); 707 pVM->hwaccm.s.savedhoststate.dr1 = ASMGetDR1(); 708 pVM->hwaccm.s.savedhoststate.dr2 = ASMGetDR2(); 709 pVM->hwaccm.s.savedhoststate.dr3 = ASMGetDR3(); 710 pVM->hwaccm.s.savedhoststate.dr6 = ASMGetDR6(); 711 pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved = true; 712 713 /* Make sure DR7 is harmless or else we could trigger breakpoints when restoring dr0-3 (!) */ 714 ASMSetDR7(0x400); 715 } 716 717 if (pCtx->dr7 & (X86_DR7_L0|X86_DR7_G0)) 718 { 719 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDR0Armed); 720 ASMSetDR0(pCtx->dr0); 721 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 722 } 723 if (pCtx->dr7 & (X86_DR7_L1|X86_DR7_G1)) 724 { 725 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDR1Armed); 726 ASMSetDR1(pCtx->dr1); 727 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 728 } 729 if (pCtx->dr7 & (X86_DR7_L2|X86_DR7_G2)) 730 { 731 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDR2Armed); 732 ASMSetDR2(pCtx->dr2); 733 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 734 } 735 if (pCtx->dr7 & (X86_DR7_L3|X86_DR7_G3)) 736 { 737 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDR3Armed); 738 ASMSetDR3(pCtx->dr3); 739 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 740 } 741 742 /* No need to sync DR6; all DR6 reads are intercepted. */ 743 #endif /* VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT */ 698 /* Sync the debug state now if any breakpoint is armed. */ 699 if ( (pCtx->dr7 & (X86_DR7_ENABLED_MASK|X86_DR7_GD)) 700 && !CPUMIsGuestDebugStateActive(pVM) 701 && !DBGFIsStepping(pVM)) 702 { 703 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxArmed); 704 705 /* Disable drx move intercepts. */ 706 pVMCB->ctrl.u16InterceptRdDRx = 0; 707 pVMCB->ctrl.u16InterceptWrDRx = 0; 708 709 /* Save the host and load the guest debug state. */ 710 int rc = CPUMR0LoadGuestDebugState(pVM, pCtx, false /* exclude DR6 */); 711 AssertRC(rc); 712 } 744 713 } 745 714 … … 1311 1280 switch (vector) 1312 1281 { 1313 #ifdef DEBUG1314 1282 case X86_XCPT_DB: 1315 1283 { 1316 #if 0 /* revisit */ 1317 rc = DBGFR0Trap01Handler(pVM, CPUMCTX2CORE(pCtx), pVMCB->guest.u64DR6); 1318 Assert(rc != VINF_EM_RAW_GUEST_TRAP); 1284 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitGuestDB); 1285 1286 /* Note that we don't support guest and host-initiated debugging at the same time. */ 1287 Assert(DBGFIsStepping(pVM)); 1288 1289 rc = DBGFR0Trap01Handler(pVM, CPUMCTX2CORE(pCtx), pCtx->dr6); 1290 if (rc == VINF_EM_RAW_GUEST_TRAP) 1291 { 1292 Log(("Trap %x (debug) at %VGv\n", vector, pCtx->rip)); 1293 1294 /* Reinject the exception. */ 1295 Event.au64[0] = 0; 1296 Event.n.u3Type = SVM_EVENT_EXCEPTION; /* trap or fault */ 1297 Event.n.u1Valid = 1; 1298 Event.n.u8Vector = X86_XCPT_DB; 1299 1300 SVMR0InjectEvent(pVM, pVMCB, pCtx, &Event); 1301 1302 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1303 goto ResumeExecution; 1304 } 1305 /* Return to ring 3 to deal with the debug exit code. */ 1319 1306 break; 1320 #endif 1321 /* @todo we don't really need to intercept this here. It's easy to sync back dr7 & dr6 after each world switch. */ 1322 /* Sync back DR6 and DR7 here. */ 1323 pCtx->dr6 = pVMCB->guest.u64DR6; 1324 pCtx->dr7 = pVMCB->guest.u64DR7; 1325 1326 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitGuestDB); 1327 Log(("Trap %x (debug) at %VGv\n", vector, pCtx->rip)); 1328 1329 /* Reinject the exception. */ 1330 Event.au64[0] = 0; 1331 Event.n.u3Type = SVM_EVENT_EXCEPTION; /* trap or fault */ 1332 Event.n.u1Valid = 1; 1333 Event.n.u8Vector = X86_XCPT_DB; 1334 1335 SVMR0InjectEvent(pVM, pVMCB, pCtx, &Event); 1336 1337 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1338 goto ResumeExecution; 1339 } 1340 #endif 1307 } 1341 1308 1342 1309 case X86_XCPT_NM: … … 1730 1697 Log2(("SVM: %VGv mov dr%d, x\n", pCtx->rip, exitCode - SVM_EXIT_WRITE_DR0)); 1731 1698 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitDRxRead); 1699 1700 if (!DBGFIsStepping(pVM)) 1701 { 1702 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxContextSwitch); 1703 1704 /* Disable drx move intercepts. */ 1705 pVMCB->ctrl.u16InterceptRdDRx = 0; 1706 pVMCB->ctrl.u16InterceptWrDRx = 0; 1707 1708 /* Save the host and load the guest debug state. */ 1709 rc = CPUMR0LoadGuestDebugState(pVM, pCtx, false /* exclude DR6 */); 1710 AssertRC(rc); 1711 1712 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1713 goto ResumeExecution; 1714 } 1715 1732 1716 rc = EMInterpretInstruction(pVM, CPUMCTX2CORE(pCtx), 0, &cbSize); 1733 1717 if (rc == VINF_SUCCESS) … … 1753 1737 Log2(("SVM: %VGv mov dr%d, x\n", pCtx->rip, exitCode - SVM_EXIT_READ_DR0)); 1754 1738 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitDRxRead); 1739 1740 if (!DBGFIsStepping(pVM)) 1741 { 1742 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxContextSwitch); 1743 1744 /* Disable drx move intercepts. */ 1745 pVMCB->ctrl.u16InterceptRdDRx = 0; 1746 pVMCB->ctrl.u16InterceptWrDRx = 0; 1747 1748 /* Save the host and load the guest debug state. */ 1749 rc = CPUMR0LoadGuestDebugState(pVM, pCtx, false /* exclude DR6 */); 1750 AssertRC(rc); 1751 1752 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1753 goto ResumeExecution; 1754 } 1755 1755 1756 rc = EMInterpretInstruction(pVM, CPUMCTX2CORE(pCtx), 0, &cbSize); 1756 1757 if (rc == VINF_SUCCESS) … … 2011 2012 * @returns VBox status code. 2012 2013 * @param pVM The VM to operate on. 2014 * @param pCtx CPU context 2013 2015 */ 2014 HWACCMR0DECL(int) SVMR0Leave(PVM pVM )2016 HWACCMR0DECL(int) SVMR0Leave(PVM pVM, PCPUMCTX pCtx) 2015 2017 { 2018 SVM_VMCB *pVMCB = (SVM_VMCB *)pVM->hwaccm.s.svm.pVMCB; 2019 2016 2020 Assert(pVM->hwaccm.s.svm.fSupported); 2021 2022 /* Save the guest debug state if necessary. */ 2023 if (CPUMIsGuestDebugStateActive(pVM)) 2024 { 2025 CPUMR0SaveGuestDebugState(pVM, pCtx, false /* skip DR6 */); 2026 2027 /* Intercept all DRx reads and writes again. Changed later on. */ 2028 pVMCB->ctrl.u16InterceptRdDRx = 0xFFFF; 2029 pVMCB->ctrl.u16InterceptWrDRx = 0xFFFF; 2030 2031 /* Resync the debug registers the next time. */ 2032 pVM->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_DEBUG; 2033 } 2034 else 2035 Assert(pVMCB->ctrl.u16InterceptRdDRx == 0xFFFF && pVMCB->ctrl.u16InterceptWrDRx == 0xFFFF); 2036 2017 2037 return VINF_SUCCESS; 2018 2038 } -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.h
r10502 r12578 56 56 * @returns VBox status code. 57 57 * @param pVM The VM to operate on. 58 * @param pCtx CPU context 58 59 */ 59 HWACCMR0DECL(int) SVMR0Leave(PVM pVM );60 HWACCMR0DECL(int) SVMR0Leave(PVM pVM, PCPUMCTX pCtx); 60 61 61 62 /** -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r12554 r12578 380 380 * @note only possible if the current state is actually ours (X86_CR0_TS flag) 381 381 */ 382 rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXCEPTION_BITMAP, HWACCM_VMX_TRAP_MASK); 382 pVM->hwaccm.s.vmx.u32TrapMask = HWACCM_VMX_TRAP_MASK; 383 rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXCEPTION_BITMAP, pVM->hwaccm.s.vmx.u32TrapMask); 383 384 AssertRC(rc); 384 385 … … 866 867 if (!pVM->hwaccm.s.fFPUOldStyleOverride) 867 868 { 868 rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXCEPTION_BITMAP, HWACCM_VMX_TRAP_MASK | RT_BIT(X86_XCPT_MF)); 869 pVM->hwaccm.s.vmx.u32TrapMask |= RT_BIT(X86_XCPT_MF); 870 rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXCEPTION_BITMAP, pVM->hwaccm.s.vmx.u32TrapMask); 869 871 AssertRC(rc); 870 872 pVM->hwaccm.s.fFPUOldStyleOverride = true; … … 966 968 if (pVM->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_DEBUG) 967 969 { 968 pCtx->dr7 &= 0xffffffff; /* upper 32 bits reserved */ 969 pCtx->dr7 &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */ 970 pCtx->dr7 |= 0x400; /* must be one */ 971 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 972 rc |= VMXWriteVMCS(VMX_VMCS_GUEST_DR7, pCtx->dr7); 973 #else 974 rc |= VMXWriteVMCS(VMX_VMCS_GUEST_DR7, 0x400); 975 #endif 976 AssertRC(rc); 977 978 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 979 /* Any guest breakpoints enabled? */ 980 if ( (pCtx->dr7 & (X86_DR7_ENABLED_MASK | X86_DR7_GD)) 981 && !pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved) 982 { 983 /* Save the host debug register; a bit paranoid if the host has no active breakpoints set in dr7, but we 984 * do not want anything from the guest to leak into the host! 985 */ 986 pVM->hwaccm.s.savedhoststate.dr0 = ASMGetDR0(); 987 pVM->hwaccm.s.savedhoststate.dr1 = ASMGetDR1(); 988 pVM->hwaccm.s.savedhoststate.dr2 = ASMGetDR2(); 989 pVM->hwaccm.s.savedhoststate.dr3 = ASMGetDR3(); 990 pVM->hwaccm.s.savedhoststate.dr6 = ASMGetDR6(); 991 pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved = true; 992 993 /* Make sure DR7 is harmless or else we could trigger breakpoints when restoring dr0-3 (!) */ 994 ASMSetDR7(0x400); 995 } 996 997 if (pCtx->dr7 & (X86_DR7_L0|X86_DR7_G0)) 998 { 999 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDR0Armed); 1000 ASMSetDR0(pCtx->dr0); 1001 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 1002 } 1003 if (pCtx->dr7 & (X86_DR7_L1|X86_DR7_G1)) 1004 { 1005 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDR1Armed); 1006 ASMSetDR1(pCtx->dr1); 1007 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 1008 } 1009 if (pCtx->dr7 & (X86_DR7_L2|X86_DR7_G2)) 1010 { 1011 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDR2Armed); 1012 ASMSetDR2(pCtx->dr2); 1013 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 1014 } 1015 if (pCtx->dr7 & (X86_DR7_L3|X86_DR7_G3)) 1016 { 1017 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDR3Armed); 1018 ASMSetDR3(pCtx->dr3); 1019 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 1020 } 1021 1022 /* No need to sync DR6; all DR6 reads are intercepted. */ 1023 #endif /* VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT */ 970 pCtx->dr6 |= X86_DR6_INIT_VAL; /* set all reserved bits to 1. */ 971 pCtx->dr6 &= ~RT_BIT(12); /* must be zero. */ 972 973 pCtx->dr7 &= 0xffffffff; /* upper 32 bits reserved */ 974 pCtx->dr7 &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */ 975 pCtx->dr7 |= 0x400; /* must be one */ 976 977 /* Resync DR7 */ 978 rc = VMXWriteVMCS(VMX_VMCS_GUEST_DR7, pCtx->dr7); 979 AssertRC(rc); 980 981 /* Sync the debug state now if any breakpoint is armed. */ 982 if ( (pCtx->dr7 & (X86_DR7_ENABLED_MASK|X86_DR7_GD)) 983 && !CPUMIsGuestDebugStateActive(pVM) 984 && !DBGFIsStepping(pVM)) 985 { 986 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxArmed); 987 988 /* Disable drx move intercepts. */ 989 pVM->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT; 990 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVM->hwaccm.s.vmx.proc_ctls); 991 AssertRC(rc); 992 993 /* Save the host and load the guest debug state. */ 994 rc = CPUMR0LoadGuestDebugState(pVM, pCtx, true /* include DR6 */); 995 AssertRC(rc); 996 } 1024 997 1025 998 /* IA32_DEBUGCTL MSR. */ … … 1113 1086 pVM->hwaccm.s.vmx.pfnStartVM = VMXR0StartVM32; 1114 1087 } 1088 1089 #ifdef DEBUG 1090 /* Intercept X86_XCPT_DB if stepping is enabled */ 1091 if (DBGFIsStepping(pVM)) 1092 pVM->hwaccm.s.vmx.u32TrapMask |= RT_BIT(X86_XCPT_DB); 1093 else 1094 pVM->hwaccm.s.vmx.u32TrapMask &= ~RT_BIT(X86_XCPT_DB); 1095 1096 rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXCEPTION_BITMAP, pVM->hwaccm.s.vmx.u32TrapMask); 1097 #endif 1115 1098 1116 1099 /* Done. */ … … 1564 1547 CPUMSetGuestCR2(pVM, ASMGetCR2()); 1565 1548 1566 /* No need to sync back DR7 here; it can only be changed by DR7 writes and debug exceptions. Both are intercepted. */ 1549 /* Sync back DR7 here. */ 1550 VMXReadVMCS(VMX_VMCS_GUEST_DR7, &val); 1551 pCtx->dr7 = val; 1567 1552 1568 1553 /* Guest CPU context: ES, CS, SS, DS, FS, GS. */ … … 1773 1758 case X86_XCPT_DB: /* Debug exception. */ 1774 1759 { 1760 uint64_t uDR6; 1761 1775 1762 /* DR6, DR7.GD and IA32_DEBUGCTL.LBR are not updated yet. 1776 1763 * … … 1782 1769 * 63:15 Reserved (0) 1783 1770 */ 1784 1785 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT1786 /* Update DR6 here. */1787 pCtx->dr6 = X86_DR6_INIT_VAL;1788 pCtx->dr6 |= (exitQualification & (X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3|X86_DR6_BD|X86_DR6_BS));1789 1790 /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */1791 pCtx->dr7 &= ~X86_DR7_GD;1792 1793 /* Paranoia. */1794 pCtx->dr7 &= 0xffffffff; /* upper 32 bits reserved */1795 pCtx->dr7 &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */1796 pCtx->dr7 |= 0x400; /* must be one */1797 1798 /* Resync DR7 */1799 rc = VMXWriteVMCS(VMX_VMCS_GUEST_DR7, pCtx->dr7);1800 AssertRC(rc);1801 #endif /* VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT */1802 1803 1771 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitGuestDB); 1804 Log(("Trap %x (debug) at %VGv exit qualification %VX64\n", vector, pCtx->rip, exitQualification)); 1805 rc = VMXR0InjectEvent(pVM, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode); 1806 AssertRC(rc); 1807 1808 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1809 goto ResumeExecution; 1772 1773 /* Note that we don't support guest and host-initiated debugging at the same time. */ 1774 Assert(DBGFIsStepping(pVM)); 1775 1776 uDR6 = X86_DR6_INIT_VAL; 1777 uDR6 |= (exitQualification & (X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3|X86_DR6_BD|X86_DR6_BS)); 1778 rc = DBGFR0Trap01Handler(pVM, CPUMCTX2CORE(pCtx), uDR6); 1779 if (rc == VINF_EM_RAW_GUEST_TRAP) 1780 { 1781 /* Update DR6 here. */ 1782 pCtx->dr6 = uDR6; 1783 1784 /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */ 1785 pCtx->dr7 &= ~X86_DR7_GD; 1786 1787 /* Paranoia. */ 1788 pCtx->dr7 &= 0xffffffff; /* upper 32 bits reserved */ 1789 pCtx->dr7 &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */ 1790 pCtx->dr7 |= 0x400; /* must be one */ 1791 1792 /* Resync DR7 */ 1793 rc = VMXWriteVMCS(VMX_VMCS_GUEST_DR7, pCtx->dr7); 1794 AssertRC(rc); 1795 1796 Log(("Trap %x (debug) at %VGv exit qualification %VX64\n", vector, pCtx->rip, exitQualification)); 1797 rc = VMXR0InjectEvent(pVM, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode); 1798 AssertRC(rc); 1799 1800 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1801 goto ResumeExecution; 1802 } 1803 /* Return to ring 3 to deal with the debug exit code. */ 1804 break; 1810 1805 } 1811 1806 … … 2036 2031 case VMX_EXIT_DRX_MOVE: /* 29 Debug-register accesses. */ 2037 2032 { 2033 if (!DBGFIsStepping(pVM)) 2034 { 2035 /* Disable drx move intercepts. */ 2036 pVM->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT; 2037 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVM->hwaccm.s.vmx.proc_ctls); 2038 AssertRC(rc); 2039 2040 /* Save the host and load the guest debug state. */ 2041 rc = CPUMR0LoadGuestDebugState(pVM, pCtx, true /* include DR6 */); 2042 AssertRC(rc); 2043 2044 #ifdef VBOX_WITH_STATISTICS 2045 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxContextSwitch); 2046 if (VMX_EXIT_QUALIFICATION_DRX_DIRECTION(exitQualification) == VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE) 2047 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitDRxWrite); 2048 else 2049 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitDRxRead); 2050 #endif 2051 2052 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 2053 goto ResumeExecution; 2054 } 2055 2038 2056 /** @todo clear VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT after the first time and restore drx registers afterwards */ 2039 2057 if (VMX_EXIT_QUALIFICATION_DRX_DIRECTION(exitQualification) == VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE) … … 2386 2404 * @returns VBox status code. 2387 2405 * @param pVM The VM to operate on. 2406 * @param pCtx CPU context 2388 2407 */ 2389 HWACCMR0DECL(int) VMXR0Leave(PVM pVM )2408 HWACCMR0DECL(int) VMXR0Leave(PVM pVM, PCPUMCTX pCtx) 2390 2409 { 2391 2410 Assert(pVM->hwaccm.s.vmx.fSupported); 2392 2411 2412 /* Save the guest debug state if necessary. */ 2413 if (CPUMIsGuestDebugStateActive(pVM)) 2414 { 2415 CPUMR0SaveGuestDebugState(pVM, pCtx, true /* save DR6 */); 2416 2417 /* Enable drx move intercepts again. */ 2418 pVM->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT; 2419 int rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVM->hwaccm.s.vmx.proc_ctls); 2420 AssertRC(rc); 2421 2422 /* Resync the debug registers the next time. */ 2423 pVM->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_DEBUG; 2424 } 2425 else 2426 Assert(pVM->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT); 2427 2393 2428 /* Clear VM Control Structure. Marking it inactive, clearing implementation specific data and writing back VMCS data to memory. */ 2394 2429 int rc = VMXClearVMCS(pVM->hwaccm.s.vmx.pVMCSPhys); -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.h
r10502 r12578 56 56 * @returns VBox status code. 57 57 * @param pVM The VM to operate on. 58 */ 59 HWACCMR0DECL(int) VMXR0Leave(PVM pVM); 58 * @param pCtx CPU context 59 */ 60 HWACCMR0DECL(int) VMXR0Leave(PVM pVM, PCPUMCTX pCtx); 60 61 61 62
Note:
See TracChangeset
for help on using the changeset viewer.