VirtualBox

Changeset 100076 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Jun 5, 2023 4:41:14 PM (20 months ago)
Author:
vboxsync
Message:

VMM/NEMR3Native-darwin-armv8: Fix setting the vTimer offset, this requires using mach_absolute_time() instead of reading the CNTVCT_EL0 directly or the guest will read an underflowed counter value programming the timer completely wrong leading to stalls without any interrupt source, bugref:10390

File:
1 edited

Legend:

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

    r100003 r100076  
    640640                          "Call to hv_vcpu_create failed on vCPU %u: %#x (%Rrc)", idCpu, hrc, nemR3DarwinHvSts2Rc(hrc));
    641641
    642     /* Set the vTiemr offset so all vCpus start at (nearly) 0. */
    643     pVCpu->nem.s.u64VTimerOff = ASMReadTSC();
    644 
    645     hrc = hv_vcpu_set_vtimer_offset(pVCpu->nem.s.hVCpu, pVCpu->nem.s.u64VTimerOff);
    646     AssertLogRelMsg(hrc == HV_SUCCESS, ("vCPU#%u: Failed to set vTimer offset to %#RX64 -> hrc = %#x\n",
    647                                         pVCpu->idCpu, pVCpu->nem.s.u64VTimerOff, hrc));
     642    /* Will be initialized in NEMHCResumeCpuTickOnAll() before executing guest code. */
     643    pVCpu->nem.s.u64VTimerOff = 0;
    648644
    649645    if (idCpu == 0)
     
    10641060                    return VINF_SUCCESS;
    10651061
     1062                LogFlowFunc(("Set vTimer activation to cNanoSecsVTimerToExpire=%#RX64 (CntvCValEl0=%#RX64, u64VTimerOff=%#RX64 cTicksVTimer=%#RX64 u64CntFrqHz=%#RX64)\n",
     1063                             cNanoSecsVTimerToExpire, pVCpu->cpum.GstCtx.CntvCValEl0, pVCpu->nem.s.u64VTimerOff, cTicksVTimer, pVM->nem.s.u64CntFrqHz));
    10661064                TMCpuSetVTimerNextActivation(pVCpu, cNanoSecsVTimerToExpire);
    10671065            }
     
    12461244         * the new offset to let the guest not notice the pause.
    12471245         */
    1248         uint64_t u64TscNew = ASMReadTSC() - pVCpu->nem.s.u64VTimerOff;
     1246        uint64_t u64TscNew = mach_absolute_time() - pVCpu->nem.s.u64VTimerOff;
    12491247        Assert(u64TscNew >= pVM->nem.s.u64VTimerValuePaused);
     1248        LogFlowFunc(("u64VTimerOffOld=%#RX64 u64TscNew=%#RX64 u64VTimerValuePaused=%#RX64 -> u64VTimerOff=%#RX64\n",
     1249                     pVCpu->nem.s.u64VTimerOff, u64TscNew, pVM->nem.s.u64VTimerValuePaused,
     1250                     pVCpu->nem.s.u64VTimerOff + (u64TscNew - pVM->nem.s.u64VTimerValuePaused)));
     1251
    12501252        pVCpu->nem.s.u64VTimerOff += u64TscNew - pVM->nem.s.u64VTimerValuePaused;
    12511253        hv_return_t hrc = hv_vcpu_set_vtimer_offset(pVCpu->nem.s.hVCpu, pVCpu->nem.s.u64VTimerOff);
     
    17371739    if (puAux)
    17381740        *puAux = 0;
    1739     *pcTicks = ASMReadTSC() - pVCpu->nem.s.u64VTimerOff; /* This is the host timer minus the offset. */
     1741    *pcTicks = mach_absolute_time() - pVCpu->nem.s.u64VTimerOff; /* This is the host timer minus the offset. */
    17401742    return VINF_SUCCESS;
    17411743}
     
    17541756VMM_INT_DECL(int) NEMHCResumeCpuTickOnAll(PVMCC pVM, PVMCPUCC pVCpu, uint64_t uPausedTscValue)
    17551757{
    1756     LogFlowFunc(("pVM=%p pVCpu=%p uPausedTscValue=%RX64\n", pVCpu, uPausedTscValue));
     1758    LogFlowFunc(("pVM=%p pVCpu=%p uPausedTscValue=%RX64\n", pVM, pVCpu, uPausedTscValue));
    17571759    VMCPU_ASSERT_EMT_RETURN(pVCpu, VERR_VM_THREAD_NOT_EMT);
    17581760    AssertReturn(VM_IS_NEM_ENABLED(pVM), VERR_NEM_IPE_9);
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