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)
|
if (exit_reason != VM_EXIT_RECALL || !previous_blocked)
|
||||||
_read_nova_state(utcb, state, exit_reason);
|
_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 (exit_reason == VM_EXIT_RECALL) {
|
||||||
if (previous_blocked)
|
if (previous_blocked)
|
||||||
state.exit_reason = exit_reason;
|
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) {
|
if (vcpu->_remote == PAUSE) {
|
||||||
vcpu->_remote = NONE;
|
vcpu->_remote = NONE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -550,8 +550,13 @@ struct Vcpu {
|
||||||
|
|
||||||
if (_dispatching == current) {
|
if (_dispatching == current) {
|
||||||
/* current thread is already dispatching */
|
/* current thread is already dispatching */
|
||||||
_block = true;
|
if (_block)
|
||||||
return;
|
/* issue pause exit next time - fall through */
|
||||||
|
_block = false;
|
||||||
|
else {
|
||||||
|
_block = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_ep_handler == current) && _block) {
|
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) {
|
} catch (Genode::Vm_session::Region_conflict) {
|
||||||
/* XXX PGMUnmapMemoryGenode on vm_session does not flush caps */
|
/* XXX PGMUnmapMemoryGenode on vm_session does not flush caps */
|
||||||
vm_session.detach(GCPhys, mapping_size);
|
vm_session.detach(GCPhys, mapping_size);
|
||||||
|
|
||||||
if (retry) {
|
if (retry) {
|
||||||
Genode::error("region conflict - ", Genode::Hex(GCPhys),
|
Genode::log("region conflict - ", Genode::Hex(GCPhys),
|
||||||
" ", Genode::Hex(mapping_size), " vmm_local=",
|
" ", Genode::Hex(mapping_size), " vmm_local=",
|
||||||
Genode::Hex(vmm_local), " ", region->cap,
|
Genode::Hex(vmm_local), " ", region->cap,
|
||||||
" region=", Genode::Hex(region->vmm_local),
|
" region=", Genode::Hex(region->vmm_local),
|
||||||
"+", Genode::Hex(region->size));
|
"+", 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;
|
return VERR_PGM_DYNMAP_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -863,8 +869,6 @@ class Pgm_guard
|
||||||
int Vcpu_handler::map_memory(Genode::Vm_connection &vm_session,
|
int Vcpu_handler::map_memory(Genode::Vm_connection &vm_session,
|
||||||
RTGCPHYS const GCPhys, RTGCUINT vbox_fault_reason)
|
RTGCPHYS const GCPhys, RTGCUINT vbox_fault_reason)
|
||||||
{
|
{
|
||||||
Pgm_guard guard(*_vm);
|
|
||||||
|
|
||||||
_ept_fault_addr_type = PGMPAGETYPE_INVALID;
|
_ept_fault_addr_type = PGMPAGETYPE_INVALID;
|
||||||
|
|
||||||
PPGMRAMRANGE const pRam = pgmPhysGetRangeAtOrAbove(_vm, GCPhys);
|
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_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage)
|
||||||
&& PGM_A20_IS_ENABLED(_vcpu))
|
&& PGM_A20_IS_ENABLED(_vcpu))
|
||||||
{
|
{
|
||||||
|
Pgm_guard guard(*_vm);
|
||||||
pgmPhysPageMakeWritable(_vm, pPage, GCPhys);
|
pgmPhysPageMakeWritable(_vm, pPage, GCPhys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -296,3 +296,10 @@ extern "C" long pathconf(char const *path, int name)
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" int siginterrupt(int, int)
|
||||||
|
{
|
||||||
|
Genode::Thread * thread = Genode::Thread::myself();
|
||||||
|
Genode::warning(__func__, " called, caller=", thread ? thread->name() : "");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
rem_tss.patch
|
||||||
mem_leak.patch
|
mem_leak.patch
|
||||||
rem_mem.patch
|
rem_mem.patch
|
||||||
|
vga.patch
|
||||||
|
register.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();
|
||||||
|
|
||||||
|
/*
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode */
|
/* Genode */
|
||||||
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
#include <cpu_session/connection.h>
|
#include <cpu_session/connection.h>
|
||||||
|
@ -31,12 +32,25 @@
|
||||||
/* vbox */
|
/* vbox */
|
||||||
#include <internal/thread.h>
|
#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)
|
static long prio_class(RTTHREADTYPE const type)
|
||||||
{
|
{
|
||||||
unsigned const VIRTUAL_GENODE_VBOX_LEVELS = 16;
|
unsigned const VIRTUAL_GENODE_VBOX_LEVELS = 16;
|
||||||
static_assert (RTTHREADTYPE_END < VIRTUAL_GENODE_VBOX_LEVELS,
|
static_assert (RTTHREADTYPE_END < VIRTUAL_GENODE_VBOX_LEVELS,
|
||||||
"prio levels exceeds 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) *
|
return (VIRTUAL_GENODE_VBOX_LEVELS - type) *
|
||||||
Genode::Cpu_session::PRIORITY_LIMIT / VIRTUAL_GENODE_VBOX_LEVELS;
|
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 "
|
log("Upgrading memory for creation of "
|
||||||
"thread '", Cstring(rtthread->szName), "'");
|
"thread '", Cstring(rtthread->szName), "'");
|
||||||
cpu_connection(rtthread->enmType)->upgrade_ram(4096);
|
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; }
|
catch (...) { break; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <util/flex_iterator.h>
|
|
||||||
#include <util/touch.h>
|
|
||||||
#include <rom_session/connection.h>
|
#include <rom_session/connection.h>
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
#include <vm_session/connection.h>
|
#include <vm_session/connection.h>
|
||||||
|
@ -45,13 +43,8 @@
|
||||||
/* Genode libc pthread binding */
|
/* Genode libc pthread binding */
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
/* LibC includes */
|
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
#include <VBox/vmm/rem.h>
|
#include <VBox/vmm/rem.h>
|
||||||
|
|
||||||
static bool debug_map_memory = false;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VirtualBox stores segment attributes in Intel format using a 32-bit
|
* VirtualBox stores segment attributes in Intel format using a 32-bit
|
||||||
* value. Genode represents the attributes in packed format using a 16-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);
|
return (v & 0xff) | (((uint32_t )v << 4) & 0x1f000);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Vcpu_sync
|
class Vcpu_handler : public Genode::List<Vcpu_handler>::Element
|
||||||
{
|
|
||||||
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>
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Genode::Entrypoint _ep;
|
Genode::Entrypoint _ep;
|
||||||
Genode::Lock _lock;
|
Genode::Lock _lock_emt;
|
||||||
|
Genode::Semaphore _sem_handler;
|
||||||
Genode::Vm_state *_state { nullptr };
|
Genode::Vm_state *_state { nullptr };
|
||||||
|
|
||||||
/* halt / wakeup handling with timeout support */
|
/* halt / wakeup handling with timeout support */
|
||||||
|
@ -106,9 +81,8 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element,
|
||||||
bool npt_ept_unmap { false };
|
bool npt_ept_unmap { false };
|
||||||
|
|
||||||
/* state machine between EMT and EP thread of a vCPU */
|
/* state machine between EMT and EP thread of a vCPU */
|
||||||
enum State { RUNNING, PAUSED, IRQ_WIN, NPT_EPT } _vm_state { PAUSED };
|
enum { RUNNING, PAUSED, IRQ_WIN, NPT_EPT } _vm_state { PAUSED };
|
||||||
|
enum { PAUSE_EXIT, RUN } _next_state { RUN };
|
||||||
Vcpu_sync::Client _ep_emt;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -171,10 +145,17 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element,
|
||||||
Genode::memcpy(fpu, pCtx->pXStateR3, sizeof(X86FXSTATE));
|
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 */
|
/* 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 */
|
/* write FPU state of vCPU to pCtx */
|
||||||
_state->fpu.value([&] (uint8_t *fpu, size_t const size) {
|
_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) {
|
if (npt_ept_unmap) {
|
||||||
Genode::error("NPT/EPT unmap not supported - stop");
|
Genode::error("NPT/EPT unmap not supported - stop");
|
||||||
while (true) {
|
while (true) {
|
||||||
_lock.lock();
|
_lock_emt.lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,10 +204,10 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element,
|
||||||
|
|
||||||
_vm_state = PAUSED;
|
_vm_state = PAUSED;
|
||||||
|
|
||||||
_lock.unlock();
|
_lock_emt.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _recall_handler()
|
bool _recall_handler()
|
||||||
{
|
{
|
||||||
if (_vm_state != RUNNING)
|
if (_vm_state != RUNNING)
|
||||||
Genode::error(__func__, " _vm_state=", (int)_vm_state, " exit_reason=", Genode::Hex(_state->exit_reason));
|
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
|
/* got recall during irq injection and the guest is ready for
|
||||||
* delivery of IRQ - just continue */
|
* delivery of IRQ - just continue */
|
||||||
run_vm();
|
return /* no-wait */ false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* are we forced to go back to emulation mode ? */
|
/* are we forced to go back to emulation mode ? */
|
||||||
if (!continue_hw_accelerated()) {
|
if (!continue_hw_accelerated()) {
|
||||||
/* go back to emulation mode */
|
/* go back to emulation mode */
|
||||||
_default_handler();
|
_default_handler();
|
||||||
return;
|
return /* wait */ true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether we have to request irq injection window */
|
/* 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 = Genode::Vm_state {}; /* reset */
|
||||||
_state->inj_info.value(_state->inj_info.value());
|
_state->inj_info.value(_state->inj_info.value());
|
||||||
_irq_win = true;
|
_irq_win = true;
|
||||||
run_vm();
|
return /* no-wait */ false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_default_handler();
|
_default_handler();
|
||||||
return;
|
return /* wait */ true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool vbox_to_state(VM *pVM, PVMCPU pVCpu)
|
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_exits ++;
|
||||||
|
|
||||||
_vm_state = IRQ_WIN;
|
_vm_state = IRQ_WIN;
|
||||||
_lock.unlock();
|
_lock_emt.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _npt_ept()
|
void _npt_ept()
|
||||||
|
@ -512,7 +491,7 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element,
|
||||||
_vm_exits ++;
|
_vm_exits ++;
|
||||||
|
|
||||||
_vm_state = NPT_EPT;
|
_vm_state = NPT_EPT;
|
||||||
_lock.unlock();
|
_lock_emt.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _irq_window_pthread()
|
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 bool hw_save_state(Genode::Vm_state *, VM *, PVMCPU) = 0;
|
||||||
virtual int vm_exit_requires_instruction_emulation(PCPUMCTX) = 0;
|
virtual int vm_exit_requires_instruction_emulation(PCPUMCTX) = 0;
|
||||||
|
|
||||||
virtual void run_vm() = 0;
|
|
||||||
virtual void pause_vm() = 0;
|
virtual void pause_vm() = 0;
|
||||||
virtual int attach_memory_to_vm(RTGCPHYS const,
|
virtual int attach_memory_to_vm(RTGCPHYS const,
|
||||||
RTGCUINT vbox_fault_reason) = 0;
|
RTGCUINT vbox_fault_reason) = 0;
|
||||||
|
@ -696,35 +674,9 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element,
|
||||||
:
|
:
|
||||||
_ep(env, stack_size,
|
_ep(env, stack_size,
|
||||||
Genode::String<12>("EP-EMT-", cpu_id).string(), location),
|
Genode::String<12>("EP-EMT-", cpu_id).string(), location),
|
||||||
_ep_emt(_ep.rpc_ep().manage(this)),
|
|
||||||
_cpu_id(cpu_id)
|
_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; }
|
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])
|
if (_vm != vm || _vcpu != &vm->aCpus[_cpu_id])
|
||||||
Genode::error("wrong CPU !?");
|
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 0
|
||||||
if (_recall_req % 1000 == 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
|
* \author Alexander Boettcher
|
||||||
* \date 2013-11-18
|
* \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
|
* This file is distributed under the terms of the GNU General Public License
|
||||||
* version 2.
|
* version 2.
|
||||||
|
@ -76,14 +76,12 @@ class Vcpu_handler_svm : public Vcpu_handler
|
||||||
next_utcb.ctrl[1] = 0;
|
next_utcb.ctrl[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _svm_recall() { Vcpu_handler::_recall_handler(); }
|
|
||||||
|
|
||||||
void _handle_vm_exception()
|
void _handle_vm_exception()
|
||||||
{
|
{
|
||||||
unsigned const exit = _state->exit_reason;
|
unsigned const exit = _state->exit_reason;
|
||||||
// Genode::warning(__func__, " ", Genode::Hex(exit), " _irq_win=", _irq_win);
|
bool recall_wait = true;
|
||||||
|
|
||||||
switch (exit) {
|
switch (exit) {
|
||||||
case RECALL: _svm_recall(); break;
|
|
||||||
case SVM_EXIT_IOIO: _svm_ioio(); break;
|
case SVM_EXIT_IOIO: _svm_ioio(); break;
|
||||||
case SVM_EXIT_VINTR: _svm_vintr(); break;
|
case SVM_EXIT_VINTR: _svm_vintr(); break;
|
||||||
// case SVM_EXIT_RDTSC: _svm_default(); 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_NPT: _svm_npt<SVM_NPT>(); break;
|
||||||
case SVM_EXIT_HLT: _svm_default(); break;
|
case SVM_EXIT_HLT: _svm_default(); break;
|
||||||
case SVM_EXIT_CPUID: _svm_default(); break;
|
case SVM_EXIT_CPUID: _svm_default(); break;
|
||||||
|
case RECALL:
|
||||||
|
recall_wait = Vcpu_handler::_recall_handler();
|
||||||
|
break;
|
||||||
case VCPU_STARTUP:
|
case VCPU_STARTUP:
|
||||||
_svm_startup();
|
_svm_startup();
|
||||||
_lock.unlock();
|
_lock_emt.unlock();
|
||||||
/* pause - no resume */
|
/* pause - no resume */
|
||||||
return;
|
break;
|
||||||
default:
|
default:
|
||||||
Genode::error(__func__, " unknown exit - stop - ",
|
Genode::error(__func__, " unknown exit - stop - ",
|
||||||
Genode::Hex(exit));
|
Genode::Hex(exit));
|
||||||
_vm_state = PAUSED;
|
_vm_state = PAUSED;
|
||||||
return;
|
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); }
|
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>();
|
_state = _state_ds.local_addr<Genode::Vm_state>();
|
||||||
|
|
||||||
/* sync with initial startup exception */
|
/* sync with initial startup exception */
|
||||||
_lock.lock();
|
_lock_emt.lock();
|
||||||
|
|
||||||
_vm_session.run(_vcpu);
|
_vm_session.run(_vcpu);
|
||||||
|
|
||||||
/* sync with initial startup exception */
|
/* sync with initial startup exception */
|
||||||
_lock.lock();
|
_lock_emt.lock();
|
||||||
// _lock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hw_save_state(Genode::Vm_state *state, VM * pVM, PVMCPU pVCpu) {
|
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 Alexander Boettcher
|
||||||
* \author Norman Feske
|
* \author Norman Feske
|
||||||
* \author Christian Helmuth
|
* \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
|
* This file is distributed under the terms of the GNU General Public License
|
||||||
* version 2.
|
* version 2.
|
||||||
|
@ -106,8 +106,6 @@ class Vcpu_handler_vmx : public Vcpu_handler
|
||||||
|
|
||||||
void _vmx_irqwin() { _irq_window(); }
|
void _vmx_irqwin() { _irq_window(); }
|
||||||
|
|
||||||
void _vmx_recall() { Vcpu_handler::_recall_handler(); }
|
|
||||||
|
|
||||||
__attribute__((noreturn)) void _vmx_invalid()
|
__attribute__((noreturn)) void _vmx_invalid()
|
||||||
{
|
{
|
||||||
unsigned const dubious = _state->inj_info.value() |
|
unsigned const dubious = _state->inj_info.value() |
|
||||||
|
@ -124,19 +122,12 @@ class Vcpu_handler_vmx : public Vcpu_handler
|
||||||
exit(-1);
|
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 _vmx_mov_crx() { _default_handler(); return; }
|
||||||
|
|
||||||
void _handle_vm_exception()
|
void _handle_vm_exception()
|
||||||
{
|
{
|
||||||
unsigned const exit = _state->exit_reason;
|
unsigned const exit = _state->exit_reason;
|
||||||
|
bool recall_wait = true;
|
||||||
|
|
||||||
switch (exit) {
|
switch (exit) {
|
||||||
case VMX_EXIT_TRIPLE_FAULT: _vmx_triple(); break;
|
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_WBINVD: _vmx_default(); break;
|
||||||
case VMX_EXIT_MOV_CRX: _vmx_mov_crx(); break;
|
case VMX_EXIT_MOV_CRX: _vmx_mov_crx(); break;
|
||||||
case VMX_EXIT_MOV_DRX: _vmx_default(); 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_TPR_BELOW_THRESHOLD: _vmx_default(); break;
|
||||||
case VMX_EXIT_EPT_VIOLATION: _vmx_ept<VMX_EXIT_EPT_VIOLATION>(); 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:
|
case VCPU_STARTUP:
|
||||||
_vmx_startup();
|
_vmx_startup();
|
||||||
_lock.unlock();
|
_lock_emt.unlock();
|
||||||
/* pause - no resume */
|
/* pause - no resume */
|
||||||
return;
|
break;
|
||||||
default:
|
default:
|
||||||
Genode::error(__func__, " unknown exit - stop - ",
|
Genode::error(__func__, " unknown exit - stop - ",
|
||||||
Genode::Hex(exit));
|
Genode::Hex(exit));
|
||||||
_vm_state = PAUSED;
|
_vm_state = PAUSED;
|
||||||
return;
|
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); }
|
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_MOV_DRX:
|
||||||
case VMX_EXIT_TPR_BELOW_THRESHOLD:
|
case VMX_EXIT_TPR_BELOW_THRESHOLD:
|
||||||
case VMX_EXIT_EPT_VIOLATION:
|
case VMX_EXIT_EPT_VIOLATION:
|
||||||
|
case VMX_EXIT_XSETBV:
|
||||||
case VCPU_STARTUP:
|
case VCPU_STARTUP:
|
||||||
case RECALL:
|
case RECALL:
|
||||||
/* todo - touch all members */
|
/* todo - touch all members */
|
||||||
|
@ -235,13 +246,12 @@ class Vcpu_handler_vmx : public Vcpu_handler
|
||||||
_state = _state_ds.local_addr<Genode::Vm_state>();
|
_state = _state_ds.local_addr<Genode::Vm_state>();
|
||||||
|
|
||||||
/* sync with initial startup exception */
|
/* sync with initial startup exception */
|
||||||
_lock.lock();
|
_lock_emt.lock();
|
||||||
|
|
||||||
_vm_session.run(_vcpu);
|
_vm_session.run(_vcpu);
|
||||||
|
|
||||||
/* sync with initial startup exception */
|
/* sync with initial startup exception */
|
||||||
_lock.lock();
|
_lock_emt.lock();
|
||||||
// _lock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hw_save_state(Genode::Vm_state *state, VM * pVM, PVMCPU pVCpu) {
|
bool hw_save_state(Genode::Vm_state *state, VM * pVM, PVMCPU pVCpu) {
|
||||||
|
|
Loading…
Reference in New Issue