Changeset 12121 in vbox
- Timestamp:
- Sep 5, 2008 9:41:05 AM (16 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/CPUM.cpp
r12016 r12121 707 707 pCtx->trHid.Attr.n.u4Type = X86_SEL_TYPE_SYS_386_TSS_BUSY; 708 708 709 pCtx->dr6 = UINT32_C(0xFFFF0FF0);709 pCtx->dr6 = X86_DR6_INIT_VAL; 710 710 pCtx->dr7 = 0x400; 711 711 -
trunk/src/VBox/VMM/HWACCM.cpp
r12078 r12121 126 126 STAM_REG(pVM, &pVM->hwaccm.s.StatExitGuestMF, STAMTYPE_COUNTER, "/HWACCM/Exit/Trap/Guest/#MF", STAMUNIT_OCCURENCES, "Nr of occurances"); 127 127 STAM_REG(pVM, &pVM->hwaccm.s.StatExitGuestDE, STAMTYPE_COUNTER, "/HWACCM/Exit/Trap/Guest/#DE", STAMUNIT_OCCURENCES, "Nr of occurances"); 128 STAM_REG(pVM, &pVM->hwaccm.s.StatExitGuestDB, STAMTYPE_COUNTER, "/HWACCM/Exit/Trap/Guest/#DB", STAMUNIT_OCCURENCES, "Nr of occurances"); 128 129 STAM_REG(pVM, &pVM->hwaccm.s.StatExitInvpg, STAMTYPE_COUNTER, "/HWACCM/Exit/Instr/Invlpg", STAMUNIT_OCCURENCES, "Nr of occurances"); 129 130 STAM_REG(pVM, &pVM->hwaccm.s.StatExitInvd, STAMTYPE_COUNTER, "/HWACCM/Exit/Instr/Invd", STAMUNIT_OCCURENCES, "Nr of occurances"); -
trunk/src/VBox/VMM/HWACCMInternal.h
r12090 r12121 34 34 #include <iprt/mp.h> 35 35 36 ////#define VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 37 36 38 #if HC_ARCH_BITS == 64 37 39 /* Enable 64 bits guest support. */ … … 110 112 */ 111 113 #ifdef VBOX_STRICT 112 #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)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) 113 115 #define HWACCM_SVM_TRAP_MASK HWACCM_VMX_TRAP_MASK 114 116 #else 115 #define HWACCM_VMX_TRAP_MASK RT_BIT(X86_XCPT_ NM) | RT_BIT(X86_XCPT_PF)116 #define HWACCM_SVM_TRAP_MASK HWACCM_VMX_TRAP_MASK117 #define HWACCM_VMX_TRAP_MASK RT_BIT(X86_XCPT_DB) | RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF) 118 #define HWACCM_SVM_TRAP_MASK RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF) 117 119 #endif 118 120 /** @} */ … … 377 379 378 380 379 #ifdef VBOX_ SAVE_HOST_DEBUG_REGISTERS381 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 380 382 struct 381 383 { … … 383 385 uint64_t dr0, dr1, dr2, dr3, dr6, dr7; 384 386 bool fHostDR7Saved; 387 bool fHostDebugRegsSaved; 385 388 } savedhoststate; 386 389 #endif … … 401 404 STAMCOUNTER StatExitGuestGP; 402 405 STAMCOUNTER StatExitGuestDE; 406 STAMCOUNTER StatExitGuestDB; 403 407 STAMCOUNTER StatExitGuestMF; 404 408 STAMCOUNTER StatExitInvpg; -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r11764 r12121 2199 2199 if (VBOX_SUCCESS(rc)) 2200 2200 { 2201 /* @todo: we don't fail if illegal bits are set/cleared for e.g. dr7 */ 2201 2202 rc = CPUMSetGuestDRx(pVM, DestRegDrx, val); 2202 2203 if (VBOX_SUCCESS(rc)) -
trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
r12090 r12121 744 744 CPUMDeactivateGuestFPUState(pVM); 745 745 746 #ifdef VBOX_WITH_ DEBUG_REGISTER_SUPPORT746 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 747 747 /* 748 748 * Check if host debug registers are armed. All context switches set DR7 back to 0x400. 749 749 */ 750 750 uint64_t u64DR7 = ASMGetDR7(); 751 if (u 32DR7 & X86_DR7_ENABLED_MASK)751 if (u64DR7 & X86_DR7_ENABLED_MASK) 752 752 { 753 753 pVM->hwaccm.s.savedhoststate.dr7 = u64DR7; … … 806 806 } 807 807 808 #ifdef VBOX_WITH_DEBUG_REGISTER_SUPPORT 808 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 809 /* Restore the host debug registers. First dr0-3, then dr6 and only then dr7! */ 810 if (pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved) 811 { 812 ASMSetDR0(pVM->hwaccm.s.savedhoststate.dr0); 813 ASMSetDR1(pVM->hwaccm.s.savedhoststate.dr1); 814 ASMSetDR2(pVM->hwaccm.s.savedhoststate.dr2); 815 ASMSetDR3(pVM->hwaccm.s.savedhoststate.dr3); 816 ASMSetDR6(pVM->hwaccm.s.savedhoststate.dr6); 817 pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved = false; 818 } 809 819 if (pVM->hwaccm.s.savedhoststate.fHostDR7Saved) 810 820 { … … 814 824 #endif 815 825 826 /* Resync the debug register on the next entry. */ 827 pVM->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_DEBUG; 816 828 return HWACCMR0Globals.pfnLeaveSession(pVM); 817 829 } -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r12091 r12121 276 276 pVMCB->ctrl.u16InterceptWrCRx = RT_BIT(0) | RT_BIT(4) | RT_BIT(8); 277 277 278 /* Intercept all DRx reads and writes. */279 pVMCB->ctrl.u16InterceptRdDRx = RT_BIT(0) | RT_BIT(1) | RT_BIT(2) | RT_BIT(3) | RT_BIT(4) | RT_BIT(5) | RT_BIT(6) | RT_BIT(7);280 pVMCB->ctrl.u16InterceptWrDRx = RT_BIT(0) | RT_BIT(1) | RT_BIT(2) | RT_BIT(3) | RT_BIT(4) | RT_BIT(5) | RT_BIT(6) | RT_BIT(7);278 /* Intercept all DRx reads and writes. (@todo not necessary to intercept all) */ 279 pVMCB->ctrl.u16InterceptRdDRx = 0xFFFF; 280 pVMCB->ctrl.u16InterceptWrDRx = 0xFFFF; 281 281 282 282 /* Currently we don't care about DRx reads or writes. DRx registers are trashed. … … 686 686 if (pVM->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_DEBUG) 687 687 { 688 val = pCtx->dr7;689 val&= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */690 val |= 0x400;/* must be one */691 #if ndef VBOX_WITH_DEBUG_REGISTER_SUPPORT692 val = 0x400;693 #e ndif694 pVMCB->guest.u64DR7 = val;695 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 692 pVMCB->guest.u64DR7 = pCtx->dr7; 693 #else 694 pVMCB->guest.u64DR7 = 0x400; 695 #endif 696 696 pVMCB->guest.u64DR6 = pCtx->dr6; 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 ASMSetDR0(pCtx->dr0); 720 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 721 } 722 if (pCtx->dr7 & (X86_DR7_L1|X86_DR7_G1)) 723 { 724 ASMSetDR1(pCtx->dr1); 725 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 726 } 727 if (pCtx->dr7 & (X86_DR7_L2|X86_DR7_G2)) 728 { 729 ASMSetDR2(pCtx->dr2); 730 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 731 } 732 if (pCtx->dr7 & (X86_DR7_L3|X86_DR7_G3)) 733 { 734 ASMSetDR3(pCtx->dr3); 735 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 736 } 737 738 /* No need to sync DR6; all DR6 reads are intercepted. */ 739 #endif /* VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT */ 697 740 } 698 741 … … 1200 1243 Log2(("exitCode = %x\n", exitCode)); 1201 1244 1202 /* Sync back the debug registers. */1245 /* Sync back DR6 as it could have been changed by hitting breakpoints. */ 1203 1246 pCtx->dr6 = pVMCB->guest.u64DR6; 1247 /* DR7.GD can be cleared by debug exceptions, so sync it back as well. */ 1204 1248 pCtx->dr7 = pVMCB->guest.u64DR7; 1205 1249 … … 1265 1309 #ifdef DEBUG 1266 1310 case X86_XCPT_DB: 1311 { 1312 #if 0 /* revisit */ 1267 1313 rc = DBGFR0Trap01Handler(pVM, CPUMCTX2CORE(pCtx), pVMCB->guest.u64DR6); 1268 1314 Assert(rc != VINF_EM_RAW_GUEST_TRAP); 1269 1315 break; 1316 #endif 1317 /* @todo we don't really need to intercept this here. It's easy to sync back dr7 & dr6 after each world switch. */ 1318 /* Sync back DR6 and DR7 here. */ 1319 pCtx->dr6 = pVMCB->guest.u64DR6; 1320 pCtx->dr7 = pVMCB->guest.u64DR7; 1321 1322 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitGuestDB); 1323 Log(("Trap %x (debug) at %VGv\n", vector, pCtx->rip)); 1324 1325 /* Reinject the exception. */ 1326 Event.au64[0] = 0; 1327 Event.n.u3Type = SVM_EVENT_EXCEPTION; /* trap or fault */ 1328 Event.n.u1Valid = 1; 1329 Event.n.u8Vector = X86_XCPT_DB; 1330 1331 SVMR0InjectEvent(pVM, pVMCB, pCtx, &Event); 1332 1333 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1334 goto ResumeExecution; 1335 } 1270 1336 #endif 1271 1337 … … 1414 1480 case X86_XCPT_GP: /* General protection failure exception.*/ 1415 1481 case X86_XCPT_UD: /* Unknown opcode exception. */ 1416 case X86_XCPT_DE: /* D ebug exception. */1482 case X86_XCPT_DE: /* Divide error. */ 1417 1483 case X86_XCPT_SS: /* Stack segment exception. */ 1418 1484 case X86_XCPT_NP: /* Segment not present exception. */ -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r12091 r12121 966 966 if (pVM->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_DEBUG) 967 967 { 968 val = pCtx->dr7 & 0xffffffff;/* upper 32 bits reserved */969 val&= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */970 val|= 0x400; /* must be one */971 #ifdef VBOX_WITH_ DEBUG_REGISTER_SUPPORT972 rc |= VMXWriteVMCS(VMX_VMCS_GUEST_DR7, val);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 973 #else 974 rc |= VMXWriteVMCS(VMX_VMCS_GUEST_DR7, 0x400); 975 #endif 976 AssertRC(rc); 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) 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 ASMSetDR0(pCtx->dr0); 1000 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 1001 } 1002 if (pCtx->dr7 & (X86_DR7_L1|X86_DR7_G1)) 1003 { 1004 ASMSetDR1(pCtx->dr1); 1005 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 1006 } 1007 if (pCtx->dr7 & (X86_DR7_L2|X86_DR7_G2)) 1008 { 1009 ASMSetDR2(pCtx->dr2); 1010 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 1011 } 1012 if (pCtx->dr7 & (X86_DR7_L3|X86_DR7_G3)) 1013 { 1014 ASMSetDR3(pCtx->dr3); 1015 Assert(pVM->hwaccm.s.savedhoststate.fHostDebugRegsSaved); 1016 } 1017 1018 /* No need to sync DR6; all DR6 reads are intercepted. */ 1019 #endif /* VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT */ 977 1020 978 1021 /* IA32_DEBUGCTL MSR. */ … … 1513 1556 CPUMSetGuestCR2(pVM, ASMGetCR2()); 1514 1557 1515 VMXReadVMCS(VMX_VMCS_GUEST_DR7, &val);1516 CPUMSetGuestDR7(pVM, val);1517 1518 1558 /* Guest CPU context: ES, CS, SS, DS, FS, GS. */ 1519 1559 VMX_READ_SELREG(ES, es); … … 1721 1761 } 1722 1762 1763 case X86_XCPT_DB: /* Debug exception. */ 1764 { 1765 /* DR6, DR7.GD and IA32_DEBUGCTL.LBR are not updated yet. 1766 * 1767 * Exit qualification bits: 1768 * 3:0 B0-B3 which breakpoint condition was met 1769 * 12:4 Reserved (0) 1770 * 13 BD - debug register access detected 1771 * 14 BS - single step execution or branch taken 1772 * 63:15 Reserved (0) 1773 */ 1774 1775 #ifdef VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT 1776 /* Update DR6 here. */ 1777 pCtx->dr6 = X86_DR6_INIT_VAL; 1778 pCtx->dr6 |= (exitQualification & (X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3|X86_DR6_BD|X86_DR6_BS)); 1779 1780 /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */ 1781 pCtx->dr7 &= ~X86_DR7_GD; 1782 1783 /* Paranoia. */ 1784 pCtx->dr7 &= 0xffffffff; /* upper 32 bits reserved */ 1785 pCtx->dr7 &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */ 1786 pCtx->dr7 |= 0x400; /* must be one */ 1787 1788 /* Resync DR7 */ 1789 rc = VMXWriteVMCS(VMX_VMCS_GUEST_DR7, pCtx->dr7); 1790 AssertRC(rc); 1791 #endif /* VBOX_WITH_HWACCM_DEBUG_REGISTER_SUPPORT */ 1792 1793 STAM_COUNTER_INC(&pVM->hwaccm.s.StatExitGuestDB); 1794 Log(("Trap %x (debug) at %VGv exit qualification %VX64\n", vector, pCtx->rip, exitQualification)); 1795 rc = VMXR0InjectEvent(pVM, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode); 1796 AssertRC(rc); 1797 1798 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1799 goto ResumeExecution; 1800 } 1801 1723 1802 #ifdef VBOX_STRICT 1803 case X86_XCPT_DE: /* Divide error. */ 1724 1804 case X86_XCPT_GP: /* General protection failure exception.*/ 1725 1805 case X86_XCPT_UD: /* Unknown opcode exception. */ 1726 case X86_XCPT_DE: /* Debug exception. */1727 1806 case X86_XCPT_SS: /* Stack segment exception. */ 1728 1807 case X86_XCPT_NP: /* Segment not present exception. */
Note:
See TracChangeset
for help on using the changeset viewer.