diff --git a/repos/base-nova/src/lib/base/vm_session.cc b/repos/base-nova/src/lib/base/vm_session.cc
index fc1a4da3f..30daf44ca 100644
--- a/repos/base-nova/src/lib/base/vm_session.cc
+++ b/repos/base-nova/src/lib/base/vm_session.cc
@@ -473,14 +473,14 @@ struct Vcpu {
if (exit_reason != VM_EXIT_RECALL || !previous_blocked)
_read_nova_state(utcb, state, exit_reason);
- /* consume potential multiple sem ups */
- Nova::sm_ctrl(vcpu->_sm_sel(), Nova::SEMAPHORE_UP);
- Nova::sm_ctrl(vcpu->_sm_sel(), Nova::SEMAPHORE_DOWNZERO);
-
if (exit_reason == VM_EXIT_RECALL) {
if (previous_blocked)
state.exit_reason = exit_reason;
+ /* consume potential multiple sem ups */
+ Nova::sm_ctrl(vcpu->_sm_sel(), Nova::SEMAPHORE_UP);
+ Nova::sm_ctrl(vcpu->_sm_sel(), Nova::SEMAPHORE_DOWNZERO);
+
if (vcpu->_remote == PAUSE) {
vcpu->_remote = NONE;
} else {
@@ -550,8 +550,13 @@ struct Vcpu {
if (_dispatching == current) {
/* current thread is already dispatching */
- _block = true;
- return;
+ if (_block)
+ /* issue pause exit next time - fall through */
+ _block = false;
+ else {
+ _block = true;
+ return;
+ }
}
if ((_ep_handler == current) && _block) {
diff --git a/repos/ports/ports/virtualbox5.hash b/repos/ports/ports/virtualbox5.hash
index 13bfd34ec..dd486cd0f 100644
--- a/repos/ports/ports/virtualbox5.hash
+++ b/repos/ports/ports/virtualbox5.hash
@@ -1 +1 @@
-0ccf5764631d03e73d2a952391c96fe457f6f5ee
+5de6eead003606684659956308561f9dffcdffba
diff --git a/repos/ports/src/virtualbox5/generic/sup_vmm.cc b/repos/ports/src/virtualbox5/generic/sup_vmm.cc
index 06d83505f..8074d83a5 100644
--- a/repos/ports/src/virtualbox5/generic/sup_vmm.cc
+++ b/repos/ports/src/virtualbox5/generic/sup_vmm.cc
@@ -823,13 +823,19 @@ static int _map_memory(Genode::Vm_connection &vm_session,
} catch (Genode::Vm_session::Region_conflict) {
/* XXX PGMUnmapMemoryGenode on vm_session does not flush caps */
vm_session.detach(GCPhys, mapping_size);
-
if (retry) {
- Genode::error("region conflict - ", Genode::Hex(GCPhys),
- " ", Genode::Hex(mapping_size), " vmm_local=",
- Genode::Hex(vmm_local), " ", region->cap,
- " region=", Genode::Hex(region->vmm_local),
- "+", Genode::Hex(region->size));
+ Genode::log("region conflict - ", Genode::Hex(GCPhys),
+ " ", Genode::Hex(mapping_size), " vmm_local=",
+ Genode::Hex(vmm_local), " ", region->cap,
+ " region=", Genode::Hex(region->vmm_local),
+ "+", Genode::Hex(region->size));
+
+ size_t detach_size = mapping_size;
+ while (detach_size) {
+ size_t const size = 4096;
+ vm_session.detach(GCPhys + (mapping_size - detach_size), size);
+ detach_size -= detach_size > size ? size : detach_size;
+ }
return VERR_PGM_DYNMAP_FAILED;
}
@@ -863,8 +869,6 @@ class Pgm_guard
int Vcpu_handler::map_memory(Genode::Vm_connection &vm_session,
RTGCPHYS const GCPhys, RTGCUINT vbox_fault_reason)
{
- Pgm_guard guard(*_vm);
-
_ept_fault_addr_type = PGMPAGETYPE_INVALID;
PPGMRAMRANGE const pRam = pgmPhysGetRangeAtOrAbove(_vm, GCPhys);
@@ -891,6 +895,7 @@ int Vcpu_handler::map_memory(Genode::Vm_connection &vm_session,
&& !PGM_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage)
&& PGM_A20_IS_ENABLED(_vcpu))
{
+ Pgm_guard guard(*_vm);
pgmPhysPageMakeWritable(_vm, pPage, GCPhys);
}
diff --git a/repos/ports/src/virtualbox5/libc.cc b/repos/ports/src/virtualbox5/libc.cc
index f49ef596a..47689b119 100644
--- a/repos/ports/src/virtualbox5/libc.cc
+++ b/repos/ports/src/virtualbox5/libc.cc
@@ -296,3 +296,10 @@ extern "C" long pathconf(char const *path, int name)
errno = EINVAL;
return -1;
}
+
+extern "C" int siginterrupt(int, int)
+{
+ Genode::Thread * thread = Genode::Thread::myself();
+ Genode::warning(__func__, " called, caller=", thread ? thread->name() : "");
+ return 0;
+}
diff --git a/repos/ports/src/virtualbox5/patches/register.patch b/repos/ports/src/virtualbox5/patches/register.patch
new file mode 100644
index 000000000..04479ac33
--- /dev/null
+++ b/repos/ports/src/virtualbox5/patches/register.patch
@@ -0,0 +1,159 @@
+--- a/src/app/virtualbox/src/VBox/VMM/VMMAll/PGMAllGst.h
++++ b/src/app/virtualbox/src/VBox/VMM/VMMAll/PGMAllGst.h
+@@ -101,9 +101,9 @@
+ if (RT_FAILURE(rc))
+ return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 4, rc);
+
+- PX86PML4 register pPml4 = pWalk->pPml4;
+- X86PML4E register Pml4e;
+- PX86PML4E register pPml4e;
++ PX86PML4 pPml4 = pWalk->pPml4;
++ X86PML4E Pml4e;
++ PX86PML4E pPml4e;
+
+ pWalk->pPml4e = pPml4e = &pPml4->a[(GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK];
+ pWalk->Pml4e.u = Pml4e.u = pPml4e->u;
+@@ -127,9 +127,9 @@
+ }
+ {
+ # if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
+- PX86PDPT register pPdpt = pWalk->pPdpt;
+- PX86PDPE register pPdpe;
+- X86PDPE register Pdpe;
++ PX86PDPT pPdpt = pWalk->pPdpt;
++ PX86PDPE pPdpe;
++ X86PDPE Pdpe;
+
+ pWalk->pPdpe = pPdpe = &pPdpt->a[(GCPtr >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
+ pWalk->Pdpe.u = Pdpe.u = pPdpe->u;
+@@ -151,8 +151,8 @@
+ # endif
+ }
+ {
+- PGSTPD register pPd = pWalk->pPd;
+- PGSTPDE register pPde;
++ PGSTPD pPd = pWalk->pPd;
++ PGSTPDE pPde;
+ GSTPDE Pde;
+
+ pWalk->pPde = pPde = &pPd->a[(GCPtr >> GST_PD_SHIFT) & GST_PD_MASK];
+@@ -201,9 +201,9 @@
+ return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 1, rc);
+ }
+ {
+- PGSTPT register pPt = pWalk->pPt;
+- PGSTPTE register pPte;
+- GSTPTE register Pte;
++ PGSTPT pPt = pWalk->pPt;
++ PGSTPTE pPte;
++ GSTPTE Pte;
+
+ pWalk->pPte = pPte = &pPt->a[(GCPtr >> GST_PT_SHIFT) & GST_PT_MASK];
+ pWalk->Pte.u = Pte.u = pPte->u;
+--- a/src/app/virtualbox/include/iprt/log.h
++++ b/src/app/virtualbox/include/iprt/log.h
+@@ -607,7 +607,7 @@
+ # define _LogIt(a_fFlags, a_iGroup, ...) \
+ do \
+ { \
+- register PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
++ PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+ if (RT_LIKELY(!LogIt_pLogger)) \
+ { /* likely */ } \
+ else \
+@@ -621,7 +621,7 @@
+ # define LogIt(a_fFlags, a_iGroup, fmtargs) \
+ do \
+ { \
+- register PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
++ PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
+ if (RT_LIKELY(!LogIt_pLogger)) \
+ { /* likely */ } \
+ else \
+@@ -632,7 +632,7 @@
+ # define LogItAlways(a_fFlags, a_iGroup, fmtargs) \
+ do \
+ { \
+- register PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX)); \
++ PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX)); \
+ if (LogIt_pLogger) \
+ LogIt_pLogger->pfnLogger fmtargs; \
+ } while (0)
+--- a/src/app/virtualbox/src/VBox/Devices/Network/DevPCNet.cpp
++++ b/src/app/virtualbox/src/VBox/Devices/Network/DevPCNet.cpp
+@@ -1244,8 +1244,8 @@
+ */
+ static void pcnetUpdateIrq(PPCNETSTATE pThis)
+ {
+- register int iISR = 0;
+- register uint16_t csr0 = pThis->aCSR[0];
++ int iISR = 0;
++ uint16_t csr0 = pThis->aCSR[0];
+
+ csr0 &= ~0x0080; /* clear INTR */
+
+--- a/src/app/virtualbox/src/VBox/Runtime/common/table/avl_Base.cpp.h
++++ b/src/app/virtualbox/src/VBox/Runtime/common/table/avl_Base.cpp.h
+@@ -266,7 +266,7 @@
+ }
+ else
+ {
+- register unsigned char uchHeight = (unsigned char)(KMAX(uchLeftHeight, uchRightHeight) + 1);
++ unsigned char uchHeight = (unsigned char)(KMAX(uchLeftHeight, uchRightHeight) + 1);
+ if (uchHeight == pNode->uchHeight)
+ break;
+ pNode->uchHeight = uchHeight;
+@@ -300,10 +300,10 @@
+ {
+ KAVLSTACK AVLStack;
+ PPKAVLNODECORE ppCurNode = ppTree;
+- register PKAVLNODECORE pCurNode;
+- register KAVLKEY Key = pNode->Key; NOREF(Key);
++ PKAVLNODECORE pCurNode;
++ KAVLKEY Key = pNode->Key; NOREF(Key);
+ #ifdef KAVL_RANGE
+- register KAVLKEY KeyLast = pNode->KeyLast; NOREF(KeyLast);
++ KAVLKEY KeyLast = pNode->KeyLast; NOREF(KeyLast);
+ #endif
+
+ AVLStack.cEntries = 0;
+@@ -400,7 +400,7 @@
+ {
+ KAVLSTACK AVLStack;
+ PPKAVLNODECORE ppDeleteNode = ppTree;
+- register PKAVLNODECORE pDeleteNode;
++ PKAVLNODECORE pDeleteNode;
+
+ AVLStack.cEntries = 0;
+
+@@ -427,7 +427,7 @@
+ /* find the rightmost node in the left tree. */
+ const unsigned iStackEntry = AVLStack.cEntries;
+ PPKAVLNODECORE ppLeftLeast = &pDeleteNode->pLeft;
+- register PKAVLNODECORE pLeftLeast = KAVL_GET_POINTER(ppLeftLeast);
++ PKAVLNODECORE pLeftLeast = KAVL_GET_POINTER(ppLeftLeast);
+
+ while (pLeftLeast->pRight != KAVL_NULL)
+ {
+--- a/src/app/virtualbox/src/VBox/Runtime/common/string/utf-16.cpp
++++ b/src/app/virtualbox/src/VBox/Runtime/common/string/utf-16.cpp
+@@ -193,7 +193,7 @@
+ RT_EXPORT_SYMBOL(RTUtf16Len);
+
+
+-RTDECL(int) RTUtf16Cmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2)
++RTDECL(int) RTUtf16Cmp(PCRTUTF16 pwsz1, PCRTUTF16 pwsz2)
+ {
+ if (pwsz1 == pwsz2)
+ return 0;
+@@ -204,8 +204,8 @@
+
+ for (;;)
+ {
+- register RTUTF16 wcs = *pwsz1;
+- register int iDiff = wcs - *pwsz2;
++ RTUTF16 wcs = *pwsz1;
++ int iDiff = wcs - *pwsz2;
+ if (iDiff || !wcs)
+ return iDiff;
+ pwsz1++;
diff --git a/repos/ports/src/virtualbox5/patches/series b/repos/ports/src/virtualbox5/patches/series
index 3ec7c43b2..c86455b0f 100644
--- a/repos/ports/src/virtualbox5/patches/series
+++ b/repos/ports/src/virtualbox5/patches/series
@@ -33,3 +33,5 @@ tm_4s.patch
rem_tss.patch
mem_leak.patch
rem_mem.patch
+vga.patch
+register.patch
diff --git a/repos/ports/src/virtualbox5/patches/vga.patch b/repos/ports/src/virtualbox5/patches/vga.patch
new file mode 100644
index 000000000..a066abd91
--- /dev/null
+++ b/repos/ports/src/virtualbox5/patches/vga.patch
@@ -0,0 +1,26 @@
+--- a/src/app/virtualbox/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
++++ b/src/app/virtualbox/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
+@@ -2249,12 +2249,23 @@
+
+ const uint64_t u64ScreenSize = (uint64_t)screen.u32LineSize * screen.u32Height;
+
++ if (!( screen.u32StartOffset <= pView->u32ViewSize
++ && u64ScreenSize <= pView->u32MaxScreenSize
++ && screen.u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize))
++ {
++ RTLogPrintf("%s - assertion failed - u32StartOffset=%#x u32ViewSize=%#x u64ScreenSize=%#RX64 u32MaxScreenSize=%#x",
++ __func__, screen.u32StartOffset, pView->u32ViewSize, u64ScreenSize, pView->u32MaxScreenSize);
++#if 0
+ ASSERT_GUEST_LOGREL_MSG_RETURN( screen.u32StartOffset <= pView->u32ViewSize
+ && u64ScreenSize <= pView->u32MaxScreenSize
+ && screen.u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize,
+ ("u32StartOffset=%#x u32ViewSize=%#x u64ScreenSize=%#RX64 u32MaxScreenSize=%#x\n",
+ screen.u32StartOffset, pView->u32ViewSize, u64ScreenSize, pView->u32MaxScreenSize),
+ VERR_INVALID_PARAMETER);
++#endif
++ return VERR_INVALID_PARAMETER;
++ }
++
+ RT_UNTRUSTED_VALIDATED_FENCE();
+
+ /*
diff --git a/repos/ports/src/virtualbox5/thread.cc b/repos/ports/src/virtualbox5/thread.cc
index 176e23faa..67819b7e8 100644
--- a/repos/ports/src/virtualbox5/thread.cc
+++ b/repos/ports/src/virtualbox5/thread.cc
@@ -12,6 +12,7 @@
*/
/* Genode */
+#include
#include
#include
#include
@@ -31,12 +32,25 @@
/* vbox */
#include
+static bool use_priorities()
+{
+ Genode::Attached_rom_dataspace const platform(genode_env(), "platform_info");
+ Genode::Xml_node const kernel = platform.xml().sub_node("kernel");
+ return kernel.attribute_value("name", Genode::String<16>("unknown")) == "nova";
+}
+
static long prio_class(RTTHREADTYPE const type)
{
unsigned const VIRTUAL_GENODE_VBOX_LEVELS = 16;
static_assert (RTTHREADTYPE_END < VIRTUAL_GENODE_VBOX_LEVELS,
"prio levels exceeds VIRTUAL_GENODE_VBOX_LEVELS");
+ /* evaluate once */
+ static bool const priorities = use_priorities();
+
+ if (!priorities)
+ return Genode::Cpu_session::DEFAULT_PRIORITY;
+
return (VIRTUAL_GENODE_VBOX_LEVELS - type) *
Genode::Cpu_session::PRIORITY_LIMIT / VIRTUAL_GENODE_VBOX_LEVELS;
}
@@ -124,6 +138,10 @@ extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
log("Upgrading memory for creation of "
"thread '", Cstring(rtthread->szName), "'");
cpu_connection(rtthread->enmType)->upgrade_ram(4096);
+ } catch (Genode::Signal_receiver::Signal_not_pending) {
+ error("signal not pending ?");
+ } catch (Out_of_caps) {
+ error("out of caps ...");
}
catch (...) { break; }
}
diff --git a/repos/ports/src/virtualbox5/vcpu.h b/repos/ports/src/virtualbox5/vcpu.h
index 636f2c62f..8c7a4f3f1 100644
--- a/repos/ports/src/virtualbox5/vcpu.h
+++ b/repos/ports/src/virtualbox5/vcpu.h
@@ -17,8 +17,6 @@
/* Genode includes */
#include
-#include
-#include
#include
#include
#include
@@ -45,13 +43,8 @@
/* Genode libc pthread binding */
#include "thread.h"
-/* LibC includes */
-#include
-
#include
-static bool debug_map_memory = false;
-
/*
* VirtualBox stores segment attributes in Intel format using a 32-bit
* value. Genode represents the attributes in packed format using a 16-bit
@@ -68,31 +61,13 @@ static inline Genode::uint32_t sel_ar_conv_from_genode(Genode::uint16_t v)
return (v & 0xff) | (((uint32_t )v << 4) & 0x1f000);
}
-namespace Vcpu_sync
-{
- struct Session : Genode::Session
- {
- GENODE_RPC(Rpc_resume, void, resume);
- GENODE_RPC(Rpc_request_pause, void, request_pause);
- GENODE_RPC_INTERFACE(Rpc_resume, Rpc_request_pause);
- };
-
- struct Client : Genode::Rpc_client
- {
- Client(Genode::Capability cap) : Rpc_client(cap) { }
-
- void resume() { call(); }
- void request_pause() { call(); }
- };
-};
-
-class Vcpu_handler : public Genode::List::Element,
- public Genode::Rpc_object
+class Vcpu_handler : public Genode::List::Element
{
protected:
Genode::Entrypoint _ep;
- Genode::Lock _lock;
+ Genode::Lock _lock_emt;
+ Genode::Semaphore _sem_handler;
Genode::Vm_state *_state { nullptr };
/* halt / wakeup handling with timeout support */
@@ -106,9 +81,8 @@ class Vcpu_handler : public Genode::List::Element,
bool npt_ept_unmap { false };
/* state machine between EMT and EP thread of a vCPU */
- enum State { RUNNING, PAUSED, IRQ_WIN, NPT_EPT } _vm_state { PAUSED };
-
- Vcpu_sync::Client _ep_emt;
+ enum { RUNNING, PAUSED, IRQ_WIN, NPT_EPT } _vm_state { PAUSED };
+ enum { PAUSE_EXIT, RUN } _next_state { RUN };
private:
@@ -171,10 +145,17 @@ class Vcpu_handler : public Genode::List::Element,
Genode::memcpy(fpu, pCtx->pXStateR3, sizeof(X86FXSTATE));
});
- _ep_emt.resume();
+ Assert(_vm_state == IRQ_WIN || _vm_state == PAUSED || _vm_state == NPT_EPT);
+ Assert(_next_state == PAUSE_EXIT || _next_state == RUN);
+
+ /* wake up vcpu ep handler */
+ _sem_handler.up();
/* wait for next exit */
- _lock.lock();
+ _lock_emt.lock();
+
+ /* next time run - recall() may change this */
+ _next_state = RUN;
/* write FPU state of vCPU to pCtx */
_state->fpu.value([&] (uint8_t *fpu, size_t const size) {
@@ -192,7 +173,7 @@ class Vcpu_handler : public Genode::List::Element,
if (npt_ept_unmap) {
Genode::error("NPT/EPT unmap not supported - stop");
while (true) {
- _lock.lock();
+ _lock_emt.lock();
}
}
@@ -223,10 +204,10 @@ class Vcpu_handler : public Genode::List::Element,
_vm_state = PAUSED;
- _lock.unlock();
+ _lock_emt.unlock();
}
- void _recall_handler()
+ bool _recall_handler()
{
if (_vm_state != RUNNING)
Genode::error(__func__, " _vm_state=", (int)_vm_state, " exit_reason=", Genode::Hex(_state->exit_reason));
@@ -252,15 +233,14 @@ class Vcpu_handler : public Genode::List::Element,
/* got recall during irq injection and the guest is ready for
* delivery of IRQ - just continue */
- run_vm();
- return;
+ return /* no-wait */ false;
}
/* are we forced to go back to emulation mode ? */
if (!continue_hw_accelerated()) {
/* go back to emulation mode */
_default_handler();
- return;
+ return /* wait */ true;
}
/* check whether we have to request irq injection window */
@@ -268,12 +248,11 @@ class Vcpu_handler : public Genode::List::Element,
*_state = Genode::Vm_state {}; /* reset */
_state->inj_info.value(_state->inj_info.value());
_irq_win = true;
- run_vm();
- return;
+ return /* no-wait */ false;
}
_default_handler();
- return;
+ return /* wait */ true;
}
inline bool vbox_to_state(VM *pVM, PVMCPU pVCpu)
@@ -500,7 +479,7 @@ class Vcpu_handler : public Genode::List::Element,
_vm_exits ++;
_vm_state = IRQ_WIN;
- _lock.unlock();
+ _lock_emt.unlock();
}
void _npt_ept()
@@ -512,7 +491,7 @@ class Vcpu_handler : public Genode::List::Element,
_vm_exits ++;
_vm_state = NPT_EPT;
- _lock.unlock();
+ _lock_emt.unlock();
}
void _irq_window_pthread()
@@ -672,7 +651,6 @@ class Vcpu_handler : public Genode::List::Element,
virtual bool hw_save_state(Genode::Vm_state *, VM *, PVMCPU) = 0;
virtual int vm_exit_requires_instruction_emulation(PCPUMCTX) = 0;
- virtual void run_vm() = 0;
virtual void pause_vm() = 0;
virtual int attach_memory_to_vm(RTGCPHYS const,
RTGCUINT vbox_fault_reason) = 0;
@@ -696,35 +674,9 @@ class Vcpu_handler : public Genode::List::Element,
:
_ep(env, stack_size,
Genode::String<12>("EP-EMT-", cpu_id).string(), location),
- _ep_emt(_ep.rpc_ep().manage(this)),
_cpu_id(cpu_id)
{ }
- void resume()
- {
- PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(_vcpu);
-
- Assert(_vm_state == IRQ_WIN || _vm_state == PAUSED || _vm_state == NPT_EPT);
-
- _vm_state = RUNNING;
- run_vm();
- }
-
- void request_pause()
- {
- _recall_req ++;
-
- if (_irq_win) {
- _recall_skip ++;
- return;
- }
-
- if (_vm_state != RUNNING)
- return;
-
- pause_vm();
- }
-
unsigned int cpu_id() { return _cpu_id; }
@@ -738,7 +690,19 @@ class Vcpu_handler : public Genode::List::Element,
if (_vm != vm || _vcpu != &vm->aCpus[_cpu_id])
Genode::error("wrong CPU !?");
- _ep_emt.request_pause();
+ _recall_req ++;
+
+ if (_irq_win) {
+ _recall_skip ++;
+ return;
+ }
+
+ asm volatile ("":::"memory");
+
+ if (_vm_state != PAUSED)
+ pause_vm();
+
+ _next_state = PAUSE_EXIT;
#if 0
if (_recall_req % 1000 == 0) {
diff --git a/repos/ports/src/virtualbox5/vcpu_svm.h b/repos/ports/src/virtualbox5/vcpu_svm.h
index 3a9e1ff5e..4d5f66c83 100644
--- a/repos/ports/src/virtualbox5/vcpu_svm.h
+++ b/repos/ports/src/virtualbox5/vcpu_svm.h
@@ -1,11 +1,11 @@
/*
- * \brief Genode/Nova specific VirtualBox SUPLib supplements
+ * \brief Genode specific VirtualBox SUPLib supplements
* \author Alexander Boettcher
* \date 2013-11-18
*/
/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
+ * Copyright (C) 2013-2019 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
@@ -76,14 +76,12 @@ class Vcpu_handler_svm : public Vcpu_handler
next_utcb.ctrl[1] = 0;
}
- void _svm_recall() { Vcpu_handler::_recall_handler(); }
-
void _handle_vm_exception()
{
unsigned const exit = _state->exit_reason;
-// Genode::warning(__func__, " ", Genode::Hex(exit), " _irq_win=", _irq_win);
+ bool recall_wait = true;
+
switch (exit) {
- case RECALL: _svm_recall(); break;
case SVM_EXIT_IOIO: _svm_ioio(); break;
case SVM_EXIT_VINTR: _svm_vintr(); break;
// case SVM_EXIT_RDTSC: _svm_default(); break;
@@ -91,17 +89,36 @@ class Vcpu_handler_svm : public Vcpu_handler
case SVM_NPT: _svm_npt(); break;
case SVM_EXIT_HLT: _svm_default(); break;
case SVM_EXIT_CPUID: _svm_default(); break;
+ case RECALL:
+ recall_wait = Vcpu_handler::_recall_handler();
+ break;
case VCPU_STARTUP:
_svm_startup();
- _lock.unlock();
+ _lock_emt.unlock();
/* pause - no resume */
- return;
+ break;
default:
Genode::error(__func__, " unknown exit - stop - ",
Genode::Hex(exit));
_vm_state = PAUSED;
return;
}
+
+ if (exit == RECALL && !recall_wait) {
+ _vm_state = RUNNING;
+ run_vm();
+ return;
+ }
+
+ /* wait until EMT thread wake's us up */
+ _sem_handler.down();
+
+ /* resume vCPU */
+ _vm_state = RUNNING;
+ if (_next_state == RUN)
+ run_vm();
+ else
+ pause_vm(); /* cause pause exit */
}
void run_vm() { _vm_session.run(_vcpu); }
@@ -154,13 +171,12 @@ class Vcpu_handler_svm : public Vcpu_handler
_state = _state_ds.local_addr();
/* sync with initial startup exception */
- _lock.lock();
+ _lock_emt.lock();
_vm_session.run(_vcpu);
/* sync with initial startup exception */
- _lock.lock();
-// _lock.unlock();
+ _lock_emt.lock();
}
bool hw_save_state(Genode::Vm_state *state, VM * pVM, PVMCPU pVCpu) {
diff --git a/repos/ports/src/virtualbox5/vcpu_vmx.h b/repos/ports/src/virtualbox5/vcpu_vmx.h
index 030f98750..fe686f04b 100644
--- a/repos/ports/src/virtualbox5/vcpu_vmx.h
+++ b/repos/ports/src/virtualbox5/vcpu_vmx.h
@@ -1,12 +1,12 @@
/*
- * \brief Genode/Nova specific VirtualBox SUPLib supplements
+ * \brief Genode specific VirtualBox SUPLib supplements
* \author Alexander Boettcher
* \author Norman Feske
* \author Christian Helmuth
*/
/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
+ * Copyright (C) 2013-2019 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
@@ -106,8 +106,6 @@ class Vcpu_handler_vmx : public Vcpu_handler
void _vmx_irqwin() { _irq_window(); }
- void _vmx_recall() { Vcpu_handler::_recall_handler(); }
-
__attribute__((noreturn)) void _vmx_invalid()
{
unsigned const dubious = _state->inj_info.value() |
@@ -124,19 +122,12 @@ class Vcpu_handler_vmx : public Vcpu_handler
exit(-1);
}
- /*
- * This VM exit is in part handled by the NOVA kernel (writing the CR
- * register) and in part by VirtualBox (updating the PDPTE registers,
- * which requires access to the guest physical memory).
- * Intel manual sections 4.4.1 of Vol. 3A and 26.3.2.4 of Vol. 3C
- * indicate the conditions when the PDPTE registers need to get
- * updated.
- */
void _vmx_mov_crx() { _default_handler(); return; }
void _handle_vm_exception()
{
unsigned const exit = _state->exit_reason;
+ bool recall_wait = true;
switch (exit) {
case VMX_EXIT_TRIPLE_FAULT: _vmx_triple(); break;
@@ -157,20 +148,39 @@ class Vcpu_handler_vmx : public Vcpu_handler
case VMX_EXIT_WBINVD: _vmx_default(); break;
case VMX_EXIT_MOV_CRX: _vmx_mov_crx(); break;
case VMX_EXIT_MOV_DRX: _vmx_default(); break;
+ case VMX_EXIT_XSETBV: _vmx_default(); break;
case VMX_EXIT_TPR_BELOW_THRESHOLD: _vmx_default(); break;
case VMX_EXIT_EPT_VIOLATION: _vmx_ept(); break;
- case RECALL: _vmx_recall(); break;
+ case RECALL:
+ recall_wait = Vcpu_handler::_recall_handler();
+ break;
case VCPU_STARTUP:
_vmx_startup();
- _lock.unlock();
+ _lock_emt.unlock();
/* pause - no resume */
- return;
+ break;
default:
Genode::error(__func__, " unknown exit - stop - ",
Genode::Hex(exit));
_vm_state = PAUSED;
return;
}
+
+ if (exit == RECALL && !recall_wait) {
+ _vm_state = RUNNING;
+ run_vm();
+ return;
+ }
+
+ /* wait until EMT thread wake's us up */
+ _sem_handler.down();
+
+ /* resume vCPU */
+ _vm_state = RUNNING;
+ if (_next_state == RUN)
+ run_vm();
+ else
+ pause_vm(); /* cause pause exit */
}
void run_vm() { _vm_session.run(_vcpu); }
@@ -204,6 +214,7 @@ class Vcpu_handler_vmx : public Vcpu_handler
case VMX_EXIT_MOV_DRX:
case VMX_EXIT_TPR_BELOW_THRESHOLD:
case VMX_EXIT_EPT_VIOLATION:
+ case VMX_EXIT_XSETBV:
case VCPU_STARTUP:
case RECALL:
/* todo - touch all members */
@@ -235,13 +246,12 @@ class Vcpu_handler_vmx : public Vcpu_handler
_state = _state_ds.local_addr();
/* sync with initial startup exception */
- _lock.lock();
+ _lock_emt.lock();
_vm_session.run(_vcpu);
/* sync with initial startup exception */
- _lock.lock();
-// _lock.unlock();
+ _lock_emt.lock();
}
bool hw_save_state(Genode::Vm_state *state, VM * pVM, PVMCPU pVCpu) {