VirtualBox

Changeset 100000 in vbox


Ignore:
Timestamp:
May 30, 2023 6:09:42 AM (18 months ago)
Author:
vboxsync
Message:

VMM: Take the vTimer expiration into account when halting due to a WFI/WFE instruction so the guest gets woken up if no other event is pending, bugref:10389

Location:
trunk
Files:
6 edited

Legend:

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

    r98103 r100000  
    171171VMMDECL(uint64_t)       TMCpuTicksPerSecond(PVMCC pVM);
    172172VMM_INT_DECL(bool)      TMCpuTickIsTicking(PVMCPUCC pVCpu);
     173
     174#if defined(VBOX_VMM_TARGET_ARMV8)
     175VMM_INT_DECL(void)      TMCpuSetVTimerNextActivation(PVMCPUCC pVCpu, uint64_t cNanoSecs);
     176VMM_INT_DECL(uint64_t)  TMCpuGetVTimerActivationNano(PVMCPUCC pVCpu);
     177#endif
    173178/** @} */
    174179
  • trunk/include/VBox/vmm/vm.h

    r99576 r100000  
    130130    VMCPUSTATE volatile     enmState;
    131131
     132#if defined(VBOX_VMM_TARGET_ARMV8)
     133    uint32_t                u32Alignment0;
     134    /** The number of nano seconds when the vTimer of the associated vCPU is supposed to activate
     135     *  required to get out of a halt (due to wfi/wfe).
     136     *
     137     * @note This actually should go into TMCPU but this drags in a whole lot of padding changes
     138     *       and I'm not sure yet whether this will remain in this form anyway.
     139     */
     140    uint64_t                cNsVTimerActivate;
     141    /** Padding up to 64 bytes. */
     142    uint8_t                 abAlignment0[64 - 12 - 8 - 4];
     143#else
    132144    /** Padding up to 64 bytes. */
    133145    uint8_t                 abAlignment0[64 - 12];
     146#endif
    134147    /** @} */
    135148
     
    517530#define VMCPU_FF_HM_UPDATE_CR3              RT_BIT_64(VMCPU_FF_HM_UPDATE_CR3_BIT)
    518531#define VMCPU_FF_HM_UPDATE_CR3_BIT          12
     532#if defined(VBOX_VMM_TARGET_ARMV8)
     533# define VMCPU_FF_VTIMER_ACTIVATED          RT_BIT_64(VMCPU_FF_VTIMER_ACTIVATED_BIT)
     534# define VMCPU_FF_VTIMER_ACTIVATED_BIT      13
     535#else
    519536/* Bit 13 used to be VMCPU_FF_HM_UPDATE_PAE_PDPES. */
     537#endif
    520538/** This action forces the VM to resync the page tables before going
    521539 * back to execute guest code. (GLOBAL FLUSH) */
     
    593611# define VMCPU_FF_EXTERNAL_HALTED_MASK          (  VMCPU_FF_INTERRUPT_IRQ | VMCPU_FF_INTERRUPT_FIQ \
    594612                                                 | VMCPU_FF_REQUEST       | VMCPU_FF_INTERRUPT_NMI  | VMCPU_FF_INTERRUPT_SMI \
    595                                                  | VMCPU_FF_UNHALT        | VMCPU_FF_TIMER          | VMCPU_FF_DBGF )
     613                                                 | VMCPU_FF_UNHALT        | VMCPU_FF_TIMER          | VMCPU_FF_DBGF \
     614                                                 | VMCPU_FF_VTIMER_ACTIVATED)
    596615#else
    597616# define VMCPU_FF_EXTERNAL_HALTED_MASK          (  VMCPU_FF_UPDATE_APIC | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC \
  • trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp

    r98103 r100000  
    660660}
    661661
     662
     663#if defined(VBOX_VMM_TARGET_ARMV8)
     664/**
     665 * Sets the number of nanoseconds from now when the vTiemr is supposed to expire next.
     666 *
     667 * @param   pVCpu           The cross context virtual CPU structure.
     668 * @param   cNanoSecs       Number of nano seconds when the timer is supposed to fire.
     669 *
     670 * @note This is required in order to kick the vCPU out of a halting state because the
     671 *       vTimer is supposed to fire an interrupt.
     672 */
     673VMM_INT_DECL(void) TMCpuSetVTimerNextActivation(PVMCPUCC pVCpu, uint64_t cNanoSecs)
     674{
     675    pVCpu->cNsVTimerActivate = cNanoSecs;
     676}
     677
     678
     679/**
     680 * Returns when the vTimer is supposed to expire next in number of nanoseconds.
     681 *
     682 * @returns Number of nanoseconds when the vTimer is supposed to
     683 */
     684VMM_INT_DECL(uint64_t) TMCpuGetVTimerActivationNano(PVMCPUCC pVCpu)
     685{
     686    return pVCpu->cNsVTimerActivate;
     687}
     688#endif
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r99999 r100000  
    18961896#else
    18971897        bool fWakeupPending = false;
    1898         //ssertReleaseFailed();
    1899         /** @todo */
     1898
     1899        if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VTIMER_ACTIVATED))
     1900        {
     1901            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_VTIMER_ACTIVATED);
     1902
     1903            fWakeupPending = true;
     1904            if (pVM->em.s.fIemExecutesAll)
     1905                rc2 = VINF_EM_RESCHEDULE;
     1906            else
     1907            {
     1908                rc2 = HMR3IsActive(pVCpu)    ? VINF_EM_RESCHEDULE_HM
     1909                    : VM_IS_NEM_ENABLED(pVM) ? VINF_EM_RESCHEDULE
     1910                    :                          VINF_EM_RESCHEDULE_REM;
     1911            }
     1912        }
    19001913#endif
    19011914
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r99740 r100000  
    12701270        pVCpu->tm.s.u64TSC         = 0;
    12711271        pVCpu->tm.s.u64TSCLastSeen = 0;
     1272#if defined(VBOX_VMM_TARGET_ARMV8)
     1273        pVCpu->cNsVTimerActivate   = UINT64_MAX;
     1274#endif
    12721275    }
    12731276}
  • trunk/src/VBox/VMM/VMMR3/VMEmt.cpp

    r99576 r100000  
    568568    }
    569569
     570#if defined(VBOX_VMM_TARGET_ARMV8)
     571    uint64_t cNsVTimerActivate = TMCpuGetVTimerActivationNano(pVCpu);
     572    const bool fVTimerActive = cNsVTimerActivate != UINT64_MAX;
     573#endif
     574
    570575    /*
    571576     * Halt loop.
     
    584589        STAM_REL_PROFILE_ADD_PERIOD(&pUVCpu->vm.s.StatHaltTimers, cNsElapsedTimers);
    585590        if (    VM_FF_IS_ANY_SET(pVM, VM_FF_EXTERNAL_HALTED_MASK)
    586             ||  VMCPU_FF_IS_ANY_SET(pVCpu, fMask))
     591            ||  VMCPU_FF_IS_ANY_SET(pVCpu, fMask)
     592#if defined(VBOX_VMM_TARGET_ARMV8)
     593            ||  cNsElapsedTimers >= cNsVTimerActivate
     594#endif           
     595            )
     596        {
     597#if defined(VBOX_VMM_TARGET_ARMV8)
     598            cNsVTimerActivate = 0;
     599#endif
    587600            break;
     601        }
    588602
    589603        /*
     
    595609            ||  VMCPU_FF_IS_ANY_SET(pVCpu, fMask))
    596610            break;
     611
     612#if defined(VBOX_VMM_TARGET_ARMV8)
     613        u64NanoTS = RT_MIN(cNsVTimerActivate, u64NanoTS);
     614#endif
    597615
    598616        /*
     
    656674                &&  Elapsed > 100000 /* 0.1 ms */)
    657675                fBlockOnce = false;
     676
     677#if defined(VBOX_VMM_TARGET_ARMV8)
     678            cNsVTimerActivate -= RT_MIN(cNsVTimerActivate, Elapsed);
     679            /* Did the vTimer expire? */
     680            if (!cNsVTimerActivate)
     681                break;
     682#endif
    658683        }
    659684    }
    660685    //if (fSpinning) RTLogRelPrintf("spun for %RU64 ns %u loops; lag=%RU64 pct=%d\n", RTTimeNanoTS() - u64Now, cLoops, TMVirtualSyncGetLag(pVM), u32CatchUpPct);
    661686
     687#if defined(VBOX_VMM_TARGET_ARMV8)
     688    if (fVTimerActive)
     689    {
     690        if (!cNsVTimerActivate)
     691            VMCPU_FF_SET(pVCpu, VMCPU_FF_VTIMER_ACTIVATED);
     692
     693        TMCpuSetVTimerNextActivation(pVCpu, cNsVTimerActivate);
     694    }
     695#endif
    662696    ASMAtomicUoWriteBool(&pUVCpu->vm.s.fWait, false);
    663697    return rc;
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