vbox6: add POKE calls in TM for remote vCPUs

and return to VMM if TM_TIMER flag is set

Issue #4313
This commit is contained in:
Alexander Boettcher 2021-10-26 15:47:29 +02:00 committed by Christian Helmuth
parent 5a21431c31
commit 3701733c8f
4 changed files with 100 additions and 7 deletions

View File

@ -1 +1 @@
4efbd1dc165327781b92e86beabd578e2339c222
95e5355642337757ad41218571699933eb420a16

View File

@ -5,3 +5,4 @@ narrowing.patch
network.patch
devahci.patch
smp_sipi.patch
tm_poke.patch

View File

@ -0,0 +1,96 @@
--- a/src/virtualbox6/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
+++ b/src/virtualbox6/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
@@ -250,7 +250,7 @@
Log5(("TMAllVirtual(%u): FF: %d -> 1\n", __LINE__, VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)));
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
#ifdef IN_RING3
- VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM);
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
#endif
}
}
@@ -408,7 +408,7 @@
if (pcNsToDeadline)
*pcNsToDeadline = 0;
#ifdef IN_RING3
- VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM);
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
#endif
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetSetFF);
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetExpired);
@@ -491,7 +491,7 @@
PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
#ifdef IN_RING3
- VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM);
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
#endif
if (pcNsToDeadline)
*pcNsToDeadline = 0;
@@ -544,7 +544,7 @@
Log5(("TMAllVirtual(%u): FF: 0 -> 1\n", __LINE__));
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
#ifdef IN_RING3
- VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM /** @todo |VMNOTIFYFF_FLAGS_POKE*/);
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
#endif
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetSetFF);
}
@@ -711,7 +711,7 @@
VM_FF_SET(pVM, VM_FF_TM_VIRTUAL_SYNC); /* Hmm? */
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
#ifdef IN_RING3
- VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM);
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
#endif
STAM_COUNTER_INC(&pVM->tm.s.StatVirtualSyncGetSetFF);
Log4(("TM: %'RU64/-%'8RU64: exp tmr=>ff [NoLock]\n", u64, pVM->tm.s.offVirtualSync - pVM->tm.s.offVirtualSyncGivenUp));
--- a/src/virtualbox6/src/VBox/VMM/VMMAll/TMAll.cpp
+++ b/src/virtualbox6/src/VBox/VMM/VMMAll/TMAll.cpp
@@ -292,7 +292,7 @@
Log5(("TMAll(%u): FF: 0 -> 1\n", __LINE__));
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
#ifdef IN_RING3
- VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM);
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
#endif
STAM_COUNTER_INC(&pVM->tm.s.StatScheduleSetFF);
}
@@ -831,6 +831,12 @@
{
Log5(("TMAll(%u): FF: %d -> 1\n", __LINE__, VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)));
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
+
+ if (pVCpu->idCpu != pVCpuDst->idCpu) {
+ Log(("FF_TIMER POKE, vCPU=%u -> vCPU=%u line=%u\n",
+ pVCpu->idCpu, pVCpuDst->idCpu, __LINE__));
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
+ }
}
LogFlow(("TMTimerPoll: expire1=%'RU64 <= now=%'RU64\n", u64Expire1, u64Now));
return tmTimerPollReturnHit(pVM, pVCpu, pVCpuDst, u64Now, pu64Delta, &pVM->tm.s.StatPollVirtual);
@@ -874,6 +880,12 @@
{
Log5(("TMAll(%u): FF: %d -> 1\n", __LINE__, VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)));
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
+
+ if (pVCpu->idCpu != pVCpuDst->idCpu) {
+ Log(("FF_TIMER POKE, vCPU=%u -> vCPU=%u line=%u\n",
+ pVCpu->idCpu, pVCpuDst->idCpu, __LINE__));
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
+ }
}
STAM_COUNTER_INC(&pVM->tm.s.StatPollSimple);
@@ -970,6 +982,11 @@
{
Log5(("TMAll(%u): FF: %d -> 1\n", __LINE__, VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)));
VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
+ if (pVCpu->idCpu != pVCpuDst->idCpu) {
+ Log(("FF_TIMER POKE, vCPU=%u -> vCPU=%u line=%u\n",
+ pVCpu->idCpu, pVCpuDst->idCpu, __LINE__));
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
+ }
}
STAM_COUNTER_INC(&pVM->tm.s.StatPollVirtualSync);
LogFlow(("TMTimerPoll: expire2=%'RU64 <= now=%'RU64\n", u64Expire2, u64Now));

View File

@ -411,7 +411,8 @@ template <typename T> bool Sup::Vcpu_impl<T>::_continue_hw_accelerated()
uint32_t check_vmcpu = VMCPU_FF_HM_TO_R3_MASK
| VMCPU_FF_PGM_SYNC_CR3
| VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
| VMCPU_FF_REQUEST;
| VMCPU_FF_REQUEST
| VMCPU_FF_TIMER;
if (!VM_FF_IS_SET(&_vm, check_vm) &&
!VMCPU_FF_IS_SET(&_vmcpu, check_vmcpu))
@ -440,8 +441,6 @@ template <typename T> bool Sup::Vcpu_impl<T>::_continue_hw_accelerated()
if (false && VMCPU_FF_IS_SET(&_vmcpu, check_vmcpu)) {
log("VMCPU_FF=", Hex(_vmcpu.fLocalForcedActions));
VERBOSE_VMCPU(VMCPU_FF_TO_R3);
/* when this flag gets set, a pause request follows
VERBOSE_VMCPU(VMCPU_FF_TIMER); */
VERBOSE_VMCPU(VMCPU_FF_PDM_CRITSECT);
VERBOSE_VMCPU(VMCPU_FF_PGM_SYNC_CR3);
VERBOSE_VMCPU(VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
@ -498,9 +497,6 @@ typename Sup::Vcpu_impl<T>::Current_state Sup::Vcpu_impl<T>::_handle_paused()
Assert(state.intr_state.value() == VMX_VMCS_GUEST_INT_STATE_NONE);
if (!_continue_hw_accelerated())
warning("unexpected pause exit");
/*
* We got a pause exit during IRQ injection and the guest is ready for
* IRQ injection. So, just continue running the vCPU.