VirtualBox

Changeset 48370 in vbox


Ignore:
Timestamp:
Sep 6, 2013 6:28:00 PM (11 years ago)
Author:
vboxsync
Message:

EM,HM: MWait fix, clearing the active bit too early.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/em.h

    r47807 r48370  
    200200VMM_INT_DECL(int)               EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
    201201VMM_INT_DECL(bool)              EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx);
     202VMM_INT_DECL(bool)              EMMonitorWaitShouldContinue(PVMCPU pVCpu, PCPUMCTX pCtx);
    202203VMM_INT_DECL(int)               EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx, RTGCPHYS GCPhys);
    203204VMM_INT_DECL(int)               EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx);
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r48177 r48370  
    219219
    220220/**
    221  * Determine if we should continue after encountering a hlt or mwait
    222  * instruction.
     221 * Determine if we should continue after encountering a mwait instruction.
    223222 *
    224223 * Clears MWAIT flags if returning @c true.
    225224 *
    226  * @returns boolean
     225 * @returns true if we should continue, false if we should halt.
    227226 * @param   pVCpu           Pointer to the VMCPU.
    228227 * @param   pCtx            Current CPU context.
    229228 */
    230 VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx)
     229VMM_INT_DECL(bool) EMMonitorWaitShouldContinue(PVMCPU pVCpu, PCPUMCTX pCtx)
    231230{
    232231    if (   pCtx->eflags.Bits.u1IF
     
    234233            ==                            (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0)) )
    235234    {
    236         pVCpu->em.s.MWait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0);
     235        if (VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)))
     236        {
     237            pVCpu->em.s.MWait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0);
     238            return true;
     239        }
     240    }
     241
     242    return false;
     243}
     244
     245
     246/**
     247 * Determine if we should continue after encountering a hlt instruction.
     248 *
     249 * @returns true if we should continue, false if we should halt.
     250 * @param   pVCpu           Pointer to the VMCPU.
     251 * @param   pCtx            Current CPU context.
     252 */
     253VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx)
     254{
     255    if (pCtx->eflags.Bits.u1IF)
    237256        return !!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC));
    238     }
    239 
    240257    return false;
    241258}
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r48329 r48370  
    40124012
    40134013        if (   rc == VINF_EM_HALT
    4014             && EMShouldContinueAfterHalt(pVCpu, pCtx))
     4014            && EMMonitorWaitShouldContinue(pVCpu, pCtx))
    40154015        {
    40164016            rc = VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r48369 r48370  
    89538953
    89548954        if (   rc == VINF_EM_HALT
    8955             && EMShouldContinueAfterHalt(pVCpu, pMixedCtx))
     8955            && EMMonitorWaitShouldContinue(pVCpu, pMixedCtx))
    89568956        {
    89578957            rc = VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r48130 r48370  
    25142514                {
    25152515                    STAM_REL_PROFILE_START(&pVCpu->em.s.StatHalted, y);
     2516                    /* If HM (or someone else) store a pending interrupt in
     2517                       TRPM, it must be dispatched ASAP without any halting.
     2518                       Anything pending in TRPM has been accepted and the CPU
     2519                       should already be the right state to receive it. */
     2520                    if (TRPMHasTrap(pVCpu))
     2521                        rc = VINF_EM_RESCHEDULE;
    25162522                    /* MWAIT has a special extension where it's woken up when
    25172523                       an interrupt is pending even when IF=0. */
    2518                     if (   (pVCpu->em.s.MWait.fWait & (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))
    2519                         ==                            (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))
     2524                    else if (   (pVCpu->em.s.MWait.fWait & (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))
     2525                             ==                            (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))
    25202526                    {
    25212527                        rc = VMR3WaitHalted(pVM, pVCpu, false /*fIgnoreInterrupts*/);
     
    25272533                        }
    25282534                    }
    2529                     else if (TRPMHasTrap(pVCpu))
    2530                         rc = VINF_EM_RESCHEDULE;
    25312535                    else
    25322536                        rc = VMR3WaitHalted(pVM, pVCpu, !(CPUMGetGuestEFlags(pVCpu) & X86_EFL_IF));
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette