From 417199ea6412c406e137f0841b549d35a83ae1ea Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Wed, 14 Jan 2015 17:31:34 +0100 Subject: [PATCH] vbox: enable support for Windows 8 Fixes #1413 --- repos/ports/run/test.vbox | 2 +- repos/ports/src/virtualbox/hm.cc | 69 +++++++++--------- repos/ports/src/virtualbox/libc.cc | 1 + repos/ports/src/virtualbox/nova/vcpu.h | 5 ++ repos/ports/src/virtualbox/nova/vcpu_svm.h | 2 +- repos/ports/src/virtualbox/nova/vcpu_vmx.h | 2 + repos/ports/src/virtualbox/nova/vmx.h | 2 - repos/ports/src/virtualbox/pgm.cc | 85 +++++++++++----------- repos/ports/src/virtualbox/unimpl.cc | 3 - 9 files changed, 88 insertions(+), 83 deletions(-) diff --git a/repos/ports/run/test.vbox b/repos/ports/run/test.vbox index 73d0fff2c..51a1c70aa 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 4b7215a11..34248d536 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 0d1019ff4..13e34d148 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 2fd8b4ecf..a08c9b98e 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 1a14d0b1c..29012b05e 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 a31c62d6b..6a07bab39 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 020c14acf..282654b1a 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 86755d6eb..cc72b199c 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)