#21353 new defect
apic timer does not trigger in time
回報者: | liowmark | 負責人: | |
---|---|---|---|
元件: | VMM | 版本: | VirtualBox 6.1.40 |
關鍵字: | apic timer | 副本: | |
Guest type: | Linux | Host type: | Windows |
描述
Rencently,I found a bug of APIC timer.Since the vbox set the last VCPU thread as the thread to wakeup all the timer and other VCPU threads will sleep 500ms until the Last VCPU thread wakeup them. If the last VCPU thread sleep a long time firstly,other VCPU thread's apic timer will not able to trigger in timer.This make other VCPU thread sleep at least 500ms.
here is may patch to the funtion apicSetTimerIcr in VMM/VMMALL/APICAll.cpp to fix the bug
#include "TMInternal.h" static VBOXSTRICTRC apicSetTimerIcr(PPDMDEVINS pDevIns, PVMCPUCC pVCpu, int rcBusy, uint32_t uInitialCount) { VMCPU_ASSERT_EMT(pVCpu); PAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM)); PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu); PXAPICPAGE pXApicPage = VMCPU_TO_XAPICPAGE(pVCpu); Log2(("APIC%u: apicSetTimerIcr: uInitialCount=%#RX32\n", pVCpu->idCpu, uInitialCount)); STAM_COUNTER_INC(&pApicCpu->StatTimerIcrWrite); /* In TSC-deadline mode, timer ICR writes are ignored, see Intel spec. 10.5.4.1 "TSC-Deadline Mode". */ if ( pApic->fSupportsTscDeadline && pXApicPage->lvt_timer.u.u2TimerMode == XAPIC_TIMER_MODE_TSC_DEADLINE) return VINF_SUCCESS; /* * The timer CCR may be modified by apicR3TimerCallback() in parallel, * so obtain the lock -before- updating it here to be consistent with the * timer ICR. We rely on CCR being consistent in apicGetTimerCcr(). */ TMTIMERHANDLE hTimer = pApicCpu->hTimer; VBOXSTRICTRC rc = PDMDevHlpTimerLockClock(pDevIns, hTimer, rcBusy); if (rc == VINF_SUCCESS) { pXApicPage->timer_icr.u32InitialCount = uInitialCount; pXApicPage->timer_ccr.u32CurrentCount = uInitialCount; if (uInitialCount) apicStartTimer(pVCpu, uInitialCount); else apicStopTimer(pVCpu); PVMCC pVM = pVCpu->CTX_SUFF(pVM); PVMCPUCC pVCpuDst = VMCC_GET_CPU(pVM, pVM->tm.s.idTimerCpu); #ifdef IN_RING3 VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE); #elif defined(IN_RING0) if (VMMGetCpu(pVM) != pVCpuDst) { switch (VMCPU_GET_STATE(pVCpuDst)) { case VMCPUSTATE_STARTED_EXEC: GVMMR0SchedPokeNoGVMNoLock(pVM, pVM->tm.s.idTimerCpu); break; case VMCPUSTATE_STARTED_HALTED: GVMMR0SchedWakeUpNoGVMNoLock(pVM, pVM->tm.s.idTimerCpu); break; default: break; /* nothing to do in other states. */ } } #endif PDMDevHlpTimerUnlockClock(pDevIns, hTimer); } return rc; }
注意:
瀏覽 TracTickets
來幫助您使用待辦事項功能
Is there a testcase that can reproduce this issue?