VirtualBox

Changeset 93218 in vbox for trunk/src


Ignore:
Timestamp:
Jan 13, 2022 10:31:55 AM (3 years ago)
Author:
vboxsync
Message:

VMM/NEMR3Native-darwin: Straighten out the runloop a bit, no need to check for FFs twice (already done in vmxHCCheckForceFlags()), move the timer polling up before the for loop as 32bit guests using the standard PIT and PIC seem to become very unresponsive due to excessive timer handling, bugref:9044

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp

    r93134 r93218  
    27172717    VmxTransient.pVmcsInfo = &pVCpu->nem.s.VmcsInfo;
    27182718
     2719    /*
     2720     * Poll timers and run for a bit.
     2721     */
     2722    /** @todo See if we cannot optimize this TMTimerPollGIP by only redoing
     2723     *        the whole polling job when timers have changed... */
     2724    uint64_t       offDeltaIgnored;
     2725    uint64_t const nsNextTimerEvt = TMTimerPollGIP(pVM, pVCpu, &offDeltaIgnored); NOREF(nsNextTimerEvt);
     2726
    27192727    const bool      fSingleStepping = DBGFIsStepping(pVCpu);
    27202728    VBOXSTRICTRC    rcStrict        = VINF_SUCCESS;
     
    27282736        { /*likely */ }
    27292737        else
     2738        {
     2739            if (rcStrict == VINF_EM_RAW_TO_R3)
     2740                rcStrict = VINF_SUCCESS;
    27302741            break;
     2742        }
    27312743
    27322744        /*
     
    27642776        AssertRCReturn(rc, rc);
    27652777
     2778        LogFlowFunc(("Running vCPU\n"));
     2779        pVCpu->nem.s.Event.fPending = false;
     2780
     2781        TMNotifyStartOfExecution(pVM, pVCpu);
     2782
     2783        Assert(!pVCpu->nem.s.fCtxChanged);
     2784        hv_return_t hrc;
     2785        if (hv_vcpu_run_until)
     2786            hrc = hv_vcpu_run_until(pVCpu->nem.s.hVCpuId, HV_DEADLINE_FOREVER);
     2787        else
     2788            hrc = hv_vcpu_run(pVCpu->nem.s.hVCpuId);
     2789
     2790        TMNotifyEndOfExecution(pVM, pVCpu, ASMReadTSC());
     2791
    27662792        /*
    2767          * Poll timers and run for a bit.
     2793         * Sync the TPR shadow with our APIC state.
    27682794         */
    2769         /** @todo See if we cannot optimize this TMTimerPollGIP by only redoing
    2770          *        the whole polling job when timers have changed... */
    2771         uint64_t       offDeltaIgnored;
    2772         uint64_t const nsNextTimerEvt = TMTimerPollGIP(pVM, pVCpu, &offDeltaIgnored); NOREF(nsNextTimerEvt);
    2773         if (   !VM_FF_IS_ANY_SET(pVM, VM_FF_EMT_RENDEZVOUS | VM_FF_TM_VIRTUAL_SYNC)
    2774             && !VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_HM_TO_R3_MASK))
    2775         {
    2776             LogFlowFunc(("Running vCPU\n"));
    2777             pVCpu->nem.s.Event.fPending = false;
    2778 
    2779             TMNotifyStartOfExecution(pVM, pVCpu);
    2780 
    2781             Assert(!pVCpu->nem.s.fCtxChanged);
    2782             hv_return_t hrc;
    2783             if (hv_vcpu_run_until)
    2784                 hrc = hv_vcpu_run_until(pVCpu->nem.s.hVCpuId, HV_DEADLINE_FOREVER);
    2785             else
    2786                 hrc = hv_vcpu_run(pVCpu->nem.s.hVCpuId);
    2787 
    2788             TMNotifyEndOfExecution(pVM, pVCpu, ASMReadTSC());
    2789 
     2795        if (   !VmxTransient.fIsNestedGuest
     2796            && (pVCpu->nem.s.VmcsInfo.u32ProcCtls & VMX_PROC_CTLS_USE_TPR_SHADOW))
     2797        {
     2798            uint64_t u64Tpr;
     2799            hrc = hv_vcpu_read_register(pVCpu->nem.s.hVCpuId, HV_X86_TPR, &u64Tpr);
     2800            Assert(hrc == HV_SUCCESS);
     2801
     2802            if (VmxTransient.u8GuestTpr != (uint8_t)u64Tpr)
     2803            {
     2804                rc = APICSetTpr(pVCpu, (uint8_t)u64Tpr);
     2805                AssertRC(rc);
     2806                ASMAtomicUoOrU64(&pVCpu->nem.s.fCtxChanged, HM_CHANGED_GUEST_APIC_TPR);
     2807            }
     2808        }
     2809
     2810        if (hrc == HV_SUCCESS)
     2811        {
    27902812            /*
    2791              * Sync the TPR shadow with our APIC state.
     2813             * Deal with the message.
    27922814             */
    2793             if (   !VmxTransient.fIsNestedGuest
    2794                 && (pVCpu->nem.s.VmcsInfo.u32ProcCtls & VMX_PROC_CTLS_USE_TPR_SHADOW))
    2795             {
    2796                 uint64_t u64Tpr;
    2797                 hrc = hv_vcpu_read_register(pVCpu->nem.s.hVCpuId, HV_X86_TPR, &u64Tpr);
    2798                 Assert(hrc == HV_SUCCESS);
    2799 
    2800                 if (VmxTransient.u8GuestTpr != (uint8_t)u64Tpr)
    2801                 {
    2802                     rc = APICSetTpr(pVCpu, (uint8_t)u64Tpr);
    2803                     AssertRC(rc);
    2804                     ASMAtomicUoOrU64(&pVCpu->nem.s.fCtxChanged, HM_CHANGED_GUEST_APIC_TPR);
    2805                 }
    2806             }
    2807 
    2808             if (hrc == HV_SUCCESS)
    2809             {
    2810                 /*
    2811                  * Deal with the message.
    2812                  */
    2813                 rcStrict = nemR3DarwinHandleExit(pVM, pVCpu, &VmxTransient);
    2814                 if (rcStrict == VINF_SUCCESS)
    2815                 { /* hopefully likely */ }
    2816                 else
    2817                 {
    2818                     LogFlow(("NEM/%u: breaking: nemR3DarwinHandleExit -> %Rrc\n", pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) ));
    2819                     STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnStatus);
    2820                     break;
    2821                 }
    2822                 //Assert(!pVCpu->cpum.GstCtx.fExtrn);
    2823             }
     2815            rcStrict = nemR3DarwinHandleExit(pVM, pVCpu, &VmxTransient);
     2816            if (rcStrict == VINF_SUCCESS)
     2817            { /* hopefully likely */ }
    28242818            else
    28252819            {
    2826                 AssertLogRelMsgFailedReturn(("hv_vcpu_run()) failed for CPU #%u: %#x %u\n",
    2827                                             pVCpu->idCpu, hrc, vmxHCCheckGuestState(pVCpu, &pVCpu->nem.s.VmcsInfo)),
    2828                                             VERR_NEM_IPE_0);
     2820                LogFlow(("NEM/%u: breaking: nemR3DarwinHandleExit -> %Rrc\n", pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) ));
     2821                STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnStatus);
     2822                break;
    28292823            }
    2830 
    2831             /*
    2832              * If no relevant FFs are pending, loop.
    2833              */
    2834             if (   !VM_FF_IS_ANY_SET(   pVM,   !fSingleStepping ? VM_FF_HP_R0_PRE_HM_MASK    : VM_FF_HP_R0_PRE_HM_STEP_MASK)
    2835                 && !VMCPU_FF_IS_ANY_SET(pVCpu, !fSingleStepping ? VMCPU_FF_HP_R0_PRE_HM_MASK : VMCPU_FF_HP_R0_PRE_HM_STEP_MASK) )
    2836                 continue;
    2837 
    2838             /** @todo Try handle pending flags, not just return to EM loops.  Take care
    2839              *        not to set important RCs here unless we've handled a message. */
    2840             LogFlow(("NEM/%u: breaking: pending FF (%#x / %#RX64)\n",
    2841                      pVCpu->idCpu, pVM->fGlobalForcedActions, (uint64_t)pVCpu->fLocalForcedActions));
    2842             STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnFFPost);
     2824            //Assert(!pVCpu->cpum.GstCtx.fExtrn);
    28432825        }
    28442826        else
    28452827        {
    2846             LogFlow(("NEM/%u: breaking: pending FF (pre exec)\n", pVCpu->idCpu));
    2847             STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnFFPre);
    2848         }
    2849         break;
     2828            AssertLogRelMsgFailedReturn(("hv_vcpu_run()) failed for CPU #%u: %#x %u\n",
     2829                                        pVCpu->idCpu, hrc, vmxHCCheckGuestState(pVCpu, &pVCpu->nem.s.VmcsInfo)),
     2830                                        VERR_NEM_IPE_0);
     2831        }
    28502832    } /* the run loop */
    28512833
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