Changeset 40356 in vbox
- Timestamp:
- Mar 5, 2012 1:51:50 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/em.h
r39327 r40356 176 176 VMMDECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); 177 177 VMMDECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); 178 VMMDECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx); 178 VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx); 179 VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx); 180 VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx); 179 181 180 182 /** @name Assembly routines -
trunk/src/VBox/VMM/Makefile.kmk
r40274 r40356 32 32 ifdef VBOX_WITH_RAW_MODE 33 33 VMM_COMMON_DEFS += VBOX_WITH_RAW_MODE 34 endif 35 ifdef VBOX_WITH_IEM 36 VMM_COMMON_DEFS += VBOX_WITH_IEM 34 37 endif 35 38 ifdef VBOX_WITH_REM -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r40274 r40356 2578 2578 } 2579 2579 2580 2581 /** 2582 * Prepare an MWAIT - essentials of the MONITOR instruction. 2583 * 2584 * @returns VINF_SUCCESS 2585 * @param pVCpu The current CPU. 2586 * @param rax The content of RAX. 2587 * @param rcx The content of RCX. 2588 * @param rdx The content of RDX. 2589 */ 2590 VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx) 2591 { 2592 pVCpu->em.s.MWait.uMonitorRAX = rax; 2593 pVCpu->em.s.MWait.uMonitorRCX = rcx; 2594 pVCpu->em.s.MWait.uMonitorRDX = rdx; 2595 pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_MONITOR_ACTIVE; 2596 /** @todo Complete MONITOR implementation. */ 2597 return VINF_SUCCESS; 2598 } 2599 2600 2601 /** 2602 * Performs an MWAIT. 2603 * 2604 * @returns VINF_SUCCESS 2605 * @param pVCpu The current CPU. 2606 * @param rax The content of RAX. 2607 * @param rcx The content of RCX. 2608 */ 2609 VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx) 2610 { 2611 pVCpu->em.s.MWait.uMWaitRAX = rax; 2612 pVCpu->em.s.MWait.uMWaitRCX = rcx; 2613 pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_ACTIVE; 2614 if (rcx) 2615 pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_BREAKIRQIF0; 2616 else 2617 pVCpu->em.s.MWait.fWait &= ~EMMWAIT_FLAG_BREAKIRQIF0; 2618 /** @todo not completely correct?? */ 2619 return VINF_EM_HALT; 2620 } 2621 2622 2580 2623 /** 2581 2624 * MONITOR Emulation. … … 2601 2644 return VERR_EM_INTERPRETER; /* not supported */ 2602 2645 2603 pVCpu->em.s.mwait.uMonitorEAX = pRegFrame->rax; 2604 pVCpu->em.s.mwait.uMonitorECX = pRegFrame->rcx; 2605 pVCpu->em.s.mwait.uMonitorEDX = pRegFrame->rdx; 2606 pVCpu->em.s.mwait.fWait |= EMMWAIT_FLAG_MONITOR_ACTIVE; 2646 EMMonitorWaitPrepare(pVCpu, pRegFrame->rax, pRegFrame->rcx, pRegFrame->rdx); 2607 2647 return VINF_SUCCESS; 2608 2648 } … … 2643 2683 } 2644 2684 2645 if (pRegFrame->ecx) 2646 { 2647 if (!(u32MWaitFeatures & X86_CPUID_MWAIT_ECX_BREAKIRQIF0)) 2648 { 2649 Log(("EMInterpretMWait: unsupported X86_CPUID_MWAIT_ECX_BREAKIRQIF0 -> recompiler\n")); 2650 return VERR_EM_INTERPRETER; /* illegal value. */ 2651 } 2652 2653 pVCpu->em.s.mwait.fWait = EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0; 2654 } 2655 else 2656 pVCpu->em.s.mwait.fWait = EMMWAIT_FLAG_ACTIVE; 2657 2658 pVCpu->em.s.mwait.uMWaitEAX = pRegFrame->rax; 2659 pVCpu->em.s.mwait.uMWaitECX = pRegFrame->rcx; 2660 2661 /** @todo not completely correct */ 2662 return VINF_EM_HALT; 2685 if (pRegFrame->ecx && !(u32MWaitFeatures & X86_CPUID_MWAIT_ECX_BREAKIRQIF0)) 2686 { 2687 Log(("EMInterpretMWait: unsupported X86_CPUID_MWAIT_ECX_BREAKIRQIF0 -> recompiler\n")); 2688 return VERR_EM_INTERPRETER; /* illegal value. */ 2689 } 2690 2691 return EMMonitorWaitPerform(pVCpu, pRegFrame->rax, pRegFrame->rcx); 2663 2692 } 2664 2693 … … 3219 3248 3220 3249 /** 3221 * Determine if we should continue after encountering a hlt or mwait instruction 3250 * Determine if we should continue after encountering a hlt or mwait 3251 * instruction. 3252 * 3253 * Clears MWAIT flags if returning @c true. 3222 3254 * 3223 3255 * @returns boolean 3224 3256 * @param pVCpu The VMCPU to operate on. 3225 * @param pCtx Current CPU context 3226 */ 3227 VMMDECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx) 3228 { 3229 if ( pCtx->eflags.Bits.u1IF 3230 || ((pVCpu->em.s.mwait.fWait & (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0)) == (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))) 3231 { 3232 pVCpu->em.s.mwait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0); 3233 return !!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)); 3257 * @param pCtx Current CPU context. 3258 */ 3259 VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx) 3260 { 3261 if ( pCtx->eflags.Bits.u1IF 3262 || ( (pVCpu->em.s.MWait.fWait & (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0)) 3263 == (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0)) ) 3264 { 3265 pVCpu->em.s.MWait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0); 3266 return !!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)); 3234 3267 } 3235 3268 -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r40280 r40356 2355 2355 2356 2356 case SVM_EXIT_HLT: 2357 /* *Check if external interrupts are pending; if so, don't switch back. */2357 /* Check if external interrupts are pending; if so, don't switch back. */ 2358 2358 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitHlt); 2359 2359 pCtx->rip++; /* skip hlt */ … … 2374 2374 pCtx->rip += 3; /* Note: hardcoded opcode size assumption! */ 2375 2375 2376 /* *Check if external interrupts are pending; if so, don't switch back. */2376 /* Check if external interrupts are pending; if so, don't switch back. */ 2377 2377 if ( rc == VINF_SUCCESS 2378 2378 || ( rc == VINF_EM_HALT -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r40280 r40356 4111 4111 4112 4112 case VMX_EXIT_HLT: /* 12 Guest software attempted to execute HLT. */ 4113 /* *Check if external interrupts are pending; if so, don't switch back. */4113 /* Check if external interrupts are pending; if so, don't switch back. */ 4114 4114 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitHlt); 4115 4115 pCtx->rip++; /* skip hlt */ … … 4130 4130 pCtx->rip += cbInstr; 4131 4131 4132 /* *Check if external interrupts are pending; if so, don't switch back. */4132 /* Check if external interrupts are pending; if so, don't switch back. */ 4133 4133 if ( rc == VINF_SUCCESS 4134 4134 || ( rc == VINF_EM_HALT -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r40274 r40356 510 510 511 511 /* Save mwait state. */ 512 rc = SSMR3PutU32(pSSM, pVCpu->em.s. mwait.fWait);512 rc = SSMR3PutU32(pSSM, pVCpu->em.s.MWait.fWait); 513 513 AssertRCReturn(rc, rc); 514 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s. mwait.uMWaitEAX);514 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMWaitRAX); 515 515 AssertRCReturn(rc, rc); 516 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s. mwait.uMWaitECX);516 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMWaitRCX); 517 517 AssertRCReturn(rc, rc); 518 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s. mwait.uMonitorEAX);518 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMonitorRAX); 519 519 AssertRCReturn(rc, rc); 520 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s. mwait.uMonitorECX);520 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMonitorRCX); 521 521 AssertRCReturn(rc, rc); 522 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s. mwait.uMonitorEDX);522 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMonitorRDX); 523 523 AssertRCReturn(rc, rc); 524 524 } … … 574 574 { 575 575 /* Load mwait state. */ 576 rc = SSMR3GetU32(pSSM, &pVCpu->em.s. mwait.fWait);576 rc = SSMR3GetU32(pSSM, &pVCpu->em.s.MWait.fWait); 577 577 AssertRCReturn(rc, rc); 578 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s. mwait.uMWaitEAX);578 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMWaitRAX); 579 579 AssertRCReturn(rc, rc); 580 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s. mwait.uMWaitECX);580 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMWaitRCX); 581 581 AssertRCReturn(rc, rc); 582 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s. mwait.uMonitorEAX);582 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMonitorRAX); 583 583 AssertRCReturn(rc, rc); 584 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s. mwait.uMonitorECX);584 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMonitorRCX); 585 585 AssertRCReturn(rc, rc); 586 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s. mwait.uMonitorEDX);586 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMonitorRDX); 587 587 AssertRCReturn(rc, rc); 588 588 } … … 1896 1896 */ 1897 1897 Log2(("EMR3ExecuteVM: rc=%Rrc\n", rc)); 1898 EMSTATE const enmOldState = pVCpu->em.s.enmState; 1898 1899 switch (rc) 1899 1900 { … … 2104 2105 } 2105 2106 2107 /* 2108 * Act on state transition. 2109 */ 2110 EMSTATE const enmNewState = pVCpu->em.s.enmState; 2111 if (enmOldState != enmNewState) 2112 { 2113 /* Clear MWait flags. */ 2114 if ( enmOldState == EMSTATE_HALTED 2115 && (pVCpu->em.s.MWait.fWait & EMMWAIT_FLAG_ACTIVE) 2116 && ( enmNewState == EMSTATE_RAW 2117 || enmNewState == EMSTATE_HWACC 2118 || enmNewState == EMSTATE_REM 2119 || enmNewState == EMSTATE_DEBUG_GUEST_RAW 2120 || enmNewState == EMSTATE_DEBUG_GUEST_HWACC 2121 || enmNewState == EMSTATE_DEBUG_GUEST_REM) ) 2122 { 2123 LogFlow(("EMR3ExecuteVM: Clearing MWAIT\n")); 2124 pVCpu->em.s.MWait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0); 2125 } 2126 } 2127 2106 2128 STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x); /* (skip this in release) */ 2107 2129 STAM_PROFILE_ADV_START(&pVCpu->em.s.StatTotal, x); … … 2159 2181 { 2160 2182 STAM_REL_PROFILE_START(&pVCpu->em.s.StatHalted, y); 2161 if (pVCpu->em.s.mwait.fWait & EMMWAIT_FLAG_ACTIVE) 2183 /* MWAIT has a special extension where it's woken up when 2184 an interrupt is pending even when IF=0. */ 2185 if ( (pVCpu->em.s.MWait.fWait & (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0)) 2186 == (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0)) 2162 2187 { 2163 /* mwait has a special extension where it's woken up when an interrupt is pending even when IF=0. */ 2164 rc = VMR3WaitHalted(pVM, pVCpu, !(pVCpu->em.s.mwait.fWait & EMMWAIT_FLAG_BREAKIRQIF0) && !(CPUMGetGuestEFlags(pVCpu) & X86_EFL_IF)); 2165 pVCpu->em.s.mwait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0); 2188 rc = VMR3WaitHalted(pVM, pVCpu, false /*fIgnoreInterrupts*/); 2189 if ( rc == VINF_SUCCESS 2190 && VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)) 2191 { 2192 Log(("EMR3ExecuteVM: Triggering reschedule on pending IRQ after MWAIT\n")); 2193 rc = VINF_EM_RESCHEDULE; 2194 } 2166 2195 } 2167 2196 else … … 2178 2207 TMR3NotifySuspend(pVM, pVCpu); 2179 2208 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x); 2180 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName( pVCpu->em.s.enmPrevState)));2209 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(enmOldState))); 2181 2210 return VINF_EM_SUSPEND; 2182 2211 … … 2207 2236 pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION; 2208 2237 VMMR3FatalDump(pVM, pVCpu, rc); 2209 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName( pVCpu->em.s.enmPrevState)));2238 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(enmOldState))); 2210 2239 return rc; 2211 2240 } … … 2225 2254 emR3Debug(pVM, pVCpu, rc); 2226 2255 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x); 2227 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName( pVCpu->em.s.enmPrevState)));2256 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(enmOldState))); 2228 2257 return rc; 2229 2258 } … … 2239 2268 TMR3NotifySuspend(pVM, pVCpu); 2240 2269 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x); 2241 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName( pVCpu->em.s.enmPrevState)));2270 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(enmOldState))); 2242 2271 return VERR_EM_INTERNAL_ERROR; 2243 2272 } -
trunk/src/VBox/VMM/VMMR3/EMRaw.cpp
r40274 r40356 364 364 } 365 365 366 #if 0367 /* Try our own instruction emulator before falling back to the recompiler. */368 DISCPUSTATE Cpu;369 rc = CPUMR3DisasmInstrCPU(pVM, pVCpu, pCtx, pCtx->rip, &Cpu, "GEN EMU");370 if (RT_SUCCESS(rc))371 {372 uint32_t size;373 374 switch (Cpu.pCurInstr->opcode)375 {376 /* @todo we can do more now */377 case OP_MOV:378 case OP_AND:379 case OP_OR:380 case OP_XOR:381 case OP_POP:382 case OP_INC:383 case OP_DEC:384 case OP_XCHG:385 STAM_PROFILE_START(&pVCpu->em.s.StatMiscEmu, a);386 rc = EMInterpretInstructionCPU(pVM, &Cpu, CPUMCTX2CORE(pCtx), 0, &size);387 if (RT_SUCCESS(rc))388 {389 pCtx->rip += Cpu.opsize;390 STAM_PROFILE_STOP(&pVCpu->em.s.StatMiscEmu, a);391 return rc;392 }393 if (rc != VERR_EM_INTERPRETER)394 AssertMsgFailedReturn(("rc=%Rrc\n", rc), rc);395 STAM_PROFILE_STOP(&pVCpu->em.s.StatMiscEmu, a);396 break;397 }398 }399 #endif /* 0 */400 366 STAM_PROFILE_START(&pVCpu->em.s.StatREMEmu, a); 401 367 Log(("EMINS: %04x:%RGv RSP=%RGv\n", pCtx->cs, (RTGCPTR)pCtx->rip, (RTGCPTR)pCtx->rsp)); -
trunk/src/VBox/VMM/include/EMInternal.h
r40274 r40356 44 44 45 45 46 /** 47 * MWait state flags.48 */ 49 /* MWait activated. */46 /** @name MWait state flags. 47 * @{ 48 */ 49 /** MWait activated. */ 50 50 #define EMMWAIT_FLAG_ACTIVE RT_BIT(0) 51 /* MWait will continue when an interrupt is pending even when IF=0. */51 /** MWait will continue when an interrupt is pending even when IF=0. */ 52 52 #define EMMWAIT_FLAG_BREAKIRQIF0 RT_BIT(1) 53 /* Monitor instruction was executed previously. */53 /** Monitor instruction was executed previously. */ 54 54 #define EMMWAIT_FLAG_MONITOR_ACTIVE RT_BIT(2) 55 /** @} */ 55 56 56 57 /** EM time slice in ms; used for capping execution time. */ … … 333 334 EMSTATE volatile enmState; 334 335 335 /** Previous Execution Manager State. */336 /** The state prior to the suspending of the VM. */ 336 337 EMSTATE enmPrevState; 337 338 … … 364 365 uint64_t u64Alignment; 365 366 366 /* MWait halt state. */367 /** MWait halt state. */ 367 368 struct 368 369 { 369 uint32_t fWait; /* type of mwait; see EMMWAIT_FLAG_**/370 uint32_t a32Padding[1];371 RTGCPTR uMWait EAX; /* mwait hints*/372 RTGCPTR uMWait ECX; /* mwait extensions*/373 RTGCPTR uMonitor EAX; /* monitored address. */374 RTGCPTR uMonitor ECX; /* monitor extension. */375 RTGCPTR uMonitor EDX; /* monitor hint. */376 } mwait;370 uint32_t fWait; /** Type of mwait; see EMMWAIT_FLAG_*. */ 371 uint32_t u32Padding; 372 RTGCPTR uMWaitRAX; /** MWAIT hints. */ 373 RTGCPTR uMWaitRCX; /** MWAIT extensions. */ 374 RTGCPTR uMonitorRAX; /** Monitored address. */ 375 RTGCPTR uMonitorRCX; /** Monitor extension. */ 376 RTGCPTR uMonitorRDX; /** Monitor hint. */ 377 } MWait; 377 378 378 379 union
Note:
See TracChangeset
for help on using the changeset viewer.