mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
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:
parent
64fac6cee7
commit
7ec37b2d8d
@ -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) {
|
||||
|
@ -1 +1 @@
|
||||
0ccf5764631d03e73d2a952391c96fe457f6f5ee
|
||||
5de6eead003606684659956308561f9dffcdffba
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
159
repos/ports/src/virtualbox5/patches/register.patch
Normal file
159
repos/ports/src/virtualbox5/patches/register.patch
Normal 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++;
|
@ -33,3 +33,5 @@ tm_4s.patch
|
||||
rem_tss.patch
|
||||
mem_leak.patch
|
||||
rem_mem.patch
|
||||
vga.patch
|
||||
register.patch
|
||||
|
26
repos/ports/src/virtualbox5/patches/vga.patch
Normal file
26
repos/ports/src/virtualbox5/patches/vga.patch
Normal 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();
|
||||
|
||||
/*
|
@ -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; }
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user