vbox5: adjust to run with Fiasco.OC

- use priorities solely with nova
- handle exceptions during vCPU creation
- avoid assertion in vga_vbda
- silence compiler warnings about outdated register keyword

Issue #3111
This commit is contained in:
Alexander Boettcher 2019-05-22 10:41:30 +02:00 committed by Christian Helmuth
parent 64fac6cee7
commit 7ec37b2d8d
11 changed files with 328 additions and 116 deletions

View File

@ -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) {

View File

@ -1 +1 @@
0ccf5764631d03e73d2a952391c96fe457f6f5ee
5de6eead003606684659956308561f9dffcdffba

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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++;

View File

@ -33,3 +33,5 @@ tm_4s.patch
rem_tss.patch
mem_leak.patch
rem_mem.patch
vga.patch
register.patch

View File

@ -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();
/*

View File

@ -12,6 +12,7 @@
*/
/* Genode */
#include <base/attached_rom_dataspace.h>
#include <base/log.h>
#include <base/thread.h>
#include <cpu_session/connection.h>
@ -31,12 +32,25 @@
/* vbox */
#include <internal/thread.h>
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; }
}

View File

@ -17,8 +17,6 @@
/* Genode includes */
#include <base/log.h>
#include <util/flex_iterator.h>
#include <util/touch.h>
#include <rom_session/connection.h>
#include <timer_session/connection.h>
#include <vm_session/connection.h>
@ -45,13 +43,8 @@
/* Genode libc pthread binding */
#include "thread.h"
/* LibC includes */
#include <setjmp.h>
#include <VBox/vmm/rem.h>
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<Session>
{
Client(Genode::Capability<Session> cap) : Rpc_client<Session>(cap) { }
void resume() { call<Rpc_resume>(); }
void request_pause() { call<Rpc_request_pause>(); }
};
};
class Vcpu_handler : public Genode::List<Vcpu_handler>::Element,
public Genode::Rpc_object<Vcpu_sync::Session, Vcpu_handler>
class Vcpu_handler : public Genode::List<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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<Vcpu_handler>::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) {

View File

@ -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<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<Genode::Vm_state>();
/* 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) {

View File

@ -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<VMX_EXIT_EPT_VIOLATION>(); 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<Genode::Vm_state>();
/* 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) {