Changeset 47619 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Aug 8, 2013 7:06:45 PM (11 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/HMAll.cpp
r46420 r47619 33 33 #include <iprt/asm.h> 34 34 #include <iprt/string.h> 35 #include <iprt/thread.h> 35 36 #include <iprt/x86.h> 36 37 #include <iprt/asm-amd64-x86.h> … … 426 427 } 427 428 429 430 /** 431 * Sets or clears the single instruction flag. 432 * 433 * When set, HM will try its best to return to ring-3 after executing a single 434 * instruction. This can be used for debugging. See also 435 * EMR3HmSingleInstruction. 436 * 437 * @returns The old flag state. 438 * @param pVCpu Pointer to the cross context CPU structure of 439 * the calling EMT. 440 * @param fEnable The new flag state. 441 */ 442 VMM_INT_DECL(bool) HMSetSingleInstruction(PVMCPU pVCpu, bool fEnable) 443 { 444 VMCPU_ASSERT_EMT(pVCpu); 445 bool fOld = pVCpu->hm.s.fSingleInstruction; 446 pVCpu->hm.s.fSingleInstruction = fEnable; 447 return fOld; 448 } 449 -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r47586 r47619 3317 3317 bool fInterceptDB = false; 3318 3318 bool fInterceptMovDRx = false; 3319 if (DBGFIsStepping(pVCpu) )3319 if (DBGFIsStepping(pVCpu) || pVCpu->hm.s.fSingleInstruction) 3320 3320 { 3321 3321 /* If the CPU supports the monitor trap flag, use it for single stepping in DBGF and avoid intercepting #DB. */ … … 6282 6282 { 6283 6283 /* 6284 * The pending-debug exceptions field is cleared on all VM-exits except VMX_EXIT_TPR_BELOW_THRESHOLD, VMX_EXIT_MTF6285 * VMX_EXIT_ APIC_WRITE, VMX_EXIT_VIRTUALIZED_EOI. See Intel spec. 27.3.4 "Saving Non-Register State".6284 * The pending-debug exceptions field is cleared on all VM-exits except VMX_EXIT_TPR_BELOW_THRESHOLD, 6285 * VMX_EXIT_MTF VMX_EXIT_APIC_WRITE, VMX_EXIT_VIRTUALIZED_EOI. See Intel spec. 27.3.4 "Saving Non-Register State". 6286 6286 */ 6287 6287 rc2 = VMXWriteVmcs32(VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS); … … 8665 8665 AssertRCReturn(rc, rc); 8666 8666 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitMtf); 8667 return VINF_EM_DBG_ST OP;8667 return VINF_EM_DBG_STEPPED; 8668 8668 } 8669 8669 … … 8760 8760 int rc = VERR_INTERNAL_ERROR_5; 8761 8761 if ( !DBGFIsStepping(pVCpu) 8762 && !pVCpu->hm.s.fSingleInstruction 8762 8763 && !CPUMIsHyperDebugStateActive(pVCpu)) 8763 8764 { -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r47444 r47619 91 91 static const char *emR3GetStateName(EMSTATE enmState); 92 92 #endif 93 static int emR3Debug(PVM pVM, PVMCPU pVCpu, intrc);93 static VBOXSTRICTRC emR3Debug(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc); 94 94 static int emR3RemStep(PVM pVM, PVMCPU pVCpu); 95 95 static int emR3RemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone); … … 775 775 case EMSTATE_TERMINATING: return "EMSTATE_TERMINATING"; 776 776 case EMSTATE_DEBUG_GUEST_RAW: return "EMSTATE_DEBUG_GUEST_RAW"; 777 case EMSTATE_DEBUG_GUEST_HM: return "EMSTATE_DEBUG_GUEST_HM"; 778 case EMSTATE_DEBUG_GUEST_IEM: return "EMSTATE_DEBUG_GUEST_IEM"; 777 779 case EMSTATE_DEBUG_GUEST_REM: return "EMSTATE_DEBUG_GUEST_REM"; 778 780 case EMSTATE_DEBUG_HYPER: return "EMSTATE_DEBUG_HYPER"; … … 792 794 * @param rc Current EM VBox status code. 793 795 */ 794 static int emR3Debug(PVM pVM, PVMCPU pVCpu, intrc)796 static VBOXSTRICTRC emR3Debug(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc) 795 797 { 796 798 for (;;) 797 799 { 798 Log(("emR3Debug: rc=%Rrc\n", rc));799 const intrcLast = rc;800 Log(("emR3Debug: rc=%Rrc\n", VBOXSTRICTRC_VAL(rc))); 801 const VBOXSTRICTRC rcLast = rc; 800 802 801 803 /* 802 804 * Debug related RC. 803 805 */ 804 switch ( rc)806 switch (VBOXSTRICTRC_VAL(rc)) 805 807 { 806 808 /* … … 808 810 */ 809 811 case VINF_EM_DBG_STEP: 812 if ( pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_RAW 813 || pVCpu->em.s.enmState == EMSTATE_DEBUG_HYPER 814 || pVCpu->em.s.fForceRAW /* paranoia */) 810 815 #ifdef VBOX_WITH_RAW_MODE 811 if ( pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_RAW812 || pVCpu->em.s.enmState == EMSTATE_DEBUG_HYPER813 || pVCpu->em.s.fForceRAW /* paranoia */)814 816 rc = emR3RawStep(pVM, pVCpu); 817 #else 818 AssertLogRelMsgFailedStmt(("Bad EM state."), VERR_EM_INTERNAL_ERROR); 819 #endif 820 else if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HM) 821 rc = EMR3HmSingleInstruction(pVM, pVCpu); 822 #ifdef VBOX_WITH_REM 823 else if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_REM) 824 rc = emR3RemStep(pVM, pVCpu); 825 #endif 815 826 else 816 827 { 817 Assert(pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_REM); 818 rc = emR3RemStep(pVM, pVCpu); 828 rc = IEMExecOne(pVCpu); /** @todo add dedicated interface... */ 829 if (rc == VINF_SUCCESS || rc == VINF_EM_RESCHEDULE) 830 rc = VINF_EM_DBG_STEPPED; 819 831 } 820 #else821 AssertLogRelMsgFailed(("%Rrc\n", rc));822 rc = VERR_EM_INTERNAL_ERROR;823 #endif824 832 break; 825 833 … … 873 881 do 874 882 { 875 switch ( rc)883 switch (VBOXSTRICTRC_VAL(rc)) 876 884 { 877 885 /* … … 905 913 continue; 906 914 #else 907 AssertLogRelMsgFailedReturn(("Not implemented\n" , rc), VERR_EM_INTERNAL_ERROR);915 AssertLogRelMsgFailedReturn(("Not implemented\n"), VERR_EM_INTERNAL_ERROR); 908 916 #endif 909 917 } … … 917 925 */ 918 926 case VERR_DBGF_NOT_ATTACHED: 919 switch ( rcLast)927 switch (VBOXSTRICTRC_VAL(rcLast)) 920 928 { 921 929 case VINF_EM_DBG_HYPER_STEPPED: … … 961 969 */ 962 970 default: 963 AssertMsgFailed(("Unexpected rc %Rrc!\n", rc));971 AssertMsgFailed(("Unexpected rc %Rrc!\n", VBOXSTRICTRC_VAL(rc))); 964 972 break; 965 973 } … … 1840 1848 /** @todo this really isn't nice, should properly handle this */ 1841 1849 rc2 = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT); 1842 if (pVM->em.s.fIemExecutesAll && rc2 == VINF_EM_RESCHEDULE_REM)1850 if (pVM->em.s.fIemExecutesAll && (rc2 == VINF_EM_RESCHEDULE_REM || rc2 == VINF_EM_RESCHEDULE_HM || rc2 == VINF_EM_RESCHEDULE_RAW)) 1843 1851 rc2 = VINF_EM_RESCHEDULE; 1844 1852 #ifdef VBOX_STRICT … … 2249 2257 */ 2250 2258 case VINF_EM_DBG_STEPPED: 2251 /* Commenting this assertion for now as it hinders with single-stepping in new AMD-V code2252 * (using guest EFLAGS.TF) and returning VINF_EM_DBG_STEPPED in the #DB handler. */2253 #if 02254 AssertMsgFailed(("VINF_EM_DBG_STEPPED cannot be here!"));2255 #endif2256 2259 case VINF_EM_DBG_STOP: 2257 2260 case VINF_EM_DBG_BREAKPOINT: … … 2262 2265 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_RAW; 2263 2266 } 2264 else 2267 else if (enmOldState == EMSTATE_HM) 2268 { 2269 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, enmOldState, EMSTATE_DEBUG_GUEST_HM)); 2270 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_HM; 2271 } 2272 else if (enmOldState == EMSTATE_REM) 2265 2273 { 2266 2274 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, enmOldState, EMSTATE_DEBUG_GUEST_REM)); 2267 2275 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_REM; 2276 } 2277 else 2278 { 2279 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, enmOldState, EMSTATE_DEBUG_GUEST_IEM)); 2280 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_IEM; 2268 2281 } 2269 2282 break; … … 2322 2335 || enmNewState == EMSTATE_DEBUG_GUEST_RAW 2323 2336 || enmNewState == EMSTATE_DEBUG_GUEST_HM 2337 || enmNewState == EMSTATE_DEBUG_GUEST_IEM 2324 2338 || enmNewState == EMSTATE_DEBUG_GUEST_REM) ) 2325 2339 { … … 2384 2398 */ 2385 2399 case EMSTATE_IEM: 2386 rc = VBOXSTRICTRC_TODO(IEMExecLots(pVCpu)); 2400 #if 0 /* For testing purposes. */ 2401 rc = VBOXSTRICTRC_TODO(EMR3HmSingleInstruction(pVM, pVCpu)); 2402 if (rc == VINF_EM_DBG_STEPPED || rc == VINF_EM_RESCHEDULE_HM || rc == VINF_EM_RESCHEDULE_REM || rc == VINF_EM_RESCHEDULE_RAW) 2403 rc = VINF_SUCCESS; 2404 else if (rc == VERR_EM_CANNOT_EXEC_GUEST) 2405 #endif 2406 rc = VBOXSTRICTRC_TODO(IEMExecLots(pVCpu)); 2387 2407 if (pVM->em.s.fIemExecutesAll) 2388 2408 { … … 2437 2457 * Debugging in the guest. 2438 2458 */ 2459 case EMSTATE_DEBUG_GUEST_RAW: 2460 case EMSTATE_DEBUG_GUEST_HM: 2461 case EMSTATE_DEBUG_GUEST_IEM: 2439 2462 case EMSTATE_DEBUG_GUEST_REM: 2440 case EMSTATE_DEBUG_GUEST_RAW:2441 2463 TMR3NotifySuspend(pVM, pVCpu); 2442 rc = emR3Debug(pVM, pVCpu, rc);2464 rc = VBOXSTRICTRC_TODO(emR3Debug(pVM, pVCpu, rc)); 2443 2465 TMR3NotifyResume(pVM, pVCpu); 2444 2466 Log2(("EMR3ExecuteVM: enmr3Debug -> %Rrc (state %d)\n", rc, pVCpu->em.s.enmState)); … … 2453 2475 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x); 2454 2476 2455 rc = emR3Debug(pVM, pVCpu, rc);2477 rc = VBOXSTRICTRC_TODO(emR3Debug(pVM, pVCpu, rc)); 2456 2478 Log2(("EMR3ExecuteVM: enmr3Debug -> %Rrc (state %d)\n", rc, pVCpu->em.s.enmState)); 2457 2479 if (rc != VINF_SUCCESS) -
trunk/src/VBox/VMM/VMMR3/EMHM.cpp
r47548 r47619 152 152 153 153 #endif /* DEBUG */ 154 155 156 /** 157 * Executes instruction in HM mode if we can. 158 * 159 * This is somewhat comparable to REMR3EmulateInstruction. 160 * 161 * @returns VBox strict status code. 162 * @retval VINF_EM_DBG_STEPPED on success. 163 * @retval VERR_EM_CANNOT_EXEC_GUEST if we cannot execute guest instructions in 164 * HM right now. 165 * 166 * @param pVM Pointer to the cross context VM structure. 167 * @param pVCpu Pointer to the cross context CPU structure for 168 * the calling EMT. 169 * @thread EMT. 170 */ 171 VMMR3_INT_DECL(VBOXSTRICTRC) EMR3HmSingleInstruction(PVM pVM, PVMCPU pVCpu) 172 { 173 if (!HMR3CanExecuteGuest(pVM, pVCpu->em.s.pCtx)) 174 return VINF_EM_RESCHEDULE; 175 176 /* 177 * Service necessary FFs before going into HM. 178 */ 179 PCPUMCTX pCtx = pVCpu->em.s.pCtx; 180 if ( VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK) 181 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK)) 182 { 183 VBOXSTRICTRC rcStrict = emR3HmForcedActions(pVM, pVCpu, pCtx); 184 if (rcStrict != VINF_SUCCESS) 185 { 186 Log(("EMR3HmSingleInstruction: FFs before -> %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 187 return rcStrict; 188 } 189 } 190 191 /* 192 * Go execute it. 193 */ 194 bool fOld = HMSetSingleInstruction(pVCpu, true); 195 VBOXSTRICTRC rcStrict = VMMR3HmRunGC(pVM, pVCpu); 196 HMSetSingleInstruction(pVCpu, fOld); 197 LogFlow(("EMR3HmSingleInstruction: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 198 199 /* 200 * Handle high priority FFs and informational status codes. We don't do 201 * normal FF processing the caller or the next call can deal with them. 202 */ 203 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK); 204 if ( VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK) 205 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK)) 206 { 207 rcStrict = emR3HighPriorityPostForcedActions(pVM, pVCpu, VBOXSTRICTRC_TODO(rcStrict)); 208 LogFlow(("EMR3HmSingleInstruction: FFs after -> %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 209 } 210 211 if (rcStrict != VINF_SUCCESS && (rcStrict < VINF_EM_FIRST || rcStrict > VINF_EM_LAST)) 212 { 213 rcStrict = emR3HmHandleRC(pVM, pVCpu, pCtx, VBOXSTRICTRC_TODO(rcStrict)); 214 Log(("EMR3HmSingleInstruction: emR3HmHandleRC -> %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 215 } 216 217 return rcStrict; 218 } 154 219 155 220 -
trunk/src/VBox/VMM/include/HMInternal.h
r47123 r47619 538 538 /** Set when the TLB has been checked until we return from the world switch. */ 539 539 volatile bool fCheckedTLBFlush; 540 uint8_t u8Alignment[4]; 540 /** Whether we're executing a single instruction. */ 541 bool fSingleInstruction; 542 uint8_t abAlignment[3]; 541 543 542 544 /** World switch exit counter. */
Note:
See TracChangeset
for help on using the changeset viewer.