diff --git a/repos/ports/run/test.vbox b/repos/ports/run/test.vbox
index 73d0fff2c1..51a1c70aa7 100644
--- a/repos/ports/run/test.vbox
+++ b/repos/ports/run/test.vbox
@@ -23,7 +23,7 @@
-
+
diff --git a/repos/ports/src/virtualbox/hm.cc b/repos/ports/src/virtualbox/hm.cc
index 4b7215a117..34248d5367 100644
--- a/repos/ports/src/virtualbox/hm.cc
+++ b/repos/ports/src/virtualbox/hm.cc
@@ -23,11 +23,23 @@
#include "sup.h"
-static bool enabled = true;
-
+static bool enabled_hm = true;
+static bool enable_pae_nx = false;
VMMR3DECL(int) HMR3Init(PVM pVM)
{
+ PCFGMNODE pCfgHM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "HM/");
+
+ /* check whether to stay for non-paged modi in recompiler */
+ int rc = CFGMR3QueryBoolDef(pCfgHM, "EnableUX",
+ &pVM->hm.s.vmx.fAllowUnrestricted, true);
+ AssertRCReturn(rc, rc);
+
+ /* check whether to enable pae and nx bit - in 64bit host mode */
+ rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "EnablePAE", &enable_pae_nx,
+ false);
+ AssertRCReturn(rc, rc);
+
/*
* We always set the fHMEnabled flag. Otherwise, the EM won't
* consult us for taking scheduling decisions. The actual switch to
@@ -53,15 +65,21 @@ VMMR3_INT_DECL(int) HMR3Term(PVM pVM)
VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
{
- enabled = pVM->hm.s.svm.fSupported || pVM->hm.s.vmx.fSupported;
+ enabled_hm = pVM->hm.s.svm.fSupported || pVM->hm.s.vmx.fSupported;
- if (!enabled || enmWhat != VMINITCOMPLETED_RING0)
+ if (!enabled_hm || enmWhat != VMINITCOMPLETED_RING0)
return VINF_SUCCESS;
int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HM_SETUP_VM, 0, NULL);
if (rc == VINF_SUCCESS) {
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
+
+ /* nova kernel supports solely on 64bit the following features */
+ if (sizeof(void *) > 4 && enable_pae_nx) {
+ CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
+ CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
+ }
}
return rc;
@@ -94,16 +112,10 @@ VMM_INT_DECL(bool) HMIsLongModeAllowed(PVM pVM)
VMMR3DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx)
{
- /* no re-schedule on AMD-V required - just works */
-/*
- if (pVM->hm.s.svm.fSupported)
+ if (pVM->hm.s.vmx.fAllowUnrestricted)
return false;
-*/
- bool reschedule = !CPUMIsGuestInPagedProtectedModeEx(pCtx);
-// PLOG("reschedule %u %u %lx", reschedule, HMR3CanExecuteGuest(pVM, pCtx), pCtx->cr0);
-
- return reschedule;
+ return !CPUMIsGuestInPagedProtectedModeEx(pCtx);
}
@@ -116,30 +128,19 @@ VMMR3DECL(bool) HMR3IsEventPending(PVMCPU pVCpu)
VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx)
{
- PVMCPU pVCpu = VMMGetCpu(pVM);
-
- /* AMD-V just works */
-/*
- if (pVM->hm.s.svm.fSupported) {
- pVCpu->hm.s.fActive = true;
- return true;
- }
-*/
- if (!enabled)
+ if (!enabled_hm)
return false;
- /* enable H/W acceleration in protected mode only */
- bool res = (pCtx->cr0 & 1) && (pCtx->cr0 & 0x80000000);
-/*
- static bool on = false;
+ PVMCPU pVCpu = VMMGetCpu(pVM);
- if (res)
- on = true;
+ if (pVM->hm.s.vmx.fAllowUnrestricted) {
+ pVCpu->hm.s.fActive = true;
+ } else
+ /* enable H/W acceleration in protected and paged mode only */
+ pVCpu->hm.s.fActive = CPUMIsGuestInPagedProtectedModeEx(pCtx);
- if (on)
- PLOG("executeguest %lx -> %x", pCtx->cr0, res);
-*/
- pVCpu->hm.s.fActive = res;
-
- return res;
+ return pVCpu->hm.s.fActive;
}
+
+
+VMM_INT_DECL(int) HMFlushTLB(PVMCPU pVCpu) { return VINF_SUCCESS; }
diff --git a/repos/ports/src/virtualbox/libc.cc b/repos/ports/src/virtualbox/libc.cc
index 0d1019ff42..13e34d148c 100644
--- a/repos/ports/src/virtualbox/libc.cc
+++ b/repos/ports/src/virtualbox/libc.cc
@@ -111,6 +111,7 @@ extern "C" char *getenv(const char *name)
// "+rem_run.e.l.f"
// "+pgm.e.l.f"
"+pdm"
+// "+cpum.e.l.f"
// "+dev_pcnet.e.l.f"
// "+dev_pic.e.l.f"
// "+dev_apic.e.l.f"
diff --git a/repos/ports/src/virtualbox/nova/vcpu.h b/repos/ports/src/virtualbox/nova/vcpu.h
index 2fd8b4ecff..a08c9b98ed 100644
--- a/repos/ports/src/virtualbox/nova/vcpu.h
+++ b/repos/ports/src/virtualbox/nova/vcpu.h
@@ -350,6 +350,9 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher
utcb->gdtr.limit = pCtx->gdtr.cbGdt;
utcb->gdtr.base = pCtx->gdtr.pGdt;
+ utcb->mtd |= Mtd::EFER;
+ utcb->write_efer(CPUMGetGuestEFER(pVCpu));
+
Assert(!(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)));
return true;
@@ -392,6 +395,8 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher
pCtx->gdtr.pGdt != utcb->gdtr.base)
CPUMSetGuestGDTR(pVCpu, utcb->gdtr.base, utcb->gdtr.limit);
+ CPUMSetGuestEFER(pVCpu, utcb->read_efer());
+
if (pCtx->cr0 != utcb->cr0)
CPUMSetGuestCR0(pVCpu, utcb->cr0);
diff --git a/repos/ports/src/virtualbox/nova/vcpu_svm.h b/repos/ports/src/virtualbox/nova/vcpu_svm.h
index 1a14d0b1c9..29012b05e2 100644
--- a/repos/ports/src/virtualbox/nova/vcpu_svm.h
+++ b/repos/ports/src/virtualbox/nova/vcpu_svm.h
@@ -34,7 +34,7 @@ class Vcpu_handler_svm : public Vcpu_handler
if (utcb->qual[0] & 0x4) {
unsigned ctrl0 = utcb->ctrl[0];
- PERR("invalid gueststate");
+ Vmm::printf("invalid gueststate\n");
utcb->ctrl[0] = ctrl0;
utcb->ctrl[1] = 0;
diff --git a/repos/ports/src/virtualbox/nova/vcpu_vmx.h b/repos/ports/src/virtualbox/nova/vcpu_vmx.h
index a31c62d6b4..6a07bab39e 100644
--- a/repos/ports/src/virtualbox/nova/vcpu_vmx.h
+++ b/repos/ports/src/virtualbox/nova/vcpu_vmx.h
@@ -135,6 +135,8 @@ class Vcpu_handler_vmx : public Vcpu_handler
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
register_handler (exc_base, Mtd::ALL | Mtd::FPU);
+ register_handler (exc_base, Mtd::ALL | Mtd::FPU);
register_handler (exc_base, Mtd::ALL | Mtd::FPU);
register_handlertr.Attr.u & X86_SEL_TYPE_SYS_TSS_BUSY_MASK);
- Assert(!CPUMIsGuestInRealModeEx(pCtx));
-
{
utcb->mtd |= Nova::Mtd::TR;
diff --git a/repos/ports/src/virtualbox/pgm.cc b/repos/ports/src/virtualbox/pgm.cc
index 020c14acf9..282654b1aa 100644
--- a/repos/ports/src/virtualbox/pgm.cc
+++ b/repos/ports/src/virtualbox/pgm.cc
@@ -521,7 +521,8 @@ bool PGMPhysIsA20Enabled(PVMCPU pVCpu)
}
-void PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t value)
+template
+static void PGMR3PhysWrite(PVM pVM, RTGCPHYS GCPhys, T value)
{
VM_ASSERT_EMT(pVM);
@@ -536,62 +537,41 @@ void PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t value)
(Genode::uint64_t)GCPhys);
return;
}
- void * pvx = vmm_memory()->lookup(GCPhys, sizeof(value));
- Assert(!pvx);
- *reinterpret_cast(pv) = value;
+ /* sanity check */
+ void * pvx = vmm_memory()->lookup(GCPhys, sizeof(value));
+ Assert(!pvx);
+
+ *reinterpret_cast(pv) = value;
+}
+
+
+void PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t value)
+{
+ PGMR3PhysWrite(pVM, GCPhys, value);
}
void PGMR3PhysWriteU16(PVM pVM, RTGCPHYS GCPhys, uint16_t value)
{
- VM_ASSERT_EMT(pVM);
-
- void *pv = guest_memory()->lookup(GCPhys, sizeof(value));
-
- if (verbose_debug)
- PDBG("%s: GCPhys=0x%llx cb=0x%zx pv=%p",
- __func__, (Genode::uint64_t)GCPhys, sizeof(value), pv);
-
- if (!pv) {
- PERR("%s: invalid write attempt phy=%llx", __func__,
- (Genode::uint64_t)GCPhys);
- return;
- }
- void * pvx = vmm_memory()->lookup(GCPhys, sizeof(value));
- Assert(!pvx);
-
- *reinterpret_cast(pv) = value;
+ PGMR3PhysWrite(pVM, GCPhys, value);
}
void PGMR3PhysWriteU32(PVM pVM, RTGCPHYS GCPhys, uint32_t value)
{
- void *pv = guest_memory()->lookup(GCPhys, sizeof(value));
-
- if (verbose_debug)
- PDBG("%s: GCPhys=0x%llx cb=0x%zx pv=%p",
- __func__, (Genode::uint64_t)GCPhys, sizeof(value), pv);
-
- if (!pv) {
- PERR("%s: invalid write attempt phy=%llx", __func__,
- (Genode::uint64_t)GCPhys);
- return;
- }
- void * pvx = vmm_memory()->lookup(GCPhys, sizeof(value));
- Assert(!pvx);
-
- *reinterpret_cast(pv) = value;
+ PGMR3PhysWrite(pVM, GCPhys, value);
}
-uint32_t PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys)
+template
+static T PGMR3PhysRead(PVM pVM, RTGCPHYS GCPhys)
{
- void *pv = guest_memory()->lookup(GCPhys, 4);
+ void *pv = guest_memory()->lookup(GCPhys, sizeof(T));
if (verbose_debug)
- PDBG("%s: GCPhys=0x%llx cb=0x%x pv=%p",
- __func__, (Genode::uint64_t)GCPhys, 4, pv);
+ PDBG("%s: GCPhys=0x%llx cb=0x%zx pv=%p",
+ __func__, (Genode::uint64_t)GCPhys, sizeof(T), pv);
if (!pv) {
PERR("%s: invalid read attempt phys=%llx", __func__,
@@ -599,10 +579,23 @@ uint32_t PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys)
return 0;
}
- void * pvx = vmm_memory()->lookup(GCPhys, 4);
+ /* sanity check */
+ void * pvx = vmm_memory()->lookup(GCPhys, sizeof(T));
Assert(!pvx);
- return *reinterpret_cast(pv);
+ return *reinterpret_cast(pv);
+}
+
+
+uint64_t PGMR3PhysReadU64(PVM pVM, RTGCPHYS GCPhys)
+{
+ return PGMR3PhysRead(pVM, GCPhys);
+}
+
+
+uint32_t PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys)
+{
+ return PGMR3PhysRead(pVM, GCPhys);
}
@@ -764,3 +757,11 @@ VMMDECL(bool) PGMIsLockOwner(PVM pVM)
{
return PDMCritSectIsOwner(&pVM->pgm.s.CritSectX);
}
+
+
+VMM_INT_DECL(void) PGMNotifyNxeChanged(PVMCPU pVCpu, bool fNxe)
+{
+ if (verbose)
+ PINF("%s - not implemented - %p", __func__,
+ __builtin_return_address(0));
+}
diff --git a/repos/ports/src/virtualbox/unimpl.cc b/repos/ports/src/virtualbox/unimpl.cc
index 86755d6ebc..cc72b199c2 100644
--- a/repos/ports/src/virtualbox/unimpl.cc
+++ b/repos/ports/src/virtualbox/unimpl.cc
@@ -40,7 +40,6 @@ DUMMY(DBGFR3StackWalkNext)
DUMMY(DBGFR3StackWalkEnd)
DUMMY(HMInvalidatePage)
-DUMMY(HMFlushTLB)
DUMMY(HMR3EmulateIoBlock)
DUMMY(HMR3PatchTprInstr)
DUMMY(HMR3CheckError)
@@ -64,7 +63,6 @@ DUMMY(PDMR3LdrGetInterfaceSymbols)
DUMMY(PDMR3LdrQueryRCModFromPC)
DUMMY(PDMCritSectBothFF)
-DUMMY(PGMNotifyNxeChanged)
DUMMY(PGMPhysGCPtr2GCPhys)
DUMMY(PGMPhysSimpleReadGCPhys)
DUMMY(PGMPhysSimpleReadGCPtr)
@@ -91,7 +89,6 @@ DUMMY(PGMR3PhysGCPhys2CCPtrExternal)
DUMMY(PGMR3PhysGCPhys2CCPtrReadOnlyExternal)
DUMMY(PGMR3PhysMMIO2MapKernel)
DUMMY(PGMR3PhysReadU16)
-DUMMY(PGMR3PhysReadU64)
DUMMY(PGMR3PhysRomProtect)
DUMMY(PGMPrefetchPage)