Opened 2 years ago
Last modified 19 months ago
#21353 new defect
apic timer does not trigger in time
Reported by: | liowmark | Owned by: | |
---|---|---|---|
Component: | VMM | Version: | VirtualBox 6.1.40 |
Keywords: | apic timer | Cc: | |
Guest type: | Linux | Host type: | Windows |
Description
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; }
Note:
See TracTickets
for help on using tickets.
Hi, is there a testcase that can reproduce this issue?