/* * \brief VirtualBox hardware-acceleration manager * \author Norman Feske * \date 2013-08-20 */ /* * Copyright (C) 2013 Genode Labs GmbH * * This file is distributed under the terms of the GNU General Public License * version 2. */ /* Genode includes */ #include /* VirtualBox includes */ #include "HMInternal.h" /* enable access to hm.s.* */ #include #include /* Genode's VirtualBox includes */ #include "sup.h" 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 * HW accelerated mode is still dependent on the result of the * HMR3CanExecuteGuest function. */ pVM->fHMEnabled = true; for (VMCPUID i = 0; i < pVM->cCpus; i++) pVM->aCpus[i].hm.s.fActive = false; pVM->fHMEnabledFixed = true; return VINF_SUCCESS; } VMMR3_INT_DECL(int) HMR3Term(PVM pVM) { return VINF_SUCCESS; } VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat) { enabled_hm = pVM->hm.s.svm.fSupported || pVM->hm.s.vmx.fSupported; 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; } VMMDECL(bool) HMIsEnabledNotMacro(PVM pVM) { Assert(pVM->fHMEnabledFixed); return pVM->fHMEnabled; } VMMR3DECL(bool) HMR3IsVmxPreemptionTimerUsed(PVM pVM) { // PLOG("HMR3IsVmxPreemptionTimerUsed"); return false; } VMMR3DECL(bool) HMR3IsActive(PVMCPU pVCpu) { return pVCpu->hm.s.fActive; } VMM_INT_DECL(bool) HMIsLongModeAllowed(PVM pVM) { return HMIsEnabled(pVM) && pVM->hm.s.fAllow64BitGuests; } VMMR3DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx) { if (pVM->hm.s.vmx.fAllowUnrestricted) return false; return !CPUMIsGuestInPagedProtectedModeEx(pCtx); } VMMR3DECL(bool) HMR3IsEventPending(PVMCPU pVCpu) { // PLOG("HMR3IsEventPending false"); return false; } VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx) { if (!enabled_hm) return false; PVMCPU pVCpu = VMMGetCpu(pVM); 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); return pVCpu->hm.s.fActive; } VMM_INT_DECL(int) HMFlushTLB(PVMCPU pVCpu) { return VINF_SUCCESS; }