VirtualBox

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


Ignore:
Timestamp:
May 25, 2023 11:44:00 AM (21 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
157636
Message:

VMM/NEMR3Native-darwin-armv8: Set the vTimer offset to account for suspending VMs, bugref:10387 bugref:10390

File:
1 edited

Legend:

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

    r99888 r99976  
    5050#include <iprt/armv8.h>
    5151#include <iprt/asm.h>
     52#include <iprt/asm-arm.h>
    5253#include <iprt/ldr.h>
    5354#include <iprt/mem.h>
     
    443444{
    444445    RT_NOREF(pVM);
    445     hv_return_t hrc = HV_SUCCESS;
    446 
    447     if (fWhat & (CPUMCTX_EXTRN_GPRS_MASK | CPUMCTX_EXTRN_PC | CPUMCTX_EXTRN_FPCR | CPUMCTX_EXTRN_FPSR))
     446
     447    hv_return_t hrc = hv_vcpu_get_sys_reg(pVCpu->nem.s.hVCpu, HV_SYS_REG_CNTV_CTL_EL0, &pVCpu->cpum.GstCtx.CntvCtlEl0);
     448    if (hrc == HV_SUCCESS)
     449        hrc = hv_vcpu_get_sys_reg(pVCpu->nem.s.hVCpu, HV_SYS_REG_CNTV_CVAL_EL0, &pVCpu->cpum.GstCtx.CntvCValEl0);
     450
     451    if (   hrc == HV_SUCCESS
     452        && (fWhat & (CPUMCTX_EXTRN_GPRS_MASK | CPUMCTX_EXTRN_PC | CPUMCTX_EXTRN_FPCR | CPUMCTX_EXTRN_FPSR)))
    448453    {
    449454        for (uint32_t i = 0; i < RT_ELEMENTS(s_aCpumRegs); i++)
     
    595600    if (hrc == HV_SUCCESS)
    596601    {
    597         pVM->nem.s.fCreatedVm = true;
     602        pVM->nem.s.fCreatedVm  = true;
     603        pVM->nem.s.u64CntFrqHz = ASMReadCntFrqEl0();
    598604        VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API);
    599605        Log(("NEM: Marked active!\n"));
     
    632638        return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
    633639                          "Call to hv_vcpu_create failed on vCPU %u: %#x (%Rrc)", idCpu, hrc, nemR3DarwinHvSts2Rc(hrc));
     640
     641    /* Set the vTiemr offset so all vCpus start at (nearly) 0. */
     642    pVCpu->nem.s.u64VTimerOff = ASMReadTSC();
     643
     644    hrc = hv_vcpu_set_vtimer_offset(pVCpu->nem.s.hVCpu, pVCpu->nem.s.u64VTimerOff);
     645    AssertLogRelMsg(hrc == HV_SUCCESS, ("vCPU#%u: Failed to set vTimer offset to %#RX64 -> hrc = %#x\n",
     646                                        pVCpu->idCpu, pVCpu->nem.s.u64VTimerOff, hrc));
    634647
    635648    if (idCpu == 0)
     
    11871200     * everything every time.  This will be optimized later.
    11881201     */
     1202
     1203    /* Update the vTimer offset after resuming if instructed. */
     1204    if (pVCpu->nem.s.fVTimerOffUpdate)
     1205    {
     1206        /*
     1207         * Program the new offset, first get the new TSC value with the old vTimer offset and then adjust the
     1208         * the new offset to let the guest not notice the pause.
     1209         */
     1210        uint64_t u64TscNew = ASMReadTSC() - pVCpu->nem.s.u64VTimerOff;
     1211        Assert(u64TscNew >= pVM->nem.s.u64VTimerValuePaused);
     1212        pVCpu->nem.s.u64VTimerOff += u64TscNew - pVM->nem.s.u64VTimerValuePaused;
     1213        hv_return_t hrc = hv_vcpu_set_vtimer_offset(pVCpu->nem.s.hVCpu, pVCpu->nem.s.u64VTimerOff);
     1214        if (hrc != HV_SUCCESS)
     1215            return nemR3DarwinHvSts2Rc(hrc);
     1216
     1217        pVCpu->nem.s.fVTimerOffUpdate = false;
     1218    }
    11891219
    11901220    /*
     
    16671697    STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatQueryCpuTick);
    16681698
    1669     AssertReleaseFailed();
    1670     return VERR_NOT_IMPLEMENTED;
     1699    if (puAux)
     1700        *puAux = 0;
     1701    *pcTicks = ASMReadTSC() - pVCpu->nem.s.u64VTimerOff; /* This is the host timer minus the offset. */
     1702    return VINF_SUCCESS;
    16711703}
    16721704
     
    16881720    AssertReturn(VM_IS_NEM_ENABLED(pVM), VERR_NEM_IPE_9);
    16891721
    1690     //AssertReleaseFailed();
     1722    pVM->nem.s.u64VTimerValuePaused = uPausedTscValue;
     1723
     1724    /*
     1725     * Set the flag to update the vTimer offset when the vCPU resumes for the first time
     1726     * (needs to be done on the actual EMT).
     1727     */
     1728    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     1729    {
     1730        PVMCPUCC pVCpuDst = pVM->apCpusR3[idCpu];
     1731        pVCpuDst->nem.s.fVTimerOffUpdate = true;
     1732    }
     1733
    16911734    return VINF_SUCCESS;
    16921735}
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