vbox: 'poke' fixes

Fixes #1364
This commit is contained in:
Christian Prochaska 2015-01-13 20:02:10 +01:00 committed by Christian Helmuth
parent 336018b493
commit 50950ec248
5 changed files with 41 additions and 22 deletions

View File

@ -1 +1 @@
463f5e20b98e410d23d633b4f4ce20c2eafa3cc1
2f00ccc22f68eb6aa656e721e4bc82a9c5e25093

View File

@ -9,7 +9,7 @@ DIR(virtualbox) := src/app/virtualbox
SHA(virtualbox) := e4c23b713e8715b8e0172fa066f2197756e901fe
PATCHES_LIST := acpi_drv dev_e1000 eminternal fake_pci_vendor iconv mouse
PATCHES_LIST += pdm_driver pdm_queue_irqs sharedfolder_pagelist timer
PATCHES_LIST += pdm_driver poke sharedfolder_pagelist
PATCHES_LIST += time-log-deadlock vbox_inc vbox_main network
PATCHES_LIST += vga_fb vga_vbva vmdk vmmdev avoid_yield serial

View File

@ -1,10 +0,0 @@
+++ src/app/virtualbox/src/VBox/VMM/VMMAll/PDMAllQueue.cpp
@@ -106,7 +106,7 @@
# ifdef VBOX_WITH_REM
REMR3NotifyQueuePending(pVM); /** @todo r=bird: we can remove REMR3NotifyQueuePending and let VMR3NotifyFF do the work. */
# endif
- VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
+ VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
#endif
}
STAM_REL_COUNTER_INC(&pQueue->StatInsert);

View File

@ -0,0 +1,39 @@
+++ src/app/virtualbox/src/VBox/VMM/VMMR3/VMEmt.cpp
@@ -804,6 +804,20 @@ static DECLCALLBACK(int) vmR3HaltGlobal1Wait(PUVMCPU pUVCpu)
*/
static DECLCALLBACK(void) vmR3HaltGlobal1NotifyCpuFF(PUVMCPU pUVCpu, uint32_t fFlags)
{
+ /*
+ * On Linux, an 'external interrupt' VM exit occurs on a regular basis, so
+ * it is not always necessary (or does not matter much if forgotten) to
+ * pass the 'VMNOTIFYFF_FLAGS_POKE' flag to this function. On Genode,
+ * however, VirtualBox does not get these regular VM exits, so we need to
+ * make sure that the EMT thread is actively woken up if needed. We know
+ * for sure that poking is needed for the correct delivery of timer and
+ * input interrupts, but there are some more places where the function is
+ * called without the 'poke' flag and we do not know for sure if this is
+ * correct. So, to be on the safe side, we let the function act as if the
+ * 'poke' flag is always set.
+ */
+ fFlags |= VMNOTIFYFF_FLAGS_POKE;
+
if (pUVCpu->vm.s.fWait)
{
int rc = SUPR3CallVMMR0Ex(pUVCpu->pVM->pVMR0, pUVCpu->idCpu, VMMR0_DO_GVMM_SCHED_WAKE_UP, 0, NULL);
@@ -814,7 +828,15 @@ static DECLCALLBACK(void) vmR3HaltGlobal1NotifyCpuFF(PUVMCPU pUVCpu, uint32_t fF
&& pUVCpu->pVCpu)
{
VMCPUSTATE enmState = VMCPU_GET_STATE(pUVCpu->pVCpu);
- if (enmState == VMCPUSTATE_STARTED_EXEC)
+ /*
+ * It can happen that the EMT thread has already handled the
+ * Forced Actions, but not switched to the 'EXEC' state yet when a
+ * worker thread adds new Forced Actions and calls this function. So,
+ * we 'poke' the EMT thread in the 'STARTED' state, too, to make sure
+ * that it will be woken up again to handle the new work.
+ */
+ if ((enmState == VMCPUSTATE_STARTED_EXEC) ||
+ (enmState == VMCPUSTATE_STARTED))
{
if (fFlags & VMNOTIFYFF_FLAGS_POKE)
{

View File

@ -1,10 +0,0 @@
+++ src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp
@@ -1901,7 +1901,7 @@
#ifdef VBOX_WITH_REM
REMR3NotifyTimerPending(pVM, pVCpuDst);
#endif
- VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM /** @todo | VMNOTIFYFF_FLAGS_POKE ?*/);
+ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
STAM_COUNTER_INC(&pVM->tm.s.StatTimerCallbackSetFF);
}
}